Files
AnyImage/openspec/changes/reorganize-cutout-shapes/design.md

7.1 KiB
Raw Blame History

Context

当前 shape.py 将四种形态映射为四个子组,再由 O Image Cutout 用 Shape 菜单选择。菜单统一传入 Normal Map 勾选值;normal_mode_for_shape() 仅在勾选时为 Depth Surface 选择 OBJECT,其余形态使用 TANGENT。

build/cutout_surface_balloon/surface-balloon-smooth-back.blend 已验证五张输入、15 个参数组合;背面算法、控制测试与实际节点布局可作为实施参考。当前工作区也已修正前置 Cleanup 和不依赖 Depth Scale 的 Split,实施从这些修正继续。

Goals / Non-Goals

Goals: 四个明确的创建预设,三个独立修改器节点组,统一厚度语义,深度入口自动生成法线,保留已验证的几何质量。

Non-Goals: 本次范围限定在 Cutout 的创建、节点资产与材质连接;AI 模型、图像区域交互和其他工具沿用现有职责。

Decisions

创建预设与节点资产分离

入口 / 内部标识 节点组 初始设置
Flat / FLAT O Image Cutout Balloon,Thickness 0
Solid / SOLID O Image Cutout Balloon,Thickness 1
Depth Solid / DEPTH_SOLID O Image Depth Cutout Balloon,Thickness 1
Depth Balloon / DEPTH_BALLOON O Image Depth Balloon Thickness 1,Double Sided 开启

Solid 是新创建的默认预设,Pie 保持四个选择。Flat 和 Solid 使用同一基础网格属性与节点组,创建后通过厚度即可转换。预设名称用于菜单、对象命名与 Operator 协议;资产名称仅用于按名称加载。

三个节点组直接设置为修改器资产,各自输出最终几何。删除总 Shape 分支及 O Image Surface、O Image Balloon、O Image Depth Surface 旧资产。复用构建函数展开公共步骤,避免为了共享代码再建立总包装组。保留 Inward Axis 的几何与对象矩阵配对转换。

两种厚度方式

O Image Cutout 和 O Image Depth Cutout 使用 Thickness Mode 菜单,顺序为 Balloon、Uniform,默认 Balloon。Balloon 的 Thickness 是无量纲倍率,Uniform 的厚度是距离;输入显示与保存必须区分两种语义,距离 socket 使用 DISTANCE,倍率使用 NONE。具体 socket 组织在实现时按 Blender 修改器接口能力选择,验收必须确认用户能辨认单位,切换时不发生隐式单位换算。

普通 Cutout 的 Balloon 模式使用正背面 ±o_balloon × Thickness;Uniform 使用当前 Surface 的等厚板片行为。两种方式在零厚度时均返回单层平面。全部预设都准备 o_balloon,即使以 Flat 创建也能直接增厚。

深度 Cutout 保留当前 Depth Surface 的采样、射线投影与 Split;Uniform 保留沿内向轴等厚的正背面。Balloon 采用实验中的平滑背面,两种方式零厚度均返回深度表面。

平滑背面进入正式构建

flowchart TD
    A[基础网格和 o_balloon] --> B[Cleanup 按原平面岛面积清理]
    B --> C[原始深度判断 Split]
    C --> D[相机射线修正与深度投影]
    D --> E[估计并平滑中心位置]
    E --> F[生成正背面及切口侧壁]
    F --> G[边缘平滑与整体 Smooth]
    G --> H[清理暂存属性与轴向输出]

令 D 为投影后正面 Z,B 为 o_balloon。以 C₀ = D − B 初始化中心位置,固定原轮廓和 Split 切口上的值,仅对内部执行 256 次邻域平滑。Thickness 为 1 时目标背面为 C − B;一般厚度场为 Thickness × max(D − C + B, 0.05 × B)。比例下限用于限制深凹处反穿,原轮廓 B 为零时厚度仍归零,不引入 Rim Thickness。

复用原型中对轮廓耳三角形、内部零轮廓弦的补点方法,保证封闭轮廓不会产生零面积面。通过来源顶点和厚度层身份连接几何,Split 两侧保持独立;正面在边缘和整体平滑关闭时保持原始深度表面位置。

保留原型的 Edge Smooth 控制与抑制轮廓收缩的平滑过程,整体 Smooth 复用项目实现。临时属性使用 o_* 专用前缀并在输出前移除,保留 UVMap、o_balloon 和用户属性。默认参数及平滑成本用五张缓存输入复验。

每个节点组承担自己的公共处理

三个资产复用同一 Cleanup 构建函数,在塑形前按原平面岛总面积清理;UI 值继续乘 0.01 转为面积。Smooth 与轴向输出在各自塑形后执行。仅深度 Cutout 提供 Split;比较式为 相邻面采样距离差 × Reference Depth × Depth Scale × Split > 面中心距离 × 平均射线距离 × 2.5,Depth Scale 既缩放显示位移也缩放切边判据。

法线策略在 Operator 层统一解析

入口 勾选关闭 勾选开启
Flat NONE TANGENT
Solid NONE TANGENT
Depth Solid OBJECT OBJECT
Depth Balloon TANGENT TANGENT

统一解析函数同时供 Job 构建和结果接收使用,保证直接调用 Operator 与 Pie 调用一致。深度入口的自动生成不会改写用户保存的勾选值。工具提示说明 Normal Map 仅控制 Flat / Solid;AI 未就绪时仍只提供两个本地入口,并忽略遗留的开启值。

复用现有法线结果加载、材质连接与轴向变换。Flat 与 Solid 共用节点后,法线的 Balloon 适配不得仅由创建时的预设名决定;按当前厚度方式和几何属性处理,验证 Flat 增厚后材质仍正确。Depth Solid 保留 OBJECT 法线的方向转换,Depth Balloon 保留 TANGENT 法线的适配。

Depth Solid 在 FACE 域保存正面法线权重 1,背面与侧壁为 0;材质读取该权重,使平滑背面使用几何法线。法线权重作为公开材质属性保留在输出网格中。

Risks / Trade-offs

  • 平滑中心场会弱化内部深度细节 → 正面保留原深度,背面用已验证的轮廓约束;通过合成曲面与五张实图同时验收。
  • 迭代与闭合细分增加成本 → 使用固定初始迭代数,测量默认预设求值时间;字段就近存取,避免重复推理与重复求值。
  • 同名 O Image Cutout 的资产职责改变 → 加载路径按新结构校验,避免复用已加载的旧 Shape 包装组;旧 .blend 中嵌入的数据保持原样,新创建对象使用新资产。源码不保留旧标识转发或迁移兼容层。
  • 法线图随默认预设开启后的材质效果可能不同 → 分别验证两个深度入口的正背面着色及两个 Inward Axis。

Migration Plan

按标识和默认值、节点构建、运行时加载与材质、验证的顺序实施。发布资产只保留三个 Cutout 节点组;同步删除旧构建和验证分支。需要回退时整体恢复源码与对应资产,避免新旧接口混装。

未归档的 gate-cutout-ai-options、replace-depth-surface-stretch-with-split 和 standardize-cutout-z-axis 涉及本次边界。未来归档时以本提案的入口名称、直接修改器架构、前置 Cleanup 和原始深度 Split 要求为准,同时保留 AI 门控与轴向约定;不回退当前工作区已完成的修复。

Open Questions

无产品决策待确认。厚度输入的具体展示方式属于实施细节,须满足倍率与距离可辨认的验收要求。