feat(node_assets): add image plane geometry nodes and validation scripts
- 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.
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from types import MethodType, SimpleNamespace
|
||||
from types import SimpleNamespace
|
||||
|
||||
SOURCE_ROOT = Path(__file__).parents[1] / "src"
|
||||
sys.path.insert(0, str(SOURCE_ROOT))
|
||||
|
||||
from anyimage.common.selection import SelectionPath
|
||||
from anyimage.common import viewport
|
||||
from anyimage.common.viewport import ImageGesture
|
||||
from anyimage.operators.cutout_tool import interaction
|
||||
from anyimage.operators.cutout_tool import main as cutout_main
|
||||
|
||||
@@ -173,69 +172,27 @@ def test_cutout_mesh_detail_maps_to_denser_sampling():
|
||||
] == [32, 16, 8, 4]
|
||||
|
||||
|
||||
def test_cutout_reuses_image_lasso_gesture_and_double_click_selects_all(monkeypatch):
|
||||
source = cutout_source(size=(65536, 32768))
|
||||
def test_cutout_lasso_submission_passes_only_the_selected_path(monkeypatch):
|
||||
source = cutout_source()
|
||||
window_manager = WindowManager()
|
||||
context = cutout_context(window_manager)
|
||||
|
||||
monkeypatch.setattr(
|
||||
cutout_main, "resolve_image_edit_click", lambda *_args: (source, True)
|
||||
)
|
||||
monkeypatch.setattr(cutout_main, "video_total_frames", lambda _image: 1)
|
||||
monkeypatch.setattr(cutout_main, "require_image_empty", lambda _name: source)
|
||||
monkeypatch.setattr(cutout_main, "serialize_matrix", lambda _matrix: "matrix")
|
||||
monkeypatch.setattr(
|
||||
cutout_main,
|
||||
"image_rgba",
|
||||
lambda *_args: (_ for _ in ()).throw(AssertionError("unexpected pixel read")),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cutout_main,
|
||||
"rasterize_selection_path",
|
||||
lambda *_args, **_kwargs: (_ for _ in ()).throw(
|
||||
AssertionError("unexpected Selection rasterization")
|
||||
),
|
||||
)
|
||||
|
||||
operator = SimpleNamespace(
|
||||
full_image=True,
|
||||
report=lambda *_args: None,
|
||||
)
|
||||
source.matrix_world = object()
|
||||
operator._submit_selection_path = MethodType(
|
||||
cutout_main.SelectCutoutSelection._submit_selection_path,
|
||||
operator,
|
||||
)
|
||||
result = cutout_main.SelectCutoutSelection.invoke(
|
||||
operator, context, SimpleNamespace(value="DOUBLE_CLICK")
|
||||
)
|
||||
|
||||
assert issubclass(cutout_main.SelectCutoutSelection, ImageGesture)
|
||||
monkeypatch.setattr(interaction, "ai_ready", lambda: False)
|
||||
path = SelectionPath(points=((0, 0), (10, 0), (0, 10)))
|
||||
operator = SimpleNamespace(source_object_name=source.name, _pie_event=object())
|
||||
result = cutout_main.SelectCutoutSelection._submit_selection_path(operator, context, path)
|
||||
assert result == {"FINISHED"}
|
||||
selection_path = SelectionPath.from_json(window_manager.pie.calls[0][2].selection_path_json)
|
||||
assert selection_path.points == (
|
||||
(0, 0),
|
||||
(65536, 0),
|
||||
(65536, 32768),
|
||||
(0, 32768),
|
||||
)
|
||||
assert window_manager.pie.calls[0][2].point_spacing == 32
|
||||
assert not hasattr(cutout_main, "pending_selection")
|
||||
assert SelectionPath.from_json(window_manager.pie.calls[0][2].selection_path_json) == path
|
||||
|
||||
|
||||
def test_cutout_tool_prioritizes_double_click_before_lasso_drag():
|
||||
assert cutout_main.CutoutTool.bl_keymap[0][1]["value"] == "DOUBLE_CLICK"
|
||||
assert cutout_main.CutoutTool.bl_keymap[1][1]["value"] == "CLICK_DRAG"
|
||||
assert [entry[0] for entry in cutout_main.CutoutTool.bl_keymap[2:]] == [
|
||||
"view3d.select",
|
||||
"view3d.select",
|
||||
]
|
||||
assert cutout_main.CutoutTool.bl_keymap[2][2] == {
|
||||
"properties": [("deselect_all", False)]
|
||||
}
|
||||
assert cutout_main.CutoutTool.bl_keymap[3][2] == {
|
||||
"properties": [("toggle", True)]
|
||||
}
|
||||
def test_cutout_tool_only_binds_lasso_drag_and_native_selection():
|
||||
keymap = cutout_main.CutoutTool.bl_keymap
|
||||
assert keymap[0][1]["value"] == "CLICK_DRAG"
|
||||
assert [entry[0] for entry in keymap[1:]] == ["view3d.select", "view3d.select"]
|
||||
assert all(entry[1]["value"] != "DOUBLE_CLICK" for entry in keymap)
|
||||
assert "full_image" not in cutout_main.SelectCutoutSelection.__annotations__
|
||||
assert keymap[1][2] == {"properties": [("deselect_all", False)]}
|
||||
assert keymap[2][2] == {"properties": [("toggle", True)]}
|
||||
|
||||
|
||||
def test_cutout_f_has_no_option_shortcut(monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user