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:
@@ -13,6 +13,9 @@ from .server.model_catalog import (
|
||||
)
|
||||
|
||||
DEFAULT_MOGE2_MODEL_KEY = "MOGE2_VITS_NORMAL"
|
||||
DEFAULT_MAX_CUTOUT_MESH_RESOLUTION = 1024
|
||||
MIN_CUTOUT_MESH_RESOLUTION = 4
|
||||
MAX_CUTOUT_MESH_RESOLUTION = 1024
|
||||
|
||||
ADDON_PACKAGE = __package__
|
||||
DEFAULT_STORAGE_ROOT = Path.home() / ".anyimage"
|
||||
@@ -46,11 +49,24 @@ def configured_storage_root():
|
||||
return DEFAULT_STORAGE_ROOT
|
||||
|
||||
|
||||
def configured_max_ai_input_size(context=None):
|
||||
def configured_max_cutout_mesh_resolution(context=None):
|
||||
preferences = addon_preferences(context)
|
||||
value = int(
|
||||
getattr(preferences, "max_ai_input_size", DEFAULT_MAX_AI_INPUT_SIZE)
|
||||
getattr(
|
||||
preferences,
|
||||
"max_cutout_mesh_resolution",
|
||||
DEFAULT_MAX_CUTOUT_MESH_RESOLUTION,
|
||||
)
|
||||
)
|
||||
return min(
|
||||
max(value, MIN_CUTOUT_MESH_RESOLUTION),
|
||||
MAX_CUTOUT_MESH_RESOLUTION,
|
||||
)
|
||||
|
||||
|
||||
def configured_max_ai_input_size(context=None):
|
||||
preferences = addon_preferences(context)
|
||||
value = int(getattr(preferences, "max_ai_input_size", DEFAULT_MAX_AI_INPUT_SIZE))
|
||||
return min(max(value, MIN_MAX_AI_INPUT_SIZE), MAX_MAX_AI_INPUT_SIZE)
|
||||
|
||||
|
||||
@@ -60,10 +76,10 @@ def device_items(owner, context):
|
||||
return device_enum_items(owner, context)
|
||||
|
||||
|
||||
def mesh_depth_model_items(owner, context):
|
||||
from .properties import mesh_depth_model_enum_items
|
||||
def geometry_model_items(owner, context):
|
||||
from .properties import geometry_model_enum_items
|
||||
|
||||
return mesh_depth_model_enum_items(owner, context)
|
||||
return geometry_model_enum_items(owner, context)
|
||||
|
||||
|
||||
class AnyImagePreferences(bpy.types.AddonPreferences):
|
||||
@@ -97,7 +113,7 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
|
||||
name="Maximum AI Input Size",
|
||||
description=(
|
||||
"Maximum source long edge eligible for Upscale and maximum long edge "
|
||||
"used by Depth and Normal analysis"
|
||||
"used by Depth, Normal and Region refinement"
|
||||
),
|
||||
default=DEFAULT_MAX_AI_INPUT_SIZE,
|
||||
min=MIN_MAX_AI_INPUT_SIZE,
|
||||
@@ -105,31 +121,30 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
|
||||
step=256,
|
||||
subtype="PIXEL",
|
||||
)
|
||||
max_cutout_mesh_resolution: bpy.props.IntProperty(
|
||||
name="Maximum Cutout Mesh Resolution",
|
||||
description="Maximum sampling resolution along the longest Cutout edge",
|
||||
default=DEFAULT_MAX_CUTOUT_MESH_RESOLUTION,
|
||||
min=MIN_CUTOUT_MESH_RESOLUTION,
|
||||
max=MAX_CUTOUT_MESH_RESOLUTION,
|
||||
step=64,
|
||||
subtype="PIXEL",
|
||||
)
|
||||
balloon_profile_algorithm: bpy.props.EnumProperty(
|
||||
name="Balloon Profile",
|
||||
description="Algorithm used to generate o_balloon for every Cutout shape",
|
||||
items=BALLOON_PROFILE_ALGORITHM_ITEMS,
|
||||
default="POISSON",
|
||||
)
|
||||
mesh_depth_model: bpy.props.EnumProperty(
|
||||
name="Mesh Depth Model",
|
||||
description="Depth model used by Depth Plane, Depth Balloon and Depth Surface",
|
||||
items=mesh_depth_model_items,
|
||||
geometry_model: bpy.props.EnumProperty(
|
||||
name="Depth & Normal Model",
|
||||
description="MoGe-2 model used for geometry and normal generation",
|
||||
items=geometry_model_items,
|
||||
default=0,
|
||||
)
|
||||
mesh_process_res_factor: bpy.props.FloatProperty(
|
||||
name="DA3 Resolution Scale",
|
||||
description="Source image scale used for Depth Anything 3 mesh conversion",
|
||||
default=100.0,
|
||||
min=1.0,
|
||||
max=100.0,
|
||||
step=100,
|
||||
precision=0,
|
||||
subtype="PERCENTAGE",
|
||||
)
|
||||
mesh_resolution_level: bpy.props.IntProperty(
|
||||
geometry_resolution_level: bpy.props.IntProperty(
|
||||
name="MoGe Resolution Level",
|
||||
description="MoGe-2 inference resolution used for mesh conversion",
|
||||
description="MoGe-2 inference resolution used for geometry and normal generation",
|
||||
default=5,
|
||||
min=0,
|
||||
max=9,
|
||||
@@ -205,34 +220,24 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
|
||||
|
||||
section = self._draw_panel(layout, "cutout", "Cutout")
|
||||
if section is not None:
|
||||
section.prop(self, "max_cutout_mesh_resolution")
|
||||
section.prop(self, "balloon_profile_algorithm")
|
||||
|
||||
def _draw_depth_normal(self, layout, models, environment_ready):
|
||||
layout.prop(self, "mesh_depth_model")
|
||||
mesh_depth_model = getattr(
|
||||
self, "mesh_depth_model", DEFAULT_MOGE2_MODEL_KEY
|
||||
)
|
||||
if mesh_depth_model not in models:
|
||||
mesh_depth_model = DEFAULT_MOGE2_MODEL_KEY
|
||||
layout.prop(self, "geometry_model")
|
||||
geometry_model = getattr(self, "geometry_model", DEFAULT_MOGE2_MODEL_KEY)
|
||||
if geometry_model not in models:
|
||||
geometry_model = DEFAULT_MOGE2_MODEL_KEY
|
||||
self._draw_model(
|
||||
layout,
|
||||
models.get(mesh_depth_model),
|
||||
models.get(geometry_model),
|
||||
environment_ready,
|
||||
)
|
||||
if mesh_depth_model.startswith("MOGE2_"):
|
||||
layout.prop(self, "mesh_resolution_level")
|
||||
else:
|
||||
layout.prop(self, "mesh_process_res_factor")
|
||||
layout.label(
|
||||
text="DA3 models cannot generate normals",
|
||||
icon="INFO",
|
||||
)
|
||||
layout.prop(self, "geometry_resolution_level")
|
||||
|
||||
def _draw_upscale(self, layout, models, environment_ready):
|
||||
layout.prop(self, "upscale_model")
|
||||
upscale_model = getattr(
|
||||
self, "upscale_model", DEFAULT_UPSCALE_MODEL_KEY
|
||||
)
|
||||
upscale_model = getattr(self, "upscale_model", DEFAULT_UPSCALE_MODEL_KEY)
|
||||
if upscale_model not in models:
|
||||
upscale_model = DEFAULT_UPSCALE_MODEL_KEY
|
||||
self._draw_model(
|
||||
|
||||
Reference in New Issue
Block a user