Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rip out function into a utility file #4557

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 7 additions & 44 deletions nodes/modifier_change/mesh_separate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'''
Expand All @@ -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)
Expand Down
70 changes: 70 additions & 0 deletions utils/modules/topology_utils.py
Original file line number Diff line number Diff line change
@@ -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