diff --git a/nodes/exchange/FCStd_read.py b/nodes/exchange/FCStd_read.py index b3ec8ce16b..3022988f9a 100644 --- a/nodes/exchange/FCStd_read.py +++ b/nodes/exchange/FCStd_read.py @@ -79,8 +79,13 @@ def sv_init(self, context): self.inputs.new('SvFilePathSocket', "File Path") self.inputs.new('SvStringsSocket', "Part Filter") self.outputs.new('SvSolidSocket', "Solid") + self.outputs.new('SvTextSocket', "Names") - def read_FCStd(self,node): + def ensure_name_socket_exists(self): + if not "Names" in self.outputs: + self.outputs.new('SvTextSocket', "Names") + + def read_FCStd(self, node): files = node.inputs['File Path'].sv_get()[0] @@ -93,6 +98,7 @@ def read_FCStd(self,node): solids = [] obj_mask = [] + names = [] if node.read_features: obj_mask.append('PartDesign') @@ -104,10 +110,13 @@ def read_FCStd(self,node): for f in files: S = LoadSolid(f, part_filter, obj_mask, node.tool_parts, node.inv_filter) - for s in S: + for s, n in S: solids.append(s) + names.append(list(n)) node.outputs['Solid'].sv_set(solids) + self.ensure_name_socket_exists() + node.outputs['Names'].sv_set(names) def process(self): @@ -151,7 +160,7 @@ def LabelReader(self,context): for obj in doc.Objects: if obj.Module in obj_mask or obj.TypeId in obj_mask: - labels.append( (obj.Label, obj.Label, obj.Label) ) # TODO, identifier [A-Za-z0-9_] + labels.append( (obj.Label, obj.Label, obj.Label) ) except Exception as err: info(f'FCStd label read error: {Fname=}') @@ -210,11 +219,11 @@ def LoadSolid(fc_file, part_filter, obj_mask, tool_parts, inv_filter): if not inv_filter: if obj.Label in part_filter or len(part_filter)==0: - solids.add(obj.Shape) + solids.add((obj.Shape, (obj.FullName, obj.Name, obj.Label))) else: if not obj.Label in part_filter: - solids.add(obj.Shape) + solids.add((obj.Shape, (obj.FullName, obj.Name, obj.Label))) except: info('FCStd read error') @@ -223,11 +232,6 @@ def LoadSolid(fc_file, part_filter, obj_mask, tool_parts, inv_filter): return solids -# unused? -def open_fc_file(fc_file): - F.open(fc_file) - Fname = doc.Name or bpy.path.display_name_from_filepath(fc_file) - F.setActiveDocument(Fname) def register(): if FreeCAD is not None: diff --git a/nodes/solid/solid_to_mesh_mk2.py b/nodes/solid/solid_to_mesh_mk2.py index 9cbf5fa559..13f64fa92b 100644 --- a/nodes/solid/solid_to_mesh_mk2.py +++ b/nodes/solid/solid_to_mesh_mk2.py @@ -3,6 +3,8 @@ from sverchok.dependencies import FreeCAD from sverchok.utils.dummy_nodes import add_dummy + + if FreeCAD is None: add_dummy('SvSolidToMeshNode', 'Solid to Mesh', 'FreeCAD') else: @@ -11,12 +13,15 @@ from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty from sverchok.node_tree import SverchCustomTreeNode - from sverchok.data_structure import updateNode, match_long_repeat as mlr + from sverchok.data_structure import updateNode, has_element, match_long_repeat as mlr from sverchok.utils.solid import mesh_from_solid_faces from sverchok.utils.sv_bmesh_utils import recalc_normals + from sverchok.utils.sv_mesh_utils import non_redundant_faces_indices_np as clean import MeshPart + def is_triangles_only(faces): + if has_element(faces): return all((len(f) == 3 for f in faces)) class SvSolidToMeshNodeMk2(bpy.types.Node, SverchCustomTreeNode): """ @@ -155,6 +160,8 @@ def basic_mesher(self): for f in rawdata[1]: b_faces.append(f) verts.append(b_verts) + + b_faces = clean(b_faces).tolist() if is_triangles_only(b_faces) else b_faces faces.append(b_faces) return verts, faces @@ -178,7 +185,10 @@ def standard_mesher(self): Relative=self.relative_surface_deviation) verts.append([v[:] for v in mesh.Topology[0]]) - faces.append(mesh.Topology[1]) + + b_faces = mesh.Topology[1] + b_faces = clean(b_faces).tolist() if is_triangles_only(b_faces) else b_faces + faces.append(b_faces) return verts, faces @@ -204,6 +214,9 @@ def mefisto_mesher(self): return verts, faces def trivial_mesher(self): + """ + this mode will produce a variety of polygon types (tris, quads, ngons...) + """ solids = self.inputs[self["shape_type"]].sv_get() verts = [] diff --git a/utils/sv_mesh_utils.py b/utils/sv_mesh_utils.py index 88b1b110bb..9bc704f968 100644 --- a/utils/sv_mesh_utils.py +++ b/utils/sv_mesh_utils.py @@ -362,6 +362,17 @@ def clean_meshes(vertices, edges, faces, return verts_out, edges_out, faces_out, verts_removed_out, edges_removed_out, faces_removed_out + +def non_redundant_faces_indices_np(faces): + F = np.array(faces) + M = np.sort(F, axis=-1, order=None) + + # from https://stackoverflow.com/a/16973510/1243487 + K = np.ascontiguousarray(M).view(np.dtype((np.void, M.dtype.itemsize * M.shape[1]))) + _, idx = np.unique(K, return_index=True) + return F[idx] + + def point_inside_mesh(bvh, point): point = Vector(point) axis = Vector((1, 0, 0))