def process(self): if not any(s.is_linked for s in self.outputs): return in_verts = self.inputs['Verts'].sv_get() in_faces = self.inputs['Faces'].sv_get() out_verts, out_faces = [], [] if in_verts and in_faces: fill = bmesh.ops.beautify_fill for verts, faces in zip(in_verts, in_faces): bm = bmesh_from_pydata(verts, [], faces) bm.verts.ensure_lookup_table() fill(bm, faces=bm.faces[:], edges=bm.edges[:], use_restrict_tag=False, method=self.beautify_mode) nv, ne, nf = pydata_from_bmesh(bm) out_verts.append(nv) out_faces.append(nf) self.outputs['Verts'].sv_set(out_verts) self.outputs['Faces'].sv_set(out_faces)
def sv_main(radius=0.3): verts_out = [] edges_out = [] faces_out = [] in_sockets = [ ['s', 'radius', radius] ] bm = bmesh.new() objname = "Plane" obj = bpy.data.objects.get(objname) if obj: bm.from_mesh(obj.data) verts, edges, faces = pydata_from_bmesh(bm) verts_out.append([verts]) edges_out.append([edges]) bm.free() out_sockets = [ ['v', 'verts', verts_out], ['s', 'edges', edges_out], ['s', 'faces', faces_out] ] return in_sockets, out_sockets
def sv_main(radius=0.3): verts_out = [] edges_out = [] faces_out = [] in_sockets = [['s', 'radius', radius]] bm = bmesh.new() objname = "Plane" obj = bpy.data.objects.get(objname) if obj: bm.from_mesh(obj.data) verts, edges, faces = pydata_from_bmesh(bm) verts_out.append([verts]) edges_out.append([edges]) bm.free() out_sockets = [['v', 'verts', verts_out], ['s', 'edges', edges_out], ['s', 'faces', faces_out]] return in_sockets, out_sockets
def process(self): xdims, ydims, zdims, sizesx, sizesy, sizesz = [s.sv_get()[0] for s in self.inputs] verts = [] for xdim, ydim, zdim, *size in zip(xdims, ydims, zdims, sizesx, sizesy, sizesz): hs0 = size[0] / 2 hs1 = size[1] / 2 hs2 = size[2] / 2 x_ = np.linspace(-hs0, hs0, xdim) y_ = np.linspace(-hs1, hs1, ydim) z_ = np.linspace(-hs2, hs2, zdim) f = np.vstack(np.meshgrid(x_,y_,z_)).reshape(3,-1).T num_items = f.shape[0]* f.shape[1] if self.randomize_factor > 0.0: np.random.seed(self.seed) noise = (np.random.normal(0, 0.5, num_items) * self.randomize_factor).reshape(3,-1).T f += noise f = f.tolist() if self.rm_doubles_distance > 0.0: bm = bmesh_from_pydata(f, [], []) bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=self.rm_doubles_distance) f, _, _ = pydata_from_bmesh(bm) verts.append(f) if verts: self.outputs['verts'].sv_set(verts)
def process(self): if not (self.inputs[0].is_linked and self.inputs[2].is_linked): return if not any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewPolys']): return out, result_bevel_faces = [], [] meshes = match_long_repeat(self.get_socket_data()) for vertices, edges, faces, bevel_edges, offset, segments, profile in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) b_edges = get_bevel_edges(bm, bevel_edges) geom = list(bm.verts) + list(b_edges) + list(bm.faces) bevel_faces = bmesh.ops.bevel( bm, geom=geom, offset=offset, offset_type=int(self.offsetType), segments=segments, profile=profile, vertex_only=self.vertexOnly, material=-1)['faces'] new_bevel_faces = [[v.index for v in face.verts] for face in bevel_faces] out.append(pydata_from_bmesh(bm)) bm.free() result_bevel_faces.append(new_bevel_faces) Vertices, Edges, Polygons, NewPolygons = self.outputs Vertices.sv_set([i[0] for i in out]) Edges.sv_set([i[1] for i in out]) Polygons.sv_set([i[2] for i in out]) NewPolygons.sv_set(result_bevel_faces)
def bisect_bmesh(bm, pp, pno, outer, inner, fill): geom_in = bm.verts[:] + bm.edges[:] + bm.faces[:] res = bmesh.ops.bisect_plane(bm, geom=geom_in, dist=0.00001, plane_co=pp, plane_no=pno, use_snap_center=False, clear_outer=outer, clear_inner=inner) # this needs work function with solid geometry if fill: fres = bmesh.ops.edgenet_prepare( bm, edges=[ e for e in res['geom_cut'] if isinstance(e, bmesh.types.BMEdge) ]) bmesh.ops.edgeloop_fill(bm, edges=fres['edges']) edges = [] faces = [] bm.verts.index_update() bm.edges.index_update() bm.faces.index_update() verts, edges, faces = pydata_from_bmesh(bm) bm.clear() bm.free() return (verts, edges, faces)
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(default=[[]]) faces_s = self.inputs['Faces'].sv_get(default=[[]]) masks_s = self.inputs['FaceMask'].sv_get(default=[[1]]) max_angle_s = self.inputs['MaxAngle'].sv_get() face_data_s = self.inputs['FaceData'].sv_get(default=[[]]) verts_out = [] edges_out = [] faces_out = [] face_data_out = [] meshes = match_long_repeat( [vertices_s, edges_s, faces_s, masks_s, max_angle_s, face_data_s]) for vertices, edges, faces, masks, max_angle, face_data in zip( *meshes): if self.split_mode == 'NONPLANAR': if isinstance(max_angle, (list, tuple)): max_angle = max_angle[0] fullList(masks, len(faces)) if face_data: fullList(face_data, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True, markup_face_data=True) bm_faces = [face for mask, face in zip(masks, bm.faces[:]) if mask] if self.split_mode == 'NONPLANAR': new_geom = bmesh.ops.connect_verts_nonplanar( bm, angle_limit=radians(max_angle), faces=bm_faces) else: new_geom = bmesh.ops.connect_verts_concave(bm, faces=bm_faces) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) #new_edges, new_faces = get_bm_geom(new_geom) if not face_data: new_face_data = [] else: new_face_data = face_data_from_bmesh_faces(bm, face_data) verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) face_data_out.append(new_face_data) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out) self.outputs['FaceData'].sv_set(face_data_out)
def make_regions(self, diagram): faces_per_site = defaultdict(list) nsites = len(diagram.point_region) nridges = len(diagram.ridge_points) open_sites = set() for ridge_idx in range(nridges): site_idx_1, site_idx_2 = diagram.ridge_points[ridge_idx] face = diagram.ridge_vertices[ridge_idx] if -1 in face: open_sites.add(site_idx_1) open_sites.add(site_idx_2) continue faces_per_site[site_idx_1].append(face) faces_per_site[site_idx_2].append(face) new_verts = [] new_edges = [] new_faces = [] for site_idx in sorted(faces_per_site.keys()): if self.closed_only and site_idx in open_sites: continue done_verts = dict() bm = bmesh.new() new_vert = bm.verts.new new_face = bm.faces.new for face in faces_per_site[site_idx]: face_bm_verts = [] for vertex_idx in face: if vertex_idx not in done_verts: bm_vert = new_vert(diagram.vertices[vertex_idx]) done_verts[vertex_idx] = bm_vert else: bm_vert = done_verts[vertex_idx] face_bm_verts.append(bm_vert) new_face(face_bm_verts) bm.verts.index_update() bm.verts.ensure_lookup_table() bm.faces.index_update() bm.edges.index_update() if self.closed_only and any(v.is_boundary for v in bm.verts): bm.free() continue if self.normals: bm.normal_update() bmesh.ops.recalc_face_normals(bm, faces=bm.faces[:]) region_verts, region_edges, region_faces = pydata_from_bmesh( bm) bm.free() new_verts.append(region_verts) new_edges.append(region_edges) new_faces.append(region_faces) return new_verts, new_edges, new_faces
def process(self): if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewEdges', 'NewPolys'])): return vertices_s = self.inputs['Vertices'].sv_get(default=[[]]) edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) mask_s = self.inputs['Mask'].sv_get(default=[[True]]) result_vertices = [] result_edges = [] result_faces = [] result_new_edges = [] result_new_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, mask_s]) for vertices, edges, faces, mask in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) fullList(mask, len(faces)) b_faces = [] for m, face in zip(mask, bm.faces): if m: b_faces.append(face) res = bmesh.ops.triangulate( bm, faces=b_faces, quad_method=int(self.quad_mode), ngon_method=int(self.ngon_mode)) b_new_edges = [tuple(v.index for v in edge.verts) for edge in res['edges']] b_new_faces = [[v.index for v in face.verts] for face in res['faces']] new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_new_edges.append(b_new_edges) result_new_faces.append(b_new_faces) if self.outputs['Vertices'].is_linked: self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces) if self.outputs['NewEdges'].is_linked: self.outputs['NewEdges'].sv_set(result_new_edges) if self.outputs['NewPolys'].is_linked: self.outputs['NewPolys'].sv_set(result_new_faces)
def process(self): if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewEdges', 'NewPolys'])): return vertices_s = self.inputs['Vertices'].sv_get(default=[[]]) edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) mask_s = self.inputs['Mask'].sv_get(default=[[True]]) result_vertices = [] result_edges = [] result_faces = [] result_new_edges = [] result_new_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, mask_s]) for vertices, edges, faces, mask in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) fullList(mask, len(faces)) b_faces = [] for m, face in zip(mask, bm.faces): if m: b_faces.append(face) res = bmesh.ops.triangulate( bm, faces=b_faces, quad_method=int(self.quad_mode), ngon_method=int(self.ngon_mode)) b_new_edges = [tuple(v.index for v in edge.verts) for edge in res['edges']] b_new_faces = [[v.index for v in face.verts] for face in res['faces']] new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_new_edges.append(b_new_edges) result_new_faces.append(b_new_faces) if self.outputs['Vertices'].is_linked: self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces) if self.outputs['NewEdges'].is_linked: self.outputs['NewEdges'].sv_set(result_new_edges) if self.outputs['NewPolys'].is_linked: self.outputs['NewPolys'].sv_set(result_new_faces)
def process(self): if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewPolys'])): return vertices_s = self.inputs['Vertices'].sv_get(default=[[]]) edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) offsets_s = self.inputs['Offset'].sv_get()[0] segments_s = self.inputs['Segments'].sv_get()[0] profiles_s = self.inputs['Profile'].sv_get()[0] bevel_edges_s = self.inputs['BevelEdges'].sv_get(default=[[]]) result_vertices = [] result_edges = [] result_faces = [] result_bevel_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, bevel_edges_s, offsets_s, segments_s, profiles_s]) for vertices, edges, faces, bevel_edges, offset, segments, profile in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) if bevel_edges: b_edges = [] for edge in bevel_edges: b_edge = [e for e in bm.edges if set([v.index for v in e.verts]) == set(edge)] b_edges.append(b_edge[0]) else: b_edges = bm.edges geom = list(bm.verts) + list(b_edges) + list(bm.faces) bevel_faces = bmesh.ops.bevel(bm, geom=geom, offset=offset, offset_type=int(self.offsetType), segments=segments, profile=profile, vertex_only=self.vertexOnly, #clamp_overlap=self.clampOverlap, material=-1)['faces'] new_bevel_faces = [[v.index for v in face.verts] for face in bevel_faces] new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_bevel_faces.append(new_bevel_faces) self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces) if self.outputs['NewPolys'].is_linked: self.outputs['NewPolys'].sv_set(result_bevel_faces)
def process(self): if not any(output.is_linked for output in self.outputs): return InVert, InEdge, InEdSel = self.inputs OutVert, OutEdg, OutFace, ONVert, ONEdg, ONFace, OOVert, OOEdg, OOFace = self.outputs vertices_s = InVert.sv_get() topo = InEdge.sv_get() if len(topo[0][0]) == 2: bmlist= [bmesh_from_pydata(v, e, [], normal_update=True) for v,e in zip(vertices_s,topo)] else: bmlist= [bmesh_from_pydata(v, [], e, normal_update=True) for v,e in zip(vertices_s,topo)] rev, ree, ref, riv, rie, rif, rsv, rse, rsf = [],[],[],[],[],[],[],[],[] if InEdSel.is_linked: if self.sel_mode == "index": useedges = [np.array(bm.edges[:])[idxs] for bm, idxs in zip(bmlist, InEdSel.sv_get())] elif self.sel_mode == "mask": useedges = [np.extract(mask, bm.edges[:]) for bm, mask in zip(bmlist, InEdSel.sv_get())] else: useedges = [bm.edges for bm in bmlist] for bm,ind in zip(bmlist,useedges): geom = subdivide_edges(bm, edges=ind, smooth=self.smooth, smooth_falloff=int(self.falloff_type), fractal=self.fractal, along_normal=self.along_normal, cuts=self.cuts, seed=self.seed, quad_corner_type=int(self.corner_type), use_grid_fill=self.grid_fill, use_single_edge=self.single_edge, use_only_quads=self.only_quads, use_smooth_even=self.smooth_even) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) rev.append(new_verts) ree.append(new_edges) ref.append(new_faces) if self.show_new: geo1 = geom['geom_inner'] riv.append([tuple(v.co) for v in geo1 if isinstance(v, bmesh.types.BMVert)]) rie.append([[v.index for v in e.verts] for e in geo1 if isinstance(e, bmesh.types.BMEdge)]) rif.append([[v.index for v in f.verts] for f in geo1 if isinstance(f, bmesh.types.BMFace)]) if self.show_old: geo2 = geom['geom_split'] rsv.append([tuple(v.co) for v in geo2 if isinstance(v, bmesh.types.BMVert)]) rse.append([[v.index for v in e.verts] for e in geo2 if isinstance(e, bmesh.types.BMEdge)]) rsf.append([[v.index for v in f.verts] for f in geo2 if isinstance(f, bmesh.types.BMFace)]) bm.free() OutVert.sv_set(rev) OutEdg.sv_set(ree) OutFace.sv_set(ref) ONVert.sv_set(riv) ONEdg.sv_set(rie) ONFace.sv_set(rif) OOVert.sv_set(rsv) OOEdg.sv_set(rse) OOFace.sv_set(rsf)
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(default=[[]]) faces_s = self.inputs['Faces'].sv_get(default=[[]]) masks_s = self.inputs['FaceMask'].sv_get(default=[[1]]) face_data_s = self.inputs['FaceData'].sv_get(default=[[]]) offset_s = self.inputs['Offset'].sv_get() verts_out = [] edges_out = [] faces_out = [] face_data_out = [] meshes = zip_long_repeat(vertices_s, edges_s, faces_s, offset_s, masks_s, face_data_s) for vertices, edges, faces, offset, masks, face_data in meshes: if isinstance(offset, (list, tuple)): offset = offset[0] masks = repeat_last_for_length(masks, len(faces)) if face_data: face_data = repeat_last_for_length(face_data, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True, markup_face_data=True) bm_faces = [face for mask, face in zip(masks, bm.faces[:]) if mask] bmesh.ops.poke(bm, faces=bm_faces, offset=offset, center_mode=self.mode, use_relative_offset=self.offset_relative) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) if not face_data: new_face_data = [] else: new_face_data = face_data_from_bmesh_faces(bm, face_data) bm.free() verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) face_data_out.append(new_face_data) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out) self.outputs['FaceData'].sv_set(face_data_out)
def make_hull(vertices): if not vertices: return False bm = bmesh.new() bm_verts = [bm.verts.new(v) for v in vertices] bmesh.ops.convex_hull(bm, input=bm_verts, use_existing_faces=False) verts, _, faces = pydata_from_bmesh(bm) bm.clear() bm.free() return (verts, faces)
def make_hull(vertices): if not vertices: return False bm = bmesh.new() bm_verts = [bm.verts.new(v) for v in vertices] bmesh.ops.convex_hull(bm, input=bm_verts, use_existing_faces=False) verts, _, faces = pydata_from_bmesh(bm) bm.clear() bm.free() return (verts, faces)
def fill_holes(vertices, edges, s): if not edges and not vertices: return False if len(edges[0]) != 2: return False bm = bmesh_from_pydata(vertices, edges, []) bmesh.ops.holes_fill(bm, edges=bm.edges[:], sides=s) verts, edges, faces = pydata_from_bmesh(bm) return (verts, edges, faces)
def fill_holes(vertices, edges, s): if not edges and not vertices: return False if len(edges[0]) != 2: return False bm = bmesh_from_pydata(vertices, edges, []) bmesh.ops.holes_fill(bm, edges=bm.edges[:], sides=s) verts, edges, faces = pydata_from_bmesh(bm) return (verts, edges, faces)
def process(self): if not self.outputs[0].is_linked: return params = match_long_repeat([s.sv_get(deepcopy=False)[0] for s in self.inputs]) get_faces = 'faces' in self.outputs and self.outputs['faces'].is_linked get_edges = 'edges' in self.outputs and self.outputs['edges'].is_linked verts_out, edges_out, faces_out = [], [], [] for xdim, ydim, zdim, *size in zip(*params): hs0 = size[0] / 2 hs1 = size[1] / 2 hs2 = size[2] / 2 x_ = np.linspace(-hs0, hs0, xdim) y_ = np.linspace(-hs1, hs1, ydim) z_ = np.linspace(-hs2, hs2, zdim) v_field = np.vstack(np.meshgrid(x_, y_, z_)).reshape(3, -1).T num_items = v_field.shape[0]* v_field.shape[1] if self.randomize_factor > 0.0: np.random.seed(self.seed) v_field += (np.random.normal(0, 0.5, num_items) * self.randomize_factor).reshape(3, -1).T if get_faces or get_edges: edges, faces = field_faces_and_edges(xdim, ydim, zdim, get_edges, get_faces) else: faces, edges = [], [] if self.rm_doubles_distance > 0.0: bm = bmesh_from_pydata(v_field.tolist(), edges, faces) bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=self.rm_doubles_distance) if self.output_numpy: verts_out.append(np.array([v.co for v in bm.verts])) faces_out.append([[e.verts[0].index, e.verts[1].index] for e in bm.edges]) edges_out.append([[i.index for i in p.verts] for p in bm.faces]) else: v_field, _, faces = pydata_from_bmesh(bm) faces_out.append(faces) edges_out.append(edges) verts_out.append(v_field) else: verts_out.append(v_field if self.output_numpy else v_field.tolist()) edges_out.append(edges) faces_out.append(faces) if verts_out: self.outputs['verts'].sv_set(verts_out) if get_edges: self.outputs['edges'].sv_set(edges_out) if get_faces: self.outputs['faces'].sv_set(faces_out)
def process(self): outputs = self.outputs if not outputs['Vertices'].is_linked: return IVerts, IFaces, IMask, Imatr = self.inputs vertices_s = IVerts.sv_get() faces_s = IFaces.sv_get() linked_extruded_polygons = outputs['ExtrudedPolys'].is_linked linked_other_polygons = outputs['OtherPolys'].is_linked result_vertices = [] result_edges = [] result_faces = [] result_extruded_faces = [] result_other_faces = [] bmlist = [bmesh_from_pydata(verts, [], faces) for verts, faces in zip(vertices_s, faces_s)] trans = Imatr.sv_get() if IMask.is_linked: flist = [np.extract(mask, bm.faces[:]) for bm, mask in zip(bmlist, IMask.sv_get())] else: flist = [bm.faces for bm in bmlist] for bm, selfaces in zip(bmlist, flist): extrfaces = extrude_discrete_faces(bm, faces=selfaces)['faces'] fullList(trans, len(extrfaces)) new_extruded_faces = [] for face, ma in zip(extrfaces, trans): normal = face.normal if normal[0] == 0 and normal[1] == 0: m_r = Matrix() if normal[2] >= 0 else Matrix.Rotation(pi, 4, 'X') else: z_axis = normal x_axis = Vector((z_axis[1] * -1, z_axis[0], 0)).normalized() y_axis = z_axis.cross(x_axis).normalized() m_r = Matrix(list([*zip(x_axis[:], y_axis[:], z_axis[:])])).to_4x4() m = (Matrix.Translation(face.calc_center_median()) * m_r).inverted() transform(bm, matrix=ma, space=m, verts=face.verts) if linked_extruded_polygons or linked_other_polygons: new_extruded_faces.append([v.index for v in face.verts]) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() new_other_faces = [f for f in new_faces if f not in new_extruded_faces] if linked_other_polygons else [] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_extruded_faces.append(new_extruded_faces) result_other_faces.append(new_other_faces) outputs['Vertices'].sv_set(result_vertices) outputs['Edges'].sv_set(result_edges) outputs['Polygons'].sv_set(result_faces) outputs['ExtrudedPolys'].sv_set(result_extruded_faces) outputs['OtherPolys'].sv_set(result_other_faces)
def process(self): outputs = self.outputs if not outputs['Vertices'].is_linked: return IVerts, IFaces, IMask, Imatr = self.inputs vertices_s = IVerts.sv_get() faces_s = IFaces.sv_get() linked_extruded_polygons = outputs['ExtrudedPolys'].is_linked linked_other_polygons = outputs['OtherPolys'].is_linked result_vertices = [] result_edges = [] result_faces = [] result_extruded_faces = [] result_other_faces = [] bmlist = [bmesh_from_pydata(verts, [], faces) for verts, faces in zip(vertices_s, faces_s)] trans = Imatr.sv_get() if IMask.is_linked: flist = [np.extract(mask, bm.faces[:]) for bm, mask in zip(bmlist, IMask.sv_get())] else: flist = [bm.faces for bm in bmlist] for bm, selfaces in zip(bmlist, flist): extrfaces = extrude_discrete_faces(bm, faces=selfaces)['faces'] fullList(trans, len(extrfaces)) new_extruded_faces = [] for face, ma in zip(extrfaces, trans): normal = face.normal if normal[0] == 0 and normal[1] == 0: m_r = Matrix() if normal[2] >= 0 else Matrix.Rotation(pi, 4, 'X') else: z_axis = normal x_axis = Vector((z_axis[1] * -1, z_axis[0], 0)).normalized() y_axis = z_axis.cross(x_axis).normalized() m_r = Matrix(list([*zip(x_axis[:], y_axis[:], z_axis[:])])).to_4x4() m = (Matrix.Translation(face.calc_center_median()) @ m_r).inverted() transform(bm, matrix=ma, space=m, verts=face.verts) if linked_extruded_polygons or linked_other_polygons: new_extruded_faces.append([v.index for v in face.verts]) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() new_other_faces = [f for f in new_faces if f not in new_extruded_faces] if linked_other_polygons else [] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_extruded_faces.append(new_extruded_faces) result_other_faces.append(new_other_faces) outputs['Vertices'].sv_set(result_vertices) outputs['Edges'].sv_set(result_edges) outputs['Polygons'].sv_set(result_faces) outputs['ExtrudedPolys'].sv_set(result_extruded_faces) outputs['OtherPolys'].sv_set(result_other_faces)
def sv_main(subdiv=2,diam=4.0,mat = []): verts_out = [] edges_out = [] faces_out = [] in_sockets = [ ['s', 'subdivisions', subdiv], ['s', 'diam', diam], ['m','mat',mat] ] # Make a new BMesh bm = bmesh.new() #uncomment for debugging #print("matrices plugged in: {0}".format(mat)) #print("length of matrix is: {0}".format(len(mat))) matr = [] if mat: for i,m in enumerate(mat): if mat[0]: #we want the matrices so we put them in a Blender Matrix() matr = Matrix(m) #uncomment for debugging #print("matrices in for: {0}".format(m)) #print("Blender Matrix is: {0}".format(matr)) else: matr = Matrix() #print("Cocoooo! we have not a plugged matrix") bmesh.ops.create_icosphere(bm, subdivisions=subdiv, diameter=diam, matrix=matr, calc_uvs=False) #gets verts edges faces with sverchok function pydata_from_bmesh(bmesh) verts, edges, faces = pydata_from_bmesh(bm) verts_out.append(verts) edges_out.append(edges) faces_out.append(faces) out_sockets = [ ['v', 'verts', verts_out], ['s', 'edges', edges_out], ['s', 'faces', faces_out] ] return in_sockets, out_sockets
def process(self): v, e, p = self.outputs vlist = [] elist = [] plist = [] if v.is_linked: bml = self.inputs['bmesh_list'].sv_get() for i in bml: V,E,P = pydata_from_bmesh(i) vlist.append(V) elist.append(E) plist.append(P) v.sv_set(vlist) e.sv_set(elist) p.sv_set(plist)
def process(self): v, e, p = self.outputs vlist = [] elist = [] plist = [] if v.is_linked: bml = self.inputs['bmesh_list'].sv_get() for i in bml: V,E,P = pydata_from_bmesh(i) vlist.append(V) elist.append(E) plist.append(P) v.sv_set(vlist) e.sv_set(elist) p.sv_set(plist)
def process(self): if not (self.inputs[0].is_linked and (self.inputs[2].is_linked or self.inputs[1].is_linked)): return if not any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewPolys']): return out, result_bevel_faces = [], [] meshes = match_long_repeat(self.get_socket_data()) # bevel(bm, # geom, offset, offset_type, segments, profile, vertex_only, clamp_overlap, # material, loop_slide, mark_seam, mark_sharp, strength, hnmode) for vertices, edges, faces, mask, offset, segments, profile in zip( *meshes): bm = bmesh_from_pydata(vertices, edges, faces) geom = self.create_geom(bm, mask) try: bevel_faces = bmesh.ops.bevel( bm, geom=geom, offset=offset, offset_type=self.offsetType, segments=segments, profile=profile, vertex_only=self.vertexOnly, # strength= (float) # hnmode= (enum in ['NONE', 'FACE', 'ADJACENT', 'FIXED_NORMAL_SHADING'], default 'NONE') material=-1)['faces'] except: print('wtf?!...') new_bevel_faces = [[v.index for v in face.verts] for face in bevel_faces] out.append(pydata_from_bmesh(bm)) bm.free() result_bevel_faces.append(new_bevel_faces) Vertices, Edges, Polygons, NewPolygons = self.outputs Vertices.sv_set([i[0] for i in out]) Edges.sv_set([i[1] for i in out]) Polygons.sv_set([i[2] for i in out]) NewPolygons.sv_set(result_bevel_faces)
def process(self): if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons'])): return vertices_s = self.inputs['Vertices'].sv_get(default=[[]]) edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) mask_s = self.inputs['Mask'].sv_get(default=[[True]]) result_vertices = [] result_edges = [] result_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, mask_s]) for vertices, edges, faces, mask in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) bm.normal_update() fullList(mask, len(faces)) b_faces = [] for m, face in zip(mask, bm.faces): if m: b_faces.append(face) bmesh.ops.recalc_face_normals(bm, faces=b_faces) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() if self.invert: new_faces = [list(reversed(face)) for face in new_faces] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) if self.outputs['Vertices'].is_linked: self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces)
def process(self): in_linked = lambda x: self.inputs[x].is_linked out_linked = lambda x: self.outputs[x].is_linked if not in_linked('Verts'): return else: if not (in_linked('Polys') or in_linked('Edges')): return if not (any(out_linked(x) for x in ['Verts', 'Edges', 'Polys'])): return verts = self.inputs['Verts'].sv_get(default=[[]]) edges = self.inputs['Edges'].sv_get(default=[[]]) faces = self.inputs['Polys'].sv_get(default=[[]]) meshes = match_long_repeat([verts, edges, faces]) r_verts = [] r_edges = [] r_faces = [] for verts, edges, faces in zip(*meshes): bm = bmesh_from_pydata(verts, edges, faces, normal_update=True) # // it's a little undocumented.. ret = bmesh.ops.dissolve_limit( bm, angle_limit=self.angle, use_dissolve_boundaries=self.use_dissolve_boundaries, verts=bm.verts, edges=bm.edges, delimit=self.delimit) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() r_verts.append(new_verts) r_edges.append(new_edges) r_faces.append(new_faces) jk = [['Verts', r_verts], ['Edges', r_edges], ['Polys', r_faces]] for x, xdata in jk: if out_linked(x): self.outputs[x].sv_set(xdata)
def create_cricket(as_pydata=False, scale=4.0): bm = bmesh_from_pydata(cricket['vert_list'], [], cricket['face_list']) bmesh.ops.mirror(bm, geom=(bm.verts[:] + bm.faces[:]), matrix=Matrix(), merge_dist=0.0, axis='X') bmesh.ops.recalc_face_normals(bm, faces=bm.faces[:]) bmesh.ops.scale(bm, vec=Vector((scale, scale, scale)), verts=bm.verts[:]) if as_pydata: verts, edges, faces = pydata_from_bmesh(bm) bm.free() return verts, edges, faces return bm
def cut_cell(verts, faces, planes, site): src_mesh = bmesh_from_pydata(verts, [], faces, normal_update=True) n_cuts = 0 for plane in planes: if len(src_mesh.verts) == 0: break geom_in = src_mesh.verts[:] + src_mesh.edges[:] + src_mesh.faces[:] plane_co = plane.projection_of_point(site) plane_no = plane.normal.normalized() if plane.side_of_point(site) > 0: plane_no = -plane_no plane_co = plane_co - 0.5 * spacing * plane_no current_verts = np.array([tuple(v.co) for v in src_mesh.verts]) signs = PlaneEquation.from_normal_and_point( plane_no, plane_co).side_of_points(current_verts) #print(f"Plane co {plane_co}, no {plane_no}, signs {signs}") if (signs <= 0).all(): # or (signs <= 0).all(): continue res = bmesh.ops.bisect_plane(src_mesh, geom=geom_in, dist=precision, plane_co=plane_co, plane_no=plane_no, use_snap_center=False, clear_outer=True, clear_inner=False) n_cuts += 1 if fill: surround = [ e for e in res['geom_cut'] if isinstance(e, bmesh.types.BMEdge) ] if surround: fres = bmesh.ops.edgenet_prepare(src_mesh, edges=surround) if fres['edges']: bmesh.ops.edgeloop_fill(src_mesh, edges=fres['edges']) if n_cuts == 0: return None return pydata_from_bmesh(src_mesh)
def mesh_insert_verts(verts, faces, add_verts_by_face, epsilon=1e-6, exclude_boundary=True, recalc_normals=True, preserve_shape=False): if preserve_shape: bvh = BVHTree.FromPolygons(verts, faces) bm = bmesh_from_pydata(verts, [], []) for face_idx, face in enumerate(faces): n = len(face) add_verts = add_verts_by_face.get(face_idx) if not add_verts: bm_verts = [bm.verts[idx] for idx in face] bm.faces.new(bm_verts) bm.faces.index_update() continue done_verts = dict((i, bm.verts[face[i]]) for i in range(n)) face_verts = [verts[i] for i in face] new_face_verts, edges, new_faces = single_face_delaunay( face_verts, add_verts, epsilon, exclude_boundary) if preserve_shape: new_face_verts = find_nearest_points(bvh, new_face_verts) for new_face in new_faces: bm_verts = [] for i in new_face: bm_vert = done_verts.get(i) if not bm_vert: bm_vert = bm.verts.new(new_face_verts[i]) bm.verts.index_update() bm.verts.ensure_lookup_table() done_verts[i] = bm_vert bm_verts.append(bm_vert) bm.faces.new(bm_verts) bm.faces.index_update() if recalc_normals: bmesh.ops.recalc_face_normals(bm, faces=bm.faces) verts, edges, faces = pydata_from_bmesh(bm) bm.free() return verts, edges, faces
def process(self): if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons'])): return vertices_s = self.inputs['Vertices'].sv_get(default=[[]]) edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) mask_s = self.inputs['Mask'].sv_get(default=[[True]]) result_vertices = [] result_edges = [] result_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, mask_s]) for vertices, edges, faces, mask in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) bm.normal_update() fullList(mask, len(faces)) b_faces = [] for m, face in zip(mask, bm.faces): if m: b_faces.append(face) bmesh.ops.recalc_face_normals(bm, faces=b_faces) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() if self.invert: new_faces = [list(reversed(face)) for face in new_faces] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) if self.outputs['Vertices'].is_linked: self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces)
def process(self): if not any(socket.is_linked for socket in self.outputs): 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) masks_s = self.inputs['FaceMask'].sv_get(default=[[1]], deepcopy=False) factors_s = self.inputs['Factor'].sv_get(deepcopy=False) iterations_s = self.inputs['Iterations'].sv_get(deepcopy=False) verts_out = [] edges_out = [] faces_out = [] meshes = match_long_repeat( [vertices_s, edges_s, faces_s, masks_s, factors_s, iterations_s]) for vertices, edges, faces, masks, factor, iterations in zip(*meshes): if isinstance(iterations, (list, tuple)): iterations = iterations[0] if isinstance(factor, (list, tuple)): factor = factor[0] masks_matched = repeat_last_for_length(masks, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True) bm_faces = [ face for mask, face in zip(masks_matched, bm.faces[:]) if mask ] bmesh.ops.planar_faces(bm, faces=bm_faces, iterations=iterations, factor=factor) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out)
def wireframe(vertices, faces, t, self): if not faces or not vertices: return False if len(faces[0]) == 2: return False bm = bmesh_from_pydata(vertices, [], faces, normal_update=True) bmesh.ops.wireframe( bm, faces=bm.faces[:], thickness=t, offset=self.offset, use_replace=self.replace, use_boundary=self.boundary, use_even_offset=self.even_offset, use_relative_offset=self.relative_offset) return pydata_from_bmesh(bm)
def process(self): in_linked = lambda x: self.inputs[x].is_linked out_linked = lambda x: self.outputs[x].is_linked if not in_linked('Verts'): return else: if not (in_linked('Polys') or in_linked('Edges')): return if not (any(out_linked(x) for x in ['Verts', 'Edges', 'Polys'])): return verts = self.inputs['Verts'].sv_get(default=[[]]) edges = self.inputs['Edges'].sv_get(default=[[]]) faces = self.inputs['Polys'].sv_get(default=[[]]) meshes = match_long_repeat([verts, edges, faces]) r_verts = [] r_edges = [] r_faces = [] for verts, edges, faces in zip(*meshes): bm = bmesh_from_pydata(verts, edges, faces, normal_update=True) # // it's a little undocumented.. ret = bmesh.ops.dissolve_limit( bm, angle_limit=self.angle, use_dissolve_boundaries=self.use_dissolve_boundaries, verts=bm.verts, edges=bm.edges, delimit=self.delimit) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() r_verts.append(new_verts) r_edges.append(new_edges) r_faces.append(new_faces) jk = [['Verts', r_verts], ['Edges', r_edges], ['Polys', r_faces]] for x, xdata in jk: if out_linked(x): self.outputs[x].sv_set(xdata)
def process(self): if not any(socket.is_linked for socket in self.outputs): return vertices_s = self.inputs['Vertices'].sv_get() radius_s = self.inputs['Radius'].sv_get() center_s = self.inputs['Center'].sv_get() verts_out = [] edges_out = [] faces_out = [] for sites, center, radius in zip_long_repeat( vertices_s, center_s, radius_s): if isinstance(radius, (list, tuple)): radius = radius[0] center = center[0] sites = np.array( [project_to_sphere(center, radius, v) for v in sites]) vor = SphericalVoronoi(sites, radius=radius, center=np.array(center)) vor.sort_vertices_of_regions() new_verts = vor.vertices.tolist() new_faces = vor.regions #new_edges = polygons_to_edges([new_faces], True)[0] bm2 = bmesh_from_pydata(new_verts, [], new_faces, normal_update=True) bmesh.ops.recalc_face_normals(bm2, faces=bm2.faces) new_verts, new_edges, new_faces = pydata_from_bmesh(bm2) bm2.free() verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out)
def process(self): InV,InE,InP,BE,O,S,Pr = self.inputs oV,oE,oP,NP = self.outputs if not (InV.is_linked and InP.is_linked): return if not (any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'NewPolys'])): return vertices_s = InV.sv_get(default=[[]]) edges_s = InE.sv_get(default=[[]]) faces_s = InP.sv_get(default=[[]]) offsets_s = O.sv_get()[0] segments_s = S.sv_get()[0] profiles_s = Pr.sv_get()[0] bevel_edges_s = BE.sv_get(default=[[]]) out,result_bevel_faces = [],[] meshes = match_long_repeat([vertices_s, edges_s, faces_s, bevel_edges_s, offsets_s, segments_s, profiles_s]) for vertices, edges, faces, bevel_edges, offset, segments, profile in zip(*meshes): bm = bmesh_from_pydata(vertices, edges, faces) if bevel_edges: b_edges = [] for edge in bevel_edges: b_edge = [e for e in bm.edges if set([v.index for v in e.verts]) == set(edge)] b_edges.append(b_edge[0]) else: b_edges = bm.edges geom = list(bm.verts) + list(b_edges) + list(bm.faces) bevel_faces = bmesh.ops.bevel(bm, geom=geom, offset=offset, offset_type=int(self.offsetType), segments=segments, profile=profile, vertex_only=self.vertexOnly, #clamp_overlap=self.clampOverlap, material=-1)['faces'] new_bevel_faces = [[v.index for v in face.verts] for face in bevel_faces] out.append(pydata_from_bmesh(bm)) bm.free() result_bevel_faces.append(new_bevel_faces) oV.sv_set([[i[0]] for i in out]) if oE.is_linked: oE.sv_set([[i[1]] for i in out]) if oP.is_linked: oP.sv_set([[i[2]] for i in out]) if NP.is_linked: NP.sv_set(result_bevel_faces)
def clip_mesh(self, bounds, vertices, edges, faces, fill=False, iterate=None): if iterate is None: iterate = get_data_nesting_level(vertices) > 2 if iterate: vertices_result = [] edges_result = [] faces_result = [] for vertices_item, edges_item, faces_item in zip(vertices, edges, faces): new_vertices, new_edges, new_faces = self.clip_mesh(bounds, vertices_item, edges_item, faces_item, fill=fill, iterate=False) if new_vertices: vertices_result.append(new_vertices) edges_result.append(new_edges) faces_result.append(new_faces) return vertices_result, edges_result, faces_result else: bm = bmesh_from_pydata(vertices, edges, faces) self.clip_bmesh(bm, bounds, fill) vertices, edges, faces = pydata_from_bmesh(bm) bm.free() return vertices, edges, faces
def process(self): # return if no outputs are connected if not any(s.is_linked for s in self.outputs): return subdivisions_s = self.inputs['Subdivisions'].sv_get()[0] radius_s = self.inputs['Radius'].sv_get()[0] out_verts = [] out_edges = [] out_faces = [] objects = match_long_repeat([subdivisions_s, radius_s]) matrix = Matrix() for subdivisions, radius in zip(*objects): if subdivisions == 0: # In this case we just return the icosahedron verts, edges, faces = icosahedron(radius) out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) continue if subdivisions > self.subdivisions_max: subdivisions = self.subdivisions_max bm = bmesh.new() bmesh.ops.create_icosphere(bm, subdivisions=subdivisions, diameter=radius, matrix=matrix) verts, edges, faces = pydata_from_bmesh(bm) bm.free() out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) self.outputs['Vertices'].sv_set(out_verts) self.outputs['Edges'].sv_set(out_edges) self.outputs['Faces'].sv_set(out_faces)
def process(self): # return if no outputs are connected if not any(s.is_linked for s in self.outputs): return subdivisions_s = self.inputs['Subdivisions'].sv_get()[0] radius_s = self.inputs['Radius'].sv_get()[0] out_verts = [] out_edges = [] out_faces = [] objects = match_long_repeat([subdivisions_s, radius_s]) matrix = Matrix() for subdivisions, radius in zip(*objects): if subdivisions == 0: # In this case we just return the icosahedron verts, edges, faces = icosahedron(radius) out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) continue if subdivisions > self.subdivisions_max: subdivisions = self.subdivisions_max bm = bmesh.new() bmesh.ops.create_icosphere(bm, subdivisions = subdivisions, diameter = radius, matrix = matrix) verts, edges, faces = pydata_from_bmesh(bm) bm.free() out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) self.outputs['Vertices'].sv_set(out_verts) self.outputs['Edges'].sv_set(out_edges) self.outputs['Faces'].sv_set(out_faces)
def process(self): # return if no outputs are connected if not any(s.is_linked for s in self.outputs): return out_verts = [] out_edges = [] out_faces = [] bm = bmesh.new() bmesh.ops.create_monkey(bm) verts, edges, faces = pydata_from_bmesh(bm) bm.free() out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) self.outputs['Vertices'].sv_set(out_verts) self.outputs['Edges'].sv_set(out_edges) self.outputs['Faces'].sv_set(out_faces)
def process(self): # return if no outputs are connected if not any(s.is_linked for s in self.outputs): return out_verts = [] out_edges = [] out_faces = [] bm = bmesh.new() bmesh.ops.create_monkey(bm) verts, edges, faces = pydata_from_bmesh(bm) bm.free() out_verts.append(verts) out_edges.append(edges) out_faces.append(faces) self.outputs['Vertices'].sv_set(out_verts) self.outputs['Edges'].sv_set(out_edges) self.outputs['Faces'].sv_set(out_faces)
def shrink_geometry(bm, dist, layers): vlayers = bm.verts.layers made_layers = [] for idx, layer in enumerate(layers): first_element = layer[0] or 0.2 if isinstance(first_element, float): data_layer = vlayers.float.new('float_layer' + str(idx)) made_layers.append(data_layer) bm.verts.ensure_lookup_table() set_data_for_layer(bm, data_layer, layer) bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=dist) bm.verts.ensure_lookup_table() verts, edges, faces = pydata_from_bmesh(bm) data_out = [verts, edges, faces] for layer_name in made_layers: data_out.append([bm.verts[i][layer_name] for i in range(len(bm.verts))]) return data_out
def split_ridges(self, vertices, edges, faces): result_verts = [] result_edges = [] result_faces = [] for face in faces: bm = bmesh.new() face_bm_verts = [] for vertex_idx in face: vertex = vertices[vertex_idx] bm_vert = bm.verts.new(vertex) face_bm_verts.append(bm_vert) bm.faces.new(face_bm_verts) bm.verts.index_update() bm.verts.ensure_lookup_table() bm.faces.index_update() bm.edges.index_update() ridge_verts, ridge_edges, ridge_faces = pydata_from_bmesh(bm) result_verts.append(ridge_verts) result_edges.append(ridge_edges) result_faces.append(ridge_faces) return result_verts, result_edges, result_faces
def process(self): if not any(s.is_linked for s in self.outputs): return in_verts = self.inputs['Verts'].sv_get() in_faces = self.inputs['Faces'].sv_get() out_verts, out_faces = [], [] if in_verts and in_faces: fill = bmesh.ops.beautify_fill for verts, faces in zip(in_verts, in_faces): bm = bmesh_from_pydata(verts, [], faces) bm.verts.ensure_lookup_table() fill(bm, faces=bm.faces[:], edges=bm.edges[:], use_restrict_tag=False, method=0) nv, ne, nf = pydata_from_bmesh(bm) out_verts.append(nv) out_faces.append(nf) self.outputs['Verts'].sv_set(out_verts) self.outputs['Faces'].sv_set(out_faces)
def process(self): # inputs if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return vertices_s = self.inputs['Vertices'].sv_get() edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) matrices_s = self.inputs['Matrices'].sv_get(default=[[]]) if is_matrix(matrices_s[0]): matrices_s = [Matrix_generate(matrices_s)] else: matrices_s = [Matrix_generate(matrices) for matrices in matrices_s] extrude_edges_s = self.inputs['ExtrudeEdges'].sv_get(default=[[]]) result_vertices = [] result_edges = [] result_faces = [] result_ext_vertices = [] result_ext_edges = [] result_ext_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, matrices_s, extrude_edges_s]) for vertices, edges, faces, matrices, extrude_edges in zip(*meshes): if not matrices: matrices = [Matrix()] bm = bmesh_from_pydata(vertices, edges, faces) if extrude_edges: b_edges = [] for edge in extrude_edges: b_edge = [e for e in bm.edges if set([v.index for v in e.verts]) == set(edge)] b_edges.append(b_edge[0]) else: b_edges = bm.edges new_geom = bmesh.ops.extrude_edge_only(bm, edges=b_edges, use_select_history=False)['geom'] extruded_verts = [v for v in new_geom if isinstance(v, bmesh.types.BMVert)] for vertex, matrix in zip(*match_long_repeat([extruded_verts, matrices])): bmesh.ops.transform(bm, verts=[vertex], matrix=matrix, space=Matrix()) extruded_verts = [tuple(v.co) for v in extruded_verts] extruded_edges = [e for e in new_geom if isinstance(e, bmesh.types.BMEdge)] extruded_edges = [tuple(v.index for v in edge.verts) for edge in extruded_edges] extruded_faces = [f for f in new_geom if isinstance(f, bmesh.types.BMFace)] extruded_faces = [[v.index for v in edge.verts] for edge in extruded_faces] new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_ext_vertices.append(extruded_verts) result_ext_edges.append(extruded_edges) result_ext_faces.append(extruded_faces) if self.outputs['Vertices'].is_linked: self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces) if self.outputs['NewVertices'].is_linked: self.outputs['NewVertices'].sv_set(result_ext_vertices) if self.outputs['NewEdges'].is_linked: self.outputs['NewEdges'].sv_set(result_ext_edges) if self.outputs['NewFaces'].is_linked: self.outputs['NewFaces'].sv_set(result_ext_faces)
def process(self): if not self.object_names: return scene = bpy.context.scene data_objects = bpy.data.objects outputs = self.outputs edgs_out = [] vers_out = [] vers_out_grouped = [] pols_out = [] mtrx_out = [] # iterate through references for obj in (data_objects.get(o.name) for o in self.object_names): edgs = [] vers = [] vers_grouped = [] pols = [] mtrx = [] with hard_freeze(self) as _: mtrx = [list(m) for m in obj.matrix_world] if obj.type == "EMPTY": mtrx_out.append(mtrx) continue try: if obj.mode == "EDIT" and obj.type == "MESH": # Mesh objects do not currently return what you see # from 3dview while in edit mode when using obj.to_mesh. me = obj.data bm = bmesh.from_edit_mesh(me) vers, edgs, pols = pydata_from_bmesh(bm) del bm else: obj_data = obj.to_mesh(scene, self.modifiers, "PREVIEW") if obj_data.polygons: pols = [list(p.vertices) for p in obj_data.polygons] vers, vers_grouped = self.get_verts_and_vertgroups(obj_data) edgs = obj_data.edge_keys bpy.data.meshes.remove(obj_data, do_unlink=True) except: print("failure in process between frozen area", self.name) vers_out.append(vers) edgs_out.append(edgs) pols_out.append(pols) mtrx_out.append(mtrx) vers_out_grouped.append(vers_grouped) if vers_out and vers_out[0]: outputs["Vertices"].sv_set(vers_out) outputs["Edges"].sv_set(edgs_out) outputs["Polygons"].sv_set(pols_out) if "Vers_grouped" in outputs and self.vergroups: outputs["Vers_grouped"].sv_set(vers_out_grouped) outputs["Matrixes"].sv_set(mtrx_out) outputs["Object"].sv_set([data_objects.get(o.name) for o in self.object_names])
def process(self): inputs = self.inputs outputs = self.outputs if not (inputs['Vertices'].is_linked and inputs['Polygons'].is_linked): return if not any(socket.is_linked for socket in outputs): return vector_in = self.scale_socket_type vertices_s = inputs['Vertices'].sv_get() edges_s = inputs['Edges'].sv_get(default=[[]]) faces_s = inputs['Polygons'].sv_get(default=[[]]) masks_s = inputs['Mask'].sv_get(default=[[1]]) heights_s = inputs['Height'].sv_get() scales_s = inputs['Scale'].sv_get() linked_extruded_polygons = outputs['ExtrudedPolys'].is_linked linked_other_polygons = outputs['OtherPolys'].is_linked result_vertices = [] result_edges = [] result_faces = [] result_extruded_faces = [] result_other_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, masks_s, heights_s, scales_s]) for vertices, edges, faces, masks, heights, scales in zip(*meshes): new_extruded_faces = [] new_extruded_faces_append = new_extruded_faces.append fullList(heights, len(faces)) fullList(scales, len(faces)) fullList(masks, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces) extruded_faces = bmesh.ops.extrude_discrete_faces(bm, faces=bm.faces)['faces'] for face, mask, height, scale in zip(extruded_faces, masks, heights, scales): if not mask: continue vec = scale if vector_in else (scale, scale, scale) # preparing matrix normal = face.normal if normal[0] == 0 and normal[1] == 0: m_r = Matrix() if normal[2] >= 0 else Matrix.Rotation(pi, 4, 'X') else: z_axis = normal x_axis = (Vector((z_axis[1] * -1, z_axis[0], 0))).normalized() y_axis = (z_axis.cross(x_axis)).normalized() m_r = Matrix(list([*zip(x_axis[:], y_axis[:], z_axis[:])])).to_4x4() dr = face.normal * height center = face.calc_center_median() translation = Matrix.Translation(center) m = (translation * m_r).inverted() # inset, scale and push operations bmesh.ops.scale(bm, vec=vec, space=m, verts=face.verts) bmesh.ops.translate(bm, verts=face.verts, vec=dr) if linked_extruded_polygons or linked_other_polygons: new_extruded_faces_append([v.index for v in face.verts]) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() new_other_faces = [f for f in new_faces if f not in new_extruded_faces] if linked_other_polygons else [] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_extruded_faces.append(new_extruded_faces) result_other_faces.append(new_other_faces) outputs['Vertices'].sv_set(result_vertices) outputs['Edges'].sv_set(result_edges) outputs['Polygons'].sv_set(result_faces) outputs['ExtrudedPolys'].sv_set(result_extruded_faces) outputs['OtherPolys'].sv_set(result_other_faces)
def section(cut_me_vertices, cut_me_edges, mx, pp, pno, FILL=False, TRI=True): """Finds the section mesh between a mesh and a plane cut_me: Blender Mesh - the mesh to be cut mx: Matrix - The matrix of object of the mesh for correct coordinates pp: Vector - A point on the plane pno: Vector - The cutting plane's normal Returns: Mesh - the resulting mesh of the section if any or Boolean - False if no section exists""" def equation_plane(point, normal_dest): # получаем коэффициенты уравнения плоскости по точке и нормали normal = normal_dest.normalized() A = normal.x B = normal.y C = normal.z D = (A*point.x+B*point.y+C*point.z)*-1 if A < 0.0: A *= -1 B *= -1 C *= -1 D *= -1 return (A, B, C, D) def point_on_plane(v1, ep): formula = ep[0]*v1.x+ep[1]*v1.y+ep[2]*v1.z+ep[3] if formula == 0.0: return True else: return False if not cut_me_edges or not cut_me_vertices: return False verts = [] ed_xsect = {} x_me = {} ep = equation_plane(pp, pno) cut_me_polygons = [] if len(cut_me_edges[0]) > 2: cut_me_polygons = cut_me_edges.copy() cut_me_edges = [] new_me = bpy.data.meshes.new('tempus') new_me.from_pydata(cut_me_vertices, cut_me_edges, cut_me_polygons) new_me.update(calc_edges=True) for ed_idx, ed in enumerate(new_me.edges): # getting a vector from each edge vertices to a point on the plane # first apply transformation matrix so we get the real section vert1 = ed.vertices[0] v1 = new_me.vertices[vert1].co * mx.transposed() vert2 = ed.vertices[1] v2 = new_me.vertices[vert2].co * mx.transposed() vec = v2-v1 mul = vec * pno if mul == 0.0: if not point_on_plane(v1, ep): # parallel and not on plane continue epv = ep[0]*vec.x + ep[1]*vec.y + ep[2]*vec.z if epv == 0: t0 = 0 else: t0 = -(ep[0]*v1.x+ep[1]*v1.y+ep[2]*v1.z + ep[3]) / epv pq = vec*t0+v1 if (pq-v1).length <= vec.length and (pq-v2).length <= vec.length: verts.append(pq) ed_xsect[ed.key] = len(ed_xsect) edges = [] for f in new_me.polygons: # get the edges that the intersecting points form # to explain this better: # If a face has an edge that is proven to be crossed then use the # mapping we created earlier to connect the edges properly ps = [ed_xsect[key] for key in f.edge_keys if key in ed_xsect] if len(ps) == 2: edges.append(tuple(ps)) x_me['Verts'] = verts x_me['Edges'] = edges bpy.data.meshes.remove(new_me) if x_me: if edges and FILL: bm = bmesh_from_pydata(verts, edges, []) bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=0.000002) fres = bmesh.ops.edgenet_prepare(bm, edges=bm.edges[:]) if not TRI: # Alt + F bmesh.ops.triangle_fill(bm, use_beauty=True, use_dissolve=False, edges=fres['edges']) else: # can generate N-Gons bmesh.ops.edgeloop_fill(bm, edges=fres['edges']) # incase there are islands generated by the above operations, and said islands have varying # normals (up/down flipped due to lack of surrounding information), then we force all faces # to conform to the normal as obtained by the Matrix that generates this cut. normal_consistent(bm, pno) bm.verts.index_update() bm.edges.index_update() bm.faces.index_update() verts, edges, faces = pydata_from_bmesh(bm) x_me['Verts'] = verts x_me['Edges'] = faces # edges -- this was outputting faces into edges when fill was ticked? bm.clear() bm.free() return x_me else: return False
def process(self): if not any(output.is_linked for output in self.outputs): return vertices_s = self.inputs['Vertices'].sv_get() edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Faces'].sv_get(default=[[]]) masks_s = self.inputs['VertMask'].sv_get(default=[[1]]) iterations_s = self.inputs['Iterations'].sv_get()[0] if not self.laplacian: clip_dist_s = self.inputs['ClipDist'].sv_get()[0] else: clip_dist_s = [0.0] factor_s = self.inputs['Factor'].sv_get()[0] if self.laplacian: border_factor_s = self.inputs['BorderFactor'].sv_get()[0] else: border_factor_s = [0.0] result_vertices = [] result_edges = [] result_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, masks_s, clip_dist_s, factor_s, border_factor_s, iterations_s]) for vertices, edges, faces, masks, clip_dist, factor, border_factor, iterations in zip(*meshes): fullList(masks, len(vertices)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True) bm.verts.ensure_lookup_table() bm.edges.ensure_lookup_table() bm.faces.ensure_lookup_table() selected_verts = [vert for mask, vert in zip(masks, bm.verts) if mask] for i in range(iterations): if self.laplacian: # for some reason smooth_laplacian_vert does not work properly if faces are not selected for f in bm.faces: f.select = True bmesh.ops.smooth_laplacian_vert(bm, verts = selected_verts, lambda_factor = factor, lambda_border = border_factor, use_x = self.use_x, use_y = self.use_y, use_z = self.use_z, preserve_volume = self.preserve_volume) else: bmesh.ops.smooth_vert(bm, verts = selected_verts, factor = factor, mirror_clip_x = self.mirror_clip_x, mirror_clip_y = self.mirror_clip_y, mirror_clip_z = self.mirror_clip_z, clip_dist = clip_dist, use_axis_x = self.use_x, use_axis_y = self.use_y, use_axis_z = self.use_z) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) self.outputs['Vertices'].sv_set(result_vertices) self.outputs['Edges'].sv_set(result_edges) self.outputs['Faces'].sv_set(result_faces)
def sv_main(verts=[],edges=[], faces=[], rseed=21, offset=20, braid = 0.0): in_sockets = [ ['v', 'Vertices', verts], ['s', 'Edges', edges], ['s', 'Faces', faces], ['s', 'rseed', rseed], ['s', 'offset', offset], ['s', 'braid', braid] ] links = [] verts_maze = [] verts_path = [] edges_path = [] faces_path = [] verts_wall = [] edges_wall = [] faces_wall = [] random.seed(rseed) if verts and edges: if faces: # don't use edges with a vertex on boundary for maze generation bm_maze = bmesh_from_pydata(verts[0], edges[0], faces[0]) # make a list of boundary verts boundary_verts = [v for v in bm_maze.verts if v.is_boundary] #remove these verts bmesh.ops.delete(bm_maze, geom=boundary_verts, context=1) #convert back to sverchok lists and generate maze on these verts_maze, edges_maze, faces_maze = pydata_from_bmesh(bm_maze) links = recursive_back_tracker_maze(verts_maze, edges_maze) if braid > 0 and braid <= 1.0: links = do_braid(verts_maze, edges_maze, links, braid) bm_maze.free() #bevel the whole mesh bm = bmesh_from_pydata(verts[0], edges[0], faces[0]) geom = list(bm.verts) + list(bm.edges) + list(bm.faces) bevel_faces = bmesh.ops.bevel(bm, geom=geom, offset=offset, offset_type=3, segments=1, profile=0.5, vertex_only=0, material=-1)['faces'] #match ids of bevelled face to links #find center of each new face in bevel mesh face_centers = [f.calc_center_median() for f in bm.faces] #make a kdtree from face centers of bevel faces kd = mathutils.kdtree.KDTree(len(face_centers)) for i, c in enumerate(face_centers): kd.insert(c, i) kd.balance() #find center of each link in maze link_centers = [] for e in links: x,y,z = zip(*[verts_maze[poi] for poi in e]) x,y,z = sum(x)/len(x), sum(y)/len(y), sum(z)/len(z) link_centers.append((x,y,z)) #find index of closest face center to the center of each link and each maze vertex path_face_ids = [kd.find(v)[1] for v in verts_maze + link_centers] #delete the walls form the path mesh bm_path = bm.copy() bm_path.faces.ensure_lookup_table() wall_faces = [ bm_path.faces[id] for id,fc in enumerate(face_centers) if id not in path_face_ids ] bmesh.ops.delete(bm_path, geom=wall_faces, context=5) verts_path, edges_path, faces_path = pydata_from_bmesh(bm_path) bm_path.free() #delete the path from the wall mesh bm.faces.ensure_lookup_table() path_faces = list(set([bm.faces[id] for id in path_face_ids])) bmesh.ops.delete(bm, geom=path_faces, context=5) verts_wall, edges_wall, faces_wall = pydata_from_bmesh(bm) bm.free() else: # no faces just make links verts_maze = verts[0] links = recursive_back_tracker_maze(verts[0], edges[0]) out_sockets = [ ['v', 'Link Vertices', [verts_maze] ], ['s', 'Link Edges', [links]], ['v', 'Path Vertices', [verts_path]], ['s', 'Path Edges', [edges_path] ], ['s', 'Path Faces', [faces_path] ], ['v', 'Wall Vertices', [verts_wall]], ['s', 'Wall Edges', [edges_wall] ], ['s', 'Wall Faces', [faces_wall] ] ] return in_sockets, out_sockets
def process(self): if not any(output.is_linked for output in self.outputs): return vertices_s = self.inputs['Vertices'].sv_get() edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Faces'].sv_get(default=[[]]) masks_s = self.inputs['EdgeMask'].sv_get(default=[[1]]) cuts_s = self.inputs['Cuts'].sv_get()[0] smooth_s = self.inputs['Smooth'].sv_get()[0] fractal_s = self.inputs['Fractal'].sv_get()[0] along_normal_s = self.inputs['AlongNormal'].sv_get()[0] seed_s = self.inputs['Seed'].sv_get()[0] result_vertices = [] result_edges = [] result_faces = [] r_inner_vertices = [] r_inner_edges = [] r_inner_faces = [] r_split_vertices = [] r_split_edges = [] r_split_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, masks_s, cuts_s, smooth_s, fractal_s, along_normal_s, seed_s]) for vertices, edges, faces, masks, cuts, smooth, fractal, along_normal, seed in zip(*meshes): fullList(masks, len(edges)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True) selected_edges = [] for m, edge in zip(masks, edges): if not m: continue found = False for bmesh_edge in bm.edges: if set(v.index for v in bmesh_edge.verts) == set(edge): found = True break if found: selected_edges.append(bmesh_edge) else: print("Cant find edge: " + str(edge)) geom = bmesh.ops.subdivide_edges(bm, edges = selected_edges, smooth = smooth, smooth_falloff = int(self.falloff_type), fractal = fractal, along_normal = along_normal, cuts = cuts, seed = seed, quad_corner_type = int(self.corner_type), use_grid_fill = self.grid_fill, use_single_edge = self.single_edge, use_only_quads = self.only_quads, use_smooth_even = self.smooth_even) new_verts, new_edges, new_faces = pydata_from_bmesh(bm) inner_verts, inner_edges, inner_faces = self.get_result_pydata(geom['geom_inner']) split_verts, split_edges, split_faces = self.get_result_pydata(geom['geom_split']) bm.free() result_vertices.append(new_verts) result_edges.append(new_edges) result_faces.append(new_faces) r_inner_vertices.append(inner_verts) r_inner_edges.append(inner_edges) r_inner_faces.append(inner_faces) r_split_vertices.append(split_verts) r_split_edges.append(split_edges) r_split_faces.append(split_faces) self.outputs['Vertices'].sv_set(result_vertices) self.outputs['Edges'].sv_set(result_edges) self.outputs['Faces'].sv_set(result_faces) self.outputs['NewVertices'].sv_set(r_inner_vertices) self.outputs['NewEdges'].sv_set(r_inner_edges) self.outputs['NewFaces'].sv_set(r_inner_faces) self.outputs['OldVertices'].sv_set(r_split_vertices) self.outputs['OldEdges'].sv_set(r_split_edges) self.outputs['OldFaces'].sv_set(r_split_faces)
def perform_mextrude(self, bm, sel): after = [] origin = Vector([0.0, 0.0, 0.0]) # faces loop for i, of in enumerate(sel): nro = nrot(self, of.normal) off = vloc(self, i) loc = gloc(self, i) of.normal_update() # initial rotation noise if not self.opt3: rot = vrot(self, i) # initial scale noise if not self.opt4: s = vsca(self, i) # extrusion loop for r in range(self.num): # random probability % for extrusions if self.var4 > int(random.random() * 100): nf = of.copy() nf.normal_update() no = nf.normal.copy() # face/obj coördinates if self.opt1: ce = nf.calc_center_bounds() else: ce = origin # per step rotation noise if self.opt3: rot = vrot(self, i + r) # per step scale noise if self.opt4: s = vsca(self, i + r) # proportional, scale * offset if self.opt2: off = s * off for v in nf.verts: v.co -= ce v.co.rotate(nro) v.co.rotate(rot) v.co += ce + loc + no * off v.co = v.co.lerp(ce, 1 - s) # extrude code from TrumanBlending for a, b in zip(of.loops, nf.loops): sf = bm.faces.new((a.vert, a.link_loop_next.vert, b.link_loop_next.vert, b.vert)) sf.normal_update() bm.faces.remove(of) of = nf bm.verts.index_update() bm.faces.index_update() after.append(of) for v in bm.verts: v.select = False for e in bm.edges: e.select = False for f in after: f.select = f not in sel out_verts, _, out_faces = pydata_from_bmesh(bm) del bm return (out_verts, out_faces) or None
def process(self): # inputs if not (self.inputs['Vertices'].is_linked and self.inputs['Polygons'].is_linked): return if not any(self.outputs[name].is_linked for name in ['Vertices', 'Edges', 'Polygons', 'ExtrudedPolys', 'OtherPolys']): return vertices_s = self.inputs['Vertices'].sv_get() edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) masks_s = self.inputs['Mask'].sv_get(default=[[1]]) heights_s = self.inputs['Height'].sv_get() scales_s = self.inputs['Scale'].sv_get() result_vertices = [] result_edges = [] result_faces = [] result_extruded_faces = [] result_other_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, masks_s, heights_s, scales_s]) offset = 0 for vertices, edges, faces, masks, heights, scales in zip(*meshes): fullList(heights, len(faces)) fullList(scales, len(faces)) fullList(masks, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces) extruded_faces = bmesh.ops.extrude_discrete_faces(bm, faces=bm.faces)['faces'] new_extruded_faces = [] for face, mask, height, scale in zip(extruded_faces, masks, heights, scales): if not mask: continue dr = face.normal * height center = face.calc_center_median() translation = Matrix.Translation(center) rotation = face.normal.rotation_difference((0,0,1)).to_matrix().to_4x4() #rotation = autorotate(z, face.normal).inverted() m = translation * rotation bmesh.ops.scale(bm, vec=(scale, scale, scale), space=m.inverted(), verts=face.verts) bmesh.ops.translate(bm, verts=face.verts, vec=dr) new_extruded_faces.append([v.index for v in face.verts]) new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() new_other_faces = [f for f in new_faces if f not in new_extruded_faces] result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_extruded_faces.append(new_extruded_faces) result_other_faces.append(new_other_faces) self.outputs['Vertices'].sv_set(result_vertices) if self.outputs['Edges'].is_linked: self.outputs['Edges'].sv_set(result_edges) if self.outputs['Polygons'].is_linked: self.outputs['Polygons'].sv_set(result_faces) if self.outputs['ExtrudedPolys'].is_linked: self.outputs['ExtrudedPolys'].sv_set(result_extruded_faces) if self.outputs['OtherPolys'].is_linked: self.outputs['OtherPolys'].sv_set(result_other_faces)
def process(self): # inputs if not self.inputs['Vertices'].is_linked: return vertices_s = self.inputs['Vertices'].sv_get() edges_s = self.inputs['Edges'].sv_get(default=[[]]) faces_s = self.inputs['Polygons'].sv_get(default=[[]]) masks_s = self.inputs['Mask'].sv_get(default=[[1]]) if self.transform_mode == "Matrix": matrices_s = [self.inputs['Matrices'].sv_get(Matrix())] heights_s = [0.0] scales_s = [1.0] else: matrices_s = [[]] heights_s = self.inputs['Height'].sv_get() scales_s = self.inputs['Scale'].sv_get() result_vertices = [] result_edges = [] result_faces = [] result_ext_vertices = [] result_ext_edges = [] result_ext_faces = [] meshes = match_long_repeat([vertices_s, edges_s, faces_s, masks_s, matrices_s, heights_s, scales_s]) for vertices, edges, faces, masks, matrix_per_iteration, height_per_iteration, scale_per_iteration in zip(*meshes): if self.transform_mode == "Matrix": if not matrix_per_iteration: matrix_per_iteration = [Matrix()] if self.multiple: if self.transform_mode == "Matrix": n_iterations = len(matrix_per_iteration) else: n_iterations = max(len(height_per_iteration), len(scale_per_iteration)) fullList(height_per_iteration, n_iterations) fullList(scale_per_iteration, n_iterations) else: n_iterations = 1 matrix_per_iteration = [matrix_per_iteration] fullList(masks, len(faces)) bm = bmesh_from_pydata(vertices, edges, faces, normal_update=True) b_faces = [] b_edges = set() b_verts = set() for mask, face in zip(masks, bm.faces): if mask: b_faces.append(face) for edge in face.edges: b_edges.add(edge) for vert in face.verts: b_verts.add(vert) extrude_geom = b_faces+list(b_edges)+list(b_verts) extruded_verts_last = [] extruded_edges_last = [] extruded_faces_last = [] matrix_spaces = [Matrix()] for idx in range(n_iterations): new_geom = bmesh.ops.extrude_face_region(bm, geom=extrude_geom, edges_exclude=set(), use_keep_orig=self.keep_original)['geom'] extruded_verts = [v for v in new_geom if isinstance(v, bmesh.types.BMVert)] extruded_faces = [f for f in new_geom if isinstance(f, bmesh.types.BMFace)] if self.transform_mode == "Matrix": matrices = matrix_per_iteration[idx] if isinstance(matrices, Matrix): matrices = [matrices] fullList(matrix_spaces, len(extruded_verts)) for vertex_idx, (vertex, matrix) in enumerate(zip(*match_long_repeat([extruded_verts, matrices]))): bmesh.ops.transform(bm, verts=[vertex], matrix=matrix, space=matrix_spaces[vertex_idx]) matrix_spaces[vertex_idx] = matrix.inverted() * matrix_spaces[vertex_idx] else: height = height_per_iteration[idx] scale = scale_per_iteration[idx] normal = get_avg_normal(extruded_faces) dr = normal * height center = get_faces_center(extruded_faces) translation = Matrix.Translation(center) rotation = normal.rotation_difference((0,0,1)).to_matrix().to_4x4() m = translation * rotation bmesh.ops.scale(bm, vec=(scale, scale, scale), space=m.inverted(), verts=extruded_verts) bmesh.ops.translate(bm, verts=extruded_verts, vec=dr) extruded_verts_last = [tuple(v.co) for v in extruded_verts] extruded_edges = [e for e in new_geom if isinstance(e, bmesh.types.BMEdge)] extruded_edges_last = [tuple(v.index for v in edge.verts) for edge in extruded_edges] extruded_faces_last = [[v.index for v in edge.verts] for edge in extruded_faces] extrude_geom = new_geom new_vertices, new_edges, new_faces = pydata_from_bmesh(bm) bm.free() result_vertices.append(new_vertices) result_edges.append(new_edges) result_faces.append(new_faces) result_ext_vertices.append(extruded_verts_last) result_ext_edges.append(extruded_edges_last) result_ext_faces.append(extruded_faces_last) self.outputs['Vertices'].sv_set(result_vertices) self.outputs['Edges'].sv_set(result_edges) self.outputs['Polygons'].sv_set(result_faces) self.outputs['NewVertices'].sv_set(result_ext_vertices) self.outputs['NewEdges'].sv_set(result_ext_edges) self.outputs['NewFaces'].sv_set(result_ext_faces)