diff --git a/docs/nodes/modifier_change/edge_boom.rst b/docs/nodes/modifier_change/edge_boom.rst new file mode 100644 index 0000000000000000000000000000000000000000..ca719070810c01bf8c3f6cb7bc406ba6611dd382 --- /dev/null +++ b/docs/nodes/modifier_change/edge_boom.rst @@ -0,0 +1,70 @@ +Edge Boom +========= + +Functionality +------------- + +This node splits the input mesh object into separate edges objects; it can be +used to create a separate object from each edge of the input mesh. + +Inputs +------ + +This node has the following inputs: + +- **Vertices**. Vertices of the input mesh. This input is mandatory. +- **Edges**. Edges of the input mesh. This input is optional: if it is not + connected, **Faces** input will be used to determine object edges. But if you + want output objects to appear in certain order, you need to connect this. +- **Faces**. Faces of the input mesh. This input is optional. This input must + be connected if **Edges** input is not connected. + +Parameters +---------- + +This node has the following parameters: + +- **Output mode**. The following modes are available: + + * **Vertices**. For each edge of the input mesh, output the first vertex of + the edge to the **Vertex1** output and the second vertex of the edge to the + **Vertex2** output. This mode is the default one. + * **Objects**. Make a separate object from each edge of the input mesh, and + output the list of it's vertices (always 2 vertices) into **Vertices** + output, and the list of it's edges (always 1 edge) into **Edges** output. + +- **Separate**. This parameter is available only when **Output mode** is set to + **Objects**. If checked, output separate list of edge objects per each input + objects. Otherwise, output one flat list of edge objects for all input + objects. Unchecked by default. + +Outputs +------- + +This node has the following outputs: + +- **Vertex1**. The first vertex of each edge. This output contains one vertex + for each edge of the input object. This output is only available when the + **Output mode** parameter is set to **Vertices**. +- **Vertex2**. The second vertex of each edge. This output contains one vertex + for each edge of the input object. This output is only available when the + **Output mode** parameter is set to **Vertices**. +- **Vertices**. Vertices of the objects into which the input mesh was split. + This output contains two vertices for each edge of the input mesh. This + output is only available when the **Output mode** parameter is set to + **Objects**. +- **Edges**. Edges of the objects into which the input mesh was split. This + output contains one edge for each edge of the input mesh. This output is only + available when the **Output mode** parameter is set to **Objects**. + +Example of usage +---------------- + +Replace each edge of a square with a segment with subdivisions: + +.. image:: https://user-images.githubusercontent.com/284644/76330373-942f2b80-630f-11ea-95ee-0c1f5f398e72.png + +Move each edge of input objects randomly: + +.. image:: https://user-images.githubusercontent.com/284644/76344998-5dafdb80-6324-11ea-9ff3-12ce2bf496c5.png + diff --git a/docs/nodes/modifier_change/modifier_change_index.rst b/docs/nodes/modifier_change/modifier_change_index.rst index 42169d23fd8db439657e9373efca5aa1a98b8cb2..7a5ff9f99c1fcb86b6824b8a8a4cfcd9b8c412aa 100644 --- a/docs/nodes/modifier_change/modifier_change_index.rst +++ b/docs/nodes/modifier_change/modifier_change_index.rst @@ -23,6 +23,7 @@ Modifier Change objects_along_edge offset polygons_boom + edge_boom polygons_to_edges recalc_normals remove_doubles diff --git a/index.md b/index.md index ade82f956d1faa3f871681b9063b56da99988b6d..de096d15cd8953d9d4ac496161483c6bb8a89181 100644 --- a/index.md +++ b/index.md @@ -125,6 +125,7 @@ SvMakeMonotone --- PolygonBoomNode + SvEdgeBoomNode SvDissolveFaces2D Pols2EdgsNode SvMeshJoinNode diff --git a/nodes/modifier_change/edge_boom.py b/nodes/modifier_change/edge_boom.py new file mode 100644 index 0000000000000000000000000000000000000000..6e2e8fa12b58bc7f12a51c574afb0facdfdb9cf7 --- /dev/null +++ b/nodes/modifier_change/edge_boom.py @@ -0,0 +1,126 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +import bpy +from bpy.props import EnumProperty, BoolProperty + +from sverchok.node_tree import SverchCustomTreeNode, throttled +from sverchok.data_structure import zip_long_repeat, updateNode +from sverchok.utils.sv_mesh_utils import polygons_to_edges + +class SvEdgeBoomNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: Edge Boom + Tooltip: decompose a mesh into list of edge objects + """ + bl_idname = 'SvEdgeBoomNode' + bl_label = 'Edge Boom' + bl_icon = 'OUTLINER_OB_EMPTY' + sv_icon = 'SV_EXPLODE' + + modes = [ + ('VER', "Vertices", "Output list of first vertices and list of second vertices of each edge", 0), + ('OBJ', "Objects", "Output list of objects, each consisting of a single edge", 1) + ] + + @throttled + def update_sockets(self, context): + self.outputs['Vertex1'].hide_safe = self.out_mode != 'VER' + self.outputs['Vertex2'].hide_safe = self.out_mode != 'VER' + self.outputs['Vertices'].hide_safe = self.out_mode != 'OBJ' + self.outputs['Edges'].hide_safe = self.out_mode != 'OBJ' + + out_mode : EnumProperty( + name = "Output mode", + description = "Output mode", + default = 'VER', + items = modes, + update = update_sockets) + + separate : BoolProperty( + name = "Separate", + description = "If checked, output separate list of edge objects for each input objects", + default = False, + update = updateNode) + + def sv_init(self, context): + self.inputs.new('SvVerticesSocket', "Vertices") + self.inputs.new('SvStringsSocket', 'Edges') + self.inputs.new('SvStringsSocket', 'Faces') + self.outputs.new('SvVerticesSocket', 'Vertex1') + self.outputs.new('SvVerticesSocket', 'Vertex2') + self.outputs.new('SvVerticesSocket', 'Vertices') + self.outputs.new('SvStringsSocket', 'Edges') + self.update_sockets(context) + + def draw_buttons(self, context, layout): + layout.label(text="Output mode:") + layout.prop(self, "out_mode", text="") + if self.out_mode == 'OBJ': + layout.prop(self, 'separate') + + def process(self): + vertices_s = self.inputs['Vertices'].sv_get() + edges_s = self.inputs['Edges'].sv_get(default=[[]]) + faces_s = self.inputs['Faces'].sv_get(default=[[]]) + + verts1_out = [] + verts2_out = [] + verts_out = [] + edges_out = [] + for vertices, edges, faces in zip_long_repeat(vertices_s, edges_s, faces_s): + new_verts1 = [] + new_verts2 = [] + if not edges: + edges = polygons_to_edges([faces], unique_edges=True)[0] + obj_verts = [] + obj_edges = [] + for i1, i2 in edges: + new_verts = [] + new_edges = [] + if i1 > i2: + i1, i2 = i2, i1 + v1, v2 = vertices[i1], vertices[i2] + new_verts1.append(v1) + new_verts2.append(v2) + new_verts.append(v1) + new_verts.append(v2) + new_edges.append([0,1]) + obj_verts.append(new_verts) + obj_edges.append(new_edges) + if self.separate: + verts_out.append(obj_verts) + edges_out.append(obj_edges) + else: + verts_out.extend(obj_verts) + edges_out.extend(obj_edges) + + verts1_out.append(new_verts1) + verts2_out.append(new_verts2) + + self.outputs['Vertex1'].sv_set(verts1_out) + self.outputs['Vertex2'].sv_set(verts2_out) + self.outputs['Vertices'].sv_set(verts_out) + self.outputs['Edges'].sv_set(edges_out) + +def register(): + bpy.utils.register_class(SvEdgeBoomNode) + +def unregister(): + bpy.utils.unregister_class(SvEdgeBoomNode) +