chore: Bump version to 0.12.13 and update documentation for color space handling
This commit is contained in:
@@ -24,7 +24,13 @@ MOGE_SURFACE_MATERIAL_NODE_GROUP_NAME = "O MoGe2 Surface Layer"
|
||||
DEPTH_PLANE_MATERIAL_NODE_GROUP_NAME = "O DA3 Depth Plane Layer"
|
||||
MOGE_MATERIAL_NODE_GROUP_NAME = "O MoGe2 Depth Plane Layer"
|
||||
SHADELESS_NODE_GROUP_NAME = "O Shadeless"
|
||||
MATERIAL_COLOR_SPACE = "AgX Base sRGB"
|
||||
VIEW_TRANSFORM_COLOR_SPACES = (
|
||||
("ACES 1.3", "ACES 1.3 sRGB"),
|
||||
("ACES 2.0", "ACES 2.0 sRGB"),
|
||||
("AgX", "AgX Base sRGB"),
|
||||
("Filmic", "Filmic sRGB"),
|
||||
("Khronos PBR Neutral", "Khronos PBR Neutral sRGB"),
|
||||
)
|
||||
DA3_PATCH_SIZE = 14
|
||||
DA3_MIN_PROCESS_RES = 252
|
||||
DA3_MAX_PROCESS_RES = 1008
|
||||
@@ -70,6 +76,36 @@ def is_image_empty(candidate):
|
||||
)
|
||||
|
||||
|
||||
def material_color_space_name(scene):
|
||||
view_settings = getattr(scene, "view_settings", None)
|
||||
view_transform = getattr(view_settings, "view_transform", "")
|
||||
normalized = str(view_transform).strip().casefold()
|
||||
for view_name, color_space in VIEW_TRANSFORM_COLOR_SPACES:
|
||||
if normalized.startswith(view_name.casefold()):
|
||||
return color_space
|
||||
return "AgX Base sRGB"
|
||||
|
||||
|
||||
def set_material_color_space(image, scene=None):
|
||||
if scene is None:
|
||||
scene = getattr(bpy.context, "scene", None)
|
||||
settings = image.colorspace_settings
|
||||
preferred = material_color_space_name(scene)
|
||||
original = settings.name
|
||||
for color_space in dict.fromkeys(
|
||||
(preferred, "AgX Base sRGB", "sRGB", original)
|
||||
):
|
||||
if not color_space:
|
||||
continue
|
||||
try:
|
||||
settings.name = color_space
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
if settings.name == color_space:
|
||||
return color_space
|
||||
return settings.name
|
||||
|
||||
|
||||
def is_animated_image(image):
|
||||
return getattr(image, "source", None) in {"MOVIE", "SEQUENCE"}
|
||||
|
||||
@@ -978,6 +1014,7 @@ def create_moge_material(
|
||||
frame_count=1,
|
||||
frame_start=1,
|
||||
use_cyclic=False,
|
||||
scene=None,
|
||||
):
|
||||
material = bpy.data.materials.new(name)
|
||||
material.use_nodes = True
|
||||
@@ -990,7 +1027,7 @@ def create_moge_material(
|
||||
uv.uv_map = "UVMap"
|
||||
uv.location = (-900.0, 200.0)
|
||||
color = nodes.new("ShaderNodeTexImage")
|
||||
color_image.colorspace_settings.name = MATERIAL_COLOR_SPACE
|
||||
set_material_color_space(color_image, scene)
|
||||
color.image = color_image
|
||||
color.interpolation = "Linear"
|
||||
color.extension = "EXTEND"
|
||||
@@ -1303,6 +1340,7 @@ def create_material(
|
||||
use_cyclic=None,
|
||||
surface_group_name=None,
|
||||
normal_image=None,
|
||||
scene=None,
|
||||
):
|
||||
material = bpy.data.materials.new(name)
|
||||
material.use_nodes = True
|
||||
@@ -1318,7 +1356,7 @@ def create_material(
|
||||
uv_map.uv_map = "UVMap"
|
||||
uv_map.location = (-1250.0, 350.0)
|
||||
material_image = color_image
|
||||
material_image.colorspace_settings.name = MATERIAL_COLOR_SPACE
|
||||
set_material_color_space(material_image, scene)
|
||||
color_texture.image = material_image
|
||||
color_texture.interpolation = "Linear"
|
||||
color_texture.extension = "EXTEND"
|
||||
@@ -1730,6 +1768,7 @@ def build_image_depth_plane(
|
||||
depth_frame_offset=texture_frame_offset,
|
||||
depth_frame_duration=texture_frame_count,
|
||||
use_cyclic=source_use_cyclic,
|
||||
scene=context.scene,
|
||||
)
|
||||
mesh.materials.append(material)
|
||||
add_depth_plane_processing(
|
||||
@@ -1834,6 +1873,7 @@ def build_depth_plane(
|
||||
depth_frame_offset=0,
|
||||
depth_frame_duration=frame_count,
|
||||
use_cyclic=source_use_cyclic,
|
||||
scene=context.scene,
|
||||
)
|
||||
mesh.materials.append(material)
|
||||
add_depth_plane_processing(
|
||||
@@ -1939,6 +1979,7 @@ def build_moge2_depth_plane(
|
||||
frame_count=len(depth),
|
||||
frame_start=source_frame_start,
|
||||
use_cyclic=source_use_cyclic,
|
||||
scene=context.scene,
|
||||
)
|
||||
mesh.materials.append(material)
|
||||
modifier = add_moge_depth_plane_processing(
|
||||
|
||||
@@ -456,6 +456,7 @@ def build_image_mesh(
|
||||
MOGE_SURFACE_MATERIAL_NODE_GROUP_NAME if moge2 else None
|
||||
),
|
||||
normal_image=normal_image,
|
||||
scene=context.scene,
|
||||
)
|
||||
mesh.materials.append(material)
|
||||
mesh_object["snapform_reference_depth"] = reference_depth
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
schema_version = "1.0.0"
|
||||
|
||||
id = "snapform"
|
||||
version = "0.12.12"
|
||||
version = "0.12.13"
|
||||
name = "SnapForm"
|
||||
tagline = "Build spatial structures from images, fast"
|
||||
maintainer = "OmooLab"
|
||||
|
||||
@@ -4,6 +4,12 @@ from contextlib import contextmanager
|
||||
from ..media import prepare_input
|
||||
|
||||
|
||||
def frame_progress_message(message, index, total):
|
||||
if total > 1:
|
||||
return f"{message} ({index + 1}/{total})"
|
||||
return message
|
||||
|
||||
|
||||
@contextmanager
|
||||
def input_frames(context, parameters):
|
||||
images, temporary_directory = prepare_input(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from ..media import copy_color_images
|
||||
from ..models import da3, geometry_adapter, moge2
|
||||
from ..outputs.depth import write_da3_depth, write_moge_depth
|
||||
from .common import input_frames
|
||||
from .common import frame_progress_message, input_frames
|
||||
from .foreground import write_optional
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ def run(context, parameters):
|
||||
images,
|
||||
progress_callback=lambda index, total: context.progress(
|
||||
0.15 + 0.65 * index / total,
|
||||
f"Estimating DA3 depth ({index + 1}/{total})",
|
||||
frame_progress_message("Estimating DA3 depth", index, total),
|
||||
),
|
||||
cancel_check=context.check_cancelled,
|
||||
)
|
||||
@@ -31,7 +31,7 @@ def run(context, parameters):
|
||||
include_points=False,
|
||||
progress_callback=lambda index, total: context.progress(
|
||||
0.15 + 0.65 * index / total,
|
||||
f"Estimating MoGe-2 depth ({index + 1}/{total})",
|
||||
frame_progress_message("Estimating MoGe-2 depth", index, total),
|
||||
),
|
||||
cancel_check=context.check_cancelled,
|
||||
)
|
||||
|
||||
@@ -2,17 +2,9 @@ from ..geometry import build_surface, foreground_mesh_mask
|
||||
from ..media import copy_color_images
|
||||
from ..models import geometry_adapter, moge2
|
||||
from ..outputs.surface import write_normal_texture, write_surface_archive
|
||||
from .common import input_frames
|
||||
from .common import frame_progress_message, input_frames
|
||||
from .foreground import write_optional
|
||||
|
||||
|
||||
def inference_progress_message(model_name, index, total):
|
||||
message = f"Estimating {model_name} geometry"
|
||||
if total > 1:
|
||||
message += f" ({index + 1}/{total})"
|
||||
return message
|
||||
|
||||
|
||||
def run(context, parameters):
|
||||
context.progress(0.02, "Preparing surface input")
|
||||
context.directory.mkdir(parents=True, exist_ok=True)
|
||||
@@ -30,7 +22,7 @@ def run(context, parameters):
|
||||
include_points=True,
|
||||
progress_callback=lambda index, total: context.progress(
|
||||
0.12 + 0.58 * index / total,
|
||||
inference_progress_message("MoGe-2", index, total),
|
||||
frame_progress_message("Estimating MoGe-2 geometry", index, total),
|
||||
),
|
||||
cancel_check=context.check_cancelled,
|
||||
)
|
||||
@@ -41,7 +33,7 @@ def run(context, parameters):
|
||||
images,
|
||||
progress_callback=lambda index, total: context.progress(
|
||||
0.12 + 0.58 * index / total,
|
||||
inference_progress_message("DA3", index, total),
|
||||
frame_progress_message("Estimating DA3 geometry", index, total),
|
||||
),
|
||||
cancel_check=context.check_cancelled,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
"""Shared ONNX Runtime session helpers."""
|
||||
|
||||
COREML_PROVIDER_OPTIONS = {
|
||||
"ModelFormat": "MLProgram",
|
||||
"MLComputeUnits": "ALL",
|
||||
"RequireStaticInputShapes": "0",
|
||||
"EnableOnSubgraphs": "0",
|
||||
}
|
||||
|
||||
|
||||
def select_providers(requested, available):
|
||||
available = set(available)
|
||||
@@ -40,6 +47,12 @@ def create_session(path, requested_device="auto"):
|
||||
requested_device,
|
||||
onnxruntime.get_available_providers(),
|
||||
)
|
||||
providers = [
|
||||
(provider, dict(COREML_PROVIDER_OPTIONS))
|
||||
if provider == "CoreMLExecutionProvider"
|
||||
else provider
|
||||
for provider in providers
|
||||
]
|
||||
return onnxruntime.InferenceSession(str(path), providers=providers)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user