Ejemplo n.º 1
0
 def process(self):
     if not self.outputs[0].is_linked:
         return
     X_ = self.inputs['pols'].sv_get()
     X = dataCorrect(X_)
     result = polygons_to_edges(X, self.unique_edges)
     self.outputs['edgs'].sv_set(result)
Ejemplo n.º 2
0
def polygons_to_edges_np(obj, unique_edges=False, output_numpy=False):
    result = []

    for pols in obj:
        regular_mesh = True
        try:
            np_pols = array(pols, dtype=int32)
        except ValueError:
            regular_mesh = False

        if not regular_mesh:
            if output_numpy:
                result.append(concatenate([pol_to_edges(p) for p in pols]))
            else:
                result.append(polygons_to_edges([pols], unique_edges)[0])
        else:

            edges = empty(list(np_pols.shape) + [2], 'i')
            edges[:, :, 0] = np_pols
            edges[:, 1:, 1] = np_pols[:, :-1]
            edges[:, 0, 1] = np_pols[:, -1]

            edges = edges.reshape(-1, 2)
            if output_numpy:
                if unique_edges:
                    result.append(unique(sort(edges), axis=0))
                else:
                    result.append(edges)
            else:
                if unique_edges:
                    result.append(unique(sort(edges), axis=0).tolist())
                else:
                    result.append(edges.tolist())
    return result
Ejemplo n.º 3
0
def get_delaunay_triangulation(verts_in):
    pt_list = [Site(pt[0], pt[1]) for pt in verts_in]
    res = computeDelaunayTriangulation(pt_list)
    polys_in = [tri for tri in res if -1 not in tri]
    #all faces hase normals -Z, should be reversed
    polys_in = [pol[::-1] for pol in polys_in]
    edges_in = polygons_to_edges([polys_in], unique_edges=True)[0]
    return edges_in, polys_in
Ejemplo n.º 4
0
    def process(self):
        if not self.outputs[0].is_linked:
            return

        polygons_ = self.inputs['pols'].sv_get(deepcopy=False)
        polygons = dataCorrect_np(polygons_)

        if self.output_numpy or isinstance(polygons[0], ndarray) or self.regular_pols:
            result = polygons_to_edges_np(polygons, self.unique_edges, self.output_numpy)
        else:
            result = polygons_to_edges(polygons, self.unique_edges)

        self.outputs['edgs'].sv_set(result)
Ejemplo n.º 5
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

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

            verts_out = []
            edges_out = []
            faces_out = []
            for sites, clipping in zip_long_repeat(vertices_s, clipping_s):
                if isinstance(clipping, (list, tuple)):
                    clipping = clipping[0]

                diagram = Voronoi(sites)
                if self.do_clip:
                    bounds = self.calc_bounds(sites, clipping)

                if self.out_mode == 'RIDGES':
                    new_verts = diagram.vertices.tolist()
                    new_faces = [e for e in diagram.ridge_vertices if not -1 in e]
                    new_edges = polygons_to_edges([new_faces], True)[0]
                    if self.join:
                        if self.do_clip:
                            new_verts, new_edges, new_faces = self.clip_mesh(bounds, new_verts, new_edges, new_faces, fill=False)
                        verts_out.append(new_verts)
                        edges_out.append(new_edges)
                        faces_out.append(new_faces)
                    else:
                        new_verts, new_edges, new_faces = self.split_ridges(new_verts, new_edges, new_faces)
                        if self.do_clip:
                            new_verts, new_edges, new_faces = self.clip_mesh(bounds, new_verts, new_edges, new_faces, fill=False, iterate=True)
                        verts_out.extend(new_verts)
                        edges_out.extend(new_edges)
                        faces_out.extend(new_faces)
                else: # REGIONS
                    new_verts, new_edges, new_faces = self.make_regions(diagram)
                    if self.join:
                        new_verts, new_edges, new_faces = mesh_join(new_verts, new_edges, new_faces)
                        new_verts = [new_verts]
                        new_edges = [new_edges]
                        new_faces = [new_faces]
                    if self.do_clip:
                        new_verts, new_edges, new_faces = self.clip_mesh(bounds, new_verts, new_edges, new_faces, fill=True)
                    verts_out.extend(new_verts)
                    edges_out.extend(new_edges)
                    faces_out.extend(new_faces)

            self.outputs['Vertices'].sv_set(verts_out)
            self.outputs['Edges'].sv_set(edges_out)
            self.outputs['Faces'].sv_set(faces_out)
Ejemplo n.º 6
0
    def process(self):
        if not self.inputs['Vertices'].is_linked:
            return

        vertices_s = self.inputs['Vertices'].sv_get(deepcopy=False)
        edges_s = self.inputs['Edges'].sv_get(default=[[]], deepcopy=False)
        faces_s = self.inputs['Faces'].sv_get(default=[[]], deepcopy=False)

        verts1_out = []
        verts2_out = []
        verts_out = []
        edges_out = []
        for vertices, edges, faces in zip_long_repeat(vertices_s, edges_s,
                                                      faces_s):
            new_verts1 = []
            new_verts2 = []
            if not edges:
                edges = polygons_to_edges([faces], unique_edges=True)[0]
            obj_verts = []
            obj_edges = []
            for i1, i2 in edges:
                new_verts = []
                new_edges = []
                if self.sort:
                    if i1 > i2:
                        i1, i2 = i2, i1
                v1, v2 = vertices[i1], vertices[i2]
                new_verts1.append(v1)
                new_verts2.append(v2)
                new_verts.append(v1)
                new_verts.append(v2)
                new_edges.append([0, 1])
                obj_verts.append(new_verts)
                obj_edges.append(new_edges)
            if self.separate:
                verts_out.append(obj_verts)
                edges_out.append(obj_edges)
            else:
                verts_out.extend(obj_verts)
                edges_out.extend(obj_edges)

            verts1_out.append(new_verts1)
            verts2_out.append(new_verts2)

        self.outputs['Vertex1'].sv_set(verts1_out)
        self.outputs['Vertex2'].sv_set(verts2_out)
        self.outputs['Vertices'].sv_set(verts_out)
        self.outputs['Edges'].sv_set(edges_out)
