def process(self): if not self.inputs['Vertices'].is_linked: return if not self.outputs['Vertices'].is_linked: return vertices_s = self.inputs['Vertices'].sv_get() points_s = self.inputs['GridPoints'].sv_get() smooth_s = self.inputs['Smooth'].sv_get() degree_s = self.inputs['Degree'].sv_get() weights_s = self.inputs['Weights'].sv_get(default=[[1.0]]) matrices_s = self.inputs['Matrix'].sv_get(default=[[Matrix()]]) verts_out = [] edges_out = [] faces_out = [] for vertices, weights, degree, matrix, smooth, grid_points in zip_long_repeat( vertices_s, weights_s, degree_s, matrices_s, smooth_s, points_s): if isinstance(grid_points, (list, tuple)): grid_points = grid_points[0] if isinstance(degree, (list, tuple)): degree = degree[0] if isinstance(smooth, (list, tuple)): smooth = smooth[0] if isinstance(matrix, list): matrix = matrix[0] has_matrix = matrix is not None and matrix != Matrix() fullList(weights, len(vertices)) smooth = smooth * len(vertices) XYZ = np.array(vertices) if has_matrix: np_matrix = np.array(matrix.to_3x3()) inv_matrix = np.linalg.inv(np_matrix) #print(matrix) #print(XYZ) translation = np.array(matrix.translation) XYZ = np.matmul(inv_matrix, XYZ.T).T + translation if self.orientation == 'X': reorder = np.array([1, 2, 0]) XYZ = XYZ[:, reorder] elif self.orientation == 'Y': reorder = np.array([2, 0, 1]) XYZ = XYZ[:, reorder] else: # Z pass x_min = XYZ[:, 0].min() x_max = XYZ[:, 0].max() y_min = XYZ[:, 1].min() y_max = XYZ[:, 1].max() xi = np.linspace(x_min, x_max, grid_points) yi = np.linspace(y_min, y_max, grid_points) XI, YI = np.meshgrid(xi, yi) spline = SmoothBivariateSpline(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], kx=degree, ky=degree, w=weights, s=smooth) ZI = spline(xi, yi) if self.orientation == 'X': YI, ZI, XI = XI, YI, ZI elif self.orientation == 'Y': ZI, XI, YI = XI, YI, ZI else: # Z pass new_verts = np.dstack((YI, XI, ZI)) if has_matrix: new_verts = new_verts - translation new_verts = np.apply_along_axis(lambda v: np_matrix @ v, 2, new_verts) new_verts = new_verts.tolist() new_verts = sum(new_verts, []) new_edges = self.make_edges(grid_points) new_faces = self.make_faces(grid_points) 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)
""" Find vector rotation according to X axis. :arg vec: Input vector. :type vec: :class:'mathutils.Vector' :return: Angle in radians. :rtype: float """ v0 = Vector((1,0)) ang = Vector.angle_signed(vec, v0) if ang < 0: ang = 2*pi + ang return ang verts_out = [] edges_out = [] faces_out = [] for verts, edges, faces, thickness, subdivisions in zip_long_repeat(verts_in, edges_in, faces_in, thickness_in, subdivisions_in): if isinstance(thickness, (list, tuple)): thickness = thickness[0] if isinstance(subdivisions, (list, tuple)): subdivisions = subdivisions[0] #faces = list(set([tuple(f) for f in faces])) uniq_faces = [] for face in faces: if set(face) in [set(f) for f in uniq_faces]: pass #print(face) else: uniq_faces.append(face) bm = bmesh_from_pydata(verts, [], uniq_faces, normal_update=True) merge_dist = thickness*0.001
def process(self): if not any(socket.is_linked for socket in self.outputs): return surfaces_s = self.inputs['Surface'].sv_get() surface_level = get_data_nesting_level(surfaces_s, data_types=(SvSurface, )) surfaces_s = ensure_nesting_level(surfaces_s, 2, data_types=(SvSurface, )) src_point_s = self.inputs['UVPoints'].sv_get(default=[[]]) src_point_s = ensure_nesting_level(src_point_s, 4) src_u_s = self.inputs['U'].sv_get() src_u_s = ensure_nesting_level(src_u_s, 3) src_v_s = self.inputs['V'].sv_get() src_v_s = ensure_nesting_level(src_v_s, 3) normal_out = [] tangent_u_out = [] tangent_v_out = [] matrix_out = [] area_out = [] du_out = [] dv_out = [] for surfaces, src_points_i, src_u_i, src_v_i in zip_long_repeat( surfaces_s, src_point_s, src_u_s, src_v_s): new_normals = [] new_tangent_u = [] new_tangent_v = [] new_area = [] new_du = [] new_dv = [] for surface, src_points, src_us, src_vs in zip_long_repeat( surfaces, src_points_i, src_u_i, src_v_i): if self.input_mode == 'VERTICES': us, vs = self.parse_input(src_points) else: maxlen = max(len(src_us), len(src_vs)) src_us = repeat_last_for_length(src_us, maxlen) src_vs = repeat_last_for_length(src_vs, maxlen) us, vs = np.array(src_us), np.array(src_vs) data = surface.derivatives_data_array(us, vs) new_normals.append(data.unit_normals().tolist()) du, dv = data.unit_tangents() new_tangent_u.append(du.tolist()) new_tangent_v.append(dv.tolist()) normals_len = [n[0] for n in data.normals_len().tolist()] new_area.append(normals_len) du_len, dv_len = data.tangent_lens() du_len = [n[0] for n in du_len.tolist()] dv_len = [n[0] for n in dv_len.tolist()] new_du.append(du_len) new_dv.append(dv_len) matrix_out.extend(data.matrices(as_mathutils=True)) normal_out.append(new_normals) tangent_u_out.append(new_tangent_u) tangent_v_out.append(new_tangent_v) area_out.append(new_area) if surface_level == 2: du_out.append(new_du) dv_out.append(new_dv) else: du_out.extend(new_du) dv_out.extend(new_dv) self.outputs['Normal'].sv_set(normal_out) self.outputs['TangentU'].sv_set(tangent_u_out) self.outputs['TangentV'].sv_set(tangent_v_out) self.outputs['Matrix'].sv_set(matrix_out) self.outputs['AreaStretch'].sv_set(area_out) self.outputs['StretchU'].sv_set(du_out) self.outputs['StretchV'].sv_set(dv_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return solid_in = self.inputs['Solid'].sv_get() sites_in = self.inputs['Sites'].sv_get() inset_in = self.inputs['Inset'].sv_get() solid_in = ensure_nesting_level(solid_in, 2, data_types=(Part.Shape,)) input_level = get_data_nesting_level(sites_in) sites_in = ensure_nesting_level(sites_in, 4) inset_in = ensure_min_nesting(inset_in, 2) nested_output = input_level > 3 need_inner = self.outputs['InnerSolid'].is_linked need_outer = self.outputs['OuterSolid'].is_linked precision = 10 ** (-self.accuracy) inner_fragments_out = [] outer_fragments_out = [] for params in zip_long_repeat(solid_in, sites_in, inset_in): new_inner_fragments = [] new_outer_fragments = [] for solid, sites, inset in zip_long_repeat(*params): verts, edges, faces = voronoi_on_solid(solid, sites, do_clip=True, clipping=None) if isinstance(inset, list): inset = repeat_last_for_length(inset, len(sites)) else: inset = [inset for i in range(len(sites))] verts = self.scale_cells(verts, sites, inset, precision) fragments = [svmesh_to_solid(vs, fs, precision, method=BMESH, remove_splitter=False) for vs, fs in zip(verts, faces)] if self.mode == 'SURFACE': if solid.Shells: shell = solid.Shells[0] else: shell = Part.Shell(solid.Faces) src = shell else: # VOLUME src = solid if need_inner: inner = [src.common(fragment) for fragment in fragments] if self.flat_output: new_inner_fragments.extend(inner) else: new_inner_fragments.append(inner) if need_outer: outer = [src.cut(fragments)] if self.flat_output: new_outer_fragments.extend(outer) else: new_outer_fragments.append(outer) if nested_output: inner_fragments_out.append(new_inner_fragments) outer_fragments_out.append(new_outer_fragments) else: inner_fragments_out.extend(new_inner_fragments) outer_fragments_out.extend(new_outer_fragments) self.outputs['InnerSolid'].sv_set(inner_fragments_out) self.outputs['OuterSolid'].sv_set(outer_fragments_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return field_s = self.inputs['Field'].sv_get() bounds_s = self.inputs['Bounds'].sv_get() samples_xy_s = self.inputs['SamplesXY'].sv_get() samples_z_s = self.inputs['SamplesZ'].sv_get() samples_value_s = self.inputs['ValueSamples'].sv_get() verts_out = [] edges_out = [] faces_out = [] inputs = zip_long_repeat(field_s, bounds_s, samples_xy_s, samples_z_s, samples_value_s) for field, bounds, samples_xy, samples_z, samples_value in inputs: if isinstance(samples_xy, (list, tuple)): samples_xy = samples_xy[0] if isinstance(samples_z, (list, tuple)): samples_z = samples_z[0] if isinstance(samples_value, (list, tuple)): samples_value = samples_value[0] b1, b2 = self.get_bounds(bounds) min_x, max_x = b1[0], b2[0] min_y, max_y = b1[1], b2[1] min_z, max_z = b1[2], b2[2] x_size = (max_x - min_x) / samples_xy y_size = (max_y - min_y) / samples_xy x_range = np.linspace(min_x, max_x, num=samples_xy) y_range = np.linspace(min_y, max_y, num=samples_xy) z_range = np.linspace(min_z, max_z, num=samples_z) xs, ys, zs = np.meshgrid(x_range, y_range, z_range, indexing='ij') xs, ys, zs = xs.flatten(), ys.flatten(), zs.flatten() field_values = field.evaluate_grid(xs, ys, zs) min_field = field_values.min() max_field = field_values.max() field_values = field_values.reshape( (samples_xy, samples_xy, samples_z)) field_stops = np.linspace(min_field, max_field, num=samples_value) new_verts = [] new_edges = [] new_faces = [] for i in range(samples_z): z_value = zs[i] z_verts = [] z_edges = [] z_faces = [] for j in range(samples_value): value = field_stops[j] contours = measure.find_contours(field_values[:, :, i], level=value) value_verts, value_edges, value_faces = make_contours( samples_xy, samples_xy, min_x, x_size, min_y, y_size, z_value, contours, make_faces=self.make_faces, connect_bounds=self.connect_bounds) if value_verts: z_verts.extend(value_verts) z_edges.extend(value_edges) z_faces.extend(value_faces) new_verts.extend(z_verts) new_edges.extend(z_edges) new_faces.extend(z_faces) if self.join: new_verts, new_edges, new_faces = mesh_join( new_verts, new_edges, new_faces) verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) else: 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)
def process(self): if not any(socket.is_linked for socket in self.outputs): return obj_vertices_s = self.inputs['ObjVertices'].sv_get() obj_edges_s = self.inputs['ObjEdges'].sv_get(default=[[]]) obj_faces_s = self.inputs['ObjFaces'].sv_get() surf_vertices_s = self.inputs['SurfVertices'].sv_get() surf_edges_s = self.inputs['SurfEdges'].sv_get(default=[[]]) surf_faces_s = self.inputs['SurfFaces'].sv_get() fill_sides_s = self.inputs['FillSides'].sv_get() def remember_connection(edges_by_face, bm_edge, bm_intersection): for face in bm_edge.link_faces: edges_by_face[face].append((bm_intersection, bm_edge.index)) cut_verts_out = [] cut_edges_out = [] cut_faces_out = [] obj_verts_out = [] obj_edges_out = [] obj_faces_out = [] inputs = zip_long_repeat(obj_vertices_s, obj_edges_s, obj_faces_s, surf_vertices_s, surf_edges_s, surf_faces_s, fill_sides_s) for obj_vertices, obj_edges, obj_faces, surf_vertices, surf_edges, surf_faces, fill_sides in inputs: if self.fill: if isinstance(fill_sides, (list, tuple)): fill_sides = fill_sides[0] # We are using bvh's raycast to calculate intersections of object's edges # with the surface. bvh = mathutils.bvhtree.BVHTree.FromPolygons( surf_vertices, surf_faces) bm_obj = bmesh_from_pydata(obj_vertices, obj_edges, obj_faces) bm_cut = bmesh.new() edges_by_face = defaultdict(list) bm_obj.verts.index_update() bm_obj.edges.index_update() for bm_edge in bm_obj.edges: v1, v2 = bm_edge.verts edge = v1.co - v2.co # Distance restriction is used to find only intersections which are within the edge, # not anywhere on the ray. distance = edge.length # Since raycast's ray is single-directioned, we have to check for intersections # twice: from V1 to V2 and from V2 to V1. cast = bvh.ray_cast(v1.co, -edge, distance) #self.debug("Edge %s: %s -> %s, Cast 0: %s", bm_edge.index, v1.co, edge, cast) intersection = cast[0] if intersection is not None: bm_intersection = bm_cut.verts.new(intersection) remember_connection(edges_by_face, bm_edge, bm_intersection) else: cast = bvh.ray_cast(v2.co, edge, distance) #self.debug("Edge %s: %s -> %s, Cast 1: %s", bm_edge.index, v2.co, -edge, cast) intersection = cast[0] if intersection is not None: bm_intersection = bm_cut.verts.new(intersection) remember_connection(edges_by_face, bm_edge, bm_intersection) bm_cut.verts.index_update() # Make "cut surface" object. # Of each object's face we are cutting, make an edge. bm_cut_edges = [] for intersections in edges_by_face.values(): if len(intersections) == 1: self.debug( "Only one of object face's edges intersects the surface" ) continue if len(intersections) > 2: # Some day we may support splitting the face in more than two pieces; # but the algorithm will be more complicated then. raise Exception( "Unsupported: more than two edges of the face intersect the surface" ) v1, v2 = intersections[0][0], intersections[1][0] bm_edge = bm_cut.edges.new((v1, v2)) bm_cut_edges.append(bm_edge) if len(bm_cut.verts) > 0: if self.fill: bmesh.ops.holes_fill(bm_cut, edges=bm_cut_edges, sides=fill_sides) new_verts_cut, new_edges_cut, new_faces_cut = pydata_from_bmesh( bm_cut) if self.make_pieces: new_verts_by_old_edge = dict() new_verts_by_old_face = dict() for old_obj_face in edges_by_face: intersections = edges_by_face[old_obj_face] if len(intersections) == 1: continue int1, int2 = intersections intersection1, intersection2 = int1[0].co, int2[0].co old_edge1, old_edge2 = int1[1], int2[1] # Create a vertex in the "object" mesh at each intersection of # it's edge with the surface. # Remember which of new vertices corresponds to which edge. if old_edge1 not in new_verts_by_old_edge: new_vert_1 = bm_obj.verts.new(intersection1) new_verts_by_old_edge[old_edge1] = new_vert_1 else: new_vert_1 = new_verts_by_old_edge[old_edge1] if old_edge2 not in new_verts_by_old_edge: new_vert_2 = bm_obj.verts.new(intersection2) new_verts_by_old_edge[old_edge2] = new_vert_2 else: new_vert_2 = new_verts_by_old_edge[old_edge2] new_verts_by_old_face[old_obj_face] = (new_vert_1, new_vert_2) bm_obj.verts.index_update() faces_to_remove = [] edges_to_remove = [] for old_obj_face in edges_by_face: intersections = edges_by_face[old_obj_face] if len(intersections) == 1: continue # Walk through the edges of each face we are cutting, in order. # Of each such face, we are making two. So in this loop we have # two states: new_face_state == True means we are on the one side of # the cut, False means we are on the another. Note that we do not know # which is which (for example, which one is "inside" the surface); but # it does not matter for us. # So new_face_verts[True] will contain vertices of one piece, # new_face_verts[False] - of another one. new_face_verts = defaultdict(list) new_face_side = True old_vert_pairs = list( zip(old_obj_face.verts, old_obj_face.verts[1:])) + [ (old_obj_face.verts[-1], old_obj_face.verts[0]) ] need_split = False for old_vert_1, old_vert_2 in old_vert_pairs: old_edge = bm_obj.edges.get((old_vert_1, old_vert_2)) if old_edge.index in new_verts_by_old_edge: edges_to_remove.append( (old_edge.verts[0], old_edge.verts[1])) need_split = True new_vert_1 = new_verts_by_old_edge[old_edge.index] self.debug( "Old edge %s - %s is to be split; use new vert %s", old_vert_1.index, old_vert_2.index, new_vert_1.index) new_face_verts[new_face_side].append(new_vert_1) # if this edge is to be split, then we are stepping from one piece of # the face to another new_face_side = not new_face_side new_face_verts[new_face_side].append(new_vert_1) new_face_verts[new_face_side].append(old_vert_2) else: self.debug("Old edge %s - %s is not to be split", old_vert_1.index, old_vert_2.index) new_face_verts[new_face_side].append(old_vert_2) if need_split: faces_to_remove.append(old_obj_face) self.debug("Splitting face: %s", [v.index for v in old_obj_face.verts]) for new_face_list in new_face_verts.values(): bm_obj.faces.new(new_face_list) # remove old faces and edges (ones we cut in two) for old_face in faces_to_remove: bm_obj.faces.remove(old_face) for old_v1, old_v2 in edges_to_remove: # we can't just remember BMEdge instances themselve, # since they will be invalidated when we remove faces. old_edge = bm_obj.edges.get((old_v1, old_v2)) if old_edge: bm_obj.edges.remove(old_edge) edges_to_split = [] for new_vert_1, new_vert_2 in new_verts_by_old_face.values(): edge = bm_obj.edges.get((new_vert_1, new_vert_2)) edges_to_split.append(edge) # Split "object" by remembered cut edges. There will be "holes" # at places we cut. split_result = bmesh.ops.split_edges(bm_obj, edges=edges_to_split) if self.fill: bmesh.ops.holes_fill(bm_obj, edges=split_result['edges'], sides=fill_sides) new_verts_obj, new_edges_obj, new_faces_obj = pydata_from_bmesh( bm_obj) else: new_verts_obj, new_edges_obj, new_faces_obj = [], [], [] bm_cut.free() bm_obj.free() cut_verts_out.append(new_verts_cut) cut_edges_out.append(new_edges_cut) cut_faces_out.append(new_faces_cut) obj_verts_out.append(new_verts_obj) obj_edges_out.append(new_edges_obj) obj_faces_out.append(new_faces_obj) self.outputs['CutVertices'].sv_set(cut_verts_out) self.outputs['CutEdges'].sv_set(cut_edges_out) self.outputs['CutFaces'].sv_set(cut_faces_out) self.outputs['ObjVertices'].sv_set(obj_verts_out) self.outputs['ObjEdges'].sv_set(obj_edges_out) self.outputs['ObjFaces'].sv_set(obj_faces_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return fields_s = self.inputs['Field'].sv_get() min_x_s = self.inputs['MinX'].sv_get() max_x_s = self.inputs['MaxX'].sv_get() min_y_s = self.inputs['MinY'].sv_get() max_y_s = self.inputs['MaxY'].sv_get() value_s = self.inputs['Value'].sv_get() z_value_s = self.inputs['Z'].sv_get() samples_s = self.inputs['Samples'].sv_get() matrix_s = self.inputs['Matrix'].sv_get(default=[Matrix()]) if isinstance(value_s[0], (list, tuple)): value_s = value_s[0] if isinstance(z_value_s[0], (list, tuple)): z_value_s = z_value_s[0] parameters = zip_long_repeat(fields_s, matrix_s, min_x_s, max_x_s, min_y_s, max_y_s, z_value_s, value_s, samples_s) verts_out = [] edges_out = [] faces_out = [] for field, matrix, min_x, max_x, min_y, max_y, z_value, value, samples in parameters: if isinstance(samples, (list, tuple)): samples = samples[0] if isinstance(value, (list, tuple)): value = value[0] if isinstance(min_x, (list, tuple)): min_x = min_x[0] if isinstance(max_x, (list, tuple)): max_x = max_x[0] if isinstance(min_y, (list, tuple)): min_y = min_y[0] if isinstance(max_y, (list, tuple)): max_y = max_y[0] if isinstance(z_value, (list, tuple)): z_value = z_value[0] has_matrix = matrix != Matrix() x_range = np.linspace(min_x, max_x, num=samples) y_range = np.linspace(min_y, max_y, num=samples) z_range = np.array([z_value]) xs, ys, zs = np.meshgrid(x_range, y_range, z_range, indexing='ij') xs, ys, zs = xs.flatten(), ys.flatten(), zs.flatten() if has_matrix: xs, ys, zs = self.apply_matrix(matrix, xs, ys, zs) field_values = field.evaluate_grid(xs, ys, zs) field_values = field_values.reshape((samples, samples)) contours = measure.find_contours(field_values, level=value) x_size = (max_x - min_x)/samples y_size = (max_y - min_y)/samples new_verts, new_edges, new_faces = make_contours(samples, min_x, x_size, min_y, y_size, z_value, contours, make_faces=self.make_faces, connect_bounds = self.connect_bounds) if has_matrix: new_verts = self.unapply_matrix(matrix, new_verts) 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)
def process(self): if not any(socket.is_linked for socket in self.outputs): return solids_out = [] edge_masks_out = [] edge_srcs_out = [] face_masks_out = [] face_srcs_out = [] if self.nest_objs: solids_in = self.inputs['Solids'].sv_get() #level = get_data_nesting_level(solids_in, data_types=(Part.Shape,)) solids_in = ensure_nesting_level(solids_in, 2, data_types=(Part.Shape, )) for solids in solids_in: result = self.make_solid(solids) solids_out.append(result.solid) edge_masks_out.append(result.edge_mask) edge_srcs_out.append(result.edge_map) face_masks_out.append(result.face_mask) face_srcs_out.append(result.face_map) else: solids_a_in = self.inputs['Solid A'].sv_get() solids_b_in = self.inputs['Solid B'].sv_get() level_a = get_data_nesting_level(solids_a_in, data_types=(Part.Shape, )) level_b = get_data_nesting_level(solids_b_in, data_types=(Part.Shape, )) solids_a_in = ensure_nesting_level(solids_a_in, 2, data_types=(Part.Shape, )) solids_b_in = ensure_nesting_level(solids_b_in, 2, data_types=(Part.Shape, )) level = max(level_a, level_b) for params in zip_long_repeat(solids_a_in, solids_b_in): new_solids = [] new_edge_masks = [] new_edge_srcs = [] new_face_masks = [] new_face_srcs = [] for solid_a, solid_b in zip_long_repeat(*params): result = self.make_solid([solid_a, solid_b]) new_solids.append(result.solid) new_edge_masks.append(result.edge_mask) new_edge_srcs.append(result.edge_map) new_face_masks.append(result.face_mask) new_face_srcs.append(result.face_map) if level == 1: solids_out.extend(new_solids) edge_masks_out.extend(new_edge_masks) edge_srcs_out.extend(new_edge_srcs) face_masks_out.extend(new_face_masks) face_srcs_out.extend(new_face_srcs) else: solids_out.append(new_solids) edge_masks_out.append(new_edge_masks) edge_srcs_out.append(new_edge_srcs) face_masks_out.append(new_face_masks) face_srcs_out.append(new_face_srcs) self.outputs['Solid'].sv_set(solids_out) if 'EdgesMask' in self.outputs: self.outputs['EdgesMask'].sv_set(edge_masks_out) if 'EdgeSources' in self.outputs: self.outputs['EdgeSources'].sv_set(edge_srcs_out) if 'FacesMask' in self.outputs: self.outputs['FacesMask'].sv_set(face_masks_out) if 'FaceSources' in self.outputs: self.outputs['FaceSources'].sv_set(face_srcs_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return curve_s = self.inputs['Curve'].sv_get() surface_s = self.inputs['Surface'].sv_get() offset_s = self.inputs['Offset'].sv_get() offset_curve_s = self.inputs['OffsetCurve'].sv_get(default=[[None]]) curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve, )) surface_s = ensure_nesting_level(surface_s, 2, data_types=(SvSurface, )) offset_s = ensure_nesting_level(offset_s, 2) if self.inputs['OffsetCurve'].is_linked: offset_curve_s = ensure_nesting_level(offset_curve_s, 2, data_types=(SvCurve, )) curves_out = [] uv_curves_out = [] for curves, surfaces, offsets, offset_curves in zip_long_repeat( curve_s, surface_s, offset_s, offset_curve_s): new_curves = [] new_uv_curves = [] for curve, surface, offset, offset_curve in zip_long_repeat( curves, surfaces, offsets, offset_curves): if self.offset_type == 'CONST': new_curve = SvCurveOffsetOnSurface(curve, surface, offset=offset, uv_space=False, axis=self.curve_axis) new_uv_curve = SvCurveOffsetOnSurface(curve, surface, offset=offset, uv_space=True, axis=self.curve_axis) else: if offset_curve is None: raise SvNoDataError(socket=self.inputs['OffsetCurve'], node=self) new_curve = SvCurveOffsetOnSurface( curve, surface, offset_curve=offset_curve, offset_curve_type=self.offset_curve_type, len_resolution=self.len_resolution, uv_space=False, axis=self.curve_axis) new_uv_curve = SvCurveOffsetOnSurface( curve, surface, offset_curve=offset_curve, offset_curve_type=self.offset_curve_type, len_resolution=self.len_resolution, uv_space=True, axis=self.curve_axis) new_curves.append(new_curve) new_uv_curves.append(new_uv_curve) curves_out.append(new_curves) uv_curves_out.append(new_uv_curves) self.outputs['Curve'].sv_set(curves_out) self.outputs['UVCurve'].sv_set(uv_curves_out)
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)
def process(self): if not any(socket.is_linked for socket in self.outputs): return vertices_s = self.inputs['ControlPoints'].sv_get() has_weights = self.inputs['Weights'].is_linked weights_s = self.inputs['Weights'].sv_get(default = [[1.0]]) knots_s = self.inputs['Knots'].sv_get(default = [[]]) degree_s = self.inputs['Degree'].sv_get() curves_out = [] knots_out = [] for vertices, weights, knots, degree in zip_long_repeat(vertices_s, weights_s, knots_s, degree_s): if isinstance(degree, (tuple, list)): degree = degree[0] n_source = len(vertices) fullList(weights, n_source) if self.knot_mode == 'AUTO' and self.is_cyclic: vertices = vertices + vertices[:degree+1] weights = weights + weights[:degree+1] n_total = len(vertices) # Create a 3-dimensional B-spline Curve if self.surface_mode == 'NURBS': curve = NURBS.Curve(normalize_kv = self.normalize_knots) else: curve = BSpline.Curve(normalize_kv = self.normalize_knots) # Set degree curve.degree = degree # Set control points (weights vector will be 1 by default) # Use curve.ctrlptsw is if you are using homogeneous points as Pw curve.ctrlpts = vertices if has_weights and self.surface_mode == 'NURBS': curve.weights = weights # Set knot vector if self.knot_mode == 'AUTO': if self.is_cyclic: self.debug("N: %s, degree: %s", n_total, degree) knots = list(range(n_total + degree + 1)) else: knots = knotvector.generate(curve.degree, n_total) self.debug('Auto knots: %s', knots) curve.knotvector = knots else: self.debug('Manual knots: %s', knots) #if not knotvector.check(curve.degree, knots, len(curve.ctrlpts)): # raise Exception("Explicitly provided knot vector is incorrect!") curve.knotvector = knots new_curve = SvExGeomdlCurve(curve) if self.is_cyclic: u_min = curve.knotvector[degree] u_max = curve.knotvector[-degree-2] new_curve.u_bounds = u_min, u_max else: u_min = min(curve.knotvector) u_max = max(curve.knotvector) new_curve.u_bounds = (u_min, u_max) curves_out.append(new_curve) knots_out.append(curve.knotvector) self.outputs['Curve'].sv_set(curves_out) self.outputs['Knots'].sv_set(knots_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return fields_s = self.inputs['Field'].sv_get() min_x_s = self.inputs['MinX'].sv_get() max_x_s = self.inputs['MaxX'].sv_get() min_y_s = self.inputs['MinY'].sv_get() max_y_s = self.inputs['MaxY'].sv_get() value_s = self.inputs['Value'].sv_get() z_value_s = self.inputs['Z'].sv_get() samples_s = self.inputs['Samples'].sv_get() matrix_s = self.inputs['Matrix'].sv_get(default=[Matrix()]) value_s = ensure_nesting_level(value_s, 2) z_value_s = ensure_nesting_level(z_value_s, 2) input_level = get_data_nesting_level(fields_s, data_types=(SvScalarField, )) nested_output = input_level > 1 fields_s = ensure_nesting_level(fields_s, 2, data_types=(SvScalarField, )) matrix_s = ensure_nesting_level(matrix_s, 2, data_types=(Matrix, )) parameters = zip_long_repeat(fields_s, matrix_s, min_x_s, max_x_s, min_y_s, max_y_s, z_value_s, value_s, samples_s) verts_out = [] edges_out = [] faces_out = [] for field_i, matrix_i, min_x_i, max_x_i, min_y_i, max_y_i, z_value_i, value_i, samples_i in parameters: new_verts = [] new_edges = [] new_faces = [] objects = zip_long_repeat(field_i, matrix_i, min_x_i, max_x_i, min_y_i, max_y_i, z_value_i, value_i, samples_i) for field, matrix, min_x, max_x, min_y, max_y, z_value, value, samples in objects: has_matrix = matrix != Matrix() x_range = np.linspace(min_x, max_x, num=samples) y_range = np.linspace(min_y, max_y, num=samples) z_range = np.array([z_value]) xs, ys, zs = np.meshgrid(x_range, y_range, z_range, indexing='ij') xs, ys, zs = xs.flatten(), ys.flatten(), zs.flatten() if has_matrix: xs, ys, zs = self.apply_matrix(matrix, xs, ys, zs) field_values = field.evaluate_grid(xs, ys, zs) field_values = field_values.reshape((samples, samples)) contours = measure.find_contours(field_values, level=value) x_size = (max_x - min_x) / samples y_size = (max_y - min_y) / samples value_verts, value_edges, value_faces = make_contours( samples, samples, min_x, x_size, min_y, y_size, z_value, contours, make_faces=self.make_faces, connect_bounds=self.connect_bounds) if has_matrix: new_verts = self.unapply_matrix(matrix, new_verts) if self.join: new_verts.extend(value_verts) new_edges.extend(value_edges) new_faces.extend(value_faces) else: new_verts.append(value_verts) new_edges.append(value_edges) new_faces.append(value_faces) if nested_output: verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) else: 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)
def process(self): if not self.activate: return vertices_s = self.inputs['ControlPoints'].sv_get() has_weights = self.inputs['Weights'].is_linked weights_s = self.inputs['Weights'].sv_get(default = [[1.0]]) u_size_s = self.inputs['USize'].sv_get() degree_u_s = self.inputs['DegreeU'].sv_get() degree_v_s = self.inputs['DegreeV'].sv_get() if self.input_mode == '1D': vertices_s = ensure_nesting_level(vertices_s, 3) else: vertices_s = ensure_nesting_level(vertices_s, 4) # we need to suppress depsgraph updates emminating from this part of the process/ with self.sv_throttle_tree_update(): inputs = zip_long_repeat(vertices_s, weights_s, u_size_s, degree_u_s, degree_v_s) object_index = 0 for vertices, weights, u_size, degree_u, degree_v in inputs: if not vertices or not weights: continue object_index += 1 if isinstance(u_size, (list, tuple)): u_size = u_size[0] if isinstance(degree_u, (tuple, list)): degree_u = degree_u[0] if isinstance(degree_v, (tuple, list)): degree_v = degree_v[0] if self.input_mode == '1D': fullList(weights, len(vertices)) else: if isinstance(weights[0], (int, float)): weights = [weights] fullList(weights, len(vertices)) for verts_u, weights_u in zip(vertices, weights): fullList(weights_u, len(verts_u)) surface_object = self.create_surface(object_index) self.debug("Object: %s", surface_object) if not surface_object: continue if self.input_mode == '1D': n_v = u_size n_u = len(vertices) // n_v vertices = grouper(vertices, n_u) weights = grouper(weights, n_u) else: n_v = len(vertices) n_u = len(vertices[0]) surface_object.data.splines.clear() for vertices_row, weights_row in zip(vertices, weights): spline = surface_object.data.splines.new(type='NURBS') spline.use_bezier_u = False spline.use_bezier_v = False spline.points.add(n_u - 1) for p, new_co, new_weight in zip(spline.points, vertices_row, weights_row): p.co = Vector(list(new_co) + [new_weight]) p.select = True spline.use_cyclic_v = self.is_cyclic_u spline.use_cyclic_u = self.is_cyclic_v spline.use_endpoint_u = not self.is_cyclic_v and self.use_endpoint_v spline.use_endpoint_v = not self.is_cyclic_u and self.use_endpoint_u surface_object = self.find_surface(object_index) bpy.context.view_layer.objects.active = surface_object bpy.ops.object.mode_set(mode = 'EDIT') bpy.ops.curve.make_segment() bpy.ops.object.mode_set(mode = 'OBJECT') spline = surface_object.data.splines[0] spline.order_u = degree_u + 1 spline.order_v = degree_v + 1 spline.resolution_u = self.resolution_v spline.resolution_v = self.resolution_u spline.use_smooth = self.smooth self.remove_non_updated_objects(object_index) self.set_corresponding_materials() objects = self.get_children() self.outputs['Objects'].sv_set(objects)
def process(self): if not any(socket.is_linked for socket in self.outputs): return vertices_s = self.inputs['Vertices'].sv_get() volume_threshold_s = self.inputs['PlanarThreshold'].sv_get() edge_threshold_s = self.inputs['EdgeThreshold'].sv_get() input_level = get_data_nesting_level(vertices_s) vertices_s = ensure_nesting_level(vertices_s, 4) volume_threshold_s = ensure_nesting_level(volume_threshold_s, 2) edge_threshold_s = ensure_nesting_level(edge_threshold_s, 2) nested_output = input_level > 3 verts_out = [] edges_out = [] faces_out = [] for params in zip_long_repeat(vertices_s, volume_threshold_s, edge_threshold_s): verts_item = [] edges_item = [] faces_item = [] for vertices, volume_threshold, edge_threshold in zip_long_repeat( *params): tri = Delaunay(np.array(vertices)) if self.join: verts_new = vertices edges_new = set() faces_new = set() for simplex_idx, simplex in enumerate(tri.simplices): if self.is_too_long(vertices, simplex, edge_threshold) or self.is_planar( vertices, simplex, volume_threshold): continue edges_new.update(set(self.make_edges(simplex))) faces_new.update(set(self.make_faces(simplex))) verts_item.append(verts_new) edges_item.append(list(edges_new)) faces_item.append(list(faces_new)) else: verts_new = [] edges_new = [] faces_new = [] for simplex in tri.simplices: if self.is_too_long(vertices, simplex, edge_threshold) or self.is_planar( vertices, simplex, volume_threshold): continue verts_simplex = self.get_verts(vertices, simplex) edges_simplex = self.make_edges([0, 1, 2, 3]) faces_simplex = self.make_faces([0, 1, 2, 3]) verts_new.append(verts_simplex) edges_new.append(edges_simplex) faces_new.append(faces_simplex) verts_item.extend(verts_new) edges_item.extend(edges_new) faces_item.extend(faces_new) if nested_output: verts_out.append(verts_item) edges_out.append(edges_item) faces_out.append(faces_item) else: verts_out.extend(verts_item) edges_out.extend(edges_item) faces_out.extend(faces_item) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out)
import random from sverchok.data_structure import zip_long_repeat from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata from sverchok.utils.logging import debug, info from sverchok.utils.turtle import Turtle if in_select_mask is None: in_select_mask = [[]] if in_paint_mask is None: in_paint_mask = [[]] out_face_mask = [] out_face_data = [] objects = zip_long_repeat(in_verts, in_faces, in_start_face_idx, in_steps, in_select_mask, in_paint_mask, in_seed) for verts, faces, start_face, steps, select_mask, paint_mask, seed in objects: info(seed) if isinstance(seed, (list, tuple)): seed = seed[0] random.seed(seed) if isinstance(start_face, (list, tuple)): if not start_face: start_face = random.choice(range(len(faces))) else: start_face = start_face[0] if isinstance(steps, (list, tuple)): steps = steps[0] bm = bmesh_from_pydata(verts, [], faces, normal_update=True) bm.verts.ensure_lookup_table()
def process(self): if not any(socket.is_linked for socket in self.outputs): return verts_in = self.inputs['Vertices'].sv_get(deepcopy=False) faces_in = self.inputs['Faces'].sv_get(deepcopy=False) sites_in = self.inputs['Sites'].sv_get(deepcopy=False) #thickness_in = self.inputs['Thickness'].sv_get() spacing_in = self.inputs['Spacing'].sv_get(deepcopy=False) verts_in = ensure_nesting_level(verts_in, 4) input_level = get_data_nesting_level(sites_in) sites_in = ensure_nesting_level(sites_in, 4) faces_in = ensure_nesting_level(faces_in, 4) #thickness_in = ensure_nesting_level(thickness_in, 2) spacing_in = ensure_min_nesting(spacing_in, 2) nested_output = input_level > 3 precision = 10 ** (-self.accuracy) verts_out = [] edges_out = [] faces_out = [] sites_out = [] for params in zip_long_repeat(verts_in, faces_in, sites_in, spacing_in): new_verts = [] new_edges = [] new_faces = [] new_sites = [] for verts, faces, sites, spacing in zip_long_repeat(*params): verts, edges, faces, sites = voronoi_on_mesh(verts, faces, sites, thickness=0, spacing = spacing, #clip_inner = self.clip_inner, clip_outer = self.clip_outer, do_clip=True, clipping=None, mode = self.mode, precision = precision) if self.mode == 'VOLUME' and self.normals: verts, edges, faces = recalc_normals(verts, edges, faces, loop=True) if self.join_mode == 'FLAT': new_verts.extend(verts) new_edges.extend(edges) new_faces.extend(faces) new_sites.extend(sites) elif self.join_mode == 'SEPARATE': new_verts.append(verts) new_edges.append(edges) new_faces.append(faces) new_sites.append(sites) else: # JOIN verts, edges, faces = mesh_join(verts, edges, faces) new_verts.append(verts) new_edges.append(edges) new_faces.append(faces) new_sites.append(sites) if nested_output: verts_out.append(new_verts) edges_out.append(new_edges) faces_out.append(new_faces) sites_out.append(new_sites) else: verts_out.extend(new_verts) edges_out.extend(new_edges) faces_out.extend(new_faces) sites_out.extend(new_sites) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Edges'].sv_set(edges_out) self.outputs['Faces'].sv_set(faces_out)