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:
@@ -396,43 +396,23 @@ class ClipboardImageTest(unittest.TestCase):
|
||||
finally:
|
||||
clipboard_image._native_copy_token = original_token
|
||||
|
||||
def test_shadeless_nodes_mix_emission_with_transparency(self):
|
||||
created_nodes = {}
|
||||
def test_plane_paste_uses_shared_material_for_both_shading_modes(self):
|
||||
from anyimage.operators.convert_to_plane import image_plane
|
||||
|
||||
def create_node(node_type):
|
||||
node = SimpleNamespace(location=None, inputs={}, outputs={})
|
||||
if node_type == "ShaderNodeBsdfTransparent":
|
||||
node.outputs["BSDF"] = object()
|
||||
elif node_type == "ShaderNodeEmission":
|
||||
node.inputs["Color"] = object()
|
||||
node.outputs["Emission"] = object()
|
||||
else:
|
||||
node.inputs = [object(), object(), object()]
|
||||
node.outputs["Shader"] = object()
|
||||
created_nodes[node_type] = node
|
||||
return node
|
||||
|
||||
nodes = SimpleNamespace(new=Mock(side_effect=create_node))
|
||||
links = SimpleNamespace(new=Mock())
|
||||
image_node = SimpleNamespace(
|
||||
outputs={"Color": object(), "Alpha": object()},
|
||||
)
|
||||
output_node = SimpleNamespace(inputs={"Surface": object()})
|
||||
|
||||
self.actions._create_shadeless_nodes(
|
||||
nodes,
|
||||
links,
|
||||
image_node,
|
||||
output_node,
|
||||
)
|
||||
|
||||
mix_node = created_nodes["ShaderNodeMixShader"]
|
||||
links.new.assert_any_call(image_node.outputs["Alpha"], mix_node.inputs[0])
|
||||
links.new.assert_any_call(
|
||||
created_nodes["ShaderNodeEmission"].outputs["Emission"],
|
||||
mix_node.inputs[2],
|
||||
)
|
||||
self.assertEqual(links.new.call_count, 5)
|
||||
image = SimpleNamespace(name="Clipboard", size=(16, 8))
|
||||
context = SimpleNamespace(mode="OBJECT", scene=object())
|
||||
for shadeless in (False, True):
|
||||
with (
|
||||
patch.object(self.actions, "create_image_material", return_value="Material") as create_material,
|
||||
patch.object(image_plane, "create_image_plane_object") as create_plane,
|
||||
patch.object(self.actions, "_place_in_view"),
|
||||
patch.object(self.actions, "_select_only"),
|
||||
):
|
||||
self.actions.add_image_plane(context, image, shadeless=shadeless)
|
||||
create_material.assert_called_once_with(
|
||||
image, image, shadeless=shadeless, scene=context.scene,
|
||||
)
|
||||
self.assertEqual(create_plane.call_args.args[3], "Material")
|
||||
|
||||
def test_reference_import_routes_to_image_empty(self):
|
||||
context = self.make_context("VIEW_3D")
|
||||
|
||||
Reference in New Issue
Block a user