feat: Add new Geometry Nodes groups for image relief and shadeless shader

- Implemented the "O Image Relief Plane" Geometry Nodes group to create a fixed-base image relief using depth images and various parameters.
- Created the "O Shadeless" shader node group to display color without scene lighting while preserving shadows and reflections.
- Introduced a preview feature for node groups, allowing for interactive visualization of node arrangements in an HTML format.
- Added a template HTML file for rendering node previews with customizable views and controls.
This commit is contained in:
2026-09-09 21:24:57 +08:00
parent f5aff50b13
commit 89087fc2e2
118 changed files with 5635 additions and 3130 deletions

View File

@@ -7,10 +7,9 @@ import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
sys.path.insert(0, str(ROOT / "tools/node_assets"))
from cutout import build_cutout_group
from cutout_volume import build_volume_fields
from cutout_rounding import build_volume_rounding
from node_asset_test_support import CUTOUT_BUILDERS
from tools.nodes.groups.image_depth_cutout import build_volume_fields
from tools.nodes.groups.image_depth_cutout import build_volume_rounding
from anyimage.operators.cutout_tool.object import load_cutout_node_group
from anyimage.operators.cutout_tool.operators import normal_mode_for_shape
from anyimage.operators.cutout_tool.geometry import refine_balloon_triangles, poisson_balloon_profile
@@ -47,7 +46,7 @@ def test_refined_boundary_ears_have_interior_balloon_samples():
def test_depth_rounding_options_are_consolidated():
bpy.ops.wm.read_factory_settings(use_empty=True)
group = build_cutout_group("DEPTH_SOLID")
group = CUTOUT_BUILDERS["DEPTH_SOLID"]()
inputs = {s.name: s for s in group.interface.items_tree if s.item_type == "SOCKET" and s.in_out == "INPUT"}
for name, default in (("Edge Round", 0.2), ("Front Inflation", 1), ("Normal Smooth", 50)):
assert inputs[name].default_value == pytest.approx(default)
@@ -131,7 +130,7 @@ def test_rounding_shares_front_and_back_falloff(amount):
group.interface.new_socket(name="Geometry", in_out="OUTPUT", socket_type="NodeSocketGeometry")
source = group.nodes.new("NodeGroupInput")
result = build_volume_fields(group, source.outputs["Geometry"])
result = build_volume_rounding(group, result, (5000, 0))
result = build_volume_rounding(group, result)
group.links.new(result, group.nodes.new("NodeGroupOutput").inputs["Geometry"])
obj.modifiers.new("Round", "NODES").node_group = group
bpy.context.view_layer.update()