def test_approximate_line_2(self):
     p1 = (0, -1, 0)
     p2 = (1, 1, 0)
     p3 = (2, -1, 0)
     p4 = (3, 1, 0)
     line = linear_approximation([p1, p2, p3, p4]).most_similar_line()
     self.assert_sverchok_data_equal(tuple(line.direction), (0.7882054448127747, 0.6154122352600098, 0.0), precision=5)
Пример #2
0
 def init_guess(verts, npoints):
     approx = linear_approximation(verts)
     line = approx.most_similar_line()
     projections = line.projection_of_points(verts)
     m = projections.min(axis=0)
     M = projections.max(axis=0)
     return np.linspace(m, M, num=npoints)
 def test_approximate_plane(self):
     p1 = (0, -1, 0)
     p2 = (1, 1, 0)
     p3 = (2, -1, 0)
     p4 = (3, 1, 0)
     plane = linear_approximation([p1, p2, p3, p4]).most_similar_plane()
     self.assert_sverchok_data_equal(tuple(plane.normal.normalized()), (0, 0, 1), precision=5)
Пример #4
0
def single_face_delaunay(face_verts,
                         add_verts,
                         epsilon=1e-6,
                         exclude_boundary=True):
    n = len(face_verts)
    face = list(range(n))
    edges = [(i, i + 1) for i in range(n - 1)] + [(n - 1, 0)]
    plane = linear_approximation(face_verts).most_similar_plane()
    face_verts_2d = [plane.point_uv_projection(v) for v in face_verts]
    if exclude_boundary:
        add_verts = [
            v for v in add_verts
            if not is_on_face_edge(v, face_verts, epsilon)
        ]
    add_verts_2d = [plane.point_uv_projection(v) for v in add_verts]
    TRIANGLES = 1
    res = delaunay_2d_cdt(face_verts_2d + add_verts_2d, edges, [face],
                          TRIANGLES, epsilon)
    new_verts_2d = res[0]
    new_edges = res[1]
    new_faces = res[2]
    new_add_verts = [
        tuple(plane.evaluate(p[0], p[1], normalize=True))
        for p in new_verts_2d[n:]
    ]
    return face_verts + new_add_verts, new_edges, new_faces
 def test_approximate_line_1(self):
     p1 = (0, 0, 0)
     p2 = (1, 0, 0)
     p3 = (2, 0, 0)
     p4 = (3, 0, 0)
     line = linear_approximation([p1, p2, p3, p4]).most_similar_line()
     self.assert_sverchok_data_equal(tuple(line.direction.normalized()), (1, 0, 0), precision=5)
Пример #6
0
    def process(self):
        if not any(output.is_linked for output in self.outputs):
            return

        vertices_s = self.inputs['Vertices'].sv_get(default=[[]])

        out_centers = []
        out_normals = []
        out_directions = []
        out_projections = []
        out_diffs = []
        out_distances = []

        for vertices in vertices_s:
            approx = linear_approximation(vertices)

            out_centers.append(approx.center)

            if self.mode == 'Line':
                line = approx.most_similar_line()
                out_directions.append(tuple(line.direction.normalized()))

                projections = []
                diffs = []
                distances = []
                for vertex in vertices:
                    projection = line.projection_of_point(vertex)
                    projections.append(tuple(projection))
                    diff = projection - Vector(vertex)
                    diffs.append(tuple(diff))
                    distances.append(diff.length)

                out_projections.append(projections)
                out_diffs.append(diffs)
                out_distances.append(distances)

            elif self.mode == 'Plane':
                plane = approx.most_similar_plane()
                out_normals.append(tuple(plane.normal.normalized()))

                projections = []
                diffs = []
                distances = list(
                    map(float, list(plane.distance_to_points(vertices))))
                projections_np = plane.projection_of_points(vertices)
                vertices_np = np.array(vertices)
                projections = list(map(tuple, list(projections_np)))
                diffs_np = projections_np - vertices_np
                diffs = list(map(tuple, list(diffs_np)))

                out_projections.append(projections)
                out_diffs.append(diffs)
                out_distances.append(distances)

        self.outputs['Center'].sv_set([out_centers])
        self.outputs['Normal'].sv_set([out_normals])
        self.outputs['Direction'].sv_set([out_directions])
        self.outputs['Projections'].sv_set(out_projections)
        self.outputs['Diffs'].sv_set(out_diffs)
        self.outputs['Distances'].sv_set(out_distances)
