- 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.
9.0 KiB
节点资产
生产节点组由脚本构建到 src/anyimage/assets/O_AnyImage.blend;运行时只加载,不创建节点组。
构建
在项目根目录执行:
uv run build_node
脚本依次构建资产、运行三项 Blender 验证和完整测试,任一步失败即退出。
脚本按 --blender、环境变量 BLENDER_BIN、项目 .env、PATH 的顺序查找 Blender。无法自动找到时,在项目根目录的 .env 中配置:
BLENDER_BIN="/absolute/path/to/blender"
.env 已被 Git 忽略。临时指定路径或跳过 Python 测试:
uv run build_node --blender "/path/to/blender"
uv run build_node --skip-tests
资产清单
| 节点组 | 构建模块 |
|---|---|
O Mesh Plane |
build_mesh_plane.py |
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、O Image Depth Cutout、O Image Depth Balloon |
build_cutout_modifiers.py |
构建从空 Factory 文件生成全部节点组,关闭 .blend1 备份,并覆盖唯一发布资产。
Depth Cutout 的布局由 cutout_depth_surface_layout.py 编排:Split 属性采样位于主链上方,原始几何旁路沿下方的 Reroute 通道汇入 Switch;长距离投影引用共用分段干线,并在 Uniform 厚度与零厚度输出附近分叉。几何统计支线就近放置在其使用区域。
三个 Cutout 节点组直接作为修改器使用,统一接收局部 XY 平面,以 -Z 表示向图片内部的方向。每组在塑形与平滑后处理 Inward Axis:默认 -Z 直接输出原生几何,+X 分支执行一次 Z 到 X 的轴转换;运行时对象矩阵使用逆变换补偿,保证两种模式落在相同世界空间位置。
O Image Depth Plane、O Image Depth Cutout 与 O Image Depth Balloon 使用 Reference Depth 作为采样深度的运算基准。
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 仅控制最终置换幅度。
flowchart TD
A[基础网格与深度图片] --> D[共用 Cleanup 按原平面岛面积清理]
D --> B[面中心采样与共享边判别]
B --> C[存入面角命名属性并 Split Edges]
C --> E[切口顶点沿原相机射线采用所属侧深度]
E --> J[固定顶点数据并投影]
J --> L[选择平滑 Balloon 或 Uniform 厚度]
L --> F[生成正背面与单层四边侧壁]
F --> G[按原顶点及正背面身份连接]
G --> H[恢复场景坐标]
H --> K[移除 o_depth_* 暂存属性]
K --> I[边缘与整体平滑及方向变换]
三个节点组在塑形前复用 Cleanup,按原平面岛的总面积清理小区域。Depth Cutout 随后执行 Split,保留分离产生的小片;Split 关闭时使用原顶点采样。
未关联选中切边的顶点使用原始 XYZ。切口顶点以 原 XYZ × 所属侧 Z / 原 Z 保持原相机射线,随后执行既有 Uniform Scale、Reference Depth 和 Depth Scale 投影。
厚度前固定顶点数据,使正背面和侧壁使用相同位置。连接时以原顶点编号和正背面身份构造临时整数坐标,合并同一身份的副本后恢复场景坐标,保持近距离分离区域各自独立。实现位于 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 与用户属性。
几何节点布局
全部五个几何节点组使用连续横排的几何主轴。主轴可适当宽松,支线内部紧凑,同一目的的计算聚在同一侧,内部间距明显小于与其他部分的距离;独立用途可在两侧错落展开。长算式横排,末端就近汇入主轴。Join Geometry、Menu Switch、Combine XYZ 的同级独立分支末端排成一列并对齐输出端,菜单分支按输入顺序上下排列,共享上游留在公共位置。必要的向左引用直接连接。Group Input 与 Named Attribute 就近放置,全接线的简单运算可折叠,常数和域设置保持可见。
geometry_layouts.py 组织平面资产布局,cutout_shape_layouts.py 和 cutout_depth_surface_layout.py 组织 Cutout 的局部计算阶段;cutout_layout.py 将阶段布局放入三个修改器,node_layout.py 验证节点边界与同级输入对齐。具体规则见 AGENTS.md。布局验收包含实际节点编辑器预览及几何求值。
修改节点组
- 修改
tools/node_assets/build_*.py; - 更新对应验证;
- 运行一键构建脚本;
- 搜索并清理旧名称、接口和路径;
- 检查
.blend、代码、测试和文档差异。
接口、节点、连线、默认值或布局变化时必须重建。只修改运行时 Python、Markdown 或打包逻辑时无需重建。
O_AnyImage.blend1 等备份不应提交或打包。