Refactor geometry node groups for image depth processing
- Introduced new utility functions in common nodes for evaluating fields and capturing attributes. - Simplified volume field calculations in image depth cutout and panorama groups by utilizing new utility functions. - Enhanced readability and maintainability of the image depth cutout and panorama node groups by removing redundant code and improving function usage. - Adjusted default values for thickness and depth scale in image relief plane group for better user experience. - Improved handling of geometry attributes and connections in image depth plane group to streamline processing.
This commit is contained in:
@@ -5,9 +5,9 @@ import math
|
||||
import bpy
|
||||
|
||||
from ..common.depth_surface import (
|
||||
_math, remove_surface_attributes, split_depth_surface, store_surface_camera,
|
||||
_math, split_depth_surface, build_surface_camera,
|
||||
)
|
||||
from ..common.nodes import float_input, group_input, interface_socket, prepare_node_group
|
||||
from ..common.nodes import float_input, group_input, interface_socket, prepare_node_group, evaluate_field
|
||||
from ..common.material import inherit_material_slots
|
||||
from ..common.smoothing import expand_smooth
|
||||
|
||||
@@ -54,20 +54,6 @@ def build_image_depth_panorama_group():
|
||||
interface_socket(group, "Geometry", "OUTPUT", "NodeSocketGeometry")
|
||||
nodes, links = group.nodes, group.links
|
||||
|
||||
def read(name):
|
||||
node = nodes.new("GeometryNodeInputNamedAttribute")
|
||||
node.data_type = "FLOAT_VECTOR"
|
||||
node.inputs["Name"].default_value = name
|
||||
return node.outputs["Attribute"]
|
||||
|
||||
def store(geometry, name, value, domain):
|
||||
node = nodes.new("GeometryNodeStoreNamedAttribute")
|
||||
node.data_type, node.domain = ("FLOAT2" if name == "UVMap" else "FLOAT_VECTOR"), domain
|
||||
node.inputs["Name"].default_value = name
|
||||
links.new(geometry, node.inputs["Geometry"])
|
||||
links.new(value, node.inputs["Value"])
|
||||
return node.outputs["Geometry"]
|
||||
|
||||
def uv(direction):
|
||||
normalize = nodes.new("ShaderNodeVectorMath")
|
||||
normalize.operation = "NORMALIZE"
|
||||
@@ -118,12 +104,11 @@ def build_image_depth_panorama_group():
|
||||
inputs = group_input(nodes, {"Subdivide"})
|
||||
sphere = _quad_sphere(group, _math(group, "ADD", _math(group, "POWER", 2, inputs.outputs["Subdivide"]), 1))
|
||||
position = nodes.new("GeometryNodeInputPosition").outputs[0]
|
||||
geometry = store(sphere, "o_panorama_direction", position, "POINT")
|
||||
longitude, latitude, z = uv(read("o_panorama_direction"))
|
||||
geometry = store(geometry, "o_panorama_uv", combine(longitude, latitude), "POINT")
|
||||
longitude, latitude, z = uv(position)
|
||||
coordinates = evaluate_field(group, combine(longitude, latitude), "FLOAT_VECTOR", "POINT")
|
||||
face = nodes.new("GeometryNodeFieldOnDomain")
|
||||
face.data_type, face.domain = "FLOAT_VECTOR", "FACE"
|
||||
links.new(read("o_panorama_direction"), face.inputs["Value"])
|
||||
links.new(position, face.inputs["Value"])
|
||||
face_u, face_v, _ = uv(face.outputs["Value"])
|
||||
correction = _math(group, "ROUND", _math(group, "SUBTRACT", face_u, longitude))
|
||||
choose = nodes.new("GeometryNodeSwitch")
|
||||
@@ -131,17 +116,20 @@ def build_image_depth_panorama_group():
|
||||
links.new(_math(group, "GREATER_THAN", _math(group, "ABSOLUTE", z), 0.999999), choose.inputs["Switch"])
|
||||
links.new(_math(group, "ADD", longitude, correction), choose.inputs["False"])
|
||||
links.new(face_u, choose.inputs["True"])
|
||||
geometry = store(geometry, "UVMap", combine(choose.outputs[0], latitude), "CORNER")
|
||||
pixel, _ = depth(read("o_panorama_uv"))
|
||||
geometry = store(geometry, "o_panorama_distance", pixel, "POINT")
|
||||
uv_map = nodes.new("GeometryNodeStoreNamedAttribute")
|
||||
uv_map.data_type, uv_map.domain = "FLOAT2", "CORNER"
|
||||
uv_map.inputs["Name"].default_value = "UVMap"
|
||||
links.new(sphere, uv_map.inputs["Geometry"])
|
||||
links.new(combine(choose.outputs[0], latitude), uv_map.inputs["Value"])
|
||||
pixel, _ = depth(coordinates)
|
||||
pixel = evaluate_field(group, pixel, "FLOAT_VECTOR", "POINT")
|
||||
nearest = nodes.new("FunctionNodeSeparateColor")
|
||||
links.new(texture(read("o_panorama_uv"), "Closest"), nearest.inputs["Color"])
|
||||
links.new(texture(coordinates, "Closest"), nearest.inputs["Color"])
|
||||
controls = group_input(nodes, {"Validity Threshold"})
|
||||
invalid = _math(group, "MAXIMUM",
|
||||
_math(group, "LESS_THAN", nearest.outputs["Alpha"], controls.outputs["Validity Threshold"]),
|
||||
_math(group, "LESS_THAN", nearest.outputs["Red"], 1e-5))
|
||||
geometry = store(geometry, "o_panorama_invalid", invalid, "POINT")
|
||||
face_invalid = read("o_panorama_invalid")
|
||||
face_invalid = evaluate_field(group, invalid, "FLOAT", "POINT")
|
||||
any_invalid = _math(group, "GREATER_THAN", face_invalid, 0)
|
||||
mixed = _math(group, "MULTIPLY", any_invalid,
|
||||
_math(group, "LESS_THAN", face_invalid, 1))
|
||||
@@ -152,36 +140,31 @@ def build_image_depth_panorama_group():
|
||||
links.new(any_invalid, selection.inputs["True"])
|
||||
delete = nodes.new("GeometryNodeDeleteGeometry")
|
||||
delete.domain, delete.mode = "FACE", "ALL"
|
||||
links.new(geometry, delete.inputs["Geometry"])
|
||||
links.new(uv_map.outputs["Geometry"], delete.inputs["Geometry"])
|
||||
links.new(selection.outputs[0], delete.inputs["Selection"])
|
||||
controls = group_input(nodes, {"Split Threshold", "Reference Distance"})
|
||||
strength = controls.outputs["Split Threshold"]
|
||||
geometry = split_depth_surface(group, delete.outputs[0], depth(combine(face_u, face_v))[0], strength,
|
||||
geometry, corner_camera, cut_vertex = split_depth_surface(group, delete.outputs[0], depth(combine(face_u, face_v))[0], strength,
|
||||
_math(group, "DIVIDE", 1, controls.outputs["Reference Distance"]),
|
||||
face_center=face.outputs["Value"])
|
||||
geometry, distance = store_surface_camera(group, geometry, read("o_panorama_distance"), strength)
|
||||
distance = build_surface_camera(group, pixel, corner_camera, cut_vertex, strength)
|
||||
axes = nodes.new("ShaderNodeSeparateXYZ")
|
||||
links.new(distance, axes.inputs[0])
|
||||
distance = nodes.new("GeometryNodeSwitch")
|
||||
distance.input_type = "FLOAT"
|
||||
links.new(read("o_panorama_invalid"), distance.inputs["Switch"])
|
||||
links.new(face_invalid, distance.inputs["Switch"])
|
||||
links.new(axes.outputs["X"], distance.inputs["False"])
|
||||
links.new(group_input(nodes, {"Invalid Distance"}).outputs["Invalid Distance"], distance.inputs["True"])
|
||||
controls = group_input(nodes, {"Depth Scale"})
|
||||
radius = _math(group, "ADD", 1, _math(group, "MULTIPLY", controls.outputs["Depth Scale"], _math(group, "SUBTRACT", distance.outputs[0], 1)))
|
||||
radial = nodes.new("ShaderNodeVectorMath")
|
||||
radial.operation = "SCALE"
|
||||
links.new(read("o_panorama_direction"), radial.inputs[0])
|
||||
links.new(position, radial.inputs[0])
|
||||
links.new(radius, radial.inputs[3])
|
||||
deform = nodes.new("GeometryNodeSetPosition")
|
||||
links.new(geometry, deform.inputs["Geometry"])
|
||||
links.new(radial.outputs[0], deform.inputs["Position"])
|
||||
geometry = remove_surface_attributes(group, deform.outputs[0])
|
||||
remove = nodes.new("GeometryNodeRemoveAttribute")
|
||||
remove.pattern_mode = "WILDCARD"
|
||||
remove.inputs["Name"].default_value = "o_panorama_*"
|
||||
links.new(geometry, remove.inputs["Geometry"])
|
||||
geometry = expand_smooth(group, remove.outputs[0], iterations_name="Smooth", weight_name="Smooth Weight")
|
||||
geometry = expand_smooth(group, deform.outputs[0], iterations_name="Smooth", weight_name="Smooth Weight")
|
||||
flip = nodes.new("GeometryNodeFlipFaces")
|
||||
links.new(geometry, flip.inputs["Mesh"])
|
||||
smooth = nodes.new("GeometryNodeSetShadeSmooth")
|
||||
|
||||
Reference in New Issue
Block a user