Пример #7
0
    def process(self):
        if not any(output.is_linked for output in self.outputs):
            return

        vertices_s = self.inputs['Vertices'].sv_get(default=[[]])

        out_centers = []
        out_normals = []
        out_directions = []
        out_projections = []
        out_diffs = []
        out_distances = []

        for vertices in vertices_s:
            approx = linear_approximation(vertices)

            out_centers.append(approx.center)

            if self.mode == 'Line':
                line = approx.most_similar_line()
                out_directions.append(tuple(line.direction.normalized()))

                projections = []
                diffs = []
                distances = []
                for vertex in vertices:
                    projection = line.projection_of_point(vertex)
                    projections.append(tuple(projection))
                    diff = projection - Vector(vertex)
                    diffs.append(tuple(diff))
                    distances.append(diff.length)

                out_projections.append(projections)
                out_diffs.append(diffs)
                out_distances.append(distances)

            elif self.mode == 'Plane':
                plane = approx.most_similar_plane()
                out_normals.append(tuple(plane.normal.normalized()))

                projections = []
                diffs = []
                distances = list(map(float, list(plane.distance_to_points(vertices))))
                projections_np = plane.projection_of_points(vertices)
                vertices_np = np.array(vertices)
                projections = list(map(tuple, list(projections_np)))
                diffs_np = projections_np - vertices_np
                diffs = list(map(tuple, list(diffs_np)))

                out_projections.append(projections)
                out_diffs.append(diffs)
                out_distances.append(distances)

        self.outputs['Center'].sv_set([out_centers])
        self.outputs['Normal'].sv_set([out_normals])
        self.outputs['Direction'].sv_set([out_directions])
        self.outputs['Projections'].sv_set(out_projections)
        self.outputs['Diffs'].sv_set(out_diffs)
        self.outputs['Distances'].sv_set(out_distances)
Пример #8
0
 def test_approximate_plane(self):
     p1 = (0, -1, 0)
     p2 = (1, 1, 0)
     p3 = (2, -1, 0)
     p4 = (3, 1, 0)
     plane = linear_approximation([p1, p2, p3, p4]).most_similar_plane()
     self.assert_sverchok_data_equal(tuple(plane.normal.normalized()),
                                     (0, 0, 1),
                                     precision=5)
Пример #9
0
 def test_approximate_line_2(self):
     p1 = (0, -1, 0)
     p2 = (1, 1, 0)
     p3 = (2, -1, 0)
     p4 = (3, 1, 0)
     line = linear_approximation([p1, p2, p3, p4]).most_similar_line()
     self.assert_sverchok_data_equal(tuple(
         line.direction), (0.7882054448127747, 0.6154122352600098, 0.0),
                                     precision=5)
Пример #10
0
 def test_approximate_line_1(self):
     p1 = (0, 0, 0)
     p2 = (1, 0, 0)
     p3 = (2, 0, 0)
     p4 = (3, 0, 0)
     line = linear_approximation([p1, p2, p3, p4]).most_similar_line()
     self.assert_sverchok_data_equal(tuple(line.direction.normalized()),
                                     (1, 0, 0),
                                     precision=5)
Пример #11
0
def nurbs_curve_matrix(curve):
    cpts = curve.get_control_points()

    approx = linear_approximation(cpts)
    plane = approx.most_similar_plane()
    normal = plane.normal

    xx = cpts[-1] - cpts[0]
    xx /= np.linalg.norm(xx)

    yy = np.cross(normal, xx)

    matrix = np.stack((xx, yy, normal)).T
    return matrix
Пример #12
0
def nurbs_curve_to_xoy(curve, target_normal=None):
    cpts = curve.get_control_points()

    approx = linear_approximation(cpts)
    plane = approx.most_similar_plane()
    normal = plane.normal

    if target_normal is not None:
        a = np.dot(normal, target_normal)
        if a > 0:
            normal = -normal

    xx = cpts[-1] - cpts[0]
    xx /= np.linalg.norm(xx)

    yy = np.cross(normal, xx)

    matrix = np.stack((xx, yy, normal)).T
    matrix = np.linalg.inv(matrix)
    center = approx.center
    new_cpts = np.array([matrix @ (cpt - center) for cpt in cpts])
    return curve.copy(control_points=new_cpts)
