Add comprehensive tests for cutout and mesh functionalities
- Introduced `test_cutout.py` to validate cutout pie menu behavior, image lasso options, and mesh detail calculations. - Added `test_mesh.py` to ensure correct tangent normal rasterization, plane source topology, and depth surface evaluations. - Created `test_mesh_blender.py` to verify material node groups, tangent baking, and local cutout building from Blender images. - Implemented tests for handling alpha regions and ensuring geometry nodes maintain expected behavior.
This commit is contained in:
@@ -5,7 +5,6 @@ from pathlib import Path
|
||||
import bpy
|
||||
import numpy as np
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).parents[1]
|
||||
sys.path.insert(0, str(PROJECT_ROOT / "src"))
|
||||
sys.path.insert(
|
||||
@@ -43,7 +42,7 @@ def write_test_normal_texture(normal, output_path):
|
||||
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
|
||||
arguments = sys.argv[sys.argv.index("--") + 1 :] if "--" in sys.argv else []
|
||||
if arguments:
|
||||
validate_real_result(Path(arguments[0]), Path(arguments[1]))
|
||||
return
|
||||
@@ -142,14 +141,14 @@ def main():
|
||||
depth_edge_socket = next(
|
||||
item
|
||||
for item in surface.modifiers[0].node_group.interface.items_tree
|
||||
if getattr(item, "in_out", None) == "INPUT"
|
||||
and item.name == "Depth Continuity"
|
||||
if getattr(item, "in_out", None) == "INPUT" and item.name == "Depth Continuity"
|
||||
)
|
||||
assert depth_edge_socket.default_value == 50.0
|
||||
assert depth_edge_socket.subtype == "PERCENTAGE"
|
||||
assert depth_edge_socket.structure_type == "SINGLE"
|
||||
culling_panel = next(
|
||||
item for item in surface.modifiers[0].node_group.interface.items_tree
|
||||
item
|
||||
for item in surface.modifiers[0].node_group.interface.items_tree
|
||||
if item.item_type == "PANEL" and item.name == "Culling"
|
||||
)
|
||||
assert [item.name for item in culling_panel.interface_items] == [
|
||||
@@ -157,7 +156,8 @@ def main():
|
||||
"Mask",
|
||||
]
|
||||
input_sockets = [
|
||||
item for item in surface.modifiers[0].node_group.interface.items_tree
|
||||
item
|
||||
for item in surface.modifiers[0].node_group.interface.items_tree
|
||||
if item.item_type == "SOCKET" and item.in_out == "INPUT"
|
||||
]
|
||||
assert all(item.structure_type == "SINGLE" for item in input_sockets)
|
||||
@@ -179,22 +179,34 @@ def main():
|
||||
assert MOGE_SURFACE_MATERIAL_NODE_GROUP_NAME in bpy.data.node_groups
|
||||
material_group = bpy.data.node_groups[MOGE_SURFACE_MATERIAL_NODE_GROUP_NAME]
|
||||
assert any(node.bl_idname == "ShaderNodeBump" for node in material_group.nodes)
|
||||
normal_map = next(
|
||||
node for node in material_group.nodes
|
||||
if node.bl_idname == "ShaderNodeNormalMap"
|
||||
)
|
||||
assert normal_map.space == "OBJECT"
|
||||
normal_maps = [
|
||||
node for node in material_group.nodes if node.bl_idname == "ShaderNodeNormalMap"
|
||||
]
|
||||
assert {node.space for node in normal_maps} == {"TANGENT", "OBJECT"}
|
||||
normal_strength = next(
|
||||
item for item in material_group.interface.items_tree
|
||||
if getattr(item, "in_out", None) == "INPUT"
|
||||
and item.name == "Normal Strength"
|
||||
item
|
||||
for item in material_group.interface.items_tree
|
||||
if getattr(item, "in_out", None) == "INPUT" and item.name == "Normal Scale"
|
||||
)
|
||||
assert normal_strength.default_value == 1.0
|
||||
assert normal_strength.min_value == 0.0
|
||||
assert normal_map.inputs["Strength"].is_linked
|
||||
normal_input = next(
|
||||
item
|
||||
for item in material_group.interface.items_tree
|
||||
if getattr(item, "in_out", None) == "INPUT" and item.name == "Normal"
|
||||
)
|
||||
assert tuple(normal_input.default_value) == (0.5, 0.5, 1.0, 1.0)
|
||||
assert all(node.inputs["Strength"].is_linked for node in normal_maps)
|
||||
layer = next(
|
||||
node
|
||||
for node in surface.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeGroup" and node.node_tree == material_group
|
||||
)
|
||||
assert layer.inputs["Object Space"].default_value is True
|
||||
assert not surface.data.has_custom_normals
|
||||
color_texture = next(
|
||||
node for node in surface.data.materials[0].node_tree.nodes
|
||||
node
|
||||
for node in surface.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeTexImage" and node.image == foreground
|
||||
)
|
||||
assert color_texture.image.name == "MoGe Surface Test.color"
|
||||
@@ -202,7 +214,8 @@ def main():
|
||||
bpy.context.scene
|
||||
)
|
||||
normal_texture = next(
|
||||
node for node in surface.data.materials[0].node_tree.nodes
|
||||
node
|
||||
for node in surface.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeTexImage"
|
||||
and node.image.colorspace_settings.name == "Non-Color"
|
||||
)
|
||||
@@ -243,12 +256,17 @@ def validate_real_result(results_path, image_path):
|
||||
assert not surface.data.has_custom_normals
|
||||
material_group = bpy.data.node_groups[MOGE_SURFACE_MATERIAL_NODE_GROUP_NAME]
|
||||
assert any(node.bl_idname == "ShaderNodeBump" for node in material_group.nodes)
|
||||
normal_map = next(
|
||||
node for node in material_group.nodes
|
||||
if node.bl_idname == "ShaderNodeNormalMap"
|
||||
normal_maps = [
|
||||
node for node in material_group.nodes if node.bl_idname == "ShaderNodeNormalMap"
|
||||
]
|
||||
assert {node.space for node in normal_maps} == {"TANGENT", "OBJECT"}
|
||||
assert all(node.inputs["Strength"].is_linked for node in normal_maps)
|
||||
layer = next(
|
||||
node
|
||||
for node in surface.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeGroup" and node.node_tree == material_group
|
||||
)
|
||||
assert normal_map.space == "OBJECT"
|
||||
assert normal_map.inputs["Strength"].is_linked
|
||||
assert layer.inputs["Object Space"].default_value is True
|
||||
attribute_names = set(surface.data.attributes.keys())
|
||||
assert {"o_depth", "o_mask"}.issubset(attribute_names)
|
||||
assert "o_depth_discontinuity" in attribute_names
|
||||
|
||||
Reference in New Issue
Block a user