Ejemplo n.º 7
0
    def process(self):
        if not any(s.is_linked for s in self.outputs):
            return

        verts_out, edges_out, polys_out = [], [], []

        params = self.get_data()
        get_edges = self.outputs['Edges'].is_linked

        for p in zip(*params):
            p = match_long_repeat(p)
            for p2 in zip(*p):
                size, vTrunc, eTrunc = p2

                verts, faces = createSolid(self.source, vTrunc, eTrunc,
                                           self.dual, self.snub)

                # resize to normal size, or if keepSize, make sure all verts are of length 'size'
                if self.keepSize:
                    rad = size / verts[-1 if self.dual else 0].length
                else:
                    rad = size
                verts = [list(i * rad) for i in verts]

                verts_out.append(verts)
                polys_out.append(faces)
                if get_edges:
                    edges_out.append(
                        polygons_to_edges([faces], unique_edges=True)[0])

        if self.outputs['Vertices'].is_linked:
            self.outputs['Vertices'].sv_set(verts_out)
        if get_edges:
            self.outputs['Edges'].sv_set(edges_out)
        if self.outputs['Polygons'].is_linked:
            self.outputs['Polygons'].sv_set(polys_out)
def order(verts, edges, verts_o, k):
    for i in edges:
        if k in i:
            # this is awesome !!
            k = i[int(not i.index(k))]
            verts_o.append(verts[k])
            return k, i
    return False, False


if verts_A and verts_B and edges_A and edges_B:

    # pols2edges
    if len(edges_A[0][0]) > 2:
        edges_A = polygons_to_edges(edges_A, unique_edges=True)
    if len(edges_B[0][0]) > 2:
        edges_B = polygons_to_edges(edges_B, unique_edges=True)

    # ordering sort edges chain
    def ordering(in_verts, in_edges):
        ed = 1
        vout = []
        for edges, verts in zip(in_edges, in_verts):
            verts_o = []
            k = 0
            while True:
                k, ed = order(verts, edges, verts_o, k)
                if ed:
                    edges.remove(ed)
                if not ed:
Ejemplo n.º 9
0
def pols_edges(obj, unique_edges=False):
    return polygons_to_edges(obj, unique_edges)
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
def edges_relax(vertices, edges, faces, iterations, k, mask=None, method=NONE, target=AVERAGE, skip_boundary=True, use_axes={0,1,2}):
    """
    supported shape preservation methods: NONE, NORMAL, BVH
    """

    def do_iteration(bvh, bm, verts):
        verts = np.asarray(verts)
        v1s = verts[edges[:,0]]
        v2s = verts[edges[:,1]]
        edge_vecs = v2s - v1s
        edge_lens = np.linalg.norm(edge_vecs, axis=1)

        if target == MINIMUM:
            target_len = np.min(edge_lens)
        elif target == MAXIMUM:
            target_len = np.max(edge_lens)
        elif target == AVERAGE:
            target_len = np.mean(edge_lens)
        else:
            raise Exception("Unsupported target edge length type")

        forces = defaultdict(lambda: np.zeros((3,)))
        counts = defaultdict(int)
        for edge_idx, (v1_idx, v2_idx) in enumerate(edges):
            edge_vec = edge_vecs[edge_idx]
            edge_len = edge_lens[edge_idx]
            d_len = (edge_len - target_len)/2.0
            dv1 =   d_len * edge_vec
            dv2 = - d_len * edge_vec
            forces[v1_idx] += dv1
            forces[v2_idx] += dv2
            counts[v1_idx] += 1
            counts[v2_idx] += 1
        
        target_verts = verts.copy()
        for v_idx in range(len(verts)):
            if skip_boundary and bm.verts[v_idx].is_boundary:
                continue
            if mask is not None and not mask[v_idx]:
                continue
            count = counts[v_idx]
            if count:
                forces[v_idx] /= count
            target_verts[v_idx] += k*forces[v_idx]

        if method == NONE:
            verts_out = target_verts.tolist()
        elif method == NORMAL:
            verts_out = []
            for bm_vert in bm.verts:
                normal = bm_vert.normal
                dv = mathutils.Vector(target_verts[bm_vert.index]) - bm_vert.co
                dv = dv - dv.project(normal)
                new_vert = tuple(bm_vert.co + dv)
                verts_out.append(new_vert)
        elif method == BVH:
            verts_out = []
            for vert in target_verts:
                new_vert, normal, idx, dist = bvh.find_nearest(vert)
                verts_out.append(tuple(new_vert))
        else:
            raise Exception("Unsupported shape preservation method")
        
        return map_mask_axes(verts, verts_out, use_axes)

    if not edges or not edges[0]:
        edges = polygons_to_edges([faces], unique_edges=True)[0]
    edges = np.array(edges)
    if mask is not None:
        mask = repeat_last_for_length(mask, len(vertices))
    bvh = BVHTree.FromPolygons(vertices, faces)
    for i in range(iterations):
        bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True)
        vertices = do_iteration(bvh, bm, vertices)
        bm.free()

    return vertices
