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,12 +1,10 @@
|
||||
"""Build the four Cutout Geometry Nodes groups stored in O_AnyImage.blend."""
|
||||
|
||||
import math
|
||||
|
||||
import bpy
|
||||
|
||||
from node_graph import expand_smooth
|
||||
|
||||
from anyimage.operators.cutout_tool.shape_types import (
|
||||
from anyimage.operators.cutout_tool.shape import (
|
||||
BALLOON_ATTRIBUTE_NAME,
|
||||
CUTOUT_NODE_GROUP_NAME,
|
||||
CUTOUT_NODE_GROUP_NAMES,
|
||||
@@ -51,9 +49,7 @@ def _localize_group_inputs(group, controls):
|
||||
for link in ordered:
|
||||
if (
|
||||
not clusters
|
||||
or link.to_node.location.x
|
||||
- clusters[-1][-1].to_node.location.x
|
||||
> 900.0
|
||||
or link.to_node.location.x - clusters[-1][-1].to_node.location.x > 900.0
|
||||
):
|
||||
clusters.append([])
|
||||
clusters[-1].append(link)
|
||||
@@ -356,9 +352,7 @@ def _set_segmented_layer_x(
|
||||
flip_side.location = (x + 2850.0, y + 350.0)
|
||||
links.new(positioned_side, flip_side.inputs["Mesh"])
|
||||
|
||||
back = _offset_geometry_x(
|
||||
group, geometry, back_x, (x + 2450.0, y - 400.0)
|
||||
)
|
||||
back = _offset_geometry_x(group, geometry, back_x, (x + 2450.0, y - 400.0))
|
||||
flip_back = nodes.new("GeometryNodeFlipFaces")
|
||||
flip_back.location = (x + 2850.0, y - 400.0)
|
||||
links.new(back, flip_back.inputs["Mesh"])
|
||||
@@ -503,17 +497,13 @@ def _build_cutout(group, geometry, thickness):
|
||||
thickness,
|
||||
(250.0, 300.0),
|
||||
)
|
||||
return _remove_zero_thickness(
|
||||
group, geometry, shaped, thickness, (3750.0, 300.0)
|
||||
)
|
||||
return _remove_zero_thickness(group, geometry, shaped, thickness, (3750.0, 300.0))
|
||||
|
||||
|
||||
def _build_balloon(group, geometry, thickness):
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
profile, _profile_factor = _profile_field(
|
||||
group, geometry, (-200.0, 0.0)
|
||||
)
|
||||
profile, _profile_factor = _profile_field(group, geometry, (-200.0, 0.0))
|
||||
front = _math(nodes, "MULTIPLY", (2400.0, 500.0))
|
||||
front.inputs[1].default_value = -1.0
|
||||
links.new(profile, front.inputs[0])
|
||||
@@ -532,9 +522,7 @@ def _build_balloon(group, geometry, thickness):
|
||||
back.outputs[0],
|
||||
(2850.0, 650.0),
|
||||
)
|
||||
return _remove_zero_thickness(
|
||||
group, geometry, shaped, thickness, (4400.0, 650.0)
|
||||
)
|
||||
return _remove_zero_thickness(group, geometry, shaped, thickness, (4400.0, 650.0))
|
||||
|
||||
|
||||
def _build_depth_balloon(
|
||||
@@ -550,9 +538,7 @@ def _build_depth_balloon(
|
||||
):
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
profile, profile_factor = _profile_field(
|
||||
group, geometry, (-200.0, 250.0)
|
||||
)
|
||||
profile, profile_factor = _profile_field(group, geometry, (-200.0, 250.0))
|
||||
camera_position = _position_field(group, depth_image, (200.0, -250.0))
|
||||
separate_camera = nodes.new("ShaderNodeSeparateXYZ")
|
||||
separate_camera.location = (650.0, -250.0)
|
||||
@@ -615,9 +601,7 @@ def _build_depth_balloon(
|
||||
front_only = _set_geometry_x(
|
||||
group, geometry, front_mix.outputs["Result"], (3500.0, 100.0)
|
||||
)
|
||||
return _remove_zero_thickness(
|
||||
group, front_only, shaped, thickness, (4850.0, 600.0)
|
||||
)
|
||||
return _remove_zero_thickness(group, front_only, shaped, thickness, (4850.0, 600.0))
|
||||
|
||||
|
||||
def _build_depth_surface(
|
||||
@@ -709,9 +693,7 @@ def build_node_group(shape):
|
||||
"the source sheet"
|
||||
)
|
||||
else:
|
||||
thickness = _float_input(
|
||||
group, "Thickness", 0.0, 0.0, None, subtype="DISTANCE"
|
||||
)
|
||||
thickness = _float_input(group, "Thickness", 0.0, 0.0, None, subtype="DISTANCE")
|
||||
thickness.description = "Final thickness in scene distance"
|
||||
|
||||
depth_image = None
|
||||
@@ -766,17 +748,15 @@ def build_node_group(shape):
|
||||
|
||||
if shape in {"DEPTH_BALLOON", "DEPTH_SURFACE"}:
|
||||
data = group.interface.new_panel(name="Data", default_closed=True)
|
||||
uniform_scale = _float_input(
|
||||
group, "Uniform Scale", 1.0, 0.0, parent=data
|
||||
)
|
||||
uniform_scale = _float_input(group, "Uniform Scale", 1.0, 0.0, parent=data)
|
||||
uniform_scale.description = (
|
||||
"Internal uniform conversion from MoGe meters to local distance"
|
||||
)
|
||||
uniform_scale.hide_in_modifier = True
|
||||
depth_image = _socket(
|
||||
group, "Depth Image", "INPUT", "NodeSocketImage", data
|
||||
depth_image = _socket(group, "Depth Image", "INPUT", "NodeSocketImage", data)
|
||||
depth_image.description = (
|
||||
f"Internally generated {CUTOUT_SHAPE_LABELS[shape]} data"
|
||||
)
|
||||
depth_image.description = f"Internally generated {CUTOUT_SHAPE_LABELS[shape]} data"
|
||||
depth_image.hide_in_modifier = True
|
||||
_socket(group, "Geometry", "OUTPUT", "NodeSocketGeometry")
|
||||
|
||||
@@ -795,7 +775,7 @@ def build_node_group(shape):
|
||||
},
|
||||
)
|
||||
geometry = controls.outputs["Geometry"]
|
||||
if shape == "CUTOUT":
|
||||
if shape == "SURFACE":
|
||||
geometry = _build_cutout(group, geometry, controls.outputs["Thickness"])
|
||||
output_location = (4050.0, 300.0)
|
||||
elif shape == "BALLOON":
|
||||
@@ -833,7 +813,7 @@ def build_node_group(shape):
|
||||
_shade_output(group, geometry, output_location)
|
||||
group.color_tag = "GEOMETRY"
|
||||
group.description = {
|
||||
"CUTOUT": "Symmetrically thicken a Surface sheet.",
|
||||
"SURFACE": "Symmetrically thicken a Surface sheet.",
|
||||
"BALLOON": "Inflate a Surface sheet from its boundary profile.",
|
||||
"DEPTH_BALLOON": (
|
||||
"Mix Balloon profile and metric image depth around a fitted plane."
|
||||
@@ -866,9 +846,7 @@ def build_cutout_modifier_group(shape_groups):
|
||||
"Mirror the complete Depth Balloon front surface across the local YZ plane"
|
||||
)
|
||||
|
||||
iterations = _socket(
|
||||
group, "Smooth Iterations", "INPUT", "NodeSocketInt"
|
||||
)
|
||||
iterations = _socket(group, "Smooth Iterations", "INPUT", "NodeSocketInt")
|
||||
iterations.default_value = 0
|
||||
iterations.min_value = 0
|
||||
iterations.max_value = 20
|
||||
@@ -882,9 +860,7 @@ def build_cutout_modifier_group(shape_groups):
|
||||
None,
|
||||
parent=options,
|
||||
)
|
||||
cleanup.description = (
|
||||
"Delete mesh islands below this absolute local-area threshold"
|
||||
)
|
||||
cleanup.description = "Delete mesh islands below this absolute local-area threshold"
|
||||
smooth = _float_input(
|
||||
group,
|
||||
"Smooth",
|
||||
@@ -915,18 +891,13 @@ def build_cutout_modifier_group(shape_groups):
|
||||
)
|
||||
depth_direction.description = "Normal direction of the fitted metric depth plane"
|
||||
|
||||
|
||||
data = group.interface.new_panel(name="Data", default_closed=True)
|
||||
uniform_scale = _float_input(
|
||||
group, "Uniform Scale", 1.0, 0.0, parent=data
|
||||
)
|
||||
uniform_scale = _float_input(group, "Uniform Scale", 1.0, 0.0, parent=data)
|
||||
uniform_scale.description = (
|
||||
"Internal uniform conversion from MoGe meters to local distance"
|
||||
)
|
||||
uniform_scale.hide_in_modifier = True
|
||||
depth_image = _socket(
|
||||
group, "Depth Image", "INPUT", "NodeSocketImage", data
|
||||
)
|
||||
depth_image = _socket(group, "Depth Image", "INPUT", "NodeSocketImage", data)
|
||||
depth_image.description = "Internally generated Cutout depth data"
|
||||
depth_image.hide_in_modifier = True
|
||||
_socket(group, "Geometry", "OUTPUT", "NodeSocketGeometry")
|
||||
@@ -947,7 +918,7 @@ def build_cutout_modifier_group(shape_groups):
|
||||
)
|
||||
|
||||
branch_y = {
|
||||
"CUTOUT": 1150.0,
|
||||
"SURFACE": 1150.0,
|
||||
"BALLOON": 550.0,
|
||||
"DEPTH_BALLOON": -50.0,
|
||||
"DEPTH_SURFACE": -650.0,
|
||||
|
||||
Reference in New Issue
Block a user