feat(cutout_tool): Implement cutout region to shape functionality
- Added interaction helpers for cutout region validation and shape menu interaction. - Created main operator for converting image regions into cutout shapes, including AI artifact generation. - Introduced object creation logic for cutout shapes, handling depth and normal textures. - Defined cutout shape identifiers and node groups for various shape types. - Implemented depth texture writing and prediction artifact generation for MoGe-2. - Developed server jobs for generating cutout artifacts, depth planes, and refining image regions. - Added region refinement logic to enhance gesture masks using BEN2.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
@@ -11,49 +10,6 @@ from .image_data import (
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ImageGeometry:
|
||||
points: object
|
||||
intrinsics: object
|
||||
valid: object
|
||||
calibration_valid: object
|
||||
image_size: tuple
|
||||
reference_depth: float
|
||||
region_transparent_fraction: float
|
||||
|
||||
|
||||
def load_image_geometry(path):
|
||||
"""Load and validate the shared image geometry Job artifact."""
|
||||
import numpy as np
|
||||
|
||||
with np.load(path, allow_pickle=False) as archive:
|
||||
geometry = ImageGeometry(
|
||||
points=np.asarray(archive["points"], dtype=np.float32),
|
||||
intrinsics=np.asarray(archive["intrinsics"], dtype=np.float32),
|
||||
valid=np.asarray(archive["valid"], dtype=bool),
|
||||
calibration_valid=np.asarray(archive["calibration_valid"], dtype=bool),
|
||||
image_size=tuple(int(value) for value in archive["image_size"]),
|
||||
reference_depth=float(archive["reference_depth"]),
|
||||
region_transparent_fraction=float(
|
||||
archive["region_transparent_fraction"]
|
||||
),
|
||||
)
|
||||
if (
|
||||
geometry.points.ndim != 3
|
||||
or geometry.points.shape[2] != 3
|
||||
or geometry.valid.shape != geometry.points.shape[:2]
|
||||
or geometry.calibration_valid.shape != geometry.points.shape[:2]
|
||||
):
|
||||
raise ValueError("The mesh point field is invalid")
|
||||
if (
|
||||
geometry.intrinsics.shape != (3, 3)
|
||||
or not geometry.reference_depth > 0.0
|
||||
or not 0.0 <= geometry.region_transparent_fraction <= 1.0
|
||||
):
|
||||
raise ValueError("The mesh camera field is invalid")
|
||||
return geometry
|
||||
|
||||
|
||||
NODE_ASSET_NAME = "O_AnyImage.blend"
|
||||
|
||||
|
||||
@@ -161,12 +117,9 @@ def set_material_color_space(image, scene=None):
|
||||
preferred = material_color_space_name(scene)
|
||||
original = settings.name
|
||||
pixels = None
|
||||
if (
|
||||
preferred != original
|
||||
and (
|
||||
getattr(image, "source", None) == "GENERATED"
|
||||
or getattr(image, "is_dirty", False)
|
||||
)
|
||||
if preferred != original and (
|
||||
getattr(image, "source", None) == "GENERATED"
|
||||
or getattr(image, "is_dirty", False)
|
||||
):
|
||||
pixels = image_pixels(image)
|
||||
for color_space in dict.fromkeys((preferred, "sRGB", original)):
|
||||
@@ -389,6 +342,7 @@ def create_image_material(
|
||||
use_cyclic=None,
|
||||
normal_image=None,
|
||||
normal_space="TANGENT",
|
||||
ior=None,
|
||||
scene=None,
|
||||
):
|
||||
material = bpy.data.materials.new(image_base_name(source_object.data))
|
||||
@@ -483,6 +437,8 @@ def create_image_material(
|
||||
else:
|
||||
shader = nodes.new("ShaderNodeBsdfPrincipled")
|
||||
shader.location = (250.0, 400.0)
|
||||
if ior is not None:
|
||||
shader.inputs["IOR"].default_value = float(ior)
|
||||
|
||||
links.new(
|
||||
material_inputs.outputs["Color"],
|
||||
|
||||
Reference in New Issue
Block a user