Add cutout shell and volume node assets for depth volume processing

- Implemented `cutout_shell.py` to build front normals and shell positions for balloon geometry.
- Created `cutout_volume.py` to establish smooth center fields and manage balloon surface attributes.
- Introduced `pisa_sr_export.py` for exporting PiSA-SR components with dependencies and asset finalization.
This commit is contained in:
2026-09-08 17:18:03 +08:00
parent 7dec3b7ca4
commit 196b964efc
71 changed files with 3440 additions and 1988 deletions

View File

@@ -33,47 +33,71 @@ uv run build_node --skip-tests
| `O Image Depth Plane` | `build_depth_plane.py` |
| `O Image Layer`、`O Image Depth Layer` | `build_material_layers.py` |
| `O Shadeless` | `build_shadeless.py` |
| `O Image Cutout` | `build_cutout.py` |
| `O Image Surface`、`O Image Balloon` | `build_cutout.py` |
| `O Image Depth Balloon`、`O Image Depth Surface` | `build_cutout.py` |
| `O Image Cutout`、`O Image Depth Cutout`、`O Image Depth Balloon` | `build_cutout_modifiers.py` |
构建从空 Factory 文件生成全部节点组,关闭 `.blend1` 备份,并覆盖唯一发布资产。
四个 Cutout Shape 子节点统一接收局部 XY 平面,并以 `-Z` 表示向图片内部的方向。`O Image Cutout` 在 Shape 分支与平滑之后处理 **Inward Axis**:默认 `-Z` 直接输出原生几何,`+X` 分支执行一次 Z 到 X 的轴转换;运行时对象矩阵使用逆变换补偿,保证两种模式落在相同世界空间位置。
Depth Cutout 的布局由 `cutout_depth_surface_layout.py` 编排:Split 属性采样位于主链上方,原始几何旁路沿下方的 Reroute 通道汇入 Switch;长距离投影引用共用分段干线,并在 Uniform 厚度与零厚度输出附近分叉。几何统计支线就近放置在其使用区域。
`O Image Depth Plane`、`O Image Cutout`、`O Image Depth Balloon` 与 `O Image Depth Surface` 统一使用 **Reference Depth** 作为采样深度的运算基准。
三个 Cutout 节点组直接作为修改器使用,统一接收局部 XY 平面,以 `-Z` 表示向图片内部的方向。每组在塑形与平滑后处理 **Inward Axis**:默认 `-Z` 直接输出原生几何,`+X` 分支执行一次 Z 到 X 的轴转换;运行时对象矩阵使用逆变换补偿,保证两种模式落在相同世界空间位置。
### Depth Surface 分离与厚度
`O Image Depth Plane`、`O Image Depth Cutout` 与 `O Image Depth Balloon` 使用 **Reference Depth** 作为采样深度的运算基准。
Options 中的 **Split** 范围为 `0–1`,默认 `0` 关闭分离,数值越大越容易分离。节点比较 `场景 Z 差 × Split > 原始面中心距离 × 2.5`;`0.5` 对应深度坡度阈值 `5`。场景 Z 差包含图片标定的 **Uniform Scale** 和 **Depth Scale**。
### Cutout 预设与厚度
| 创建入口 | 修改器节点组 | 默认设置 |
| --- | --- | --- |
| Flat | O Image Cutout | Balloon,Thickness 0 |
| Solid(默认) | O Image Cutout | Balloon,Thickness 1 |
| Depth Solid | O Image Depth Cutout | Balloon,Thickness 1 |
| Depth Balloon | O Image Depth Balloon | Thickness 1,Double Sided 开启 |
前两种节点组提供 **Mode**,默认显示 Balloon。两个独立输入均显示为 **Thickness**:第一个是 Balloon 的无量纲倍率,第二个是 Uniform 的距离,各自保存数值。普通 Cutout 在零厚度时输出平面,深度 Cutout 输出深度表面。全部基础网格包含 POINT 域的 `o_balloon`,Flat 可直接调整为 Solid。
深度 Cutout 的 Balloon 厚度由 `cutout_volume.py` 构造平滑中心,再由 `cutout_rounding.py` 处理圆润轮廓与凸起方向。Options 中位于 Front Inflation 前的 **Edge Round** 默认 0.2,正背面共用 `1 − smootherstep(0, max(o_balloon), o_balloon)` 衰减权重。正面向中心加 Balloon 的轮廓靠拢,背面按 Balloon 值补充饱满度。Options 中的 **Normal Smooth** 默认 50:在中心曲面上平滑并归一化法线,背面沿该方向凸起,正面按边缘权重过渡。两个边缘范围及法线影响固定为 1。
中心位置以投影正面 Z 减去 `o_balloon` 初始化,固定轮廓与切口,在内部通过一个 Blur Attribute 执行 256 次邻域平滑,边界 Weight 为 0。圆润处理前,深凹处保留至少 `0.05 × o_balloon` 的厚度。轮廓零厚度点按来源身份合并,暂存字段使用 POINT 域 `o_balloon_surface_*` 并在输出前清理。`cutout_shell.py` 让薄厚度的 Balloon 从正面沿法线向内生长,再按平滑过渡达到 Thickness 为 1 的圆润体积;大于 1 时继续沿用该体积公式。Uniform 沿正面法线偏移指定距离,同样受 Normal Smooth 控制。Thickness 为 0 时返回原深度表面。整体 Smooth 复用公共构建函数,三个 Cutout 节点组的 Smooth 默认 0,Smooth Weight 默认 1。
`cutout_inflation.py` 在邻域中拟合深度已有的结构性鼓起,Options 中 **Front Inflation** 默认 1。Balloon 令结构量为 k、Thickness 与 Front Inflation 的乘积为 a,正面增加 `o_balloon × (cbrt((k+0.25)³+(a+0.25)³−0.25³)−k−0.25)`,通过有理化形式求值以保持小厚度精度。已有 1 倍鼓起、两个参数均为 1 时,额外增加约 0.323 倍 Balloon。Uniform 直接增加 `Thickness × Front Inflation`,不受结构量或轮廓权重限制;Front Inflation 为 1 时,正面边缘和中心的增量均等于背面的厚度距离。两种模式厚度为 0 时仍返回原表面,单层侧壁直接连接正背面。
**Normal Smooth** 同时控制正面、背面与 Uniform 的法线;正面膨胀在基础法线平滑之后使用 5.12 倍迭代范围,默认 50 对应额外 256 次,保持大膨胀量下的连续方向。设置为 0 时两阶段均停止平滑。Front Inflation 为 0 时关闭正面额外鼓起。
Normal Map 勾选控制 Flat 与 Solid 的 TANGENT 法线;Depth Solid 固定生成 OBJECT 法线,Depth Balloon 固定生成 TANGENT 法线。材质读取 `o_normal_scale`:普通 Cutout 和 Depth Balloon 使用 POINT 域的轮廓适配权重;Depth Cutout 使用 FACE 域的正面标记,让背面与切口保留几何法线。该属性属于输出材质协议,随 UVMap 与 o_balloon 保留。
Options 依次排列 Cleanup Threshold、Split Threshold、Reference Depth、Edge Round、Front Inflation、Normal Smooth、Smooth Weight;各节点组仅显示适用项,Depth Balloon 的 Depth Direction 位于末尾。
### Depth Cutout 分离与厚度
Options 中的 **Split Threshold** 范围为 `0–1`,默认 `0` 关闭分离,数值越大越容易分离。节点比较 `原始 Z 差 × Uniform Scale × Split Threshold > 原始面中心距离 × 2.5`;`0.5` 对应深度坡度阈值 `5`。**Uniform Scale** 将原始深度标定到网格单位,**Depth Scale** 仅控制最终置换幅度。
```mermaid
flowchart TD
A[基础网格与深度图片] --> B[面中心采样与共享边判别]
A[基础网格与深度图片] --> D[共用 Cleanup 按原平面岛面积清理]
D --> B[面中心采样与共享边判别]
B --> C[存入面角命名属性并 Split Edges]
C --> D[Cleanup 清理拆后平面区域]
D --> E[切口顶点沿原相机射线采用所属侧深度]
C --> E[切口顶点沿原相机射线采用所属侧深度]
E --> J[固定顶点数据并投影]
J --> F[生成正背面与分段侧壁]
F --> G[按原顶点及厚度层身份连接]
J --> L[选择平滑 Balloon 或 Uniform 厚度]
L --> F[生成正背面与单层四边侧壁]
F --> G[按原顶点及正背面身份连接]
G --> H[恢复场景坐标]
H --> K[移除 o_depth_* 暂存属性]
K --> I[外层 Smooth 与方向变换]
K --> I[边缘与整体平滑及方向变换]
```
Split 关闭时使用原顶点采样,Cleanup 仍处理原平面区域。Depth Surface 的 Cleanup 在分离后、投影和厚度前执行;其他 Shape 保持原清理流程。
三个节点组在塑形前复用 Cleanup,按原平面岛的总面积清理小区域。Depth Cutout 随后执行 Split,保留分离产生的小片;Split 关闭时使用原顶点采样。
未关联选中切边的顶点使用原始 XYZ。切口顶点以 `原 XYZ × 所属侧 Z / 原 Z` 保持原相机射线,随后执行既有 Uniform Scale、Reference Depth 和 Depth Scale 投影。
厚度前固定顶点数据,使正背面和侧壁使用相同位置。连接时以原顶点编号和厚度层构造临时整数坐标,合并同一身份的副本后恢复场景坐标,保持近距离分离区域各自独立。实现位于 `cutout_depth_surface.py`,由 `build_cutout.py` 构建进共享节点资产。
厚度前固定顶点数据,使正背面和侧壁使用相同位置。连接时以原顶点编号和正背面身份构造临时整数坐标,合并同一身份的副本后恢复场景坐标,保持近距离分离区域各自独立。实现位于 `cutout_depth_surface.py`,由 `build_cutout_modifiers.py` 构建进共享节点资产。
暂存值通过 Store Named Attribute 写入保留前缀 `o_depth_`:面中心与相机采样使用 FACE,所属侧相机采样与切口标记使用 CORNER,最终相机坐标、表面位置、源顶点编号与厚度分段数使用 POINT。计算区域就近使用 Named Attribute,末尾用一个 Wildcard 模式的 Remove Named Attribute 匹配 `o_depth_*`,输出保留 UVMap 与用户属性。
暂存值通过 Store Named Attribute 写入保留前缀 `o_depth_`:面中心与相机采样使用 FACE,所属侧相机采样与切口标记使用 CORNER,最终相机坐标、表面位置与源顶点编号使用 POINT。计算区域就近使用 Named Attribute,末尾用一个 Wildcard 模式的 Remove Named Attribute 匹配 `o_depth_*`,输出保留 UVMap 与用户属性。
### 几何节点布局
全部七个几何节点组使用连续横排的几何主轴。主轴可适当宽松,支线内部紧凑,同一目的的计算聚在同一侧,内部间距明显小于与其他部分的距离;独立用途可在两侧错落展开。长算式横排,末端就近汇入主轴。Join Geometry、Menu Switch、Combine XYZ 的同级独立分支末端排成一列并对齐输出端,菜单分支按输入顺序上下排列,共享上游留在公共位置。必要的向左引用直接连接。Group Input 与 Named Attribute 就近放置,全接线的简单运算可折叠,常数和域设置保持可见。
全部五个几何节点组使用连续横排的几何主轴。主轴可适当宽松,支线内部紧凑,同一目的的计算聚在同一侧,内部间距明显小于与其他部分的距离;独立用途可在两侧错落展开。长算式横排,末端就近汇入主轴。Join Geometry、Menu Switch、Combine XYZ 的同级独立分支末端排成一列并对齐输出端,菜单分支按输入顺序上下排列,共享上游留在公共位置。必要的向左引用直接连接。Group Input 与 Named Attribute 就近放置,全接线的简单运算可折叠,常数和域设置保持可见。
`geometry_layouts.py` 组织平面、外层 Cutout 和三个 Shape 的布局,`cutout_depth_surface_layout.py` 组织 Depth Surface;`node_layout.py` 统一放置局部输入、隐藏未使用输出并检查节点边界。具体规则见 [AGENTS.md](../../AGENTS.md)。布局验收包含实际节点编辑器预览,以及重排前后的运算、默认值、实际连接和几何结果比较。
`geometry_layouts.py` 组织平面资产布局,`cutout_shape_layouts.py` 和 `cutout_depth_surface_layout.py` 组织 Cutout 的局部计算阶段;`cutout_layout.py` 将阶段布局放入三个修改器,`node_layout.py` 验证节点边界与同级输入对齐。具体规则见 [AGENTS.md](../../AGENTS.md)。布局验收包含实际节点编辑器预览及几何求值。
## 修改节点组