diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..6a1c326 Binary files /dev/null and b/.DS_Store differ diff --git a/__init__.py b/__init__.py index 1189e57..0cacd52 100644 --- a/__init__.py +++ b/__init__.py @@ -47,8 +47,7 @@ def nodes_index(): ("curve.intersect_surface_plane", "SvExCrossSurfacePlaneNode"), ("curve.fourier_curve", "SvFourierCurveNode"), ("curve.approximate_fourier_curve", "SvApproxFourierCurveNode"), - ("curve.interpolate_fourier_curve", "SvInterpFourierCurveNode"), - ("curve.geodesic_curve", "SvExGeodesicCurveNode") + ("curve.interpolate_fourier_curve", "SvInterpFourierCurveNode") ]), ("Extra Fields", [ ("field.vfield_lines_on_surface", "SvExVFieldLinesOnSurfNode"), @@ -75,6 +74,13 @@ def nodes_index(): ("sdf_primitives.sdf_cylinder", "SvExSdfCylinderNode"), ("sdf_primitives.sdf_rounded_cylinder", "SvExSdfRoundedCylinderNode"), ("sdf_primitives.sdf_capsule", "SvExSdfCapsuleNode"), + ("sdf_primitives.sdf_gyroid", "SvExSdfGyroidNode"), + ("sdf_primitives.sdf_graded_gyroid", "SvExSdfGradedGyroidNode"), + ("sdf_primitives.sdf_functionally_graded_gyroid", "SvExSdfFunctionallyGradedGyroidNode"), + ("sdf_primitives.sdf_schwarzP", "SvExSdfSchwarzPNode"), + ("sdf_primitives.sdf_schwarzD", "SvExSdfSchwarzDNode"), + ("sdf_primitives.sdf_MO", "SvExSdfMONode"), + ("sdf_primitives.sdf_EB", "SvExSdfEBNode"), None, ("sdf_primitives.sdf2d_circle", "SvExSdf2dCircleNode"), ("sdf_primitives.sdf2d_hexagon", "SvExSdf2dHexagonNode"), diff --git a/nodes/.DS_Store b/nodes/.DS_Store new file mode 100644 index 0000000..5d7c352 Binary files /dev/null and b/nodes/.DS_Store differ diff --git a/nodes/sdf/sdf_transition_linear.py b/nodes/sdf/sdf_transition_linear.py index 5a9ce31..f4de3b9 100644 --- a/nodes/sdf/sdf_transition_linear.py +++ b/nodes/sdf/sdf_transition_linear.py @@ -94,4 +94,3 @@ def register(): def unregister(): if sdf is not None: bpy.utils.unregister_class(SvExSdfLinearTransitionNode) - diff --git a/nodes/sdf_primitives/sdf_EB.py b/nodes/sdf_primitives/sdf_EB.py new file mode 100644 index 0000000..5b6b48d --- /dev/null +++ b/nodes/sdf_primitives/sdf_EB.py @@ -0,0 +1,108 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfEBNode', "SDF EB", 'sdf') +else: + from sdf import * + +class SvExSdfEBNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF EB + Tooltip: SDF EB + """ + bl_idname = 'SvExSdfEBNode' + bl_label = 'SDF EB' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness : FloatProperty( + name = "Thickness", + default = 0.1, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness").prop_name = 'thickness' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, origin in zip_long_repeat(*params): + sdf = EB(thickness, size=(size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfEBNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfEBNode) diff --git a/nodes/sdf_primitives/sdf_MO.py b/nodes/sdf_primitives/sdf_MO.py new file mode 100644 index 0000000..2dddd00 --- /dev/null +++ b/nodes/sdf_primitives/sdf_MO.py @@ -0,0 +1,117 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfMONode', "SDF MO", 'sdf') +else: + from sdf import * + +class SvExSdfMONode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF MO + Tooltip: SDF MO + """ + bl_idname = 'SvExSdfMONode' + bl_label = 'SDF MO' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness : FloatProperty( + name = "Thickness", + default = 0.1, + min = 0.0, + update=updateNode) + + slant : FloatProperty( + name = "Slant", + default = 1.0, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness").prop_name = 'thickness' + self.inputs.new('SvStringsSocket', "Slant").prop_name = 'slant' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + slant_s = self.inputs['Slant'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2) + slant_s = ensure_nesting_level(slant_s, 2) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, slant_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, slant, origin in zip_long_repeat(*params): + sdf = MO(thickness, slant, size=(size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfMONode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfMONode) diff --git a/nodes/sdf_primitives/sdf_functionally_graded_gyroid.py b/nodes/sdf_primitives/sdf_functionally_graded_gyroid.py new file mode 100644 index 0000000..1ee5fd4 --- /dev/null +++ b/nodes/sdf_primitives/sdf_functionally_graded_gyroid.py @@ -0,0 +1,107 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfFunctionallyGradedGyroidNode', "SDF Functionally Graded Gyroid", 'sdf') +else: + from sdf import * + +class SvExSdfFunctionallyGradedGyroidNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF Functionally Graded Gyroid + Tooltip: SDF Functionally Graded Gyroid + """ + bl_idname = 'SvExSdfFunctionallyGradedGyroidNode' + bl_label = 'SDF Functionally Graded Gyroid' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvScalarFieldSocket', "Thickness") + self.inputs.new('SvScalarFieldSocket', "Value") + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + value_s = self.inputs['Value'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2, data_types=(SvScalarField,)) + value_s = ensure_nesting_level(value_s, 2, data_types=(SvScalarField,)) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, value_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, value, origin in zip_long_repeat(*params): + thickness = scalar_field_to_sdf(thickness, 0) + value = scalar_field_to_sdf(value, 0) + sdf = FG_gyroid(thickness, value, size=(size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfFunctionallyGradedGyroidNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfFunctionallyGradedGyroidNode) diff --git a/nodes/sdf_primitives/sdf_graded_gyroid.py b/nodes/sdf_primitives/sdf_graded_gyroid.py new file mode 100644 index 0000000..9aa110c --- /dev/null +++ b/nodes/sdf_primitives/sdf_graded_gyroid.py @@ -0,0 +1,139 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfGradedGyroidNode', "SDF GradedGyroid", 'sdf') +else: + from sdf import * + +class SvExSdfGradedGyroidNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF Graded Gyroid + Tooltip: SDF Graded Gyroid + """ + bl_idname = 'SvExSdfGradedGyroidNode' + bl_label = 'SDF Graded Gyroid' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness_min : FloatProperty( + name = "Thickness minimum", + default = 0.1, + min = 0.0, + update=updateNode) + + thickness_max : FloatProperty( + name = "Thickness maximum", + default = 0.1, + min = 0.0, + update=updateNode) + + value_min : FloatProperty( + name = "Value minimum", + default = 0.0, + min = -1.73, + update=updateNode) + + value_max : FloatProperty( + name = "Value maximum", + default = 0.0, + min = -1.73, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness minimum").prop_name = 'thickness_min' + self.inputs.new('SvStringsSocket', "Thickness maximum").prop_name = 'thickness_max' + + self.inputs.new('SvStringsSocket', "Value minimum").prop_name = 'value_min' + self.inputs.new('SvStringsSocket', "Value maximum").prop_name = 'value_max' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_min_s = self.inputs['Thickness minimum'].sv_get() + thickness_max_s = self.inputs['Thickness maximum'].sv_get() + + value_min_s = self.inputs['Value minimum'].sv_get() + value_max_s = self.inputs['Value maximum'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_min_s = ensure_nesting_level(thickness_min_s, 2) + thickness_max_s = ensure_nesting_level(thickness_max_s, 2) + + value_min_s = ensure_nesting_level(value_min_s, 2) + value_max_s = ensure_nesting_level(value_max_s, 2) + + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_min_s, thickness_max_s, value_min_s, value_max_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness_min,thickness_max, value_min, value_max, origin in zip_long_repeat(*params): + sdf = graded_gyroid(thickness_min, thickness_max, value_min, value_max, size=(size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfGradedGyroidNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfGradedGyroidNode) diff --git a/nodes/sdf_primitives/sdf_gyroid.py b/nodes/sdf_primitives/sdf_gyroid.py new file mode 100644 index 0000000..d6efe16 --- /dev/null +++ b/nodes/sdf_primitives/sdf_gyroid.py @@ -0,0 +1,117 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfGyroidNode', "SDF Gyroid", 'sdf') +else: + from sdf import * + +class SvExSdfGyroidNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF Gyroid + Tooltip: SDF Gyroid + """ + bl_idname = 'SvExSdfGyroidNode' + bl_label = 'SDF Gyroid' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness : FloatProperty( + name = "Thickness", + default = 0.1, + min = 0.0, + update=updateNode) + + value : FloatProperty( + name = "Value", + default = 0.0, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness").prop_name = 'thickness' + self.inputs.new('SvStringsSocket', "Value").prop_name = 'value' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + value_s = self.inputs['Value'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2) + value_s = ensure_nesting_level(value_s, 2) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, value_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, value, origin in zip_long_repeat(*params): + sdf = gyroid(thickness, value, size=(size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfGyroidNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfGyroidNode) diff --git a/nodes/sdf_primitives/sdf_schwarzD.py b/nodes/sdf_primitives/sdf_schwarzD.py new file mode 100644 index 0000000..46cf2c7 --- /dev/null +++ b/nodes/sdf_primitives/sdf_schwarzD.py @@ -0,0 +1,108 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfSchwarzDNode', "SDF Schwarz D", 'sdf') +else: + from sdf import * + +class SvExSdfSchwarzDNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF Schwarz D + Tooltip: SDF Schwarz D + """ + bl_idname = 'SvExSdfSchwarzDNode' + bl_label = 'SDF Schwarz D' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness : FloatProperty( + name = "Thickness", + default = 0.1, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness").prop_name = 'thickness' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, origin in zip_long_repeat(*params): + sdf = schwarzD(thickness, size=(size_x,size_y,size_z),center = origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfSchwarzDNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfSchwarzDNode) diff --git a/nodes/sdf_primitives/sdf_schwarzP.py b/nodes/sdf_primitives/sdf_schwarzP.py new file mode 100644 index 0000000..0496e8c --- /dev/null +++ b/nodes/sdf_primitives/sdf_schwarzP.py @@ -0,0 +1,108 @@ +import numpy as np + +import bpy +from bpy.props import FloatProperty, EnumProperty, BoolProperty, IntProperty, FloatVectorProperty + +from sverchok.node_tree import SverchCustomTreeNode +from sverchok.data_structure import updateNode, zip_long_repeat, ensure_nesting_level +from sverchok.utils.dummy_nodes import add_dummy +from sverchok_extra.dependencies import sdf +from sverchok_extra.utils.sdf import * + +if sdf is None: + add_dummy('SvExSdfSchwarzPNode', "SDF Schwarz P", 'sdf') +else: + from sdf import * + +class SvExSdfSchwarzPNode(bpy.types.Node, SverchCustomTreeNode): + """ + Triggers: SDF Schwarz P + Tooltip: SDF Schwarz P + """ + bl_idname = 'SvExSdfSchwarzPNode' + bl_label = 'SDF Schwarz P' + bl_icon = 'MESH_CAPSULE' + + size_x : FloatProperty( + name = "X Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_y : FloatProperty( + name = "Y Size", + default = 1.0, + min = 0.0, + update=updateNode) + + size_z : FloatProperty( + name = "Z Size", + default = 1.0, + min = 0.0, + update=updateNode) + + thickness : FloatProperty( + name = "Thickness", + default = 0.1, + min = 0.0, + update=updateNode) + + origin: FloatVectorProperty( + name="Origin", + default=(0, 0, 0), + size=3, + update=updateNode) + + flat_output : BoolProperty( + name = "Flat output", + default = True, + update=updateNode) + + def draw_buttons(self, context, layout): + layout.prop(self, 'flat_output') + + def sv_init(self, context): + self.inputs.new('SvStringsSocket', "XSize").prop_name = 'size_x' + self.inputs.new('SvStringsSocket', "YSize").prop_name = 'size_y' + self.inputs.new('SvStringsSocket', "ZSize").prop_name = 'size_z' + self.inputs.new('SvStringsSocket', "Thickness").prop_name = 'thickness' + self.inputs.new('SvVerticesSocket', "Origin").prop_name = 'origin' + self.outputs.new('SvScalarFieldSocket', "SDF") + + def process(self): + if not any(socket.is_linked for socket in self.outputs): + return + + size_x_s = self.inputs['XSize'].sv_get() + size_y_s = self.inputs['YSize'].sv_get() + size_z_s = self.inputs['ZSize'].sv_get() + thickness_s = self.inputs['Thickness'].sv_get() + origins_s = self.inputs['Origin'].sv_get() + + size_x_s = ensure_nesting_level(size_x_s, 2) + size_y_s = ensure_nesting_level(size_y_s, 2) + size_z_s = ensure_nesting_level(size_z_s, 2) + thickness_s = ensure_nesting_level(thickness_s, 2) + origins_s = ensure_nesting_level(origins_s, 3) + + fields_out = [] + for params in zip_long_repeat(size_x_s, size_y_s, size_z_s, thickness_s, origins_s): + new_fields = [] + for size_x, size_y, size_z, thickness, origin in zip_long_repeat(*params): + sdf = schwarzP(thickness, size = (size_x,size_y,size_z),center=origin).translate(origin) + field = SvExSdfScalarField(sdf) + new_fields.append(field) + if self.flat_output: + fields_out.extend(new_fields) + else: + fields_out.append(new_fields) + + self.outputs['SDF'].sv_set(fields_out) + +def register(): + if sdf is not None: + bpy.utils.register_class(SvExSdfSchwarzPNode) + +def unregister(): + if sdf is not None: + bpy.utils.unregister_class(SvExSdfSchwarzPNode)