Ejemplo n.º 12
0
    def make_bevel(self, curve, bevel_verts, bevel_edges, bevel_faces, taper, twist, steps):
        spline = self.build_spline(curve, self.bevel_mode, self.is_cyclic)

        t_values = np.linspace(0.0, 1.0, num = steps)
        if self.is_cyclic:
            t_values = t_values[:-1]
        if self.flip_curve:
            t_for_curve = 1.0 - t_values
        else:
            t_for_curve = t_values
        if self.flip_taper:
            t_for_taper = 1.0 - t_values
        else:
            t_for_taper = t_values
        if self.flip_twist:
            t_for_twist = 1.0 - t_values
        else:
            t_for_twist = t_values

        spline_vertices = [Vector(v) for v in spline.eval(t_for_curve).tolist()]
        spline_tangents = [Vector(v) for v in spline.tangent(t_for_curve, h=self.tangent_precision).tolist()]
        taper_values = [self.get_taper_scale(v) for v in taper.eval(t_for_taper).tolist()]
        twist_values = [self.get_twist_value(v) for v in twist.eval(t_for_twist).tolist()]

        if bevel_faces:
            bevel_faces = ensure_nesting_level(bevel_faces, 2)
        if not bevel_edges and bevel_faces:
            bevel_edges = polygons_to_edges([bevel_faces], True)[0]

        mesh = bmesh.new()
        prev_level_vertices = None
        first_level_vertices = None
        for spline_vertex, spline_tangent, taper_value, twist_value in zip(spline_vertices, spline_tangents, taper_values, twist_values):
            # Scaling and rotation matrix
            scale_x, scale_y = taper_value
            matrix = self.get_matrix(spline_tangent, twist_value, scale_x, scale_y)
            level_vertices = []
            for bevel_vertex in bevel_verts:
                new_vertex = matrix @ Vector(bevel_vertex) + spline_vertex
                level_vertices.append(mesh.verts.new(new_vertex))
            if prev_level_vertices is not None:
                for i,j in bevel_edges:
                    v1 = prev_level_vertices[i]
                    v2 = level_vertices[i]
                    v3 = level_vertices[j]
                    v4 = prev_level_vertices[j]
                    mesh.faces.new([v4, v3, v2, v1])

            if first_level_vertices is None:
                first_level_vertices = level_vertices
            prev_level_vertices = level_vertices

        if not self.is_cyclic:
            if self.cap_start:
                if not bevel_faces:
                    mesh.faces.new(list(reversed(first_level_vertices)))
                else:
                    for face in bevel_faces:
                        cap = [first_level_vertices[i] for i in reversed(face)]
                        mesh.faces.new(cap)
            if self.cap_end and prev_level_vertices is not None:
                if not bevel_faces:
                    mesh.faces.new(prev_level_vertices)
                else:
                    for face in bevel_faces:
                        cap = [prev_level_vertices[i] for i in face]
                        mesh.faces.new(cap)
        else:
            for i,j in bevel_edges:
                v1 = first_level_vertices[i]
                v2 = prev_level_vertices[i]
                v3 = prev_level_vertices[j]
                v4 = first_level_vertices[j]
                mesh.faces.new([v1, v2, v3, v4])

        mesh.verts.index_update()
        mesh.verts.ensure_lookup_table()
        mesh.faces.index_update()
        mesh.edges.index_update()

        return mesh
Ejemplo n.º 13
0
def faces_relax(vertices, edges, faces, iterations, k, mask=None, method=NONE, target=AVERAGE, skip_boundary=True, use_axes={0,1,2}):
    """
    supported shape preservation methods: NONE, NORMAL, BVH
    """

    def do_iteration(bvh, bm):
        areas = np.array([face.calc_area() for face in bm.faces])
        vert_cos = np.array([tuple(vert.co) for vert in bm.verts])
        if target == MINIMUM:
            target_area = areas.min()
        elif target == MAXIMUM:
            target_area = areas.max()
        elif target == AVERAGE:
            target_area = areas.mean()
        else:
            raise Exception("Unsupported target face area type")

        forces = defaultdict(lambda: np.zeros((3,)))
        counts = defaultdict(int)
        for bm_face in bm.faces:
            face_vert_idxs = [vert.index for vert in bm_face.verts]
            face_verts = vert_cos[face_vert_idxs]
            mean = face_verts.mean(axis=0)
            face_verts_0 = face_verts - mean
            src_area = areas[bm_face.index]
            scale = sqrt(target_area / src_area)
            dvs = (scale - 1) * face_verts_0
            for vert_idx, dv in zip(face_vert_idxs, dvs):
                forces[vert_idx] += dv
                counts[vert_idx] += 1
        
        target_verts = vert_cos.copy()
        for bm_vert in bm.verts:
            idx = bm_vert.index
            if skip_boundary and bm_vert.is_boundary:
                continue
            if mask is not None and not mask[idx]:
                continue
            count = counts[idx]
            if count:
                forces[idx] /= count
            force = forces[idx]
            target_verts[idx] += k*force

        if method == NONE:
            verts_out = target_verts.tolist()
        elif method == NORMAL:
            verts_out = []
            for bm_vert in bm.verts:
                idx = bm_vert.index
                dv = mathutils.Vector(target_verts[idx]) - bm_vert.co
                normal = bm_vert.normal
                dv = dv - dv.project(normal)
                new_vert = tuple(bm_vert.co + dv)
                verts_out.append(new_vert)

        elif method == BVH:
            verts_out = []
            for bm_vert in bm.verts:
                new_vert, normal, idx, dist = bvh.find_nearest(bm_vert.co)
                verts_out.append(tuple(new_vert))

        else:
            raise Exception("Unsupported shape preservation method")

        return map_mask_axes(vert_cos, verts_out, use_axes)

    if mask is not None:
        mask = repeat_last_for_length(mask, len(vertices))
    if not edges or not edges[0]:
        edges = polygons_to_edges([faces], unique_edges=True)[0]

    bvh = BVHTree.FromPolygons(vertices, faces)
    for i in range(iterations):
        bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True)
        vertices = do_iteration(bvh, bm)
        bm.free()

    return vertices
