Refactor image handling and update foreground processing
- Changed the logic in `remove_background_faces` to keep only faces with all foreground vertices. - Updated background job to save foreground images with a new naming convention (`color.0001.png`). - Replaced `copy_frames` with `copy_color_images` in various jobs to ensure consistent image naming. - Introduced a new function `copy_color_images` to handle the copying of images with a specific naming format. - Updated the BEN2 model to save output images with a new prefix for better clarity. - Modified tests to reflect changes in image naming and processing logic. - Added a new shadeless node group for improved material handling in geometry nodes. - Enhanced validation scripts to check for new image naming conventions and ensure proper functionality.
This commit is contained in:
@@ -7,6 +7,7 @@ GROUP_NAME = "O DA3 Surface"
|
||||
MOGE_SURFACE_GROUP_NAME = "O MoGe2 Surface"
|
||||
DEPTH_PLANE_GROUP_NAME = "O DA3 Depth Plane"
|
||||
MOGE_DEPTH_PLANE_GROUP_NAME = "O MoGe2 Depth Plane"
|
||||
SHADELESS_GROUP_NAME = "O Shadeless"
|
||||
MATERIAL_DISPLACEMENT_ATTRIBUTE = "o_material_displacement"
|
||||
BACKGROUND_DEPTH_ATTRIBUTE = "o_background_depth"
|
||||
DEPTH_SCALE_ATTRIBUTE = "o_depth_scale"
|
||||
@@ -800,9 +801,9 @@ def build_depth_plane_group():
|
||||
"NodeSocketImage",
|
||||
parent=data_panel,
|
||||
)
|
||||
foreground_image = new_socket(
|
||||
color_image = new_socket(
|
||||
interface,
|
||||
"Foreground Image",
|
||||
"Color Image",
|
||||
"INPUT",
|
||||
"NodeSocketImage",
|
||||
parent=data_panel,
|
||||
@@ -835,7 +836,7 @@ def build_depth_plane_group():
|
||||
socket.min_value = 1
|
||||
frame_data.append(socket)
|
||||
depth_image.hide_in_modifier = True
|
||||
foreground_image.hide_in_modifier = True
|
||||
color_image.hide_in_modifier = True
|
||||
material.hide_in_modifier = True
|
||||
for socket in frame_data:
|
||||
socket.hide_in_modifier = True
|
||||
@@ -848,7 +849,7 @@ def build_depth_plane_group():
|
||||
images_input = new_group_input(
|
||||
nodes,
|
||||
(100.0, 1250.0),
|
||||
{"Depth Image", "Foreground Image"},
|
||||
{"Depth Image", "Color Image"},
|
||||
)
|
||||
frames_input = new_group_input(
|
||||
nodes,
|
||||
@@ -973,7 +974,7 @@ def build_depth_plane_group():
|
||||
foreground_texture.location = (350.0, 900.0)
|
||||
links.new(images_input.outputs["Depth Image"], depth_texture.inputs["Image"])
|
||||
links.new(
|
||||
images_input.outputs["Foreground Image"],
|
||||
images_input.outputs["Color Image"],
|
||||
foreground_texture.inputs["Image"],
|
||||
)
|
||||
links.new(grid.outputs["UV Map"], depth_texture.inputs["Vector"])
|
||||
@@ -1141,10 +1142,13 @@ def build_moge_depth_plane_group():
|
||||
depth_image = new_socket(
|
||||
interface, "Depth Image", "INPUT", "NodeSocketImage", data_panel
|
||||
)
|
||||
color_image = new_socket(
|
||||
interface, "Color Image", "INPUT", "NodeSocketImage", data_panel
|
||||
)
|
||||
material = new_socket(
|
||||
interface, "Material", "INPUT", "NodeSocketMaterial", data_panel
|
||||
)
|
||||
for socket in (depth_image, material):
|
||||
for socket in (depth_image, color_image, material):
|
||||
socket.hide_in_modifier = True
|
||||
frame_sockets = []
|
||||
for name, socket_type, default in (
|
||||
@@ -1176,7 +1180,7 @@ def build_moge_depth_plane_group():
|
||||
background_depth_value.inputs[0],
|
||||
)
|
||||
images = new_group_input(
|
||||
nodes, (-500.0, 1100.0), {"Depth Image"}
|
||||
nodes, (-500.0, 1100.0), {"Depth Image", "Color Image"}
|
||||
)
|
||||
frames = new_group_input(
|
||||
nodes,
|
||||
@@ -1241,18 +1245,42 @@ def build_moge_depth_plane_group():
|
||||
depth_texture.interpolation = "Linear"
|
||||
depth_texture.extension = "EXTEND"
|
||||
depth_texture.location = (-250.0, 1100.0)
|
||||
color_texture = nodes.new("GeometryNodeImageTexture")
|
||||
color_texture.interpolation = "Closest"
|
||||
color_texture.extension = "EXTEND"
|
||||
color_texture.location = (-250.0, 850.0)
|
||||
links.new(images.outputs["Depth Image"], depth_texture.inputs["Image"])
|
||||
links.new(images.outputs["Color Image"], color_texture.inputs["Image"])
|
||||
links.new(grid.outputs["UV Map"], depth_texture.inputs["Vector"])
|
||||
links.new(grid.outputs["UV Map"], color_texture.inputs["Vector"])
|
||||
frame = build_sequence_frame(
|
||||
nodes, links, frames.outputs["Frame"], frames, 1800.0
|
||||
)
|
||||
links.new(frame, depth_texture.inputs["Frame"])
|
||||
links.new(frame, color_texture.inputs["Frame"])
|
||||
|
||||
clamp_depth = nodes.new("ShaderNodeMath")
|
||||
clamp_depth.operation = "MAXIMUM"
|
||||
clamp_depth.location = (0.0, 750.0)
|
||||
links.new(depth_texture.outputs["Color"], clamp_depth.inputs[0])
|
||||
links.new(background_depth_value.outputs[0], clamp_depth.inputs[1])
|
||||
color_mask = new_compare(
|
||||
nodes,
|
||||
"FLOAT",
|
||||
"GREATER_THAN",
|
||||
(0.0, 1000.0),
|
||||
0.5,
|
||||
)
|
||||
links.new(
|
||||
color_texture.outputs["Alpha"],
|
||||
input_socket(color_mask, "A", 0),
|
||||
)
|
||||
masked_depth = nodes.new("ShaderNodeMix")
|
||||
masked_depth.data_type = "FLOAT"
|
||||
masked_depth.location = (200.0, 850.0)
|
||||
links.new(color_mask.outputs["Result"], masked_depth.inputs[0])
|
||||
links.new(background_depth_value.outputs[0], masked_depth.inputs[2])
|
||||
links.new(clamp_depth.outputs[0], masked_depth.inputs[3])
|
||||
displacement_menu = nodes.new("GeometryNodeMenuSwitch")
|
||||
displacement_menu.data_type = "FLOAT"
|
||||
displacement_menu.enum_items.clear()
|
||||
@@ -1276,7 +1304,7 @@ def build_moge_depth_plane_group():
|
||||
scaled_depth = nodes.new("ShaderNodeMath")
|
||||
scaled_depth.operation = "MULTIPLY"
|
||||
scaled_depth.location = (250.0, 750.0)
|
||||
links.new(clamp_depth.outputs[0], scaled_depth.inputs[0])
|
||||
links.new(masked_depth.outputs["Result"], scaled_depth.inputs[0])
|
||||
links.new(geometry_strength.outputs[0], scaled_depth.inputs[1])
|
||||
normal = nodes.new("GeometryNodeInputNormal")
|
||||
normal.location = (0.0, 500.0)
|
||||
@@ -1320,6 +1348,80 @@ def build_moge_depth_plane_group():
|
||||
return group
|
||||
|
||||
|
||||
def build_shadeless_group():
|
||||
group = bpy.data.node_groups.new(SHADELESS_GROUP_NAME, "ShaderNodeTree")
|
||||
interface = group.interface
|
||||
new_socket(interface, "Shader", "OUTPUT", "NodeSocketShader")
|
||||
new_socket(interface, "Color", "INPUT", "NodeSocketColor")
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
group_input = nodes.new("NodeGroupInput")
|
||||
group_input.location = (-900.0, -350.0)
|
||||
group_output = nodes.new("NodeGroupOutput")
|
||||
group_output.location = (850.0, 100.0)
|
||||
|
||||
diffuse = nodes.new("ShaderNodeBsdfDiffuse")
|
||||
diffuse.location = (250.0, -150.0)
|
||||
emission = nodes.new("ShaderNodeEmission")
|
||||
emission.location = (250.0, -400.0)
|
||||
links.new(group_input.outputs["Color"], diffuse.inputs["Color"])
|
||||
links.new(group_input.outputs["Color"], emission.inputs["Color"])
|
||||
|
||||
light_path = nodes.new("ShaderNodeLightPath")
|
||||
light_path.location = (-900.0, 150.0)
|
||||
bounce_count = nodes.new("ShaderNodeMath")
|
||||
bounce_count.operation = "SUBTRACT"
|
||||
bounce_count.label = "Bounce Count"
|
||||
bounce_count.location = (-500.0, -50.0)
|
||||
links.new(light_path.outputs["Ray Depth"], bounce_count.inputs[0])
|
||||
links.new(light_path.outputs["Transmission Depth"], bounce_count.inputs[1])
|
||||
refracted = nodes.new("ShaderNodeMath")
|
||||
refracted.operation = "SUBTRACT"
|
||||
refracted.label = "Camera or Refracted"
|
||||
refracted.inputs[0].default_value = 1.0
|
||||
refracted.location = (-250.0, -50.0)
|
||||
links.new(bounce_count.outputs[0], refracted.inputs[1])
|
||||
|
||||
reflection_limit = nodes.new("ShaderNodeMath")
|
||||
reflection_limit.operation = "SUBTRACT"
|
||||
reflection_limit.label = "Limit Reflections"
|
||||
reflection_limit.inputs[0].default_value = 2.0
|
||||
reflection_limit.location = (-650.0, 450.0)
|
||||
links.new(light_path.outputs["Ray Depth"], reflection_limit.inputs[1])
|
||||
camera_reflected = nodes.new("ShaderNodeMath")
|
||||
camera_reflected.operation = "MULTIPLY"
|
||||
camera_reflected.label = "Camera Ray to Glossy"
|
||||
camera_reflected.location = (-400.0, 400.0)
|
||||
links.new(reflection_limit.outputs[0], camera_reflected.inputs[0])
|
||||
links.new(light_path.outputs["Is Glossy Ray"], camera_reflected.inputs[1])
|
||||
shadow_or_reflect = nodes.new("ShaderNodeMath")
|
||||
shadow_or_reflect.operation = "MAXIMUM"
|
||||
shadow_or_reflect.label = "Shadow or Reflection?"
|
||||
shadow_or_reflect.location = (-100.0, 350.0)
|
||||
links.new(camera_reflected.outputs[0], shadow_or_reflect.inputs[0])
|
||||
links.new(light_path.outputs["Is Shadow Ray"], shadow_or_reflect.inputs[1])
|
||||
shader_factor = nodes.new("ShaderNodeMath")
|
||||
shader_factor.operation = "MAXIMUM"
|
||||
shader_factor.label = "Shadow, Reflect or Refract?"
|
||||
shader_factor.location = (150.0, 300.0)
|
||||
links.new(shadow_or_reflect.outputs[0], shader_factor.inputs[0])
|
||||
links.new(refracted.outputs[0], shader_factor.inputs[1])
|
||||
|
||||
mix = nodes.new("ShaderNodeMixShader")
|
||||
mix.location = (550.0, 100.0)
|
||||
links.new(shader_factor.outputs[0], mix.inputs["Fac"])
|
||||
links.new(diffuse.outputs["BSDF"], mix.inputs[1])
|
||||
links.new(emission.outputs["Emission"], mix.inputs[2])
|
||||
links.new(mix.outputs["Shader"], group_output.inputs["Shader"])
|
||||
group.color_tag = "SHADER"
|
||||
group.description = (
|
||||
"Display color without scene lighting while preserving shadows "
|
||||
"and reflections."
|
||||
)
|
||||
group.use_fake_user = True
|
||||
return group
|
||||
|
||||
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
@@ -1336,6 +1438,7 @@ def main():
|
||||
configure_moge_surface_group(moge_surface_group)
|
||||
build_depth_plane_group()
|
||||
build_moge_depth_plane_group()
|
||||
build_shadeless_group()
|
||||
OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(OUTPUT_PATH), check_existing=False)
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ sys.path.insert(
|
||||
|
||||
from snapform.blender.depth_plane import (
|
||||
DEPTH_PLANE_MATERIAL_NODE_GROUP_NAME,
|
||||
MATERIAL_COLOR_SPACE,
|
||||
SHADELESS_NODE_GROUP_NAME,
|
||||
SURFACE_MATERIAL_NODE_GROUP_NAME,
|
||||
add_depth_plane_processing,
|
||||
create_material,
|
||||
@@ -133,7 +135,6 @@ def main():
|
||||
foreground,
|
||||
1.0,
|
||||
displacement_image=depth,
|
||||
foreground_image=foreground,
|
||||
)
|
||||
mesh.materials.append(material)
|
||||
material_group = bpy.data.node_groups[DEPTH_PLANE_MATERIAL_NODE_GROUP_NAME]
|
||||
@@ -232,6 +233,47 @@ def main():
|
||||
for node in material.node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeTexImage"
|
||||
)
|
||||
shadeless_material = create_material(
|
||||
"Shadeless",
|
||||
foreground,
|
||||
1.0,
|
||||
shadeless=True,
|
||||
)
|
||||
shadeless_group = bpy.data.node_groups[SHADELESS_NODE_GROUP_NAME]
|
||||
shadeless_nodes = [
|
||||
node
|
||||
for node in shadeless_material.node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeGroup"
|
||||
and node.node_tree == shadeless_group
|
||||
]
|
||||
assert len(shadeless_nodes) == 1
|
||||
assert not any(
|
||||
node.bl_idname == "ShaderNodeEmission"
|
||||
for node in shadeless_material.node_tree.nodes
|
||||
)
|
||||
assert [
|
||||
item.name
|
||||
for item in shadeless_group.interface.items_tree
|
||||
if item.item_type == "SOCKET" and item.in_out == "INPUT"
|
||||
] == ["Color"]
|
||||
assert [
|
||||
item.name
|
||||
for item in shadeless_group.interface.items_tree
|
||||
if item.item_type == "SOCKET" and item.in_out == "OUTPUT"
|
||||
] == ["Shader"]
|
||||
assert {
|
||||
node.label: node.operation
|
||||
for node in shadeless_group.nodes
|
||||
if node.bl_idname == "ShaderNodeMath"
|
||||
} == {
|
||||
"Bounce Count": "SUBTRACT",
|
||||
"Camera or Refracted": "SUBTRACT",
|
||||
"Limit Reflections": "SUBTRACT",
|
||||
"Camera Ray to Glossy": "MULTIPLY",
|
||||
"Shadow or Reflection?": "MAXIMUM",
|
||||
"Shadow, Reflect or Refract?": "MAXIMUM",
|
||||
}
|
||||
assert foreground.colorspace_settings.name == MATERIAL_COLOR_SPACE
|
||||
surface_material = create_material("Surface", foreground, 1.0)
|
||||
surface_group = bpy.data.node_groups[SURFACE_MATERIAL_NODE_GROUP_NAME]
|
||||
surface_group_nodes = [
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
import bpy
|
||||
import numpy as np
|
||||
@@ -13,13 +15,81 @@ sys.path.insert(
|
||||
str(next((PROJECT_ROOT / "src" / "snapform" / "wheels").glob("blendjob-*.whl"))),
|
||||
)
|
||||
|
||||
import snapform.blender.depth_plane as depth_plane
|
||||
|
||||
from snapform.blender.depth_plane import (
|
||||
MOGE_DEPTH_PLANE_NODE_GROUP_NAME,
|
||||
MOGE_MATERIAL_NODE_GROUP_NAME,
|
||||
build_moge2_depth_plane,
|
||||
create_color_image,
|
||||
get_modifier_input,
|
||||
modifier_input_identifier,
|
||||
)
|
||||
|
||||
|
||||
def validate_single_frame_source_types():
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
directory = Path(temporary)
|
||||
color_path = directory / "color.0001.png"
|
||||
seed = bpy.data.images.new("Color Seed", width=2, height=2, alpha=True)
|
||||
seed.pixels[:] = [0.2, 0.4, 0.8, 1.0] * 4
|
||||
seed.filepath_raw = str(color_path)
|
||||
seed.file_format = "PNG"
|
||||
seed.save()
|
||||
bpy.data.images.remove(seed, do_unlink=True)
|
||||
|
||||
still_source_image = bpy.data.images.load(
|
||||
str(color_path), check_existing=False
|
||||
)
|
||||
still_source = bpy.data.objects.new("Still Source", None)
|
||||
still_source.empty_display_type = "IMAGE"
|
||||
still_source.data = still_source_image
|
||||
bpy.context.collection.objects.link(still_source)
|
||||
still_color = create_color_image(
|
||||
still_source, directory, assign_to_source=False
|
||||
)
|
||||
assert still_color.source == "FILE"
|
||||
|
||||
animated_source = SimpleNamespace(
|
||||
data=SimpleNamespace(
|
||||
source="SEQUENCE",
|
||||
name="Sequence Source.png",
|
||||
use_fake_user=False,
|
||||
),
|
||||
image_user=None,
|
||||
)
|
||||
sequence_color = create_color_image(
|
||||
animated_source, directory, assign_to_source=False
|
||||
)
|
||||
assert sequence_color.source == "SEQUENCE"
|
||||
|
||||
depth = np.ones((1, 2, 2), dtype=np.float32)
|
||||
mask = np.ones((1, 2, 2), dtype=bool)
|
||||
intrinsics = np.array(
|
||||
[[[1.0, 0.0, 0.5], [0.0, 1.0, 0.5], [0.0, 0.0, 1.0]]],
|
||||
dtype=np.float32,
|
||||
)
|
||||
path = directory / "single-frame-results.npz"
|
||||
np.savez(path, depth=depth, mask=mask, intrinsics=intrinsics)
|
||||
with patch.object(depth_plane, "is_animated_image", return_value=True):
|
||||
plane = build_moge2_depth_plane(
|
||||
bpy.context,
|
||||
still_source,
|
||||
path,
|
||||
delete_source=False,
|
||||
color_image=sequence_color,
|
||||
data_frames_directory=directory,
|
||||
)
|
||||
textures = [
|
||||
node.image
|
||||
for node in plane.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeTexImage"
|
||||
]
|
||||
assert sequence_color in textures
|
||||
depth_images = [image for image in textures if image != sequence_color]
|
||||
assert len(depth_images) == 1
|
||||
assert depth_images[0].source == "SEQUENCE"
|
||||
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
image = bpy.data.images.new("MoGe Test", width=64, height=48, alpha=True)
|
||||
@@ -45,11 +115,14 @@ def main():
|
||||
mask=mask,
|
||||
intrinsics=intrinsics,
|
||||
)
|
||||
material_image = image.copy()
|
||||
material_image.name = "MoGe Test.color"
|
||||
plane = build_moge2_depth_plane(
|
||||
bpy.context,
|
||||
source,
|
||||
path,
|
||||
delete_source=True,
|
||||
color_image=material_image,
|
||||
)
|
||||
assert plane.modifiers[0].node_group.name == MOGE_DEPTH_PLANE_NODE_GROUP_NAME
|
||||
assert MOGE_MATERIAL_NODE_GROUP_NAME in bpy.data.node_groups
|
||||
@@ -73,6 +146,9 @@ def main():
|
||||
assert sockets["Background Depth"].structure_type == "SINGLE"
|
||||
assert sockets["Background Depth"].subtype == "DISTANCE"
|
||||
assert sockets["Background Depth"].default_value == 1.0
|
||||
assert sockets["Color Image"].hide_in_modifier
|
||||
color_identifier = modifier_input_identifier(geometry_group, "Color Image")
|
||||
assert get_modifier_input(plane.modifiers[0], color_identifier) == material_image
|
||||
material_group = bpy.data.node_groups[MOGE_MATERIAL_NODE_GROUP_NAME]
|
||||
assert not any(node.bl_idname == "ShaderNodeNormalMap" for node in material_group.nodes)
|
||||
assert any(node.bl_idname == "ShaderNodeBump" for node in material_group.nodes)
|
||||
@@ -84,14 +160,90 @@ def main():
|
||||
]
|
||||
assert image_textures
|
||||
assert all(node.extension == "EXTEND" for node in image_textures)
|
||||
assert any(node.image.name == "MoGe Test.depth" for node in image_textures)
|
||||
static_depth = next(
|
||||
node.image
|
||||
for node in image_textures
|
||||
if node.image.name == "MoGe Test.depth"
|
||||
)
|
||||
assert static_depth.source != "SEQUENCE"
|
||||
geometry_textures = [
|
||||
node
|
||||
for node in geometry_group.nodes
|
||||
if node.bl_idname == "GeometryNodeImageTexture"
|
||||
]
|
||||
assert geometry_textures
|
||||
assert len(geometry_textures) == 2
|
||||
assert all(node.extension == "EXTEND" for node in geometry_textures)
|
||||
color_texture = next(
|
||||
node
|
||||
for node in geometry_textures
|
||||
if any(
|
||||
link.to_node == node
|
||||
and link.to_socket == node.inputs["Image"]
|
||||
and link.from_socket.name == "Color Image"
|
||||
for link in geometry_group.links
|
||||
)
|
||||
)
|
||||
depth_texture = next(node for node in geometry_textures if node != color_texture)
|
||||
assert color_texture.interpolation == "Closest"
|
||||
assert depth_texture.interpolation == "Linear"
|
||||
color_frame_link = next(
|
||||
link
|
||||
for link in geometry_group.links
|
||||
if link.to_node == color_texture
|
||||
and link.to_socket == color_texture.inputs["Frame"]
|
||||
)
|
||||
depth_frame_link = next(
|
||||
link
|
||||
for link in geometry_group.links
|
||||
if link.to_node == depth_texture
|
||||
and link.to_socket == depth_texture.inputs["Frame"]
|
||||
)
|
||||
assert color_frame_link.from_socket == depth_frame_link.from_socket
|
||||
alpha_compare = next(
|
||||
node
|
||||
for node in geometry_group.nodes
|
||||
if node.bl_idname == "FunctionNodeCompare"
|
||||
and node.operation == "GREATER_THAN"
|
||||
and any(
|
||||
link.from_node == color_texture
|
||||
and link.from_socket == color_texture.outputs["Alpha"]
|
||||
and link.to_node == node
|
||||
for link in geometry_group.links
|
||||
)
|
||||
)
|
||||
masked_depth = next(
|
||||
node
|
||||
for node in geometry_group.nodes
|
||||
if node.bl_idname == "ShaderNodeMix"
|
||||
and any(
|
||||
link.from_node == alpha_compare and link.to_node == node
|
||||
for link in geometry_group.links
|
||||
)
|
||||
)
|
||||
assert masked_depth.data_type == "FLOAT"
|
||||
masked_sources = {
|
||||
link.from_node
|
||||
for link in geometry_group.links
|
||||
if link.to_node == masked_depth
|
||||
}
|
||||
assert alpha_compare in masked_sources
|
||||
assert any(
|
||||
node.bl_idname == "ShaderNodeMath" and node.operation == "MAXIMUM"
|
||||
for node in masked_sources
|
||||
)
|
||||
assert any(
|
||||
node.bl_idname == "ShaderNodeMath"
|
||||
and node.operation == "MULTIPLY"
|
||||
and node.inputs[1].default_value == -1.0
|
||||
for node in masked_sources
|
||||
)
|
||||
assert any(
|
||||
link.from_node == masked_depth
|
||||
and link.to_node.bl_idname == "ShaderNodeMath"
|
||||
and link.to_node.operation == "MULTIPLY"
|
||||
for link in geometry_group.links
|
||||
)
|
||||
validate_single_frame_source_types()
|
||||
print("MoGe-2 depth plane validation passed")
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ def main():
|
||||
)
|
||||
image = bpy.data.images.new("MoGe Surface Test", width=width, height=height)
|
||||
foreground = bpy.data.images.new(
|
||||
"MoGe Surface Test.foreground",
|
||||
"MoGe Surface Test.color",
|
||||
width=width,
|
||||
height=height,
|
||||
)
|
||||
@@ -197,7 +197,8 @@ def main():
|
||||
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.foreground"
|
||||
assert color_texture.image.name == "MoGe Surface Test.color"
|
||||
assert color_texture.image.colorspace_settings.name == "AgX Base sRGB"
|
||||
normal_texture = next(
|
||||
node for node in surface.data.materials[0].node_tree.nodes
|
||||
if node.bl_idname == "ShaderNodeTexImage"
|
||||
@@ -220,6 +221,8 @@ def validate_real_result(results_path, image_path):
|
||||
normal_path = results_path.with_name("normal.png")
|
||||
if not normal_path.is_file():
|
||||
raise ValueError(f"Surface normal texture is missing: {normal_path}")
|
||||
color_image = bpy.data.images.load(str(image_path), check_existing=False)
|
||||
color_image.name = f"{image_path.stem}.color"
|
||||
surface = build_image_mesh(
|
||||
bpy.context,
|
||||
source,
|
||||
@@ -228,6 +231,7 @@ def validate_real_result(results_path, image_path):
|
||||
True,
|
||||
False,
|
||||
True,
|
||||
color_image=color_image,
|
||||
normal_path=normal_path,
|
||||
)
|
||||
assert len(surface.data.vertices) > 100
|
||||
|
||||
Reference in New Issue
Block a user