Skip to content

Commit

Permalink
Merge pull request #5124 from nortikin/fix_5123_Quadriflow_node
Browse files Browse the repository at this point in the history
fix #5123 Add quadriflow node
  • Loading branch information
satabol authored May 25, 2024
2 parents 12cc37a + d6f5dd1 commit 25764cf
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 0 deletions.
8 changes: 8 additions & 0 deletions dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ def draw_message(box, package, dependencies=None):
except ImportError:
pyacvd = None

pyQuadriFlow_d = sv_dependencies["pyQuadriFlow"] = SvDependency("pyQuadriFlow","https://github.com/satabol/pyQuadriFlow")
pyQuadriFlow_d.pip_installable = True
try:
import pyQuadriFlow
pyQuadriFlow_d.module = pyQuadriFlow
except ImportError:
pyQuadriFlow = None

settings.pip = pip
settings.sv_dependencies = sv_dependencies
settings.ensurepip = ensurepip
Expand Down
31 changes: 31 additions & 0 deletions docs/nodes/modifier_change/quadriflow.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Quadriflow
==========

.. image:: https://github.com/nortikin/sverchok/assets/14288520/094fb95a-e199-438e-b1e8-dcca9132ebe5
:target: https://github.com/nortikin/sverchok/assets/14288520/094fb95a-e199-438e-b1e8-dcca9132ebe5


Description
-----------

This node is a fork of the operator in Blender:

.. image:: https://github.com/nortikin/sverchok/assets/14288520/181ab570-c13d-496a-b5b8-c8418fe31bf9
:target: https://github.com/nortikin/sverchok/assets/14288520/181ab570-c13d-496a-b5b8-c8418fe31bf9

Functionality
-------------

.. image:: https://github.com/nortikin/sverchok/assets/14288520/642dab70-49e3-4142-8de9-32381502e5d2
:target: https://github.com/nortikin/sverchok/assets/14288520/642dab70-49e3-4142-8de9-32381502e5d2

Warning
-------

This is a time consumer node so be carefully with settings.

Examples
--------

.. image:: https://github.com/nortikin/sverchok/assets/14288520/33de8b65-962f-4b05-8bcf-f537690cefd6
:target: https://github.com/nortikin/sverchok/assets/14288520/33de8b65-962f-4b05-8bcf-f537690cefd6
2 changes: 2 additions & 0 deletions index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@
- SvOffsetLineNode
- SvContourNode
- ---
- SvQuadriFlowNode
- ---
- SvDualMeshNode
- SvDiamondMeshNode
- SvClipVertsNode
Expand Down
2 changes: 2 additions & 0 deletions menus/full_by_data_type.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@
- SvOffsetLineNode
- SvContourNode
- ---
- SvQuadriFlowNode
- ---
- SvDualMeshNode
- SvDiamondMeshNode
- SvClipVertsNode
Expand Down
2 changes: 2 additions & 0 deletions menus/full_nortikin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@
- SvOffsetLineNode
- SvContourNode
- ---
- SvQuadriFlowNode
- ---
- SvDualMeshNode
- SvDiamondMeshNode
- SvClipVertsNode
Expand Down
217 changes: 217 additions & 0 deletions nodes/modifier_change/quadriflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# ##### 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 #####

# Implements the QuadriFlow Node
# sverchok/nodes/modifier_change/quadriflow.py

import bpy
import bmesh
from bpy.props import IntProperty, BoolProperty, EnumProperty
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, match_long_repeat, flatten_data
from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata, pydata_from_bmesh

enable_module = False
try:
import pyQuadriFlow
from pyQuadriFlow.pyQuadriFlow import pyquadriflow
enable_module = True
except ModuleNotFoundError:
enable_module = False

from itertools import chain
import traceback
class SvQuadriFlowNode(bpy.types.Node,SverchCustomTreeNode):
bl_idname = "SvQuadriFlowNode" # Use this for index.md reference
bl_label = "Quadriflow"
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = None

sv_dependencies = ['pyQuadriFlow']

#maxSubdivision = 6 # creates a self.maxSubdivision attribute
flag_preserve_sharp : BoolProperty(
name = "Preserve Sharp",
description = "Try to preserve sharp features on the mesh",
default = False,
update = updateNode) # type: ignore

flag_preserve_boundary : BoolProperty(
name = "Preserve Mesh Boundary",
description = "Try to preserve mesh boundary on the mesh",
default = False,
update = updateNode) # type: ignore

flag_adaptive_scale : BoolProperty(
name = "Preserve Adaptive Scale",
description = "???",
default = False,
update = updateNode) # type: ignore

flag_aggresive_sat : BoolProperty(
name = "Preserve Aggresive Sat",
description = "???",
default = False,
update = updateNode) # type: ignore

flag_minimum_cost_flow : BoolProperty(
name = "Minimum Cost Flow",
description = "???",
default = False,
update = updateNode) # type: ignore

quad_modes = [
( "BEAUTY", "Beauty", "Split the quads in nice triangles, slower method", 1),
( "FIXED", "Fixed", "Split the quads on the 1st and 3rd vertices", 2),
( "ALTERNATE", "Fixed Alternate", "Split the quads on the 2nd and 4th vertices", 3),
("SHORT_EDGE", "Shortest Diagonal", "Split the quads based on the distance between the vertices", 4)
]