Ejemplo n.º 14
0
    def process(self):

        if 'vecLine' in self.inputs and \
                'vecPlane' in self.inputs and \
                'edgPlane' in self.inputs:
            print(self.name, 'is starting')
            if self.inputs['vecLine'].links and \
                    self.inputs['vecPlane'].links and \
                    self.inputs['edgPlane'].links:
                if self.bindCircle:
                    circle = [ (Vector((sin(radians(i)),cos(radians(i)),0))*self.circle_rad)/4 \
                              for i in range(0,360,30) ]
                vec = self.inputs['vecLine'].sv_get()
                vecplan = self.inputs['vecPlane'].sv_get()
                edgplan = self.inputs['edgPlane'].sv_get()
                if len(edgplan[0][0]) > 2:
                    edgplan = polygons_to_edges(edgplan)
                thick = self.inputs['thick'].sv_get()[0][0]
                threshold_coplanar = 0.005
                sinuso60 = 0.8660254037844386
                sinuso60_minus = 0.133974596
                sinuso30 = 0.5
                sinuso45 = 0.7071067811865475
                thick_2 = thick/2
                thick_3 = thick/3
                thick_6 = thick/6
                threshold = self.threshold
                if 'vecContr' in self.inputs and self.inputs['vecContr'].links:
                    vecont = self.inputs['vecContr'].sv_get()
                    #edgcont = self.inputs['edgContr'].sv_get()
                    vec_cont = Vector_generate(vecont)
                    loc_cont = [ [ i[0] ] for i in vec_cont ]
                    norm_cont = [ [ NM(i[0],i[len(i)//2], i[-1]) ] for i in vec_cont ] # довести до ума
                else:
                    vec_cont = []
                if 'vecTube' in self.inputs and self.inputs['vecTube'].links:
                    vectube = self.inputs['vecTube'].sv_get()
                    vec_tube = Vector_generate(vectube)
                    tube_radius = self.inputs['radTube'].sv_get()[0][0]
                    circle_tube = [ (Vector((sin(radians(i)),cos(radians(i)),0))*tube_radius) \
                              for i in range(0,360,15) ]
                else:
                    vec_tube = []
                outeup = []
                outelo = []
                vupper = []
                vlower = []
                centers = []
                vec_ = Vector_generate(vec)
                vecplan_ = Vector_generate(vecplan)
                for centersver, vecp, edgp in zip(vecplan,vecplan_,edgplan):
                    tubes_flag_bed_solution_i_know = False
                    newinds1 = [list(e) for e in edgp]
                    newinds2 = newinds1.copy()
                    vupperob = vecp.copy()
                    vlowerob = vecp.copy()
                    deledges1 = []
                    deledges2 = []
                    # to define bounds
                    x = [i[0] for i in vecp]
                    y = [i[1] for i in vecp]
                    z = [i[2] for i in vecp]
                    m1x,m2x,m1y,m2y,m1z,m2z = max(x), min(x), max(y), min(y), max(z), min(z)
                    l = Vector((sum(x)/len(x),sum(y)/len(y),sum(z)/len(z)))
                    n_select = [vecp[0],vecp[len(vecp)//2], vecp[-1]] # довести до ума
                    n_select.sort(key=lambda x: sum(x[:]), reverse=False)
                    n_ = NM(n_select[0],n_select[1],n_select[2])
                    n_.normalize()
                    # а виновта ли нормаль?
                    if n_[0] < 0:
                        n = n_ * -1
                    else:
                        n = n_
                    cen = [sum(i) for i in zip(*centersver)]
                    centers.append(Vector(cen)/len(centersver))
                    k = 0
                    lenvep = len(vecp)
                    # KDtree collections closest to join edges to sockets
                    tree = KDT.KDTree(lenvep)
                    for i,v in enumerate(vecp):
                        tree.insert(v,i)
                    tree.balance()
                    # vertical edges iterations
                    # every edge is object - two points, one edge
                    for v in vec_:
                        if not v: continue
                        # sort vertices by Z value
                        # find two vertices - one lower, two upper
                        vlist = [v[0],v[1]]
                        vlist.sort(key=lambda x: x[2], reverse=False)
                        # flip if coplanar to enemy plane
                        # flip plane coplanar
                        if vec_cont:
                            fliped = self.get_coplanar(v[0], loc_cont,norm_cont, vec_cont)
                        else:
                            fliped = False
                        shortedge = (vlist[1]-vlist[0]).length
                        if fliped:
                            two, one = vlist
                        else:
                            one, two = vlist
                        # coplanar to owner
                        cop = abs(D2P(one,l,n))
                        # defining bounds
                        inside = one[0]<m1x and one[0]>m2x and one[1]<m1y and one[1]>m2y \
                                 and one[2]<=m1z and one[2]>=m2z
                        # if in bounds and coplanar do:
                        #print(self.name,l, cop, inside)
                        if cop < threshold_coplanar and inside and shortedge > thick*threshold:
                            '''
                            huge calculations. if we can reduce...
                            '''
                            # find shift for thickness in sockets
                            diry = two - one
                            diry.normalize()
                            # solution for vertical wafel - cool but not in diagonal case
                            # angle = radians(degrees(atan(n.y/n.x))+90)
                            dirx_ = self.rotation_on_axis(diry, n, radians(90))
                            dirx = dirx_*thick_2
                            # вектор, индекс, расстояние
                            # запоминаем порядок находим какие удалить рёбра
                            # делаем выборку левая-правая точка
                            nearv_1, near_1 = tree.find(one)[:2]
                            nearv_2, near_2 = tree.find(two)[:2]
                            # indexes of two nearest points
                            # удалить рёбра что мешают спать заодно
                            try:
                                en_0, en_1, de1 = self.calc_indexes(edgp, near_1)
                                deledges1.extend(de1)
                                en_2, en_3, de2 = self.calc_indexes(edgp, near_2)
                                deledges2.extend(de2)
                            except:
                                print('Waffel Wrong crossection node')
                                break
                            # print(vecp, one, dirx, en_0, en_1)
                            # left-right indexes and vectors
                            # с учётом интерполяций по высоте
                            l1, r1, lz1, rz1 = \
                                    self.calc_leftright(vecp, one, dirx, en_0, en_1, thick_2, diry)
                            l2, r2, lz2, rz2 = \
                                    self.calc_leftright(vecp, two, dirx, en_2, en_3, thick_2, diry)
                            # print(left2, right2, l2, r2, lz2, rz2)
                            # средняя точка и её смещение по толщине материала
                            three = (one-two)/2 + two

                            # rounded section
                            if self.rounded:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ

                                # outeob1 = [[lenvep+k+8,lenvep+k],[lenvep+k+1,lenvep+k+2],
                                #           [lenvep+k+2,lenvep+k+3],[lenvep+k+3,lenvep+k+4],
                                #           [lenvep+k+4,lenvep+k+5],[lenvep+k+5,lenvep+k+6],
                                #           [lenvep+k+6,lenvep+k+7],[lenvep+k+7,lenvep+k+8],
                                #           [lenvep+k+9,lenvep+k+1]]

                                # outeob2 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],
                                #           [lenvep+k+2,lenvep+k+3],[lenvep+k+3,lenvep+k+4],
                                #           [lenvep+k+4,lenvep+k+5],[lenvep+k+5,lenvep+k+6],
                                #           [lenvep+k+6,lenvep+k+7],[lenvep+k+7,lenvep+k+8],
                                #           [lenvep+k+8,lenvep+k+9]]


                                outeob1 = [[lenvep+k+8,lenvep+k]]
                                outeob1.extend([[lenvep+k+i,lenvep+k+i+1] for i in range(1,10,1)])
                                outeob1.append([lenvep+k+9,lenvep+k+1])

                                outeob2 = [[lenvep+k+i,lenvep+k+i+1] for i in range(0,10,1)]


                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep+k], [lenvep+k+9, r1]])
                                newinds2.extend([[l2, lenvep+k+9], [lenvep+k, r2]])
                                '''Вектора'''
                                round1 = diry*thick_3
                                round2 = diry*thick_3*sinuso30
                                round2_= dirx/3 + dirx*(2*sinuso60/3)
                                round3 = diry*thick_3*sinuso60_minus
                                round3_= dirx/3 + dirx*(2*sinuso30/3)
                                round4 = dirx/3
                                vupperob.extend([lz2,
                                                 three+round1-dirx, three+round2-round2_,
                                                 three+round3-round3_, three-round4,
                                                 three+round4, three+round3+round3_,
                                                 three+round2+round2_, three+round1+dirx,
                                                 rz2])
                                vlowerob.extend([rz1,
                                                 three-round1-dirx, three-round2-round2_,
                                                 three-round3-round3_, three-round4,
                                                 three+round4, three-round3+round3_,
                                                 three-round2+round2_, three-round1+dirx,
                                                 lz1])
                                k += 10
                            elif  self.rounded_outside:
                                '''рёбра вовнешнее'''
                                # пазы формируем независимо от верх низ

                                outeob1 = [[lenvep+k+28,lenvep+k]]
                                outeob1.extend([[lenvep+k+i,lenvep+k+i+1] for i in range(1,30,1)])
                                outeob1.append([lenvep+k+29,lenvep+k+1])

                                outeob2 = [[lenvep+k+i,lenvep+k+i+1] for i in range(0,30,1)]

                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep+k], [lenvep+k+29, r1]])
                                newinds2.extend([[l2, lenvep+k+29], [lenvep+k, r2]])
                                '''Вектора'''
                                round1 = diry*thick_3
                                round2 = diry*thick_3*sinuso30
                                round2_= dirx/3 + dirx*(2*sinuso60/3)
                                round3 = diry*thick_3*sinuso60_minus
                                round3_= dirx/3 + dirx*(2*sinuso30/3)
                                round4 = dirx/3
                                vupperob.extend([lz2,
                                                 three+round1-dirx, three+round2-round2_,
                                                 three+round3-round3_, three-round4,
                                                 three+round4, three+round3+round3_,
                                                 three+round2+round2_, three+round1+dirx,
                                                 rz2])
                                vlowerob.extend([rz1,
                                                 three-round1-dirx, three-round2-round2_,
                                                 three-round3-round3_, three-round4,
                                                 three+round4, three-round3+round3_,
                                                 three-round2+round2_, three-round1+dirx,
                                                 lz1])
                                k += 10

                            # streight section
                            else:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ
                                outeob1 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],[lenvep+k+2,lenvep+k+3]]
                                outeob2 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],[lenvep+k+2,lenvep+k+3]]
                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep+k], [lenvep+k+3, r1]])
                                newinds2.extend([[l2, lenvep+k+3], [lenvep+k, r2]])
                                '''Вектора'''
                                vupperob.extend([lz2, three-dirx,
                                                 three+dirx, rz2])
                                vlowerob.extend([rz1, three+dirx,
                                                 three-dirx, lz1])
                                k += 4
                            newinds1.extend(outeob1)
                            newinds2.extend(outeob2)

                            # circles to bing panels section
                            if self.bindCircle:
                                CP = self.circl_place
                                if CP == 'Midl':
                                    crcl_cntr = IL2P(one, two, Vector((0,0,0)), Vector((0,0,-1)))
                                elif CP == 'Up' and not fliped:
                                    crcl_cntr = two - diry*self.circle_rad*2
                                elif CP == 'Down' and not fliped:
                                    crcl_cntr = one + diry*self.circle_rad*2
                                elif CP == 'Up' and fliped:
                                    crcl_cntr = one + diry*self.circle_rad*2
                                elif CP == 'Down' and fliped:
                                    crcl_cntr = two - diry*self.circle_rad*2
                                # forgot howto 'else' in line iteration?
                                outeob1 = [ [lenvep+k+i,lenvep+k+i+1] for i in range(0,11) ]
                                outeob1.append([lenvep+k,lenvep+k+11])
                                outeob2 = [ [lenvep+k+i,lenvep+k+i+1] for i in range(12,23) ]
                                outeob2.append([lenvep+k+12,lenvep+k+23])
                                newinds1.extend(outeob1+outeob2)
                                newinds2.extend(outeob1+outeob2)
                                mat_rot_cir = n.rotation_difference(Vector((0,0,1))).to_matrix().to_4x4()
                                circle_to_add_1 = [vecir*mat_rot_cir+crcl_cntr+ \
                                        dirx_*self.circle_rad for vecir in circle ]
                                circle_to_add_2 = [vecir*mat_rot_cir+crcl_cntr- \
                                        dirx_*self.circle_rad for vecir in circle ]
                                vupperob.extend(circle_to_add_1+circle_to_add_2)
                                vlowerob.extend(circle_to_add_1+circle_to_add_2)
                                k += 24

                            # TUBE section
                            if vec_tube and not tubes_flag_bed_solution_i_know:
                                for v in vec_tube:
                                    tubeverlength = len(v)
                                    if tubeverlength == 2:
                                        crcl_cntr = IL2P(v[0], v[1], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [ [lenvep+k+i,lenvep+k+i+1] for i in range(0,23) ]
                                                outeob.append([lenvep+k,lenvep+k+23])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                mat_rot_cir = n.rotation_difference(Vector((0,0,1))).to_matrix().to_4x4()
                                                circle_to_add = [ vecir*mat_rot_cir+crcl_cntr for vecir in circle_tube ]
                                                vupperob.extend(circle_to_add)
                                                vlowerob.extend(circle_to_add)
                                                k += 24
                                    else:
                                        tubeshift = tubeverlength//2
                                        crcl_cntr = IL2P(v[0], v[tubeshift], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [ [lenvep+k+i,lenvep+k+i+1] for i in range(tubeshift-1) ]
                                                outeob.append([lenvep+k,lenvep+k+tubeshift-1])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                for tubevert in range(tubeshift):
                                                    tubevert_out = IL2P(v[tubevert], v[tubevert+tubeshift], l, n)
                                                    vupperob.append(tubevert_out)
                                                    vlowerob.append(tubevert_out)
                                                k += tubeshift

                                tubes_flag_bed_solution_i_know = True
                        elif cop < threshold_coplanar and inside and shortedge <= thick*threshold:
                            vupperob.extend([one,two])
                            vlowerob.extend([one,two])
                            newinds1.append([lenvep+k,lenvep+k+1])
                            newinds2.append([lenvep+k,lenvep+k+1])
                            k += 2
                    del tree
                    for e in deledges1:
                        if e in newinds1:
                            newinds1.remove(e)
                    for e in deledges2:
                        if e in newinds2:
                            newinds2.remove(e)
                    if vupperob or vlowerob:
                        outeup.append(newinds2)
                        outelo.append(newinds1)
                        vupper.append(vupperob)
                        vlower.append(vlowerob)
                vupper = Vector_degenerate(vupper)
                vlower = Vector_degenerate(vlower)
                centers = Vector_degenerate([centers])

                if 'vert' in self.outputs:
                    if self.out_up_down == 'Up':
                        out = dataCorrect(vupper)
                    else:
                        out = dataCorrect(vlower)
                    self.outputs['vert'].sv_set(out)
                if 'edge' in self.outputs and self.outputs['edge'].links:
                    if self.out_up_down == 'Up':
                        self.outputs['edge'].sv_set(outeup)
                    else:
                        self.outputs['edge'].sv_set(outelo)
                if 'centers' in self.outputs and self.outputs['centers'].links:
                    self.outputs['centers'].sv_set(centers)
                print(self.name, 'is finishing')
Ejemplo n.º 15
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, False), (1, False), (2, False)]

            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])

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

            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)