Пример #13
0
    def do_iteration(bvh, bm):
        verts_out = []
        face_centers = np.array([face.calc_center_median() for face in bm.faces])
        for bm_vert in bm.verts:
            co = bm_vert.co
            if (skip_boundary and bm_vert.is_boundary) or (mask is not None and not mask[bm_vert.index]):
                new_vert = tuple(co)
            else:    
                normal = bm_vert.normal
                cs = np.array([face_centers[face.index] for face in bm_vert.link_faces])
                
                if method == NONE:
                    new_vert = cs.mean(axis=0)
                elif method == NORMAL:
                    median = mathutils.Vector(cs.mean(axis=0))
                    dv = median - co
                    dv = dv - dv.project(normal)
                    new_vert = co + dv
                elif method == LINEAR:
                    approx = linear_approximation(cs)
                    median = mathutils.Vector(approx.center)
                    plane = approx.most_similar_plane()
                    dist = plane.distance_to_point(bm_vert.co)
                    new_vert = median + plane.normal.normalized() * dist
                elif method == BVH:
                    median = mathutils.Vector(cs.mean(axis=0))
                    new_vert, normal, idx, dist = bvh.find_nearest(median)
                else:
                    raise Exception("Unsupported volume preservation method")
                
                new_vert = tuple(new_vert)
                new_vert = mask_axes(tuple(co), new_vert, use_axes)
                
            verts_out.append(new_vert)

        return verts_out
