diff --git a/nodes/modifier_change/mesh_separate.py b/nodes/modifier_change/mesh_separate.py index f0794e2025..7fe076c64f 100644 --- a/nodes/modifier_change/mesh_separate.py +++ b/nodes/modifier_change/mesh_separate.py @@ -23,7 +23,7 @@ from sverchok.node_tree import SverchCustomTreeNode from sverchok.data_structure import zip_long_repeat from sverchok.utils.nodes_mixins.sockets_config import ModifierLiteNode - +from sverchok.utils.modules.topology_utils import separate_loose class SvSeparateMeshNode(ModifierLiteNode, bpy.types.Node, SverchCustomTreeNode): '''Separate Loose mesh parts''' @@ -42,54 +42,17 @@ def sv_init(self, context): def process(self): if not any(s.is_linked for s in self.outputs): return + verts = self.inputs['Vertices'].sv_get(deepcopy=False) poly = self.inputs['Poly Egde'].sv_get(deepcopy=False) + verts_out = [] poly_edge_out = [] - for ve, pe in zip_long_repeat(verts, poly): - # build links - node_links = {} - for edge_face in pe: - for i in edge_face: - if i not in node_links: - node_links[i] = set() - node_links[i].update(edge_face) - nodes = set(node_links.keys()) - n = nodes.pop() - node_set_list = [set([n])] - node_stack = collections.deque() - node_stack_append = node_stack.append - node_stack_pop = node_stack.pop - node_set = node_set_list[-1] - # find separate sets - while nodes: - for node in node_links[n]: - if node not in node_set: - node_stack_append(node) - if not node_stack: # new mesh part - n = nodes.pop() - node_set_list.append(set([n])) - node_set = node_set_list[-1] - else: - while node_stack and n in node_set: - n = node_stack_pop() - nodes.discard(n) - node_set.add(n) - # create new meshes from sets, new_pe is the slow line. - if len(node_set_list) > 1: - for node_set in node_set_list: - mesh_index = sorted(node_set) - vert_dict = {j: i for i, j in enumerate(mesh_index)} - new_vert = [ve[i] for i in mesh_index] - new_pe = [[vert_dict[n] for n in fe] - for fe in pe - if fe[0] in node_set] - verts_out.append(new_vert) - poly_edge_out.append(new_pe) - elif node_set_list: # no reprocessing needed - verts_out.append(ve) - poly_edge_out.append(pe) + for ve, pe in zip_long_repeat(verts, poly): + nve, npe = separate_loose(ve, pe) + verts_out.extend(nve) + poly_edge_out.extend(npe) self.outputs['Vertices'].sv_set(verts_out) self.outputs['Poly Egde'].sv_set(poly_edge_out) diff --git a/utils/modules/topology_utils.py b/utils/modules/topology_utils.py new file mode 100644 index 0000000000..a53c06b4fc --- /dev/null +++ b/utils/modules/topology_utils.py @@ -0,0 +1,70 @@ +# This file is part of project Sverchok. It's copyrighted by the contributors +# recorded in the version control history of the file, available from +# its original location https://github.com/nortikin/sverchok/commit/master +# +# SPDX-License-Identifier: GPL3 +# License-Filename: LICENSE + +import collections + +def separate_loose(ve, pe): + """ + this function will take verts and polygons or edges. + if you pass it verts and edges/polygons it will return the individual mesh islands + if you pass it verts and boundary edges it will return the separate boundaries per object. + + """ + + # build links + node_links = {} + for edge_face in pe: + for i in edge_face: + if i not in node_links: + node_links[i] = set() + node_links[i].update(edge_face) + + nodes = set(node_links.keys()) + n = nodes.pop() + node_set_list = [set([n])] + node_stack = collections.deque() + node_stack_append = node_stack.append + node_stack_pop = node_stack.pop + node_set = node_set_list[-1] + + # find separate sets + while nodes: + for node in node_links[n]: + if node not in node_set: + node_stack_append(node) + if not node_stack: # new mesh part + n = nodes.pop() + node_set_list.append(set([n])) + node_set = node_set_list[-1] + else: + while node_stack and n in node_set: + n = node_stack_pop() + nodes.discard(n) + node_set.add(n) + + # create new meshes from sets, new_pe is the slow line. + verts = [] + poly_edges = [] + if len(node_set_list) > 1: + + for node_set in node_set_list: + mesh_index = sorted(node_set) + vert_dict = {j: i for i, j in enumerate(mesh_index)} + new_vert = [ve[i] for i in mesh_index] + new_pe = [[vert_dict[n] for n in fe] + for fe in pe + if fe[0] in node_set] + + verts.append(new_vert) + poly_edges.append(new_pe) + + + elif node_set_list: # no reprocessing needed + verts.append(ve) + poly_edges.append(pe) + + return verts, poly_edges \ No newline at end of file