Ejemplo n.º 16
0
    def process(self):
        n_id = node_id(self)
        nvBGL.callback_disable(n_id)
        inputs = self.inputs
        # end early
        if not self.activate:
            return

        if self.mode == 'Number':
            if not inputs['Number'].is_linked:
                return
            numbers = inputs['Number'].sv_get(default=[[]])
        elif self.mode == 'Curve':
            if not inputs['Curve'].is_linked:
                return
            curves = inputs['Curve'].sv_get(default=[[]])
        else:
            if not inputs['Vecs'].is_linked:
                return
            vecs = inputs['Vecs'].sv_get(default=[[]])

        edges = inputs['Edges'].sv_get(default=[[]])
        polygons = inputs['Polygons'].sv_get(default=[[]])
        vector_color = inputs['Vector Color'].sv_get(default=[[self.vector_color]])
        edge_color = inputs['Edge Color'].sv_get(default=[[self.edge_color]])
        poly_color = inputs['Polygon Color'].sv_get(default=[[self.polygon_color]])
        seed_set(self.random_seed)
        x, y, config = self.create_config()

        config.vector_color = vector_color
        config.edge_color = edge_color
        config.poly_color = poly_color
        config.edges = edges


        if self.mode == 'Number':
            config.size = self.drawing_size
            geom = generate_number_geom(config, numbers)
        elif self.mode == 'Path':
            geom = generate_graph_geom(config, vecs)
        elif self.mode == 'Curve':
            paths = []
            for curve in curves:
                t_min, t_max = curve.get_u_bounds()
                ts = np_linspace(t_min, t_max, num=self.curve_samples, dtype=np_float64)
                paths.append(curve.evaluate_array(ts).tolist())

            geom = generate_graph_geom(config, paths)

        else:
            config.polygons = polygons
            if not inputs['Edges'].is_linked and self.edge_toggle:
                config.edges = polygons_to_edges(polygons, unique_edges=True)

            geom = generate_mesh_geom(config, vecs)


        draw_data = {
            'mode': 'custom_function',
            'tree_name': self.id_data.name[:],
            'loc': (x, y),
            'custom_function': view_2d_geom,
            'args': (geom, config)
        }
        nvBGL.callback_enable(n_id, draw_data)