Пример #14
0
    def process(self):
        verts = self.inputs['Vertices'].sv_get()

        if self.inputs['PolyEdge'].is_linked:
            poly_edge = self.inputs['PolyEdge'].sv_get()
            poly_in = True
        else:
            poly_in = False
            poly_edge = repeat_last([[]])

        verts_out = []
        poly_edge_out = []
        item_order = []

        poly_output = poly_in and self.outputs['PolyEdge'].is_linked
        order_output = self.outputs['Item order'].is_linked
        vert_output = self.outputs['Vertices'].is_linked

        if not any((vert_output, order_output, poly_output)):
            return

        if self.mode == 'XYZ':
            # should be user settable
            op_order = [(0, self.reverse_x), (1, self.reverse_y),
                        (2, self.reverse_z)]

            for v, p in zip(verts, poly_edge):
                s_v = ((e[0], e[1], e[2], i) for i, e in enumerate(v))

                for item_index, rev in op_order:
                    s_v = sorted(s_v, key=itemgetter(item_index), reverse=rev)

                verts_out.append([v[:3] for v in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        elif self.mode == 'AXYZ':

            for v, p in zip(verts, poly_edge):
                matrix = linear_approximation(
                    v).most_similar_plane().get_matrix().inverted()

                s_v = ((e[0], e[1], e[2], i) for i, e in enumerate(v))

                def key(item):
                    x, y, z = matrix @ Vector(item[:3])
                    if self.reverse_x:
                        x = -x
                    if self.reverse_y:
                        y = -y
                    if self.reverse_z:
                        z = -z
                    return x, y, z


#                 def by_axis(i):
#                     def key(item):
#                         v = matrix @ Vector(item[:3])
#                         return v[i]
#                     return key

                s_v = sorted(s_v, key=key)
                #                 for i in [2,1,0]:
                #                     s_v = sorted(s_v, key=by_axis(i))
                verts_out.append([v[:3] for v in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        elif self.mode == 'ADIR':
            for v, p in zip(verts, poly_edge):
                direction = linear_approximation(
                    v).most_similar_line().direction

                s_v = ((e[0], e[1], e[2], i) for i, e in enumerate(v))

                def key(item):
                    return Vector(item[:3]).dot(direction)

                s_v = sorted(s_v, key=key)
                if self.reverse:
                    s_v = reversed(s_v)

                verts_out.append([v[:3] for v in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        elif self.mode == 'ACYL':

            for v, p in zip(verts, poly_edge):
                data = linear_approximation(v)
                matrix = data.most_similar_plane().get_matrix().inverted()
                center = Vector(data.center)

                s_v = ((e[0], e[1], e[2], i) for i, e in enumerate(v))

                def key(item):
                    v = matrix @ (Vector(item[:3]) - center)
                    rho, phi, z = to_cylindrical(v)
                    return (phi, z, rho)

                s_v = sorted(s_v, key=key)
                if self.reverse:
                    s_v = reversed(s_v)

                verts_out.append([v[:3] for v in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        if self.mode == 'DIST':
            base_points = self.inputs['Base Point'].sv_get()
            bp_iter = repeat_last(base_points[0])

            for v, p, v_base in zip(verts, poly_edge, bp_iter):
                s_v = sorted(((v_c, i) for i, v_c in enumerate(v)),
                             key=lambda v: distK(v[0], v_base))
                verts_out.append([vert[0] for vert in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        if self.mode == 'AXIS':
            if self.inputs['Mat'].is_linked:
                mat = Matrix_generate(self.inputs['Mat'].sv_get())
            else:
                mat = [Matrix.Identity(4)]
            mat_iter = repeat_last(mat)

            def f(axis, q):
                if axis.dot(q.axis) > 0:
                    return q.angle
                else:
                    return -q.angle

            for v, p, m in zip(Vector_generate(verts), poly_edge, mat_iter):
                axis = m @ Vector((0, 0, 1))
                axis_norm = m @ Vector((1, 0, 0))
                base_point = m @ Vector((0, 0, 0))
                intersect_d = [
                    intersect_point_line(v_c, base_point, axis) for v_c in v
                ]
                rotate_d = [
                    f(axis, (axis_norm + v_l[0]).rotation_difference(v_c))
                    for v_c, v_l in zip(v, intersect_d)
                ]
                s_v = ((data[0][1], data[1], i)
                       for i, data in enumerate(zip(intersect_d, rotate_d)))
                s_v = sorted(s_v, key=itemgetter(0, 1))

                verts_out.append([v[i[-1]].to_tuple() for i in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append(
                        [list(map(lambda n: v_index[n], pe)) for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        if self.mode == 'USER':
            if self.inputs['Index Data'].is_linked:
                index = self.inputs['Index Data'].sv_get()
            else:
                return

            for v, p, i in zip(verts, poly_edge, index):

                s_v = sorted([(data[0], data[1], i)
                              for i, data in enumerate(zip(i, v))],
                             key=itemgetter(0))

                verts_out.append([obj[1] for obj in s_v])

                if poly_output:
                    v_index = {item[-1]: j for j, item in enumerate(s_v)}
                    poly_edge_out.append([[v_index[k] for k in pe]
                                          for pe in p])
                if order_output:
                    item_order.append([i[-1] for i in s_v])

        if self.mode == 'CONNEX':
            if self.inputs['PolyEdge'].is_linked:
                edges = self.inputs['PolyEdge'].sv_get()
                for v, p in zip(verts, edges):
                    pols = []
                    if len(p[0]) > 2:
                        pols = [p[:]]
                        p = polygons_to_edges([p], True)[0]

                    vect_new, pol_edge_new, index_new = sort_vertices_by_connexions(
                        v, p, self.limit_mode)
                    if len(pols) > 0:
                        new_pols = []
                        for pol in pols[0]:
                            new_pol = []
                            for i in pol:
                                new_pol.append(index_new.index(i))
                            new_pols.append(new_pol)
                        pol_edge_new = [new_pols]

                    verts_out.append(vect_new)
                    poly_edge_out.append(pol_edge_new)
                    item_order.append(index_new)

        if vert_output:
            self.outputs['Vertices'].sv_set(verts_out)
        if poly_output:
            self.outputs['PolyEdge'].sv_set(poly_edge_out)
        if order_output:
            self.outputs['Item order'].sv_set(item_order)
Пример #15
0
 def calc_value(points):
     approx = linear_approximation(points)
     line = approx.most_similar_line()
     line_direction = np.array(line.direction)
     return abs(direction.dot(line_direction))