Add new functionality for image rectification and depth metadata handling
- Implemented a preview tool for rectifying images with interactive aspect controls in `preview.py`. - Added tests for depth metadata loading to ensure consistent schema usage in `test_depth_metadata.py`. - Developed comprehensive tests for cutout calibration processes in `test_cutout_calibration.py`, including stability checks and depth calibration. - Created tests for frame compositing operations in `test_frame_compositing.py`, ensuring correct handling of depth and transparency. - Introduced material slot inheritance functionality in `material_slots.py` to manage geometry material assignments. - Built shared shader nodes for material processing in `shader.py`, including roughness and bump mapping setups.
This commit is contained in:
@@ -10,7 +10,7 @@ from ..common.depth_surface import (
|
||||
_math, split_depth_surface, build_surface_camera, CUT_ATTRIBUTE,
|
||||
)
|
||||
from ..common.nodes import float_input, group_input, interface_socket, prepare_node_group, evaluate_field, remove_attributes
|
||||
from ..common.material import inherit_material_slots
|
||||
from ..common.material_slots import inherit_material_slots
|
||||
from ..common.smoothing import expand_smooth
|
||||
from ..common.boundary_smoothing import smooth_boundary_depth, smooth_cut_boundary
|
||||
|
||||
@@ -42,19 +42,24 @@ def build_image_depth_panorama_group():
|
||||
group["anyimage_asset_revision"] = 15
|
||||
interface_socket(group, "Geometry", "INPUT", "NodeSocketGeometry")
|
||||
subdivide = interface_socket(group, "Subdivide", "INPUT", "NodeSocketInt")
|
||||
subdivide.default_value, subdivide.min_value, subdivide.max_value = 7, 0, 8
|
||||
float_input(group, "Depth Scale", 1, maximum=1, subtype="FACTOR")
|
||||
float_input(group, "Split Threshold", 0, maximum=1, subtype="FACTOR")
|
||||
subdivide.description = "Increase mesh density to represent finer shapes. Higher levels create more vertices and require more processing time."
|
||||
subdivide.default_value, subdivide.min_value, subdivide.max_value = 8, 0, 8
|
||||
float_input(group, "Depth Scale", 1, maximum=1, subtype="FACTOR").description = "Blend between a sphere at zero and the estimated depth surface at one."
|
||||
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."
|
||||
smooth = interface_socket(group, "Smooth", "INPUT", "NodeSocketInt")
|
||||
smooth.description = "Set the number of mesh smoothing passes. Higher values smooth the surface more but may soften details. Zero disables smoothing."
|
||||
smooth.default_value, smooth.min_value, smooth.max_value = 0, 0, 20
|
||||
interface_socket(group, "Valid Only", "INPUT", "NodeSocketBool").default_value = True
|
||||
valid_only = interface_socket(group, "Depth Mask", "INPUT", "NodeSocketBool")
|
||||
valid_only.default_value = True
|
||||
valid_only.description = "Remove mesh areas marked invalid by the depth mask."
|
||||
group.interface.move(valid_only, smooth.position)
|
||||
options = group.interface.new_panel("Options", default_closed=True)
|
||||
boundary_smooth = interface_socket(group, "Boundary Smooth", "INPUT", "NodeSocketInt", options)
|
||||
boundary_smooth.default_value, boundary_smooth.min_value, boundary_smooth.max_value = 5, 0, 20
|
||||
boundary_smooth.description = "Smooth boundary distance and cut-edge geometry on the sphere"
|
||||
float_input(group, "Smooth Weight", 1, maximum=1, subtype="FACTOR", parent=options)
|
||||
float_input(group, "Validity Threshold", 0.9, maximum=1, subtype="FACTOR", parent=options)
|
||||
float_input(group, "Invalid Distance", 100, minimum=1e-5, subtype="DISTANCE", parent=options)
|
||||
boundary_smooth.default_value, boundary_smooth.min_value, boundary_smooth.max_value = 2, 0, 20
|
||||
boundary_smooth.description = "Smooth depth and geometry near cut edges on the panorama surface. Zero disables boundary smoothing."
|
||||
float_input(group, "Smooth Weight", 1, maximum=1, subtype="FACTOR", parent=options).description = "Control the strength of each mesh smoothing pass. Higher values move vertices more."
|
||||
float_input(group, "Mask Threshold", 0.9, maximum=1, subtype="FACTOR", parent=options).description = "Set the minimum depth mask value treated as valid. Higher values exclude more partially valid boundary areas."
|
||||
float_input(group, "Invalid Distance", 100, minimum=1e-5, subtype="DISTANCE", parent=options).description = "Set the fallback distance from the panorama center for invalid depth areas kept when Depth Mask is disabled."
|
||||
data = group.interface.new_panel("Data", default_closed=True)
|
||||
interface_socket(group, "Depth Image", "INPUT", "NodeSocketImage", data).hide_in_modifier = True
|
||||
interface_socket(group, "Geometry", "OUTPUT", "NodeSocketGeometry")
|
||||
@@ -131,9 +136,9 @@ def build_image_depth_panorama_group():
|
||||
pixel = evaluate_field(group, pixel, "FLOAT_VECTOR", "POINT")
|
||||
nearest = nodes.new("FunctionNodeSeparateColor")
|
||||
links.new(texture(coordinates, "Closest"), nearest.inputs["Color"])
|
||||
controls = group_input(nodes, {"Validity Threshold"})
|
||||
controls = group_input(nodes, {"Mask Threshold"})
|
||||
invalid = _math(group, "MAXIMUM",
|
||||
_math(group, "LESS_THAN", nearest.outputs["Alpha"], controls.outputs["Validity Threshold"]),
|
||||
_math(group, "LESS_THAN", nearest.outputs["Alpha"], controls.outputs["Mask Threshold"]),
|
||||
_math(group, "LESS_THAN", nearest.outputs["Red"], 1e-5))
|
||||
face_invalid = evaluate_field(group, invalid, "FLOAT", "POINT")
|
||||
any_invalid = _math(group, "GREATER_THAN", face_invalid, 0)
|
||||
@@ -147,11 +152,11 @@ def build_image_depth_panorama_group():
|
||||
links.new(mixed, delete.inputs["Selection"])
|
||||
selection = nodes.new("GeometryNodeSwitch")
|
||||
selection.input_type = "GEOMETRY"
|
||||
links.new(group_input(nodes, {"Valid Only"}).outputs["Valid Only"], selection.inputs["Switch"])
|
||||
links.new(group_input(nodes, {"Depth Mask"}).outputs["Depth Mask"], selection.inputs["Switch"])
|
||||
links.new(delete.outputs[0], selection.inputs["False"])
|
||||
links.new(culled, selection.inputs["True"])
|
||||
controls = group_input(nodes, {"Split Threshold"})
|
||||
strength = controls.outputs["Split Threshold"]
|
||||
controls = group_input(nodes, {"Depth Split"})
|
||||
strength = controls.outputs["Depth Split"]
|
||||
face_camera = depth(combine(face_u, face_v))[0]
|
||||
radial = nodes.new("ShaderNodeSeparateXYZ")
|
||||
links.new(face_camera, radial.inputs[0])
|
||||
|
||||
Reference in New Issue
Block a user