- Implemented `image_plane.py` to build the Image Plane Geometry Nodes group with customizable parameters for geometry, subdivide, and thickness. - Created `image_plane_validation.py` to validate the functionality of the image plane, ensuring correct geometry generation and material assignment. - Developed `material_layers.py` to construct shader node groups for image materials, including depth and normal handling. - Authored `plane_layouts.py` to define node arrangements for image geometry assets. - Introduced `shadeless.py` to create a shadeless shader node group that displays color without scene lighting while preserving shadows and reflections.
146 lines
5.9 KiB
Python
146 lines
5.9 KiB
Python
"""Arrange staggered calculation branches on both sides of the geometry path."""
|
|
|
|
from cutout_layout import route_geometry
|
|
|
|
# Main geometry advances left to right. Local fields grow to either side of it;
|
|
# a long calculation may start before the geometry input or span several stages.
|
|
POSITIONS = {
|
|
"Position": (-240, 110),
|
|
"Store Named Attribute": (0, 0),
|
|
"Store Named Attribute.001": (260, 0),
|
|
"Store Named Attribute.002": (520, 0),
|
|
"Store Named Attribute.003": (780, 0),
|
|
"Split Edges": (1060, 0),
|
|
"Switch": (1360, 0),
|
|
# Face sampling stays near its stores; selection forms a dense field cluster.
|
|
"Named Attribute": (-440, 380),
|
|
"Evaluate on Domain": (-220, 380),
|
|
"Image Texture": (20, 380),
|
|
"Named Attribute.003": (260, 260),
|
|
"Named Attribute.001": (-1090, 1060),
|
|
"Separate XYZ": (-870, 1060),
|
|
"Named Attribute.002": (-390, 590),
|
|
"Corners of Edge": (-1090, 910),
|
|
"Face of Corner": (-910, 910),
|
|
"Corners of Edge.001": (-1090, 770),
|
|
"Face of Corner.001": (-910, 770),
|
|
"Evaluate at Index": (-170, 750),
|
|
"Evaluate at Index.002": (-170, 610),
|
|
"Evaluate at Index.001": (-710, 1060),
|
|
"Evaluate at Index.003": (-710, 920),
|
|
"Vector Math": (10, 710),
|
|
"Math": (-530, 1040),
|
|
"Math.001": (-350, 1040),
|
|
"Math.002": (-170, 1040),
|
|
"Math.003": (190, 1040),
|
|
"Math.004": (190, 790),
|
|
"Math.005": (370, 980),
|
|
"Math.006": (190, 620),
|
|
"Math.007": (550, 910),
|
|
"Edge Neighbors": (370, 590),
|
|
"Math.008": (550, 590),
|
|
"Math.009": (730, 810),
|
|
"Evaluate on Domain.001": (730, 670),
|
|
"Evaluate on Domain.002": (910, 670),
|
|
"Math.010": (1090, 670),
|
|
"Math.011": (1360, 280),
|
|
# Camera-ray reconstruction runs below; scene projection runs above.
|
|
"Named Attribute.004": (1290, -440),
|
|
"Image Texture.001": (1510, -440),
|
|
"Separate XYZ.001": (1740, -440),
|
|
"Named Attribute.005": (1510, -710),
|
|
"Separate XYZ.002": (1740, -710),
|
|
"Math.014": (1960, -440),
|
|
"Vector Math.001": (2180, -440),
|
|
"Named Attribute.006": (1740, -940),
|
|
"Math.012": (1510, -940),
|
|
"Math.013": (1960, -940),
|
|
"Switch.001": (2600, -240),
|
|
"Store Named Attribute.004": (2920, 0),
|
|
"Named Attribute.007": (2340, 1080),
|
|
"Vector Math.002": (2560, 1080),
|
|
"Separate XYZ.003": (2740, 1080),
|
|
"Math.015": (3100, 730),
|
|
"Math.016": (3280, 730),
|
|
"Math.017": (2740, 910),
|
|
"Combine XYZ": (2920, 1040),
|
|
"Position.001": (2920, 790),
|
|
"Mix": (3100, 950),
|
|
"Separate XYZ.004": (3280, 950),
|
|
"Combine XYZ.001": (3460, 850),
|
|
"Set Position": (3870, 0),
|
|
# Front and rear caps share a single extrusion along the geometry axis.
|
|
"Position.002": (4560, 340),
|
|
"Store Named Attribute.005": (4560, 0),
|
|
"Vector Math.003": (4780, 340),
|
|
"Set Position.001": (4780, 0),
|
|
"Index": (5010, 340),
|
|
"Store Named Attribute.006": (5010, 0),
|
|
"Extrude Mesh": (5500, 0),
|
|
"Combine XYZ.003": (5260, 350),
|
|
"Separate Geometry": (5780, 0),
|
|
"Flip Faces.001": (6300, 0),
|
|
"Join Geometry": (6970, 0),
|
|
"Combine XYZ.004": (6070, -530),
|
|
"Set Position.002": (6300, -320),
|
|
"Flip Faces": (6740, -320),
|
|
# Identity decoding above and position restoration below have independent,
|
|
# horizontally spread readers rather than equally tall vertical stacks.
|
|
"Named Attribute.008": (6240, 880),
|
|
"Integer Math": (6470, 880),
|
|
"Named Attribute.009": (6240, 650),
|
|
"Integer Math.001": (6470, 650),
|
|
"Position.004": (6240, 410),
|
|
"Separate XYZ.006": (6470, 410),
|
|
"Combine XYZ.002": (6670, 650),
|
|
"Set Position.003": (7410, 0),
|
|
"Merge by Distance": (7640, 0),
|
|
"Position.003": (6910, -950),
|
|
"Separate XYZ.005": (7160, -950),
|
|
"Math.018": (7380, -750),
|
|
"Combine XYZ.005": (7600, -680),
|
|
"Named Attribute.010": (7600, -370),
|
|
"Vector Math.004": (7830, -340),
|
|
"Set Position.004": (8080, 0),
|
|
"Math.019": (8310, 260),
|
|
"Switch.002": (8310, 0),
|
|
"Remove Named Attribute": (9000, 0),
|
|
"Set Shade Smooth": (9220, 0),
|
|
"Group Output": (9440, 0),
|
|
}
|
|
|
|
INPUT_REGIONS = (
|
|
(("Store Named Attribute",), (-240, 0)),
|
|
(("Switch",), (1100, -300)),
|
|
(("Image Texture",), (30, 520)),
|
|
(("Math.002",), (-350, 1140)),
|
|
(("Math.003",), (10, 1140)),
|
|
(("Math.011",), (1100, 320)),
|
|
(("Image Texture.001",), (1290, -270)),
|
|
(("Math.012",), (1290, -940)),
|
|
(("Vector Math.002",), (2340, 1200)),
|
|
(("Math.015", "Math.016"), (2920, 680)),
|
|
(("Mix",), (2920, 900)),
|
|
(("Math.019",), (8080, 300)),
|
|
)
|
|
|
|
|
|
def layout_geometry_references(group, stage):
|
|
"""Separate the split bypass and long projection references from fields."""
|
|
links = group.links
|
|
entry = stage["Store Named Attribute"].inputs["Geometry"]
|
|
source = entry.links[0].from_socket
|
|
fork = route_geometry(group, source, [(-3250, -40), (-1450, -40), (-290, -40)])
|
|
links.new(fork, entry)
|
|
bypass = route_geometry(group, fork, [(-210, -280), (500, -280), (1100, -280)])
|
|
links.new(bypass, stage["Switch"].inputs["False"])
|
|
|
|
projection = next(n.outputs["Geometry"] for n in group.nodes if n.bl_idname == "GeometryNodeStoreNamedAttribute" and n.inputs["Name"].default_value == "o_balloon_surface_front_normal")
|
|
shared = next(n.outputs["Geometry"] for n in group.nodes if n.bl_idname == "GeometryNodeStoreNamedAttribute" and n.inputs["Name"].default_value == "o_balloon_surface_inflation_normal")
|
|
uniform = next(link.to_socket for link in shared.links if link.to_node.bl_idname == "GeometryNodeStoreNamedAttribute" and link.to_node.inputs["Name"].default_value == "o_balloon_surface_thickness")
|
|
fork = route_geometry(group, projection, [(4360, -40), (4650, -1700), (8500, -1700), (11400, -1700)])
|
|
uniform_route = route_geometry(group, shared, [(8250, -40), (8460, -1450), (11400, -1450), (11420, -370)])
|
|
links.new(uniform_route, uniform)
|
|
surface_route = route_geometry(group, fork, [(13500, -1700), (16800, -1700)])
|
|
links.new(surface_route, stage["Switch.002"].inputs["True"])
|