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:
2026-08-31 11:36:27 +08:00
parent 08309f719d
commit 87d7721128
80 changed files with 4823 additions and 4297 deletions

View File

@@ -0,0 +1,126 @@
"""Cutout Region validation and Shape-menu interaction helpers."""
from ...preferences import (
MAX_CUTOUT_MESH_RESOLUTION,
MIN_CUTOUT_MESH_RESOLUTION,
)
from ..common.image_data import image_rgba
from ..common.image_region import rasterize_region_path
from .geometry import CUTOUT_ALPHA_THRESHOLD
def validate_cutout_region(
source_object,
region_path,
):
image = source_object.data
rgba = image_rgba(image)
rasterize_region_path(
tuple(image.size),
region_path,
source_alpha=rgba[:, :, 3],
alpha_threshold=CUTOUT_ALPHA_THRESHOLD,
antialias=True,
)
def cutout_mesh_resolution(image_size, point_spacing):
longest_edge = max(int(value) for value in image_size)
detail = round(longest_edge / max(int(point_spacing), 1))
return max(
MIN_CUTOUT_MESH_RESOLUTION,
min(MAX_CUTOUT_MESH_RESOLUTION, detail),
)
def _pie_button(
pie,
shape,
label,
icon,
source_name,
region_path_json,
refine_region,
generate_normal,
mesh_resolution,
):
operator = pie.operator(
"anyimage.cutout_region_to_shape",
text=label,
icon=icon,
)
operator.source_object_name = source_name
operator.region_path_json = region_path_json
operator.shape = shape
operator.refine_region = refine_region
operator.generate_normal = generate_normal
operator.mesh_resolution = mesh_resolution
def open_shape_pie(
context,
event,
source_object,
region_path,
refine_region=False,
):
source_name = source_object.name
region_path_json = region_path.to_json()
settings = context.scene.anyimage_settings
point_spacing = settings.cutout_point_spacing
generate_normal = bool(getattr(settings, "cutout_generate_normal", False))
mesh_resolution = cutout_mesh_resolution(source_object.data.size, point_spacing)
def draw(menu, _context):
pie = menu.layout.menu_pie()
_pie_button(
pie,
"SURFACE",
"Surface",
"MESH_GRID",
source_name,
region_path_json,
refine_region,
generate_normal,
mesh_resolution,
)
_pie_button(
pie,
"BALLOON",
"Balloon",
"MESH_UVSPHERE",
source_name,
region_path_json,
refine_region,
generate_normal,
mesh_resolution,
)
_pie_button(
pie,
"DEPTH_BALLOON",
"Depth Balloon",
"META_BALL",
source_name,
region_path_json,
refine_region,
generate_normal,
mesh_resolution,
)
_pie_button(
pie,
"DEPTH_SURFACE",
"Depth Surface",
"SURFACE_NCURVE",
source_name,
region_path_json,
refine_region,
generate_normal,
mesh_resolution,
)
context.window_manager.popup_menu_pie(
event,
draw,
title="Cutout Shape",
icon="MESH_DATA",
)