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

Some new field primitive nodes #5173

Open
wants to merge 4 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
93 changes: 93 additions & 0 deletions docs/nodes/field/twist_field.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Twist / Whirld Field
====================

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

This node generates a Vector Field, which does Twist or Whirl transformation of
some region of space, or combination of Twist and Whirl.

We call Twist a transformation which you get if you take some object, for
example a cube, then rotate one of it's sides (for example, bottom one) around
some axis, counterclockwise, and rotate the opposite side (top side, for
example) around the same axis clockwise.

Whirl transformation rotates all parts of object in the same direction, just
with different angle; the farther from whirl axis, the bigger is rotation
angle.

Both Twist and Whirl transformation require some axis for rotation. This axis
can be defined by a point, through which the axis goes, and the direction
vector.

Inputs
------

This node has the following inputs:

* **Center**. Rotation center; a point on twist / whirl axis. The default value
is the origin, `(0, 0, 0)`.
* **Axis**. Direction vector of the twist / whirl axis. The default value is Z
axis, `(0, 0, 1)`.
* **TwistAngle**. This is not exactly an angle, but a coefficient, which
defines the force of twist transformation. More specifically, the plane lying
at distance of 1 from rotation center in direction of rotation axis, will be
rotated by angle specified in this input; plane passing through rotation
center will not be rotated by twist transformation; all other planes
perpendicular to rotation axis will be rotated on an angle proportional to
distance from rotation center. The value is specified in radians. The default
value is `pi/2`.
* **WhirlAngle**. Similar to previous input, this is not exactly an angle, but
a coefficient, which defines the force of whirl transformation. More
specifically, points at distance 1 from rotation axis will be rotated by
angle specified in this input. All other points will be rotated by angle
which is proportional to distance from rotation axis. The value is specified
in radians. The default value is 0.
* **MinZ**, **MaxZ**. These inputs are available only when **Use Min Z** /
**Use Max Z** parameters are enabled. Both twist and whirl transformation
will stop at these distances from rotation center along rotation axis.
Positive direction of rotation axis is the one defined by **Axis** input. The
default values are 0.0 and 1.0, correspondingly.
* **MinR**, **MaxR**. These inputs are available only when **Use Min R** /
**Use Max R** parameters are enabled. Both twist and whirl transformations
will be ceased for points which have distance from rotation axis below
**MinR** or above **MaxR** values. The default values are 0.0 and 1.0.

Parameters
----------

This node has the following parameters:

* **Use Min Z**, **Use Max Z**. If enabled, these parameters will allow to
define a part of space along rotation axis which will be transformed; space
outside this area will not be twisted any further.
* **Use Min R**, **Use Max R**. If enabled, these parameters allow to define a
(cylindrical) part of space in terms of distance from rotation axis, which
should be transformed; outside this area, the space will not be twisted any
further.

Outputs
-------

This node has the following output:

* **Field**. The generated vector field.

Examples of usage
-----------------

Example of Twist transformation:

.. image:: https://github.com/user-attachments/assets/edb22301-0dd3-492b-abea-a20a2f2ee772
:target: https://github.com/user-attachments/assets/edb22301-0dd3-492b-abea-a20a2f2ee772

Example of Whirl transformation:

.. image:: https://github.com/user-attachments/assets/3467f0e7-884a-496e-9516-133d3c5596f4
:target: https://github.com/user-attachments/assets/3467f0e7-884a-496e-9516-133d3c5596f4

Twist and Whirl combined:

.. image:: https://github.com/user-attachments/assets/0b351703-97ae-4960-9f86-42f7c2825c0b
:target: https://github.com/user-attachments/assets/0b351703-97ae-4960-9f86-42f7c2825c0b

3 changes: 3 additions & 0 deletions menus/full_by_data_type.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@
- SvExDecomposeVectorFieldNode
- SvExScalarFieldPointNode
- SvAttractorFieldNodeMk2
- SvTwistFieldNode
- SvTaperFieldNode
- SvRotationFieldNode
- SvExImageFieldNode
- SvMeshSurfaceFieldNode
Expand All @@ -433,6 +435,7 @@
- icon_name: TOOL_SETTINGS
- SvExScalarFieldMathNode
- SvExVectorFieldMathNode
- SvVectorFieldFilterNode
- SvScalarFieldCurveMapNode
- SvExFieldDiffOpsNode
- SvScalarFieldCurvatureNode
Expand Down
30 changes: 16 additions & 14 deletions nodes/field/attractor_field_mk2.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat

