Add cutout profile and teddy balloon height calculations

- Implemented cotangent Poisson field and Poisson balloon profile in cutout_profile.py.
- Added teddy balloon heights calculation and related functions in cutout_teddy.py.
- Introduced interaction utilities for image editing in interaction.py.
- Developed depth normalization and analysis functions in cutout_depth.py.
- Created a validation script for cutout assets in validate_cutout_asset.py.
This commit is contained in:
2026-08-27 22:46:57 +08:00
parent 6c8358f92f
commit 7d39fe8c5e
40 changed files with 3058 additions and 3896 deletions

View File

@@ -187,23 +187,13 @@ def moge2_model_enum_items(_owner, _context):
)
def balloon_depth_model_enum_items(_owner, _context):
models = [
model
for model in model_catalog()
if model.get("family") == "moge2" and model.get("enabled")
]
models.sort(key=lambda model: model.get("key") != DEFAULT_MOGE2_MODEL_KEY)
return _model_items(models)
def depth_plane_model_enum_items(_owner, _context):
models = [
model
for model in model_catalog()
if model.get("family") in {"moge2", "da3"} and model.get("enabled")
]
models.sort(key=lambda model: model.get("key") != DEFAULT_MOGE2_MODEL_KEY)
models.sort(key=lambda model: model.get("family") != "moge2")
items = _model_items(models)
items.append(
("ORIGINAL", "Original", "Use the original image as depth", len(items))
@@ -217,7 +207,7 @@ def surface_model_enum_items(_owner, _context):
for model in model_catalog()
if model.get("family") in {"moge2", "da3"} and model.get("enabled")
]
models.sort(key=lambda model: model.get("key") != DEFAULT_MOGE2_MODEL_KEY)
models.sort(key=lambda model: model.get("family") != "moge2")
return _model_items(models)
@@ -250,74 +240,7 @@ def upscale_model_label(model_key):
return model.label if model is not None else model_key
BALLOON_MODE_ITEMS = (
(
"POISSON",
"Poisson",
"Use a global Poisson field for smooth inflation",
),
(
"TEDDY",
"Teddy / Chordal Axis",
"Use a Teddy-style chordal axis and local oval sections",
),
)
def balloon_mode_property():
return bpy.props.EnumProperty(
name="Mode",
description="Algorithm used to inflate the saved lasso region",
items=BALLOON_MODE_ITEMS,
default="POISSON",
)
def balloon_thickness_property():
return bpy.props.FloatProperty(
name="Thickness",
description="Scale the Balloon thickness while keeping the lasso region",
default=1.0,
min=0.05,
soft_max=5.0,
)
def balloon_resolution_property():
return bpy.props.FloatProperty(
name="Resolution (m)",
description=(
"Distance in meters between sampled mesh points; smaller values "
"create more geometry"
),
default=0.1,
min=0.005,
soft_min=0.02,
soft_max=0.5,
max=10.0,
)
def balloon_reuse_material_property():
return bpy.props.BoolProperty(
name="Reuse Material",
description="Reuse a compatible Balloon material made from the same image",
default=True,
)
def balloon_contour_analysis_property():
return bpy.props.BoolProperty(
name="Contour",
description=(
"Use BEN2 Alpha above 0.5 to analyze the lasso contour before "
"building the Balloon"
),
default=False,
)
def image_edit_refine_selection_property():
def refine_selection_property():
return bpy.props.BoolProperty(
name="Refine Selection",
description="Use BEN2 to fit the gesture mask to foreground content",
@@ -332,6 +255,7 @@ def cutout_normal_analysis_property():
default=False,
)
def cutout_point_spacing_property():
return bpy.props.IntProperty(
name="Point Spacing",
@@ -345,45 +269,12 @@ def cutout_point_spacing_property():
)
def balloon_depth_analysis_property():
return bpy.props.BoolProperty(
name="Depth",
description=("Use MoGe-2 to add adjustable image depth to the Balloon mesh"),
default=False,
)
def balloon_depth_model_property():
return bpy.props.EnumProperty(
name="Depth Model",
description="MoGe-2 model used for Balloon depth",
items=balloon_depth_model_enum_items,
default=0,
)
def balloon_radial_zoom_property(scale):
return bpy.props.FloatVectorProperty(
size=2,
default=(scale, scale),
min=0.01,
options={"HIDDEN", "SKIP_SAVE"},
)
class AnyImageSettings(bpy.types.PropertyGroup):
cutout_point_spacing: cutout_point_spacing_property()
cutout_normal_analysis: cutout_normal_analysis_property()
image_edit_refine_selection: image_edit_refine_selection_property()
balloon_mode: balloon_mode_property()
balloon_thickness: balloon_thickness_property()
balloon_resolution: balloon_resolution_property()
balloon_reuse_material: balloon_reuse_material_property()
balloon_contour_analysis: balloon_contour_analysis_property()
balloon_depth_analysis: balloon_depth_analysis_property()
balloon_depth_model: balloon_depth_model_property()
balloon_thickness_radial_zoom: balloon_radial_zoom_property(100.0)
balloon_resolution_radial_zoom: balloon_radial_zoom_property(1000.0)
cutout_refine_selection: refine_selection_property()
image_box_refine_selection: refine_selection_property()
image_lasso_refine_selection: refine_selection_property()
input_path: bpy.props.StringProperty(
name="Image or Video",
description="A single image or video file used for reconstruction",