Ejemplo n.º 17
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            edges_s = self.inputs['Edges'].sv_get()
            faces_s = self.inputs['Faces'].sv_get()
            vertex_weight_s = self.inputs['VertexWeight'].sv_get()
            edge_weight_s = self.inputs['EdgeWeight'].sv_get()
            face_weight_s = self.inputs['FaceWeight'].sv_get()
            tangent_weight_s = self.inputs['TangentWeight'].sv_get()
            degree_u_s = self.inputs['DegreeU'].sv_get()
            degree_v_s = self.inputs['DegreeV'].sv_get()

            surface_out = []
            control_points_out = []
            weights_out = []
            inputs = zip_long_repeat(vertices_s, edges_s, faces_s, degree_u_s,
                                     degree_v_s, vertex_weight_s,
                                     edge_weight_s, face_weight_s,
                                     tangent_weight_s)
            for vertices, edges, faces, degree_u, degree_v, vertex_weights, edge_weights, face_weights, tangent_weights in inputs:
                fullList(degree_u, len(faces))
                fullList(degree_v, len(faces))

                if not edges:
                    edges = polygons_to_edges([faces], True)[0]

                fullList(vertex_weights, len(vertices))
                fullList(tangent_weights, len(vertices))
                fullList(edge_weights, len(edges))
                fullList(face_weights, len(faces))

                bm = bmesh_from_pydata(vertices,
                                       edges,
                                       faces,
                                       normal_update=True,
                                       markup_edge_data=True)
                normals = [vertex.normal for vertex in bm.verts]
                edge_planes_dict = dict()
                for edge in bm.edges:
                    edge_v = edge.verts[1].co - edge.verts[0].co
                    edge_c = (edge.verts[0].co + edge.verts[1].co) / 2.0
                    edge_ort_plane = PlaneEquation.from_normal_and_point(
                        edge_v, edge_c)
                    face_normals = [face.normal for face in edge.link_faces]
                    faces_normal = sum(face_normals, Vector())
                    projected_faces_normal = edge_ort_plane.projection_of_point(
                        faces_normal)
                    #print("EV: %s, No.sum: %s, Pr.N: %s" % (edge_v, faces_normal, projected_faces_normal))
                    edge_plane = PlaneEquation.from_normal_and_point(
                        projected_faces_normal, edge_c)
                    edge_planes_dict[(edge.verts[0].index,
                                      edge.verts[1].index)] = edge_plane
                    edge_planes_dict[(edge.verts[1].index,
                                      edge.verts[0].index)] = edge_plane
                bm.free()

                vert_planes = [
                    PlaneEquation.from_normal_and_point(normal, point)
                    for normal, point in zip(normals, vertices)
                ]

                edge_weights_dict = dict()
                #edge_planes_dict = dict()
                for (i, j), edge_weight in zip(edges, edge_weights):
                    edge_weights_dict[(i, j)] = edge_weight
                    edge_weights_dict[(j, i)] = edge_weight
                    #edge_planes_dict[(i, j)] = edge_plane
                    #edge_planes_dict[(j, i)] = edge_plane

                for i, (face, degree_u, degree_v, face_weight) in enumerate(
                        zip(faces, degree_u, degree_v, face_weights)):
                    if len(face) != 4:
                        self.info("Face #%s is not a Quad, skip it", i)
                        continue
                    face_verts = [vertices[i] for i in face]
                    face_planes = [vert_planes[i] for i in face]
                    face_vert_weights = [vertex_weights[i] for i in face]
                    face_tangent_weights = [tangent_weights[i] for i in face]
                    #face_edges = list(zip(face, face[1:])) + [(face[-1], face[0])]
                    #face_edge_weights = [edge_weights_dict[edge] for edge in face_edges]
                    surface, ctrlpts, weights = self.make_surface(
                        face, degree_u, degree_v, face_verts, face_planes,
                        face_vert_weights, face_tangent_weights, face_weight,
                        edge_weights_dict, edge_planes_dict)
                    surface_out.append(surface)
                    control_points_out.append(list(map(tuple, ctrlpts)))
                    weights_out.append(weights)

            self.outputs['Surfaces'].sv_set(surface_out)
            self.outputs['ControlPoints'].sv_set(control_points_out)
            self.outputs['Weights'].sv_set(weights_out)