from sverchok.utils.field.scalar import (SvScalarFieldPointDistance,
SvMergedScalarField, SvKdtScalarField,
SvLineAttractorScalarField, SvPlaneAttractorScalarField,
SvCircleAttractorScalarField,
SvEdgeAttractorScalarField,
SvBvhAttractorScalarField,
SvBvhEdgesAttractorScalarField
from sverchok.utils.field.scalar import SvMergedScalarField
from sverchok.utils.field.vector_operations import (
SvAverageVectorField,
SvSelectVectorField)
from sverchok.utils.field.attractor import (SvScalarFieldPointDistance,
SvKdtScalarField,
SvLineAttractorScalarField, SvPlaneAttractorScalarField,
SvCircleAttractorScalarField,
SvEdgeAttractorScalarField,
SvBvhAttractorScalarField,
SvVectorFieldPointDistance,
SvKdtVectorField,
SvLineAttractorVectorField, SvPlaneAttractorVectorField,
SvCircleAttractorVectorField,
SvEdgeAttractorVectorField,
SvBvhAttractorVectorField
)
from sverchok.utils.field.vector import (SvVectorFieldPointDistance,
SvAverageVectorField, SvKdtVectorField,
SvLineAttractorVectorField, SvPlaneAttractorVectorField,
SvCircleAttractorVectorField,
SvEdgeAttractorVectorField,
SvBvhAttractorVectorField,
SvSelectVectorField)
from sverchok.utils.math import all_falloff_types, falloff_array
from sverchok.utils.kdtree import SvKdTree

Expand Down
2 changes: 1 addition & 1 deletion nodes/field/compose_vector_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sverchok.data_structure import zip_long_repeat, updateNode

from sverchok.utils.math import coordinate_modes
from sverchok.utils.field.vector import SvComposedVectorField
from sverchok.utils.field.vector_operations import SvComposedVectorField

class SvComposeVectorFieldNode(SverchCustomTreeNode, bpy.types.Node):
"""
Expand Down
1 change: 0 additions & 1 deletion nodes/field/coordinate_scalar_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from sverchok.utils.field.scalar import SvCoordinateScalarField


class SvCoordScalarFieldNode(SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: Coordinate Scalar Field
Expand Down
5 changes: 3 additions & 2 deletions nodes/field/differential_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat

from sverchok.utils.field.scalar import (SvVectorFieldDivergence, SvScalarFieldLaplacian)
from sverchok.utils.field.vector import (SvScalarFieldGradient, SvVectorFieldRotor)
from sverchok.utils.field.differential import (
SvVectorFieldDivergence, SvScalarFieldLaplacian,
SvScalarFieldGradient, SvVectorFieldRotor)
from sverchok.utils.modules.sockets import SvDynamicSocketsHandler, SocketInfo

sockets_handler = SvDynamicSocketsHandler()
Expand Down
3 changes: 1 addition & 2 deletions nodes/field/frame_along_curve.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import numpy as np

import bpy
from mathutils import Quaternion
from bpy.props import EnumProperty, IntProperty, FloatProperty
from bpy.props import EnumProperty, IntProperty
from mathutils import Matrix

from sverchok.node_tree import SverchCustomTreeNode
Expand Down
1 change: 0 additions & 1 deletion nodes/field/merge_scalar_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from sverchok.utils.field.scalar import SvMergedScalarField, SvScalarField


class SvMergeScalarFieldsNode(SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: Merge / Join Scalar Fields
Expand Down
2 changes: 1 addition & 1 deletion nodes/field/mesh_normal_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat
from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata
from sverchok.utils.field.vector import SvBvhAttractorVectorField
from sverchok.utils.field.attractor import SvBvhAttractorVectorField
from sverchok.utils.field.rbf import SvBvhRbfNormalVectorField
from sverchok.dependencies import scipy
from sverchok.utils.math import rbf_functions
Expand Down
3 changes: 2 additions & 1 deletion nodes/field/rotation_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat

from sverchok.utils.field.vector import (SvAverageVectorField, SvRotationVectorField, SvSelectVectorField)
from sverchok.utils.field.vector import (SvRotationVectorField)
from sverchok.utils.field.vector_operations import (SvAverageVectorField, SvSelectVectorField)
from sverchok.utils.math import all_falloff_types, falloff_array

class SvRotationFieldNode(SverchCustomTreeNode, bpy.types.Node):
Expand Down
2 changes: 1 addition & 1 deletion nodes/field/scalar_field_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat

from sverchok.utils.field.scalar import SvScalarFieldPointDistance
from sverchok.utils.field.attractor import SvScalarFieldPointDistance
from sverchok.utils.math import falloff_types, falloff_array

class SvScalarFieldPointNode(SverchCustomTreeNode, bpy.types.Node):
Expand Down
112 changes: 112 additions & 0 deletions nodes/field/taper_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# 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 numpy as np

import bpy
from bpy.props import FloatProperty, EnumProperty, BoolProperty

from sverchok.node_tree import SverchCustomTreeNode
from sverchok.data_structure import updateNode, zip_long_repeat
from sverchok.utils.field.vector_primitives import SvTaperVectorField

class SvTaperFieldNode(SverchCustomTreeNode, bpy.types.Node):
"""
Triggers: Taper Field
Tooltip: Generate taper field
"""
bl_idname = 'SvTaperFieldNode'
bl_label = 'Taper Field'
bl_icon = 'OUTLINER_OB_EMPTY'
sv_icon = 'SV_EX_ATTRACT'

def update_sockets(self, context):
self.inputs['MinZ'].hide_safe = not self.use_min_z
self.inputs['MaxZ'].hide_safe = not self.use_max_z
updateNode(self, context)

use_min_z : BoolProperty(
name = "Use Min Z",
default = False,
update = update_sockets)

use_max_z : BoolProperty(
name = "Use Max Z",
default = False,
update = update_sockets)

min_z : FloatProperty(
name = "Min Z",
default = 0.0,
update = updateNode)

max_z : FloatProperty(
name = "Max Z",
default = 1.0,
update = updateNode)

flat_output : BoolProperty(
name = "Flat Output",
default = True,
update = updateNode)

def draw_buttons(self, context, layout):
layout.label(text='Restrict Along Axis:')
r = layout.row(align=True)
r.prop(self, 'use_min_z', toggle=True)
r.prop(self, 'use_max_z', toggle=True)
layout.prop(self, 'flat_output')

def sv_init(self, context):
d = self.inputs.new('SvVerticesSocket', "Point")
d.use_prop = True
d.default_property = (0.0, 0.0, 0.0)

d = self.inputs.new('SvVerticesSocket', "Vertex")
d.use_prop = True
d.default_property = (0.0, 0.0, 1.0)

self.inputs.new('SvStringsSocket', 'MinZ').prop_name = 'min_z'
self.inputs.new('SvStringsSocket', 'MaxZ').prop_name = 'max_z'

self.outputs.new('SvVectorFieldSocket', "Field")

def process(self):
if not any(socket.is_linked for socket in self.outputs):
return

point_s = self.inputs['Point'].sv_get()
vertex_s = self.inputs['Vertex'].sv_get()
if self.use_min_z:
min_z_s = self.inputs['MinZ'].sv_get()
else:
min_z_s = [[None]]
if self.use_max_z:
max_z_s = self.inputs['MaxZ'].sv_get()
else:
max_z_s = [[None]]

fields_out = []
for params in zip_long_repeat(point_s, vertex_s, min_z_s, max_z_s):
new_fields = []
for point, vertex, min_z, max_z in zip_long_repeat(*params):
field = SvTaperVectorField.from_base_point_and_vertex(point, vertex,
min_z = min_z, max_z = max_z)
new_fields.append(field)
if self.flat_output:
fields_out.extend(new_fields)
else:
fields_out.append(new_fields)

self.outputs['Field'].sv_set(fields_out)

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

def unregister():
bpy.utils.unregister_class(SvTaperFieldNode)

Loading
Loading