Created by: vicdoval
This PR Introduces a Mixin to create multi-level recursive nodes.
When used the nesting properties have to be defined in the sv_init function After the data is processed in the process_data function
This mixin is used to vectorize any node.
In the init function some socket properties have to be defined in order to work properly
They can also be defined in the pre_setup function that will be called before getting the input data
for every input socket(s):
if socket is mandatory:
s.is_mandatory = True (Default value is False)
the desired nesting level
s.nesting_level =
3 for vectors lists (Default for Vertices Socket)
2 for number lists (Default)
1 for single item
the socket default mode
s.default_mode =
'NONE' to leave empty
'EMPTY_LIST' for [[]] (Default)
'MATRIX' for Matrix()
'MASK' for [[True]]
if pre_processing desired:
s.pre_processing =
'ONE_ITEM' for values like the number of subdivision (one value per object).
It will match one value per object independently if the list is [[1,2]] or [[1],[2]]
In case of more complex inputs no preprocessing will be made
'NONE' not doing any preprocessing. (Default)
a node pseudo-code:
from sverchok.utils.nodes_mixins.recursive_nodes import SvRecursiveNode
...
class SvAwesomeNode(bpy.types.Node, SverchCustomTreeNode, SvRecursiveNode):
...
def sv_init(self, context):
p1 = self.inputs.new('SvVerticesSocket', "Param1")
p1.is_mandatory = True
p1.nesting_level = 3
p1.default_mode = 'NONE'
p2 = self.inputs.new('SvStringsSocket', "Param2")
p2.nesting_level = 3
self.outputs.new('SvStringsSocket', "Res1")
self.outputs.new('SvStringsSocket', "Res2")
def pre_setup(self):
if self.option == 'SOME_OPTION':
self.inputs[0].nesting_level = 2
def process_data(self, params):
param1, param2 = params
res1, res2 = awesome_func(param1, param2, self.option)
return res1, res2
this mixing also adds the list_match property to let the user choose among repeat_last, cycle and match short and so on
to add this property to the layout:
def draw_buttons_ext(self, context, layout):
layout.prop(self, 'list_match')
def rclick_menu(self, context, layout):
layout.prop_menu_enum(self, "list_match", text="List Match")
As example a have implemented it in 4 nodes: Vector Polar Output, Calculate Normals, Mesh Join and Merge by distance
but i did not remove the originals nodes to compare them in case someone wants to add some idea to the PR (otherwise i will remove them soon)
This implementation leaves out of the nodes code sv_get and sv_set functions and allows the coder to work only with the needed levels of nesting.
-
Code changes complete. -
Code documentation complete. -
Documentation for users complete (or not required, if user never sees these changes). -
Manual testing done. -
Unit-tests implemented. -
Ready for merge.