Refactor comparison operations in geometry nodes
- Introduced a new `compare_node` function to streamline comparison operations across various geometry nodes. - Replaced instances of mathematical comparison nodes with the new `compare_node` function in multiple files, enhancing code readability and maintainability. - Updated related logic in cutout, depth surface, and image processing groups to utilize the new comparison method. - Ensured consistent handling of boolean logic through the introduction of a `boolean_node` function for combining boolean inputs.
This commit is contained in:
@@ -6,7 +6,8 @@ from anyimage.operators.cutout_tool.shape import NORMAL_REDUCTION_ATTRIBUTE_NAME
|
||||
|
||||
from ..common.nodes import (
|
||||
interface_socket, group_input, float_input, bool_input, vector_input,
|
||||
evaluate_field, store_float_attribute, read_float_attribute, prepare_node_group,
|
||||
compare_node, evaluate_field, store_float_attribute, read_float_attribute,
|
||||
prepare_node_group,
|
||||
)
|
||||
from ..common.depth_surface import _math
|
||||
from ..common.normal_map import ROTATION_ATTRIBUTE, FACE_ATTRIBUTE, AXIS_ATTRIBUTE
|
||||
@@ -67,7 +68,7 @@ def _align_front(group, geometry, controls):
|
||||
def _boundary_edge_field(group):
|
||||
"""Report one on edges that carry a single face."""
|
||||
neighbors = group.nodes.new('GeometryNodeInputMeshEdgeNeighbors')
|
||||
return _math(group, 'COMPARE', neighbors.outputs['Face Count'], 1)
|
||||
return compare_node(group, 'EQUAL', neighbors.outputs['Face Count'], 1, data_type='INT')
|
||||
|
||||
|
||||
def _fold_to_plane(group, geometry, tolerance):
|
||||
@@ -76,7 +77,7 @@ def _fold_to_plane(group, geometry, tolerance):
|
||||
position = nodes.new('GeometryNodeInputPosition')
|
||||
components = nodes.new('ShaderNodeSeparateXYZ')
|
||||
links.new(position.outputs[0], components.inputs[0])
|
||||
beyond = _math(group, 'GREATER_THAN', components.outputs['Y'], tolerance)
|
||||
beyond = compare_node(group, 'GREATER_THAN', components.outputs['Y'], tolerance)
|
||||
target = nodes.new('ShaderNodeCombineXYZ')
|
||||
links.new(components.outputs['X'], target.inputs['X'])
|
||||
links.new(components.outputs['Z'], target.inputs['Z'])
|
||||
@@ -91,8 +92,8 @@ def _fold_to_plane(group, geometry, tolerance):
|
||||
links.new(normal.outputs[0], normal_axes.inputs[0])
|
||||
flat = nodes.new('FunctionNodeBooleanMath')
|
||||
flat.operation = 'AND'
|
||||
links.new(_math(group, 'LESS_THAN', center, tolerance), flat.inputs[0])
|
||||
links.new(_math(group, 'GREATER_THAN', _math(group, 'ABSOLUTE', normal_axes.outputs['Y']), 1 - 1e-3), flat.inputs[1])
|
||||
links.new(compare_node(group, 'LESS_THAN', center, tolerance), flat.inputs[0])
|
||||
links.new(compare_node(group, 'GREATER_THAN', _math(group, 'ABSOLUTE', normal_axes.outputs['Y']), 1 - 1e-3), flat.inputs[1])
|
||||
delete = nodes.new('GeometryNodeDeleteGeometry')
|
||||
delete.domain, delete.mode = 'FACE', 'ALL'
|
||||
links.new(place.outputs[0], delete.inputs['Geometry'])
|
||||
@@ -106,10 +107,10 @@ def _clean_crease(group, geometry, tolerance):
|
||||
heights = _edge_abs_y(group)
|
||||
edge_plane = nodes.new('FunctionNodeBooleanMath')
|
||||
edge_plane.operation = 'AND'
|
||||
links.new(_math(group, 'LESS_THAN', heights[0], tolerance), edge_plane.inputs[0])
|
||||
links.new(_math(group, 'LESS_THAN', heights[1], tolerance), edge_plane.inputs[1])
|
||||
links.new(compare_node(group, 'LESS_THAN', heights[0], tolerance), edge_plane.inputs[0])
|
||||
links.new(compare_node(group, 'LESS_THAN', heights[1], tolerance), edge_plane.inputs[1])
|
||||
neighbors = nodes.new('GeometryNodeInputMeshEdgeNeighbors')
|
||||
interior = _math(group, 'COMPARE', neighbors.outputs['Face Count'], 2)
|
||||
interior = compare_node(group, 'EQUAL', neighbors.outputs['Face Count'], 2, data_type='INT')
|
||||
fold = nodes.new('FunctionNodeBooleanMath')
|
||||
fold.operation = 'AND'
|
||||
links.new(edge_plane.outputs[0], fold.inputs[0])
|
||||
@@ -147,7 +148,7 @@ def _clean_crease(group, geometry, tolerance):
|
||||
def _off_plane_edge_field(group, tolerance):
|
||||
"""Report one on edges that keep an endpoint off the symmetry plane."""
|
||||
heights = _edge_abs_y(group)
|
||||
return _math(group, 'GREATER_THAN', _math(group, 'MAXIMUM', heights[0], heights[1]), tolerance)
|
||||
return compare_node(group, 'GREATER_THAN', _math(group, 'MAXIMUM', heights[0], heights[1]), tolerance)
|
||||
|
||||
|
||||
def _edge_abs_y(group):
|
||||
@@ -179,14 +180,9 @@ def _boundary_fields(group, tolerance):
|
||||
links.new(position.outputs[0], components.inputs[0])
|
||||
seam = nodes.new('FunctionNodeBooleanMath')
|
||||
seam.operation = 'AND'
|
||||
links.new(_math(group, 'GREATER_THAN', boundary, 0), seam.inputs[0])
|
||||
links.new(compare_node(group, 'GREATER_THAN', boundary, 0), seam.inputs[0])
|
||||
links.new(
|
||||
_math(
|
||||
group,
|
||||
'LESS_THAN',
|
||||
_math(group, 'ABSOLUTE', components.outputs['Y']),
|
||||
tolerance,
|
||||
),
|
||||
compare_node(group, 'LESS_THAN', _math(group, 'ABSOLUTE', components.outputs['Y']), tolerance),
|
||||
seam.inputs[1],
|
||||
)
|
||||
return boundary, seam.outputs[0]
|
||||
@@ -306,12 +302,16 @@ def build_image_cutout_symmetry_group():
|
||||
links.new(is_boundary, boundary.inputs[0])
|
||||
# The seam sits on the plane and welds through the merge, so only off-plane edges need walls.
|
||||
links.new(_off_plane_edge_field(group, snap_tolerance), boundary.inputs[1])
|
||||
fill_smooth = _math(group, 'MULTIPLY', inputs['Fill Smooth'], inputs['Fill Sides'])
|
||||
front = _relax_fill(group, front, boundary_field, fill_smooth)
|
||||
fill_smooth = nodes.new('GeometryNodeSwitch')
|
||||
fill_smooth.input_type = 'INT'
|
||||
fill_smooth.inputs['False'].default_value = 0
|
||||
links.new(inputs['Fill Sides'], fill_smooth.inputs['Switch'])
|
||||
links.new(inputs['Fill Smooth'], fill_smooth.inputs['True'])
|
||||
front = _relax_fill(group, front, boundary_field, fill_smooth.outputs[0])
|
||||
walled = _build_wall(group, front, boundary.outputs[0])
|
||||
wall_shade = nodes.new('GeometryNodeSetShadeSmooth')
|
||||
wall_shade.domain = 'FACE'
|
||||
links.new(_math(group, 'COMPARE', read_float_attribute(group, FACE_ATTRIBUTE), 3), wall_shade.inputs['Selection'])
|
||||
links.new(compare_node(group, 'EQUAL', read_float_attribute(group, FACE_ATTRIBUTE), 3), wall_shade.inputs['Selection'])
|
||||
links.new(walled, wall_shade.inputs['Geometry'])
|
||||
body = nodes.new('GeometryNodeSwitch')
|
||||
body.input_type = 'GEOMETRY'
|
||||
@@ -323,14 +323,14 @@ def build_image_cutout_symmetry_group():
|
||||
mark_back.inputs['Name'].default_value = FACE_ATTRIBUTE
|
||||
mark_back.inputs['Value'].default_value = 2
|
||||
links.new(_mirror(group, body.outputs[0]), mark_back.inputs['Geometry'])
|
||||
links.new(_math(group, 'COMPARE', read_float_attribute(group, FACE_ATTRIBUTE), 1), mark_back.inputs['Selection'])
|
||||
links.new(compare_node(group, 'EQUAL', read_float_attribute(group, FACE_ATTRIBUTE), 1), mark_back.inputs['Selection'])
|
||||
join = nodes.new('GeometryNodeJoinGeometry')
|
||||
for geometry in (body.outputs[0], mark_back.outputs['Geometry']):
|
||||
links.new(geometry, join.inputs[0])
|
||||
position = nodes.new('GeometryNodeInputPosition')
|
||||
axis = nodes.new('ShaderNodeSeparateXYZ')
|
||||
links.new(position.outputs[0], axis.inputs[0])
|
||||
on_axis = _math(group, 'LESS_THAN', _math(group, 'ABSOLUTE', axis.outputs['Y']), snap_tolerance)
|
||||
on_axis = compare_node(group, 'LESS_THAN', _math(group, 'ABSOLUTE', axis.outputs['Y']), snap_tolerance)
|
||||
merge = nodes.new('GeometryNodeMergeByDistance')
|
||||
merge.inputs['Distance'].default_value = 0.01
|
||||
links.new(join.outputs[0], merge.inputs['Geometry'])
|
||||
|
||||
Reference in New Issue
Block a user