Ejemplo n.º 18
0
    def process(self):
        if bpy.app.background:
            return
        self.handle_attr_socket()
        if not (self.id_data.sv_show and self.activate):
            callback_disable(node_id(self))
            return
        n_id = node_id(self)
        callback_disable(n_id)
        inputs = self.inputs
        # end early
        if not self.activate:
            return

        if not any([inputs['Vertices'].is_linked, inputs['Matrix'].is_linked]):
            return

        if inputs['Vertices'].is_linked:
            vecs = inputs['Vertices'].sv_get(default=[[]])

            edges = inputs['Edges'].sv_get(default=[[]])
            polygons = inputs['Polygons'].sv_get(default=[[]])
            matrix = inputs['Matrix'].sv_get(default=[[]])
            vector_color = inputs['Vector Color'].sv_get(
                default=[[self.vector_color]])
            edge_color = inputs['Edge Color'].sv_get(
                default=[[self.edge_color]])
            poly_color = inputs['Polygon Color'].sv_get(
                default=[[self.polygon_color]])
            seed_set(self.random_seed)
            config = self.create_config()

            config.vector_color = vector_color
            config.edge_color = edge_color
            config.poly_color = poly_color
            config.edges = edges

            if self.use_dashed:
                add_dashed_shader(config)

            config.polygons = polygons
            config.matrix = matrix
            if not inputs['Edges'].is_linked and self.display_edges:
                config.edges = polygons_to_edges(polygons, unique_edges=True)

            geom = generate_mesh_geom(config, vecs)

            draw_data = {
                'tree_name': self.id_data.name[:],
                'custom_function': view_3d_geom,
                'args': (geom, config)
            }
            callback_enable(n_id, draw_data)

        elif inputs['Matrix'].is_linked:
            matrices = inputs['Matrix'].sv_get(deepcopy=False,
                                               default=[Matrix()])

            gl_instructions = {
                'tree_name': self.id_data.name[:],
                'custom_function': draw_matrix,
                'args': (matrices, self.matrix_draw_scale)
            }
            callback_enable(n_id, gl_instructions)