ngon_modes = [
( "BEAUTY", "Beauty", "Arrange the new triangles nicely, slower method", 1),
("EAR_CLIP", "Clip", "Split the ngons using a scanfill algorithm", 2)
]

quad_mode: EnumProperty(
name='Quads mode',
description="Quads processing mode",
items=quad_modes,
default="BEAUTY",
update=updateNode) # type: ignore

ngon_mode: EnumProperty(
name="Polygons mode",
description="Polygons processing mode",
items=ngon_modes,
default="BEAUTY",
update=updateNode) # type: ignore


# Mute Node Implementation
@property
def sv_internal_links(self):
mapping = [
(self.inputs['Vertices'],self.outputs['Vertices']),
(self.inputs['Faces'],self.outputs['Faces'])
]
return mapping

def sv_init(self,context):
self.width = 200
self.inputs.new('SvVerticesSocket', "vertices")
#self.inputs.new('SvVerticesSocket', "Edges")
self.inputs.new('SvStringsSocket', "faces")
self.inputs["vertices"].label = "vertices"
self.inputs["faces"].label = "Faces"

socket = self.inputs.new('SvStringsSocket', "number_faces")
socket.use_prop=True
socket.default_property_type = 'int'
socket.default_int_property = 1000
socket.label = "Number of Faces"

socket = self.inputs.new('SvStringsSocket', "seed")
socket.use_prop=True
socket.default_property_type = 'int'
socket.default_int_property = 0
socket.label = "Seed"

self.outputs.new('SvVerticesSocket', "vertices")
self.outputs.new('SvStringsSocket', "faces")
self.outputs["vertices"].label = "vertices"
self.outputs["faces"].label = "Faces"

def draw_buttons(self, context, layout):
layout.prop(self, "flag_preserve_sharp")
layout.prop(self, "flag_preserve_boundary")
layout.prop(self, "flag_adaptive_scale")
layout.prop(self, "flag_aggresive_sat")
layout.prop(self, "flag_minimum_cost_flow")

col = layout.column()
col.row().label(text="Triangulate mesh polygons:")
row = col.row()
split = row.split(factor=0.4)
split.column().label(text="Quads mode:")
split.column().row(align=True).prop(self, "quad_mode", text='')

row = col.row()
split = row.split(factor=0.5)
split.column().label(text="Polygons mode:")
split.column().row(align=True).prop(self, "ngon_mode", text='')




def process(self):
if not enable_module:
raise Exception("The dependent library is not installed (pyQuadriFlow).")

outputs = self.outputs
if not any( [o.is_linked for o in outputs]):
return

verts_sets = self.inputs['vertices'].sv_get(default=[],deepcopy=False)
faces_sets = self.inputs['faces'].sv_get(default=[],deepcopy=False)
_number_faces_sets = self.inputs['number_faces'].sv_get(default=[[4000]],deepcopy=False)
number_faces_sets = flatten_data(_number_faces_sets)
_seed_sets = self.inputs['seed'].sv_get(default=[[0]],deepcopy=False)
seed_sets = flatten_data(_seed_sets)

new_meshes = {
'vertices':[],
'edges':[],
'faces':[]
}

if(verts_sets != [] and faces_sets != []):
for verts_set, faces_set, number_faces_set, seed_set in zip(*match_long_repeat([verts_sets,faces_sets, number_faces_sets, seed_sets])):
bm_I = bmesh_from_pydata(verts_set, [], faces_set, markup_face_data=True, normal_update=True)
b_faces = []
for face in bm_I.faces:
b_faces.append(face)
res = bmesh.ops.triangulate( bm_I, faces=b_faces, quad_method=self.quad_mode, ngon_method=self.ngon_mode )
new_vertices_I, new_edges_I, new_faces_I = pydata_from_bmesh(bm_I, ret_edges=False)
bm_I.free()

#new_mesh = {'vertices': new_vertices_I, 'faces': new_faces_I}

new_mesh = pyquadriflow(number_faces_set,
seed_set,
new_vertices_I,
new_faces_I,
self.flag_preserve_sharp,
self.flag_preserve_boundary,
self.flag_adaptive_scale,
self.flag_aggresive_sat,
self.flag_minimum_cost_flow
)

new_meshes['vertices'].append(new_mesh['vertices'])
#new_meshes['edges'].append(new_mesh['edges'])
new_meshes['faces'].append(new_mesh['faces'])

self.outputs['vertices'].sv_set(new_meshes['vertices'])
#self.outputs['Edges'].sv_set(new_meshes['edges'])
self.outputs['faces'].sv_set(new_meshes['faces'])

def register():
bpy.utils.register_class(SvQuadriFlowNode)

def unregister():
bpy.utils.unregister_class(SvQuadriFlowNode)
1 change: 1 addition & 0 deletions settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ def draw_freecad_ops():
draw_message(box, "numexpr")
draw_message(box, "ezdxf")
draw_message(box, "pyacvd")
draw_message(box, "pyQuadriFlow")

draw_freecad_ops()

Expand Down

0 comments on commit 25764cf

Please sign in to comment.