Add tools and tests for AnyImage model management and documentation
- Implement sync_models.py for preparing and uploading ONNX artifacts. - Create build_node.py for building and validating Blender scripts. - Add docs.py for building and previewing documentation with Mike or MkDocs. - Introduce model_exports.py for exporting PyTorch models to ONNX format. - Develop pack.py for packaging the project with dependencies for different platforms. - Add test_sync_models.py to validate sync_models functionality. - Add test_tool_commands.py to ensure repository tools have correct command scripts. - Initialize tools package with __init__.py.
This commit is contained in:
@@ -21,11 +21,7 @@ flowchart TD
|
||||
Ready --> Build --> Create
|
||||
```
|
||||
|
||||
Surface 与 Balloon 可以完全在 Blender 中完成;启用 Fit to Foreground、生成 Depth Shape 或 Normal Map 时,中间会经过一次 Server Job。
|
||||
|
||||
两条路径的区别只在中间是否需要 Server 产物。回到 Blender 后,它们都使用最终的 `RegionMask` 构建同一种 `BaseShape`,再由同一入口创建对象。Server 不创建 Blender Mesh,也不访问 `bpy`。
|
||||
|
||||
下文中的 Blender 侧文件相对 `src/anyimage/operators/cutout_tool/`,Server 侧文件相对 `src/anyimage/server/`。
|
||||
Surface 与 Balloon 直接使用 `RegionMask` 构建 `BaseShape`;Fit to Foreground、Depth Shape 和 Normal Map 先通过 Server Job 生成所需产物。
|
||||
|
||||
## 节点说明
|
||||
|
||||
@@ -33,13 +29,13 @@ Surface 与 Balloon 可以完全在 Blender 中完成;启用 Fit to Foreground
|
||||
|
||||
Cutout 工具由 `__init__.py` 注册,交互从 `main.py` 中的 `SelectCutoutRegion` 开始。它接收 Lasso 或双击整图手势,把图片空间路径保存为 `RegionPath`,然后调用 `interaction.py` 打开 Shape 饼菜单。
|
||||
|
||||
`interaction.py` 在这里完成 Region 有效性检查、读取三个工具选项,并根据 **Mesh Sampling Spacing** 换算期望网格分辨率;它不定义 Operator。菜单中的 Surface、Balloon、Depth Balloon 和 Depth Surface,以及它们对应的节点分支索引,统一来自 `shape.py`。
|
||||
`interaction.py` 完成 Region 有效性检查、读取三个工具选项,并根据 **Mesh Sampling Spacing** 换算期望网格分辨率。菜单中的 Surface、Balloon、Depth Balloon 和 Depth Surface,以及它们对应的节点分支索引,统一来自 `shape.py`。
|
||||
|
||||
### 栅格化 Region
|
||||
|
||||
用户选定 Shape 后,`main.py` 中的 `CutoutRegionToShape` 接过主线。它使用 `operators/common/image_region.py` 把 `RegionPath` 栅格化为 `RegionMask`:`values` 保存局部像素权重,`bounds` 保存它在源图中的位置。套索外和源图透明区域不会进入最终 Region。
|
||||
用户选定 Shape 后,`main.py` 中的 `CutoutRegionToShape` 接过主线。它使用 `common/image_region.py` 把 `RegionPath` 栅格化为 `RegionMask`:`values` 保存局部像素权重,`bounds` 保存它在源图中的位置。套索外和源图透明区域不会进入最终 Region。
|
||||
|
||||
此时也会应用 **Maximum Cutout Mesh Resolution**。它限制裁切区域的最长采样边,对四种 Shape 一视同仁,与是否使用 AI 无关。
|
||||
此时也会应用 **Maximum Cutout Mesh Resolution**,统一限制四种 Shape 裁切区域的最长采样边。
|
||||
|
||||
### 需要后台生成数据?
|
||||
|
||||
@@ -49,23 +45,23 @@ Cutout 工具由 `__init__.py` 注册,交互从 `main.py` 中的 `SelectCutout
|
||||
- 选择 Depth Balloon 或 Depth Surface;
|
||||
- 开启 **Generate Normal Map**。
|
||||
|
||||
没有开启两个 AI 选项的 Surface 和 Balloon 会直接沿用本地 `RegionMask`。
|
||||
Surface 和 Balloon 的本地路径直接沿用 `RegionMask`。
|
||||
|
||||
### 执行 Fit to Foreground,生成 Depth / Normal 产物
|
||||
|
||||
`main.py` 把请求提交给 `server/jobs/cutout.py`。这个 Job 只生成本次 Shape 实际需要的产物:
|
||||
`main.py` 把请求提交给 `server/jobs/cutout.py`,生成本次 Shape 需要的产物:
|
||||
|
||||
- **Fit to Foreground** 调用 `server/region/refine_region.py`,写出收紧后的 `region.png` 和 `region_bounds.json`;
|
||||
- 需要 Vector Depth 时写出相机空间 XYZ 组成的 `vector-depth.exr`,需要 Z Depth 时写出 `z-depth.exr`,两者都配套 `depth.json`;
|
||||
- **Generate Normal Map** 根据既定空间写出 `tangent-normal.png` 或 `object-normal.png`。
|
||||
|
||||
Depth 与 Normal Map 同时需要时,共享同一次 MoGe-2 Prediction。Prediction 只存在于 Server 内存,Job 目录只保留 Blender 可直接加载的图片和 JSON。Depth Surface 的 Normal Map 编码为 Cutout 对象空间,其正面是对象局部 `-X`;其余 Shape 使用 Tangent Space。Normal Space 由 `main.normal_mode_for_shape()` 根据 Shape 决定,不是单独的用户选项。
|
||||
Depth 与 Normal Map 共享同一次 MoGe-2 Prediction。Depth Surface 的 Normal Map 编码为 Cutout 对象空间,其正面是对象局部 `-X`;其余 Shape 使用 Tangent Space。`main.normal_mode_for_shape()` 根据 Shape 确定 Normal Space。
|
||||
|
||||
**Maximum AI Input Size** 只限制 BEN2 和 MoGe-2 看到的分析图长边。它不改变网格密度,也不降低最终颜色图分辨率。DA3 不进入这条正式路径,只保留 Debug 功能。
|
||||
**Maximum AI Input Size** 约束 BEN2 和 MoGe-2 的分析图长边;网格密度使用 **Maximum Cutout Mesh Resolution**,最终颜色图使用源图裁切分辨率。
|
||||
|
||||
### 构建 BaseShape
|
||||
|
||||
Job 完成后,`main.py` 在 Blender 主线程读取可选的 RegionMask,直接加载并 Pack Depth 与 Normal 图片;本地路径则直接使用已有数据。两者最终都进入 `main.create_cutout_shape()`,再调用 `geometry.py` 中的 `build_base_shape()`:
|
||||
Job 完成后,`main.py` 在 Blender 主线程读取可选的 RegionMask,加载并 Pack Depth 与 Normal 图片。`main.create_cutout_shape()` 调用 `geometry.py` 中的 `build_base_shape()`:
|
||||
|
||||
1. 从最终 `RegionMask` 提取外轮廓和孔洞;
|
||||
2. 按 Mesh Sampling Spacing 生成轮廓与内部采样点;
|
||||
@@ -77,7 +73,7 @@ Job 完成后,`main.py` 在 Blender 主线程读取可选的 RegionMask,直
|
||||
|
||||
### 创建 Blender 对象
|
||||
|
||||
`main.create_cutout_shape()` 把 `BaseShape` 和可选产物交给 `object.py` 的 `create_shape_object()`。这里创建裁切后的 Color Image、Material、Mesh Object,并挂上统一的 `O Image Cutout` Modifier。材质通过 `operators/common/mesh_result.py` 创建,Cutout 使用 `1.2` 的 IOR。Color Image 是按最终 Region 包围矩形裁切的源图 RGBA;RegionMask 不写入颜色图 Alpha,源图原有 Alpha 会原样保留。
|
||||
`main.create_cutout_shape()` 把 `BaseShape` 和可选产物交给 `object.py` 的 `create_shape_object()`。这里创建裁切后的 Color Image、Material、Mesh Object,并挂上统一的 `O Image Cutout` Modifier。材质通过 `common/object.py` 创建,Cutout 使用 `1.2` 的 IOR。Color Image 按最终 Region 包围矩形裁切源图并保留 RGBA。
|
||||
|
||||
| Shape | Modifier 如何形成结果 | 必需后台产物 |
|
||||
| --- | --- | --- |
|
||||
@@ -88,6 +84,6 @@ Job 完成后,`main.py` 在 Blender 主线程读取可选的 RegionMask,直
|
||||
|
||||
Depth Shape 的 Base Plane Depth,以及 Depth Balloon 的 Direction,都由 `object.py` 调用 `geometry.py` 的标定函数,根据最终 Region Alpha 计算。透明像素达到 `5%` 时使用有效 Region 自适应标定,否则使用稳定的固定基准。
|
||||
|
||||
Normal Map 是材质细节,不改变上述四种 Shape 的几何分类。关闭时材质使用几何法线;开启时,`object.py` 把生成的图片和已经确定的 Normal Space 交给材质节点。最后 `main.py` 提交 Undo,整条 Cutout 流程结束。
|
||||
Normal Map 关闭时材质使用几何法线;开启时,`object.py` 把生成的图片和已经确定的 Normal Space 交给材质节点。最后 `main.py` 提交 Undo,整条 Cutout 流程结束。
|
||||
|
||||
Balloon 与 Depth Balloon 的材质会创建 Geometry Attribute 节点,把 `o_balloon` 的 Float 输出直接连接到 `O Image Layer` 已有的 **Normal Scale**;Surface 与 Depth Surface 不建立这条连接。
|
||||
|
||||
Reference in New Issue
Block a user