Ejemplo n.º 19
0
def voronoi3d_layer(n_src_sites,
                    all_sites,
                    make_regions,
                    do_clip,
                    clipping,
                    skip_added=True):
    diagram = Voronoi(all_sites)
    src_sites = all_sites[:n_src_sites]

    region_verts = dict()
    region_verts_map = dict()
    n_sites = n_src_sites if skip_added else len(all_sites)
    for site_idx in range(n_sites):
        region_idx = diagram.point_region[site_idx]
        region = diagram.regions[region_idx]
        vertices = [tuple(diagram.vertices[i, :]) for i in region]
        region_verts[site_idx] = vertices
        region_verts_map[site_idx] = {
            vert_idx: i
            for i, vert_idx in enumerate(region)
        }

    open_sites = set()
    region_faces = defaultdict(list)
    for ridge_idx, sites in enumerate(diagram.ridge_points):
        site_from, site_to = sites
        ridge = diagram.ridge_vertices[ridge_idx]
        if -1 in ridge:
            open_sites.add(site_from)
            open_sites.add(site_to)

        site_from_ok = not skip_added or site_from < n_src_sites
        site_to_ok = not skip_added or site_to < n_src_sites

        if make_regions:
            if site_from_ok:
                face_from = [region_verts_map[site_from][i] for i in ridge]
                region_faces[site_from].append(face_from)

            if site_to_ok:
                face_to = [region_verts_map[site_to][i] for i in ridge]
                region_faces[site_to].append(face_to)
        else:
            if site_from_ok and site_to_ok:
                face_from = [region_verts_map[site_from][i] for i in ridge]
                region_faces[site_from].append(face_from)
                face_to = [region_verts_map[site_to][i] for i in ridge]
                region_faces[site_to].append(face_to)

    verts = [region_verts[i] for i in range(n_sites) if i not in open_sites]
    faces = [region_faces[i] for i in range(n_sites) if i not in open_sites]

    empty_faces = [len(f) == 0 for f in faces]
    verts = [vs for vs, mask in zip(verts, empty_faces) if not mask]
    faces = [fs for fs, mask in zip(faces, empty_faces) if not mask]
    edges = polygons_to_edges(faces, True)

    if not make_regions:
        verts_n, edges_n, faces_n = [], [], []
        for verts_i, edges_i, faces_i in zip(verts, edges, faces):
            used_verts = set(sum(faces_i, []))
            mask = [i in used_verts for i in range(len(verts_i))]
            verts_i, edges_i, faces_i = mask_vertices(verts_i, edges_i,
                                                      faces_i, mask)
            verts_n.append(verts_i)
            edges_n.append(edges_i)
            faces_n.append(faces_i)
        verts, edges, faces = verts_n, edges_n, faces_n

    if do_clip:
        verts_n, edges_n, faces_n = [], [], []
        bounds = calc_bounds(src_sites, clipping)
        for verts_i, edges_i, faces_i in zip(verts, edges, faces):
            bm = bmesh_from_pydata(verts_i, edges_i, faces_i)
            bmesh_clip(bm, bounds, fill=True)
            verts_i, edges_i, faces_i = pydata_from_bmesh(bm)
            bm.free()
            verts_n.append(verts_i)
            edges_n.append(edges_i)
            faces_n.append(faces_i)
        verts, edges, faces = verts_n, edges_n, faces_n

    return verts, edges, faces