Refactor depth reference handling and cleanup
- Unified reference depth calculation to use a single implementation in common/depth.py. - Removed server-side reference depth computation and adjusted depth.json to only include image_size and intrinsics. - Updated depth texture handling to ignore transparent, invalid, and non-positive pixels when calculating reference depth. - Changed reference depth calculation to use the 95th percentile of valid depth values. - Adjusted depth direction fitting to return a flat direction when no samples are available. - Removed cleanup threshold parameters from Cutout and related nodes, simplifying the interface. - Updated tests to verify new reference depth logic and ensure compatibility with existing functionality.
This commit is contained in:
@@ -3,27 +3,6 @@ from .nodes import math_node
|
||||
from anyimage.operators.cutout_tool.shape import BALLOON_ATTRIBUTE_NAME
|
||||
|
||||
|
||||
def _island_cleanup(group, geometry, cleanup):
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
mesh_island = nodes.new("GeometryNodeInputMeshIsland")
|
||||
face_area = nodes.new("GeometryNodeInputMeshFaceArea")
|
||||
island_area = nodes.new("GeometryNodeAccumulateField")
|
||||
island_area.data_type = "FLOAT"
|
||||
island_area.domain = "FACE"
|
||||
links.new(face_area.outputs["Area"], island_area.inputs["Value"])
|
||||
links.new(mesh_island.outputs["Island Index"], island_area.inputs["Group ID"])
|
||||
|
||||
tiny = math_node(nodes, "LESS_THAN")
|
||||
links.new(island_area.outputs["Total"], tiny.inputs[0])
|
||||
links.new(cleanup, tiny.inputs[1])
|
||||
delete = nodes.new("GeometryNodeDeleteGeometry")
|
||||
delete.domain = "FACE"
|
||||
links.new(geometry, delete.inputs["Geometry"])
|
||||
links.new(tiny.outputs[0], delete.inputs["Selection"])
|
||||
return delete.outputs["Geometry"]
|
||||
|
||||
|
||||
def _profile_field(group, geometry):
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import bpy
|
||||
from anyimage.operators.cutout_tool.shape import NORMAL_REDUCTION_ATTRIBUTE_NAME
|
||||
from ..common.nodes import interface_socket, group_input, math_node, float_input, menu_switch, read_float_attribute, store_float_attribute, prepare_node_group
|
||||
from ..common.cutout import _extrude_layers, _island_cleanup, _offset_geometry_y, _remove_zero_thickness, _set_layer_y, _shade_output
|
||||
from ..common.cutout import _extrude_layers, _offset_geometry_y, _remove_zero_thickness, _set_layer_y, _shade_output
|
||||
|
||||
|
||||
NODE_GROUP_NAME = "O Image Cutout"
|
||||
@@ -157,8 +157,6 @@ def build_image_cutout_group():
|
||||
interface_socket(group, 'Mode', 'INPUT', 'NodeSocketMenu')
|
||||
float_input(group, 'Thickness', 1.0, maximum=2.0).description = 'Control how much the surface bulges in Balloon mode. Zero removes the bulge.'
|
||||
float_input(group, 'Shell Thickness', 0.0, maximum=1.0, subtype='DISTANCE').description = 'Add thickness behind the original surface while keeping the front surface in place.'
|
||||
options = group.interface.new_panel(name='Options', default_closed=True)
|
||||
float_input(group, 'Cleanup Threshold', 0.0, parent=options)
|
||||
interface_socket(group, 'Geometry', 'OUTPUT', 'NodeSocketGeometry')
|
||||
controls = group_input(group.nodes, set())
|
||||
balloon = _build_balloon(group, controls.outputs['Geometry'], controls.outputs['Thickness'])
|
||||
@@ -167,14 +165,6 @@ def build_image_cutout_group():
|
||||
group.links.new(balloon, choose.inputs['Balloon'])
|
||||
group.links.new(shell, choose.inputs['Shell'])
|
||||
geometry = choose.outputs[0]
|
||||
planar_inputs = [link.to_socket for link in group.links if link.from_node.bl_idname == 'NodeGroupInput' and link.from_socket.name == 'Geometry']
|
||||
base = group_input(group.nodes, {'Geometry', 'Cleanup Threshold'})
|
||||
area = math_node(group.nodes, 'MULTIPLY')
|
||||
area.inputs[1].default_value = 0.01
|
||||
group.links.new(base.outputs['Cleanup Threshold'], area.inputs[0])
|
||||
cleaned = _island_cleanup(group, base.outputs['Geometry'], area.outputs[0])
|
||||
for target in planar_inputs:
|
||||
group.links.new(cleaned, target)
|
||||
profile = read_float_attribute(group, 'o_balloon')
|
||||
amount = group_input(group.nodes, {'Thickness'})
|
||||
enabled = math_node(group.nodes, 'GREATER_THAN')
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""Build O Image Depth Cutout."""
|
||||
import bpy
|
||||
from anyimage.operators.cutout_tool.shape import NORMAL_REDUCTION_ATTRIBUTE_NAME
|
||||
from ..common.nodes import interface_socket, group_input, math_node, float_input, read_float_attribute, store_float_attribute, prepare_node_group, sample_field, evaluate_field
|
||||
from ..common.nodes import interface_socket, group_input, float_input, read_float_attribute, store_float_attribute, prepare_node_group, sample_field, evaluate_field
|
||||
from ..common.boundary_smoothing import smooth_cut_boundary
|
||||
from ..common.cutout import _island_cleanup, _position_field, _remove_zero_thickness, _shade_output
|
||||
from ..common.cutout import _position_field, _remove_zero_thickness, _shade_output
|
||||
from ..common.depth_surface import _math, project_depth_surface, build_surface_camera, split_depth_surface, sample_face_camera, thicken_depth_surface
|
||||
from ..common.smoothing import edge_boundary_field
|
||||
from ..common.cutout_boundary import original_boundary_field, remove_boundary_triangles, taper_split_profile
|
||||
@@ -344,7 +344,6 @@ def build_image_depth_cutout_group():
|
||||
float_input(group, 'Depth Scale', 1.0, maximum=2.0)
|
||||
float_input(group, 'Depth Split', 0.1, maximum=1, subtype='FACTOR').description = 'Split the mesh where depth changes abruptly. Higher values detect smaller depth jumps. Zero disables splitting.'
|
||||
options = group.interface.new_panel(name='Options', default_closed=True)
|
||||
float_input(group, 'Cleanup Threshold', 0.0, parent=options)
|
||||
float_input(group, 'Smooth Weight', 1.0, maximum=1, subtype='FACTOR', parent=options).description = 'Control the strength of boundary smoothing. Higher values move boundary vertices more.'
|
||||
float_input(group, 'Reference Depth', 1.0, subtype='DISTANCE', parent=options)
|
||||
boundary_smooth = interface_socket(group, 'Boundary Smooth', 'INPUT', 'NodeSocketInt', options)
|
||||
@@ -358,14 +357,9 @@ def build_image_depth_cutout_group():
|
||||
float_input(group, 'Uniform Scale', 1.0, parent=data).hide_in_modifier = True
|
||||
interface_socket(group, 'Depth Image', 'INPUT', 'NodeSocketImage', data).hide_in_modifier = True
|
||||
interface_socket(group, 'Geometry', 'OUTPUT', 'NodeSocketGeometry')
|
||||
base = group_input(group.nodes, {'Geometry', 'Cleanup Threshold'})
|
||||
area = math_node(group.nodes, 'MULTIPLY')
|
||||
area.inputs[1].default_value = 0.01
|
||||
group.links.new(base.outputs['Cleanup Threshold'], area.inputs[0])
|
||||
cleaned = _island_cleanup(group, base.outputs['Geometry'], area.outputs[0])
|
||||
cleaned = store_float_attribute(group, cleaned, NORMAL_REDUCTION_ATTRIBUTE_NAME, 0.0, domain='FACE')
|
||||
controls = group_input(group.nodes, set())
|
||||
geometry = _build_depth_surface(group, cleaned, controls)
|
||||
geometry = store_float_attribute(group, controls.outputs['Geometry'], NORMAL_REDUCTION_ATTRIBUTE_NAME, 0.0, domain='FACE')
|
||||
geometry = _build_depth_surface(group, geometry, controls)
|
||||
_shade_output(group, geometry)
|
||||
prepare_node_group(group)
|
||||
for item in group.interface.items_tree:
|
||||
|
||||
@@ -42,7 +42,7 @@ def build_image_relief_plane_group(image_plane_group):
|
||||
thickness.description = "Set the thickness of the flat base beneath the relief."
|
||||
vector_input(group, "Depth Direction", (0, 0, 1), subtype="DIRECTION").description = "Set the direction used to orient the reference depth plane."
|
||||
depth_offset = _interface_socket(group, "Depth Offset", "INPUT", "NodeSocketFloat")
|
||||
depth_offset.default_value = 1.0
|
||||
depth_offset.default_value = 0.0
|
||||
depth_offset.min_value = -10.0
|
||||
depth_offset.max_value = 10.0
|
||||
depth_offset.subtype = "DISTANCE"
|
||||
|
||||
Reference in New Issue
Block a user