Add geometry nodes asset and validation script

- Implemented a new geometry nodes asset in `build_geometry_nodes_asset.py` to handle mesh refinement and topology fixing.
- Created a validation script in `validate_geometry_nodes_asset.py` to ensure the integrity and functionality of the geometry node group.
- Added input handling for various parameters including resolution, iterations, and smoothing options.
- Included checks for node group structure and attributes to validate the geometry processing pipeline.
This commit is contained in:
2026-08-11 13:23:13 +08:00
parent fc27c23fd1
commit 07d836d9ad
15 changed files with 2408 additions and 68 deletions

View File

@@ -81,7 +81,7 @@
## Image Empty 去背景
1. 确认 `Host > Models` 中的 `BEN2 Base` 已就绪;首次安装 Runtime 时会默认下载。
2. 在 3D View 选中 Image Empty,右键选择 `Remove Background`。
2. 在 3D View 选中 Image Empty,右键打开 `SnapForm` 子菜单并选择 `Remove Background`。
3. 完成后以 Fake User 保留原 Image datablock,新建并 Pack 一张透明 PNG 到当前 `.blend`,然后只把
当前 Empty 的 `data` 换成新图;Empty 的 Transform、显示尺寸、Offset 及其他设置保持不变。
4. 新 Image 使用原图去掉格式后再追加 `.foreground` 的名称。例如 `img.png` 生成
@@ -103,7 +103,7 @@ Cyclic 沿用原 Empty 的设置。序列帧无法被 Blender 整体 Pack,因
## Image Empty 转深度面片
1. 在 3D View 选中 `Object Type = Empty`、`Display As = Image` 的对象。
2. 右键选择 `Convert to Depth Plane`,通过 `Depth from` 选择深度来源:
2. 右键打开 `SnapForm` 子菜单并选择 `Convert to Depth Plane`,通过 `Depth from` 选择深度来源:
- `AI Generated`:显示 Model、Use Ray Pose 和 Resolution Scale。实际 Process Res 为图片长边像素数
乘以 Resolution Scale;范围为 `0.1–1.0`,默认 `1.0`。计算后的 Process Res 会直接显示在
`Resolution Scale (… px)` 标签中。
@@ -144,6 +144,58 @@ Cyclic 沿用原 Empty 的设置。序列帧无法被 Blender 整体 Pack,因
`8×12` 个面。随后的 Simple Subdivision 修改器使用原生名称,Viewport Levels 固定为
`1`,Render Levels 固定为 `2`,不再随 Resolution Scale 或 Subdivision 动态变化。
## Image Empty 转透视网格
1. 在 3D View 选中仅包含一帧的 Image Empty,右键打开 `SnapForm` 子菜单并选择
`Convert to Mesh`。该入口独立于
`Convert to Depth Plane`,当前不处理视频或序列帧。
2. Host 请求 DA3 的 `depth`、`conf` 与 `intrinsics`,同时固定运行 BEN2 取得前景 alpha。Depth 不做
smoothing,也不在 Host 中剔面或减面;Host 只反投影完整有效拓扑,并计算 confidence percentile、
camera-space edge stretch 与 background 标记。
3. Blender 把勾选 `Usage > Modifier` 的 `O Refine DA3 Mesh` 节点组直接作为 Geometry Nodes 修改器
添加到 Mesh,不另设修改器名称。节点组内没有子节点组,依次完成:
- 修改器顶层依次显示 `Resolution`、`Relax Iterations`、`Smooth`;默认展开的 `Culling` Panel
包含 `Confidence`、`Stretch`、`Background`。`Stretch = 100%` 明确选择全部面,剔面后同时删除
Face Count 为零的孤立顶点;
- 每轮 Remesh Iteration 依次执行 Connected Merge、循环拓扑修复与一次 Smooth,使新拓扑在进入下一轮
Merge 前先稳定;拓扑修复删除非流形面、单面拓扑和小面积 mesh islands;
- 默认 `Resolution` 为原始有效三角边长中位数乘以 `sqrt(10) * 2`。`sqrt(10)` 来自原先 90% 面数缩减
的二维边距估计,再乘以 2 为迭代合并留出更平滑、稳定的默认尺度;节点内部 Connected Merge 的
Distance 为 `Resolution * 0.5`;
- Smooth 采用 `O Smooth` 的边界检测和模糊法线权重,固定开放边界与薄面,只保留一个
`Smooth` 程度系数;节点组不再额外执行 Flip Faces;
- 从修改前的原始表面以 nearest-surface 重新采样 `UVMap`,最终明确写为 Corner 域 `2D Vector`。
4. 节点组随插件放在 `O_SnapForm.blend`。Blender 4.5 首次 Append 后复用同一 datablock;
Blender 5.0 以 linked ID 载入后调用 Pack,后续 Mesh 继续复用。插件不会为每个 Mesh 新建节点组,
也不会在添加后重命名 Geometry Nodes 修改器。节点组只启用 `Usage > Modifier`,不 Mark as Asset;
修改器关闭 `show_group_selector`。`Fix Topology` 位于默认折叠的 `Options` Panel。
节点图按 Culling、Remesh、Topology Fix、Island Cleanup 与 UV 分区摆放;各区就近使用独立的
Group Input,并隐藏没有连线的接口,避免跨越整个节点图的输入连线。
5. Host 准备过程固定显示 6 个编号阶段:验证 DA3 数据、反投影、准备 DA3/BEN2 attributes、构建原始
拓扑、投影 UV/attributes、写出网格。状态栏显示 `Post-processing n/6: ...`。
6. Host 在 job 根目录写出 `mesh.npz` 与 `texture.png`。NPZ 保存 camera-space `vertices`、
`faces`、`uv`、`intrinsics`、`image_size` 与有效深度中位数 `reference_depth`。Blender 读取这些
数据后直接创建 Mesh 与原图材质,不需要 Open3D 或 OpenCV 进入 Blender Python 环境。
Mesh 保留下列结构化 attributes:
- 点域:`o_depth`、`o_confidence`、`o_confidence_percentile`、`o_background`;
- 面域:`o_face_confidence`、`o_edge_stretch`、`o_background_face`。
7. 网格以 `reference_depth` 截面匹配 Image Empty 的显示矩形:该截面的投影四角与 Empty 的可见
边界重合,主点同时匹配 Empty Offset。网格对象直接沿用源 Empty 的 `matrix_world`,因此位置、旋转、
缩放及父级关系产生的世界变换保持一致。更近的顶点沿 Empty 局部 `+Z` 方向凸出,三角面正面朝向
观察相机,启用 Backface Culling 时可从正面看到。
8. 转换对话框不再提供后处理参数,只保留模型设置、`Create Matching Camera`、`Unshaded` 与
`Delete Original`。`Unshaded` 使用与 Depth Plane 相同的 Emission/Transparent 材质路径;普通材质的
Bump Distance 按 `abs(object.scale.z) × camera scale_z` 缩放,与透视网格实际深度尺度一致。
相机默认关闭;开启后会在 Empty 局部 `+Z` 侧创建一台朝向局部 `-Z` 的透视相机,并成为生成 Mesh
的子级,使二者移动时保持投影关系。开启 `Delete Original` 时,网格成功创建后删除源 Empty。
网格、材质与相机会归入同一个 `Convert to Mesh` Undo 步骤。
Debug 的 Textured Mesh GLB 会把 depth、confidence 与 confidence percentile 写入自定义顶点
attributes。其他 DA3 Debug 三维输出会同时写出未压缩的 `prediction.attributes.npz`,保存完整
depth、confidence、intrinsics、extrinsics 与 confidence percentile。当前 trimesh 的 glTF 点图元
导出器只写 Position/Color,无法可靠把任意 attribute 嵌入点云 GLB,因此点云先以 companion NPZ
保留完整结构;后续若改为 SnapForm 自有 glTF writer,可再把这些字段直接嵌入点图元。
所有任务使用统一的状态栏进度显示。变化中的阶段说明显示在右侧的进度条内部,取消按钮
位于进度条右侧。状态字段支持阶段、当前操作与预计剩余秒数,界面统一组合为紧凑文案并保证
进度单调递增。任务进程与 Host 请求在后台启动,按钮点击后立即进入进度状态。Image Depth 的阶段包括 Runtime 启动、输入准备、模型加载、深度估算、缓存
@@ -234,6 +286,7 @@ Blender 为 Packed Image 或序列帧生成的输入副本也归档到对应 job
- `download-model`
- `export-reconstruction`
- `generate-depth-plane`
- `generate-image-mesh`
- `remove-background`
- `remove-image-background`
- `generate-original-depth-plane`