feat(cutout_tool): Implement cutout region to shape functionality
- Added interaction helpers for cutout region validation and shape menu interaction. - Created main operator for converting image regions into cutout shapes, including AI artifact generation. - Introduced object creation logic for cutout shapes, handling depth and normal textures. - Defined cutout shape identifiers and node groups for various shape types. - Implemented depth texture writing and prediction artifact generation for MoGe-2. - Developed server jobs for generating cutout artifacts, depth planes, and refining image regions. - Added region refinement logic to enhance gesture masks using BEN2.
This commit is contained in:
@@ -25,9 +25,10 @@ AnyImage 的扩展偏好设置按功能分组。Environment 区包含:
|
||||
Environment 检测后显示 Diagnostics。Depth & Normal、Remove Background、Upscale 与 Cutout 是默认展开的可折叠功能区,各自包含对应设置和模型状态。其中:
|
||||
|
||||
- **Default Upscale Model**:Upscale 使用的模型,默认是 General WDN x4v3。
|
||||
- **Maximum AI Input Size**:Upscale、Depth 与 Normal 分析输入的长边上限,默认 2048 px;只缩放分析输入,不降低颜色贴图分辨率。
|
||||
- **Maximum AI Input Size**:Upscale、Depth、Normal Map 与 Fit to Foreground 的 AI 输入长边上限,默认 2048 px;只缩放分析输入,不降低颜色贴图分辨率。
|
||||
- **Maximum Cutout Mesh Resolution**:所有 Cutout Shape 的网格采样长边上限,默认 1024,独立于 AI 输入尺寸。
|
||||
|
||||
Depth Plane 的 Depth Model 依次列出三档 MoGe-2 与两档 DA3;选择 DA3 时会提示该模型不能生成 normal。Cutout 固定使用 MoGe-2:全局选择 MoGe-2 时沿用对应档位,选择 DA3 时回退默认 MoGe-2。可选模型的 **Ready** 状态或 **Download** 按钮直接位于模型选择项下方;BEN2 等固定模型则显示在所属功能区。Cutout 区只保留 Balloon Profile。
|
||||
Depth & Normal 只列出三档 MoGe-2,Depth Plane 与 Cutout Depth / Normal Map 使用同一个显式选择,不存在生产回退。可选模型的 **Ready** 状态或 **Download** 按钮位于选择项下方;Cutout 区提供独立网格上限与 Balloon Profile。
|
||||
|
||||
如果准备把 Storage Root 放到其他磁盘,建议在首次安装 Environment 之前修改。更换目录后,旧目录中的环境和模型不会自动移动。
|
||||
|
||||
@@ -54,7 +55,7 @@ Depth Plane 的 Depth Model 依次列出三档 MoGe-2 与两档 DA3;选择 DA3
|
||||
- AnyImage 扩展偏好设置中的 MoGe-2 ViT-S Normal、BEN2 Base 和 Real-ESRGAN General WDN x4v3 显示 **Ready**。
|
||||
- 选中 Image Empty 后,右键菜单底部显示 **AI Environment Settings…**。
|
||||
|
||||
**Convert to Depth Plane**、**Remove Background** 和 **Upscale** 在 AI 未就绪时仍可点击,点击后会根据状态转入 **Set Up AI Environment…** 或 **Download Required Models…**。普通 Plane、Image 编辑,以及未启用 Refine / Normal 的 Cutout Surface 与 Balloon 不要求安装 AI Environment。
|
||||
**Convert to Depth Plane**、**Remove Background** 和 **Upscale** 在 AI 未就绪时仍可点击,点击后会根据状态转入 **Set Up AI Environment…** 或 **Download Required Models…**。普通 Plane、Image 编辑,以及未启用 **Fit to Foreground** / **Generate Normal Map** 的 Cutout Surface 与 Balloon 不要求安装 AI Environment。
|
||||
|
||||
## 下一步
|
||||
|
||||
|
||||
@@ -21,36 +21,38 @@ Cutout 用套索从一张 Image Empty 中选择区域,再生成 Surface、Ball
|
||||
|
||||
四种结果都保留源 Image Empty,并在同一位置创建新网格。它们共享选区轮廓、UV、材质和基础三角网格,因此可以从同一张图多次生成不同 Shape 进行比较。
|
||||
|
||||
无论是否启用 Refine Selection,套索超出图片的部分都不会生成网格,源图中 `Alpha <= 0.1` 的像素也始终从 Region 中排除。双击使用完整画面时同样只为 `Alpha > 0.1` 的 Region 生成网格。
|
||||
无论是否启用 Fit to Foreground,套索超出图片的部分都不会生成网格,源图中 `Alpha <= 0.1` 的像素也始终从 Region 中排除。双击使用完整画面时同样只为 `Alpha > 0.1` 的 Region 生成网格。
|
||||
|
||||
## 工具设置
|
||||
|
||||
- **Point Spacing**:相邻网格点大约对应多少源图像素。数值越小,网格越密,轮廓和变形细节越多。
|
||||
- **Normal**:使用 MoGe-2 生成法线贴图。默认关闭。
|
||||
- **Refine Selection**:用 BEN2 把几何套索收紧到其中的前景内容。默认关闭。
|
||||
选项按执行意图排列:
|
||||
|
||||
Surface 与 Balloon 在 Normal、Refine 都关闭时完全在 Blender 中生成,不需要 AI Environment。开启任一 AI 选项,或选择 Depth Shape 时,会提交后台任务。
|
||||
- **Fit to Foreground**:用 BEN2 把几何套索贴合到其中的前景主体,默认关闭。
|
||||
- **Mesh Sampling Spacing**:相邻网格采样点大约对应多少源图像素;数值越小,三角网格越密。
|
||||
- **Generate Normal Map**:是否使用 MoGe-2 生成法线贴图,默认关闭;空间由 Shape 自动决定。
|
||||
|
||||
Point Spacing 先按完整源图换算基础密度;选区裁切后的长边若超过全局 **Maximum AI Input Size**,网格密度会按分析图的等比缩放比例降低。颜色贴图始终保留原裁切分辨率,不会使用限制后的临时分析图。建议先用默认 `32` 观察形状;轮廓需要更细时再逐步减小。
|
||||
Surface 与 Balloon 在 **Generate Normal Map**、**Fit to Foreground** 都关闭时完全在 Blender 中生成,不需要 AI Environment。开启任一 AI 选项,或选择 Depth Shape 时,会提交后台任务。
|
||||
|
||||
Mesh Sampling Spacing 先按完整源图换算期望密度,再由 Cutout 区的 **Maximum Cutout Mesh Resolution** 限制裁切区域的最长采样边。这个网格上限对 Surface、Balloon 与 Depth Shape 完全相同。**Maximum AI Input Size** 只限制 Fit to Foreground、Depth 和 Normal Map 的模型分析图;颜色贴图始终保留原裁切分辨率。建议先用默认 `32` 观察形状,轮廓需要更细时再逐步减小。
|
||||
|
||||
## 调整修改器
|
||||
|
||||
四个 Shape 都使用同一个 `O Image Cutout` Geometry Nodes 修改器。创建时 Shape 菜单已经设为饼菜单所选类型;切换 Shape 后,Blender 只显示该类型实际使用的输入。常用参数包括:
|
||||
|
||||
- **Thickness**:Surface / Depth Surface 使用场景距离;Balloon / Depth Balloon 使用鼓起高度倍率。
|
||||
- **Cleanup**:碎岛面积阈值;创建时根据 Point Spacing 和图片平面尺寸自动写入。为便于在修改器中调节,显示值放大了 `100` 倍,节点内部会还原为实际面积,因此这次显示缩放不会改变默认清理效果。
|
||||
- **Cleanup**:碎岛面积阈值;创建时根据 Mesh Sampling Spacing 和图片平面尺寸自动写入。为便于在修改器中调节,显示值放大了 `100` 倍,节点内部会还原为实际面积,因此这次显示缩放不会改变默认清理效果。
|
||||
- **Smooth Iterations**:位于外层,控制平滑次数,默认 `0`;**Smooth** 位于 Options 中,控制每次平滑的混合强度。四种 Shape 都可使用。
|
||||
- **Depth Scale**:Depth Shape 的深度强度;`0` 回到基础平面或 Balloon。
|
||||
|
||||
两个 Depth Shape 共用 **Base Plane Depth**;Depth Balloon 还提供 **Depth Direction**。生成前会检查最终 Region 输入的 Alpha:`Alpha < 0.1` 的像素达到 `5%` 时,根据有效 Region 自适应 Base Plane Depth,并为 Depth Balloon 拟合 Direction;不足 `5%` 时使用稳定的固定基准。这个判断不依赖双击全图或 Refine Selection。插件自动写入的 Depth Image 与 Uniform Scale 位于折叠的 Data 面板,一般无需手动修改。
|
||||
两个 Depth Shape 共用 **Base Plane Depth**;Depth Balloon 还提供 **Depth Direction**。生成前会检查最终 Region 输入的 Alpha:`Alpha < 0.1` 的像素达到 `5%` 时,根据有效 Region 自适应 Base Plane Depth,并为 Depth Balloon 拟合 Direction;不足 `5%` 时使用稳定的固定基准。这个判断不依赖双击全图或 Fit to Foreground。插件自动写入的 Depth Image 与 Uniform Scale 位于折叠的 Data 面板,一般无需手动修改。
|
||||
|
||||
Balloon 的轮廓高度算法由扩展 Preferences 中的 **Balloon Profile** 控制:Poisson 更平滑,Teddy 更强调轮廓骨架。修改默认值只影响之后创建的 Shape。
|
||||
|
||||
## Refine 与 Normal
|
||||
## Fit to Foreground 与 Normal Map
|
||||
|
||||
Refine Selection 只在“套索与源图可见 Alpha 的交集”内收紧最终 Region,不把 AI 生成的颜色写回原图。材质继续使用当前 Image Empty 的源颜色和原 Alpha。
|
||||
Fit to Foreground 只在“套索与源图可见 Alpha 的交集”内收紧最终 Region,不把 AI 生成的颜色写回原图。材质使用按最终 Region 包围矩形裁切的当前 Image Empty 源图,保留源颜色和原 Alpha,不把 RegionMask 写入 Alpha。
|
||||
|
||||
Normal 设为 **None** 时使用几何法线;**Tangent** 把 MoGe-2 结果作为基于完整图片平面的浮雕细节,**Object** 则直接编码到 Cutout 对象局部轴。两种模式都不根据 Geometry Nodes 的成品网格再次烘焙。Normal 保持模型分析分辨率,Color Image 仍保留原始裁切分辨率;Depth 与 Normal 同时需要时共享同一次 Prediction,不会重复运行模型。
|
||||
Normal Map 关闭时使用几何法线。开启后,Depth Surface 自动使用 Object Space,把模型法线编码到 Cutout 对象局部轴;Surface、Balloon 与 Depth Balloon 自动使用 Tangent Space,作为相对图片平面的浮雕细节。用户不直接选择 Normal Space,两种路径都不根据 Geometry Nodes 的成品网格再次烘焙。Normal Map 保持模型分析分辨率,Color Image 仍保留原始裁切分辨率;Depth 与 Normal Map 同时需要时共享同一次 Prediction,不会重复运行模型。
|
||||
|
||||
## 当前范围
|
||||
|
||||
|
||||
@@ -16,12 +16,6 @@ Depth Plane 将一张静态图片转换为带深度位移的网格,适合快
|
||||
|
||||
默认推荐。MoGe-2 估算尺度一致的深度与相机信息,使用 **MoGe Resolution Level** 控制处理精度。第一次使用建议保持 `5`。
|
||||
|
||||
### DA3
|
||||
|
||||
DA3 提供另一种深度结果,使用 **DA3 Resolution Scale** 按原图长边计算处理尺寸。比例越高,通常会保留更多细节,也会增加耗时和内存占用。
|
||||
|
||||
切换模型后,如果对应文件尚未下载,先在同一设置区点击 **Download**。
|
||||
|
||||
## 调整结果
|
||||
|
||||
生成对象使用运行时创建的 `O Image Depth Plane` Geometry Nodes 修改器:
|
||||
|
||||
@@ -39,7 +39,7 @@ Environment 或默认模型缺失不会让四个 AI 功能变灰;点击功能
|
||||
|
||||
## Cutout Depth Surface 边缘破碎或细节太多
|
||||
|
||||
先增大 **Point Spacing** 降低基础网格密度,再调整 **Cleanup** 清理小块,并用 **Smooth** 稳定表面。必要时降低模型分辨率。
|
||||
先增大 **Mesh Sampling Spacing** 降低基础网格密度,再调整 **Cleanup** 清理小块,并用 **Smooth** 稳定表面。必要时降低模型分辨率。
|
||||
|
||||
## 动画面片不播放
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ Image Box、Lasso、Line、Polyline 与 Perspective 直接编辑静态 Image Emp
|
||||
| **Image Polyline** | 逐点构建精确多边形 |
|
||||
| **Image Perspective** | 将任意顺序输入的四个角矫正为矩形 |
|
||||
|
||||
在 3D Viewport 左侧工具栏长按 Image Mask 图标,可以在 Box、Lasso、Line 与 Polyline 之间切换。**Refine Selection** 只显示在 Box / Lasso;Line / Polyline 保持几何直线边界。Perspective 使用独立图标。
|
||||
在 3D Viewport 左侧工具栏长按 Image Mask 图标,可以在 Box、Lasso、Line 与 Polyline 之间切换。**Fit to Foreground** 只显示在 Box / Lasso;Line / Polyline 保持几何直线边界。Perspective 使用独立图标。
|
||||
|
||||
<div class="screenshot-placeholder" markdown>
|
||||
**截图占位:Image 工具组与 Tool Settings**
|
||||
|
||||
显示包含四个工具的 Image Mask 组、独立 Perspective,以及 Box / Lasso 的 Refine Selection。
|
||||
显示包含四个工具的 Image Mask 组、独立 Perspective,以及 Box / Lasso 的 Fit to Foreground。
|
||||
|
||||
目标文件:`images/image-tools/tool-group.png`
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@ Image Box、Lasso、Line、Polyline 与 Perspective 直接编辑静态 Image Emp
|
||||
- 关闭:保留选区内;
|
||||
- 开启:保留选区外。
|
||||
|
||||
Cutout、Box 与 Lasso 分别保存各自的 **Refine Selection** 设置;在一个工具中切换不会改变另外两个工具。启用后,BEN2 会先把几何选区收紧到其中的前景,再应用反选。例如框住一个苹果并开启反选,最终会清理苹果本身、保留其余内容。Line / Polyline 不提供 Refine,以保持直线边界和明确的裁切方向。
|
||||
Cutout、Box 与 Lasso 分别保存各自的 **Fit to Foreground** 设置;在一个工具中切换不会改变另外两个工具。启用后,BEN2 会先把几何 Region 收紧到其中的前景,再应用反选。例如框住一个苹果并开启反选,最终会清理苹果本身、保留其余内容。Line / Polyline 不提供 Fit to Foreground,以保持直线边界和明确的裁切方向。
|
||||
|
||||
结果会直接更新当前 Empty 的图片,并把画布紧裁切到最终可见 Alpha。只有一个 Image Empty 使用该图片时,工具更新原 Image;两个或更多 Image Empty 共用它时,工具为当前 Empty 创建独立结果,其他 Empty 保持不变。对象 Transform 不变,显示尺寸与 Image Offset 会更新,使剩余像素保持在原图片平面上的位置。透明区只修改 Alpha,保留源 RGB 供纹理过滤使用。未形成有效区域的单击会静默结束;有效选区没有可见像素时只显示警告,不修改图片。
|
||||
|
||||
@@ -69,7 +69,7 @@ Cutout、Box 与 Lasso 分别保存各自的 **Refine Selection** 设置;在
|
||||
|
||||
`Backspace` 返回上一步,右键或 `Esc` 取消。四点会自动排序,点击顺序不会改变输出旋转。
|
||||
|
||||
Perspective 只执行图片 Homography 与紧裁切,不做 Refine,也不尝试从当前 View 推导真实相机。结果保持源 Empty 的 Transform,并按原四边形覆盖范围近似更新显示位置与尺寸。选区完全位于图片外或没有可见像素时不会执行。
|
||||
Perspective 只执行图片 Homography 与紧裁切,不提供 Fit to Foreground,也不尝试从当前 View 推导真实相机。结果保持源 Empty 的 Transform,并按原四边形覆盖范围近似更新显示位置与尺寸。选区完全位于图片外或没有可见像素时不会执行。
|
||||
|
||||
<div class="screenshot-placeholder" markdown>
|
||||
**截图占位:Perspective 比例确认**
|
||||
|
||||
@@ -9,18 +9,18 @@ AnyImage 把运行环境、模型和任务结果放在 Blender 之外,多个 B
|
||||
- **Ready** 表示模型文件已经就绪。
|
||||
- **Download** 用于按需下载模型。
|
||||
- Depth & Normal 与 Upscale 的下载按钮位于当前模型选择项下方;切换选择后,可直接下载对应模型。
|
||||
- Depth Model 先列出三档 MoGe-2,再列出两档 DA3;DA3 不输出 normal,选择后会在设置下方提示。
|
||||
- Depth & Normal 只列出三档 MoGe-2;Depth Plane 与 Cutout 共用这个显式选择。
|
||||
- Remove Background 使用的 BEN2 固定模型显示在对应功能区;Cutout 区只包含 Balloon Profile。
|
||||
- 默认安装会准备 MoGe-2 ViT-S Normal、BEN2 Base 和 Real-ESRGAN General WDN x4v3。
|
||||
- DA3、更大的 MoGe-2,以及可选的 SAFMN Real x4、Real-ESRGAN x4plus 需要时再下载即可。
|
||||
- 更大的 MoGe-2,以及可选的 SAFMN Real x4、Real-ESRGAN x4plus 需要时再下载即可。
|
||||
- 可公开取得的 ONNX 制品使用经过大小与 SHA-256 校验的原址,并以 OmooLab R2 为镜像;不会把源码仓库名称推测成 Hugging Face 下载地址。
|
||||
- Real-ESRGAN General WDN x4v3 与 SAFMN Real x4 的上游只发布 PyTorch 权重,当前 ONNX 均从官方权重导出并仅从 R2 下载。
|
||||
|
||||
较大的模型不一定适合所有图片。建议先用默认模型完成构图,再针对细节与性能需求比较其他模型。
|
||||
|
||||
## 全局 AI 输入尺寸
|
||||
## AI 输入与 Cutout 网格尺寸
|
||||
|
||||
Environment 区的 **Maximum AI Input Size** 默认 `2048 px`,可在 `256–8192 px` 之间调整。它既是允许执行 Upscale 的当前图片长边上限,也是 Depth 与 Normal 分析输入的最大长边;Upscale 在达到上限时置灰,Depth 与 Normal 则保持宽高比缩小分析输入。颜色贴图仍使用当前图片的原始分辨率。Cutout 在完成套索裁切后再应用上限,因此整张图片很大但选区较小时不会被无谓缩小。
|
||||
Environment 区的 **Maximum AI Input Size** 默认 `2048 px`,可在 `256–8192 px` 之间调整。它是 Upscale 的可执行源图长边上限,也是 Depth、Normal Map 与 Fit to Foreground 模型分析输入的最大长边;颜色贴图仍使用原始分辨率。Cutout 区的 **Maximum Cutout Mesh Resolution** 默认 `1024`,独立限制所有 Shape 的网格采样密度,不会因为某个 Shape 是否使用 AI 而改变含义。
|
||||
## Device
|
||||
|
||||
扩展偏好设置中的 **Device** 控制 Depth Plane、Cutout 的 AI 增强、Remove Background 和 Upscale 等正式任务。
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
| --- | --- | --- | --- |
|
||||
| Clipboard Image | 剪贴板静态图 | Reference、Plane、节点或笔刷纹理 | 不需要 |
|
||||
| Convert to Plane | 单图、Movie、Sequence | 带材质的普通网格 | 不需要 |
|
||||
| Convert to Depth Plane | 静态图 | 带深度位移的整图面片 | DA3 或 MoGe-2 |
|
||||
| Convert to Depth Plane | 静态图 | 带深度位移的整图面片 | MoGe-2 |
|
||||
| Cutout | 静态图局部选区 | 四种局部 Shape | 按 Shape 与选项决定 |
|
||||
| Remove Background | 单图、Movie、Sequence | 透明图片或序列 | BEN2 |
|
||||
| Upscale | 单图、Movie、Sequence | 4× 图片或序列 | Upscale 模型 |
|
||||
| Image Mask / Perspective | 静态图 | 原位更新的裁切或矫正图 | Refine 时使用 BEN2 |
|
||||
| Image Mask / Perspective | 静态图 | 原位更新的裁切或矫正图 | Fit to Foreground 时使用 BEN2 |
|
||||
|
||||
## 普通 Plane
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
## Cutout
|
||||
|
||||
只需要图片局部,或希望按轮廓生成 Balloon / Depth Surface 时,使用工具栏中的 **Cutout**。普通 Surface 与 Balloon 可以完全在 Blender 内完成,Refine、Normal 与 Depth Shape 按需调用 AI。
|
||||
只需要图片局部,或希望按轮廓生成 Balloon / Depth Surface 时,使用工具栏中的 **Cutout**。普通 Surface 与 Balloon 可以完全在 Blender 内完成,Fit to Foreground、Generate Normal Map 与 Depth Shape 按需调用 AI。
|
||||
|
||||
[阅读 Cutout 指南](cutout.md)
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ flowchart TD
|
||||
Menu --> Runtime["注册 JobRuntime"]
|
||||
```
|
||||
|
||||
`__init__.py` 按依赖顺序注册,并在注销时逆序清理。扩展级设置统一由 `preferences.addon_preferences()` 读取;`runtime.py` 只消费 `configured_storage_root` 回调,不持有 Blender 偏好设置的定位逻辑。交互中的临时状态和 Debug 参数保存在 `Scene.anyimage_settings`。全局 `max_ai_input_size` 在 `preferences.py` 定义与读取,由 Operator 冻结到每次 Job 请求;Upscale 还用它判断当前 Image 是否允许执行。
|
||||
`__init__.py` 按依赖顺序注册,并在注销时逆序清理。扩展级设置统一由 `preferences.addon_preferences()` 读取;`runtime.py` 只消费 `configured_storage_root` 回调,不持有 Blender 偏好设置的定位逻辑。交互中的临时状态和 Debug 参数保存在 `Scene.anyimage_settings`。`max_ai_input_size` 与 `max_cutout_mesh_resolution` 都在 `preferences.py` 定义与读取:前者由 Operator 冻结到 AI Job 请求,后者在 Blender 侧统一限制所有 Cutout Shape 的网格采样密度。Upscale 还用 AI 输入上限判断当前 Image 是否允许执行。
|
||||
|
||||
## 同步与异步路径
|
||||
|
||||
无需 AI 或媒体处理的功能直接在 Blender 中完成,例如 Plane、普通 Image Mask、Perspective,以及未启用 Refine/Normal 的 Surface 和 Balloon。需要模型或独立文件处理时,功能 Operator 派生自 `JobOperatorBase`:
|
||||
无需 AI 或媒体处理的功能直接在 Blender 中完成,例如 Plane、普通 Image Mask、Perspective,以及未启用 Fit to Foreground / Generate Normal Map 的 Surface 和 Balloon。需要模型或独立文件处理时,功能 Operator 派生自 `JobOperatorBase`:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Image 数据块
|
||||
|
||||
`image_data.py` 处理 Blender `Image` 数据块及其在 Image Empty 上的使用方式,包括像素读取、动画帧、Job 输入、结果 Image 创建和 Empty 引用替换。它不处理 Viewport 手势或选区算法。
|
||||
`image_data.py` 处理 Blender `Image` 数据块及其在 Image Empty 上的使用方式,包括像素读取、动画帧、Job 输入、结果 Image 创建和 Empty 引用替换。它不处理 Viewport 手势或 Region 算法。
|
||||
|
||||
| 函数 | 职责 |
|
||||
| --- | --- |
|
||||
@@ -25,7 +25,7 @@
|
||||
| `image_data.depth_data_name()` | 生成 Depth 结果数据块文件名。 |
|
||||
| `image_data.color_data_name()` | 生成 Color 结果数据块文件名。 |
|
||||
| `image_data.load_color_result_image()` | 加载、命名、Pack 并配置 Job 的 Color 或 Sequence 结果;不修改 Empty。 |
|
||||
| `image_data.load_normal_result_image()` | 加载、命名、设为 Non-Color 并 Pack Normal 结果。 |
|
||||
| `image_data.load_normal_result_image()` | 加载、命名、设为 Non-Color 并 Pack Normal Map。 |
|
||||
| `image_data.create_pixel_result_image()` | 从本地编辑后的 RGBA 像素创建 Packed Image;不修改 Empty。 |
|
||||
| `image_data.replace_empty_image()` | 执行 Image Empty 结果替换、共享引用分流、旧数据清理、帧设置继承和可选画布对齐。 |
|
||||
| `image_data.image_empty_bounds()` | 计算 Image Empty 在对象局部坐标中的实际显示边界。 |
|
||||
@@ -39,7 +39,7 @@
|
||||
- Region 是用户在图片空间圈定的业务范围;`RegionPath` 保存路径点、反选状态和填充规则。
|
||||
- `RegionMask` 是 Region 的栅格化结果,只包含局部像素权重 `values` 和源图 `bounds`。
|
||||
- Mask 只表示二维像素权重或 Alpha 运算,不作为手势、协议或业务范围的别名。
|
||||
- Selection 只用于 Blender 对象选择和界面动作 Refine Selection,不表示中间数据。
|
||||
- Selection 只用于 Blender 对象选择;图片业务范围统一称为 Region,细化动作称为 Fit to Foreground。
|
||||
|
||||
`image_interaction.py` 处理 3D Viewport 中的点击、坐标投影、`ImageRegionGesture`、工具设置和预览绘制;`image_region.py` 负责图片空间 Region 的值、栅格化和 Alpha 裁切。前者负责用户如何圈定 Region,后者负责 Region 如何变成 Mask。
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
| `image_interaction.image_edit_poll()` | 判断当前上下文是否允许启动 Image 编辑工具。 |
|
||||
| `image_interaction.resolve_image_edit_click()` | 解析点击到 Image Empty,并保持或恢复选择状态。 |
|
||||
| `image_interaction.active_view3d_tool_id()` | 取得当前 View3D Workspace Tool ID。 |
|
||||
| `image_interaction.apply_region_settings()` | 将当前 Region 工具的 Refine 设置同步到手势 Operator。 |
|
||||
| `image_interaction.draw_region_settings()` | 绘制 Region 工具的公共 Refine 设置。 |
|
||||
| `image_interaction.apply_region_settings()` | 将当前 Region 工具的 Fit to Foreground 设置同步到手势 Operator。 |
|
||||
| `image_interaction.draw_region_settings()` | 绘制 Region 工具的公共 Fit to Foreground 设置。 |
|
||||
| `image_interaction.draw_dashed_line()` | 绘制手势或透视框虚线。 |
|
||||
| `image_interaction.draw_polygon_fill()` | 绘制手势或透视框填充预览。 |
|
||||
| `image_interaction.gesture_property()` | 声明统一的 Box、Lasso、Line 和 Polyline RNA 属性。 |
|
||||
@@ -69,16 +69,24 @@
|
||||
| `image_region.rasterize_region_path()` | 把 `RegionPath` 栅格化为 `RegionMask`,并可与源 Alpha 相交。 |
|
||||
| `image_region.crop_pixels_to_alpha()` | 按 Alpha 非零区域紧裁切 RGBA 像素。 |
|
||||
|
||||
## Mesh 结果构建
|
||||
## Depth 产物
|
||||
|
||||
`mesh_result.py` 集中 Convert to Plane 与 Cutout 共同使用的结果构建能力:读取图片几何产物、创建材质、加载节点资产、设置修改器输入,并完成结果对象替换。
|
||||
|
||||
`ImageGeometry` 表示按图片像素组织的三维点、相机内参、有效区域、参考深度和选区统计;`load_image_geometry()` 从 `image_geometry.npz` 读取并校验这组数据。
|
||||
`depth_data.py` 负责 Blender 侧共享的 Depth 文件加载和相机尺度换算;Server 已经写好 EXR,Blender 不再从点场创建第二张 Depth Image。
|
||||
|
||||
| 函数 | 职责 |
|
||||
| --- | --- |
|
||||
| `mesh_result.load_image_geometry()` | 读取并校验 `image_geometry.npz`,返回用于构建 Mesh 的 `ImageGeometry`。 |
|
||||
| `mesh_result.create_image_material()` | 从 Image Empty 创建包含颜色、位移、Normal、Alpha 和动画设置的完整材质。 |
|
||||
| `depth_data.load_depth_metadata()` | 读取并校验 `depth.json` 中的图片尺寸、相机内参与参考深度。 |
|
||||
| `depth_data.load_depth_result_image()` | 直接加载、命名、设为 Non-Color 并 Pack `vector-depth.exr` 或 `z-depth.exr`。 |
|
||||
| `depth_data.camera_depth_values()` | 从已加载 Depth Image 读取用于本地标定的 Z 与有效区。 |
|
||||
| `depth_data.depth_uniform_scale()` | 根据相机内参、参考深度和 Image Empty 范围计算统一尺度。 |
|
||||
|
||||
## Mesh 结果构建
|
||||
|
||||
`mesh_result.py` 集中 Convert to Plane 与 Cutout 共同使用的结果构建能力:创建材质、加载节点资产、设置修改器输入,并完成结果对象替换。
|
||||
|
||||
| 函数 | 职责 |
|
||||
| --- | --- |
|
||||
| `mesh_result.create_image_material()` | 从 Image Empty 创建包含颜色、位移、Normal Map、Alpha 和动画设置的完整材质。 |
|
||||
| `mesh_result.load_asset_node_group()` | 从随扩展分发的 Blend 资产加载指定 Node Group。 |
|
||||
| `mesh_result.modifier_input_identifier()` | 按接口名称解析 Geometry Nodes Modifier 输入 Identifier。 |
|
||||
| `mesh_result.set_modifier_input()` | 跨受支持 Blender RNA 形式设置 Modifier 输入。 |
|
||||
@@ -88,7 +96,7 @@
|
||||
|
||||
## AI 任务准备
|
||||
|
||||
`ai_job.py` 处理多个 AI 功能共同使用的任务准备,包括输入路径校验、Environment 与模型检查、Device 选择,以及 DA3 和 MoGe-2 请求参数组装。它不包含业务 Operator、结果导入或 Undo 操作。
|
||||
`ai_job.py` 处理多个 AI 功能共同使用的任务准备,包括输入路径校验、Environment 与模型检查、Device 选择和模型请求参数组装。DA3 参数只供 Debug Operator 使用;正式几何流程只组装 MoGe-2 参数。它不包含业务 Operator、结果导入或 Undo 操作。
|
||||
|
||||
| 函数 | 职责 |
|
||||
| --- | --- |
|
||||
@@ -98,5 +106,5 @@
|
||||
| `ai_job.require_environment()` | 要求 AnyImage AI Environment 已就绪。 |
|
||||
| `ai_job.invoke_ai_setup_if_needed()` | Environment 未就绪时启动安装交互。 |
|
||||
| `ai_job.require_model()` | 校验模型标识和下载状态,并返回模型记录。 |
|
||||
| `ai_job.da3_parameters()` | 组装 DA3 正式任务与 Debug 共用参数。 |
|
||||
| `ai_job.da3_parameters()` | 组装 `debug-da3` 参数。 |
|
||||
| `ai_job.moge2_parameters()` | 组装 MoGe-2 正式任务与 Debug 共用参数。 |
|
||||
|
||||
@@ -1,23 +1,8 @@
|
||||
# AI 环境管理
|
||||
|
||||
本页对应 `src/anyimage/operators/ai_setup.py`。该模块把环境安装、必需模型下载和模型缓存清理组织成 Blender 可调用的 Operator。
|
||||
AI 环境管理从当前安装状态出发,补齐独立运行环境和必需模型,并提供设置入口与模型缓存释放操作。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
src/anyimage/
|
||||
├── operators/ai_setup.py # 环境与模型管理入口
|
||||
├── preferences.py # 环境位置和扩展级设置
|
||||
├── properties.py # 环境状态与模型目录
|
||||
├── runtime.py # BlendJob Runtime 访问入口
|
||||
└── server/
|
||||
├── app.py # 下载 Job 注册
|
||||
├── model_catalog.py # 模型元数据
|
||||
├── model_download.py # 模型文件下载
|
||||
└── model_manager.py # 模型资源与 Session 缓存
|
||||
```
|
||||
|
||||
## 主流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -27,10 +12,31 @@ flowchart TD
|
||||
Ready -- "否" --> Environment{"运行环境是否就绪?"}
|
||||
Environment -- "否" --> Install["安装隔离 Python 环境"]
|
||||
Environment -- "是" --> Download["下载缺失的必需模型"]
|
||||
Install --> Download
|
||||
Download --> Done
|
||||
Install --> Download --> Done
|
||||
```
|
||||
|
||||
`SetupAIEnvironment` 是统一入口:首次使用时选择普通源或镜像安装隔离环境;环境已存在时,只补齐必需模型。单模型下载和必需模型批量下载都通过 Job Server 执行,因此状态、错误与进度沿用同一套 Runtime 通道。
|
||||
`SetupAIEnvironment` 是统一入口。首次使用时先安装运行环境,再下载默认模型;环境已经存在时,只补齐缺失模型。环境安装由 Blender Operator 启动,模型下载通过 Job Server 执行。
|
||||
|
||||
`OpenAIEnvironmentSettings` 将用户带到扩展首选项。`ClearModels` 清除 Runtime 中的 `model_manager` 资源,使已加载的模型 Session 释放;它不负责删除磁盘上的模型文件。
|
||||
## 节点说明
|
||||
|
||||
### 读取状态,选择下一步
|
||||
|
||||
入口位于 `src/anyimage/operators/ai_setup.py`。`SetupAIEnvironment` 通过 `properties.py` 中的 `ai_status()` 读取环境和模型状态,并根据结果结束、安装环境或调用 `DownloadRequiredModels`。对话框同时显示预计下载量和缺失模型名称。
|
||||
|
||||
`runtime.py` 提供当前 Environment 与 Server 状态;Server 正忙时不会启动新的安装流程。`OpenAIEnvironmentSettings` 也在 `ai_setup.py` 中,它只负责打开 AnyImage 的扩展首选项。
|
||||
|
||||
### 安装独立环境
|
||||
|
||||
环境尚未就绪时,`SetupAIEnvironment` 调用 Runtime 注册的安装 Operator。普通源与中国镜像使用同一条安装流程,`use_mirror` 只决定 uv、Python 和 Python 包的下载源,不改变模型来源。
|
||||
|
||||
安装完成后继续进入模型下载,不在 Blender Python 中加载 ONNX Runtime 或模型依赖。
|
||||
|
||||
### 下载模型
|
||||
|
||||
`ai_setup.py` 中的 `DownloadModel` 处理单个模型,`DownloadRequiredModels` 处理默认必需模型集合。两者先检查 Environment、Blender Online Access 和模型记录,再提交 `download-model` 或 `download-required-models` Job。
|
||||
|
||||
Job 在 `server/app.py` 注册;`server/model_catalog.py` 保存模型名称、文件和来源,`server/model_download.py` 下载并校验文件,`server/model_manager.py` 管理模型目录与已加载 Session。下载进度和错误通过同一套 BlendJob Runtime 返回 Blender。
|
||||
|
||||
### 释放模型缓存
|
||||
|
||||
`ai_setup.py` 中的 `ClearModels` 调用 `runtime.clear_resource("model_manager")`,释放 Server 中已加载的模型 Session。它不会删除磁盘上的模型文件,下次推理仍可从现有文件重新加载。
|
||||
|
||||
@@ -1,34 +1,41 @@
|
||||
# 剪贴板图片
|
||||
|
||||
剪贴板功能把操作系统中的图片转换为 Packed Blender Image,再根据当前编辑器创建对象、节点或画笔纹理。它完全运行在 Blender 进程中,不使用 Job Server。
|
||||
剪贴板图片从 `Ctrl/Cmd + V` 开始,把操作系统中的图片变成 Packed Blender Image,并放到当前编辑器支持的位置。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
operators/clipboard_image/
|
||||
├── __init__.py # Operator、原生复制优先级与快捷键
|
||||
├── clipboard.py # Windows、macOS、Linux 剪贴板读取
|
||||
└── actions.py # Image 复用、Pack 与各编辑器落点
|
||||
```
|
||||
|
||||
## 处理流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Paste["Ctrl/Cmd + V"] --> Priority{"刚执行过 Blender Copy?"}
|
||||
Priority -- "是" --> Native["交回原生 Paste"]
|
||||
Priority -- "否" --> Read["读取系统图片"]
|
||||
Read --> Image["按内容哈希复用或创建 Packed Image"]
|
||||
Read --> Image["复用或创建 Packed Image"]
|
||||
Image --> Target{"当前编辑器"}
|
||||
Target --> View["Reference / Plane"]
|
||||
Target --> Node["Image Node"]
|
||||
Target --> Paint["Brush Texture"]
|
||||
```
|
||||
|
||||
`TrackNativeCopy` 在相同快捷键下记录系统剪贴板变化标记。如果剪贴板没有在 Blender Copy 之后变化,Paste Operator 返回 `PASS_THROUGH`,让 Blender 原生对象或节点粘贴优先执行。
|
||||
整条流程运行在 Blender 进程中,不使用 Job Server。快捷键会先尊重 Blender 自己的 Copy/Paste;只有系统剪贴板出现新的图片内容时,AnyImage 才接管粘贴。
|
||||
|
||||
`clipboard.py` 封装平台差异:Windows 读取 DIB/DIBV5,macOS 与 Linux 调用平台提供的图片导出命令。模块最终都返回编码后的图片字节和扩展名,后续流程不再关心来源平台。
|
||||
## 节点说明
|
||||
|
||||
`actions.py` 以 SHA-256 标记 Packed Image,相同内容可复用已有数据块。3D View 中的 Reference 和 Plane 使用鼠标位置或视图落点;Plane 复用 `convert_to_plane/mesh_plane.py` 的基础网格与 `O Mesh Plane` 资产。Node Editor 根据树类型选择对应 Image 节点,绘制模式则为当前画笔配置 Texture。
|
||||
### 判断是否交给 Blender
|
||||
|
||||
快捷键只注册到 3D View 与 Node Editor;编辑器内部的具体支持范围由 `target_for_context()` 决定。创建成功后图片始终 Pack 到当前 `.blend`,避免依赖临时剪贴板文件。
|
||||
`operators/clipboard_image/__init__.py` 注册 `TrackNativeCopy`、`PasteClipboardImage` 和 3D View、Node Editor 快捷键。`TrackNativeCopy` 记录 Blender Copy 时的系统剪贴板变化标记;粘贴时若标记没有变化,`PasteClipboardImage` 返回 `PASS_THROUGH`,让 Blender 继续处理对象或节点粘贴。
|
||||
|
||||
同一文件随后调用 `actions.target_for_context()` 判断当前编辑器是否支持图片落点。
|
||||
|
||||
### 读取系统图片
|
||||
|
||||
`clipboard.py` 负责平台差异。Windows 读取 DIB 或 DIBV5 并补成 BMP;macOS 和 Linux 调用系统提供的图片导出命令。无论来源平台,输出都收敛为图片字节和扩展名,后续步骤不再判断操作系统。
|
||||
|
||||
### 创建或复用 Packed Image
|
||||
|
||||
`actions.py` 对图片内容计算 SHA-256。相同内容已经粘贴过时会复用现有 Packed Image,否则创建新 Image 并 Pack 到当前 `.blend`,避免依赖临时剪贴板文件。
|
||||
|
||||
### 放到当前编辑器
|
||||
|
||||
落点仍在 `actions.py` 中完成:3D View 创建 Reference 或 Plane,Node Editor 创建与当前节点树匹配的 Image 节点,绘制模式把 Image 配置为当前画笔的 Texture。鼠标位置和视图位置也在这里换算。
|
||||
|
||||
Plane 路径调用 `convert_to_plane/mesh_plane.py` 创建基础网格,并使用 `convert_to_plane/nodes.py` 提供的 `O Mesh Plane` 节点组。`clipboard_image/__init__.py` 只负责入口和快捷键,具体 Blender 数据始终由 `actions.py` 创建。
|
||||
|
||||
@@ -1,61 +1,42 @@
|
||||
# Plane 转换
|
||||
|
||||
Plane 转换包含两条路径:普通 Plane 在 Blender 内同步完成;Depth Plane 先通过 `generate-depth-plane` Job 取得深度场,再回到 Blender 构建面片。两者共享图片命名、材质与基础四边形能力,但使用不同的 Geometry Nodes。
|
||||
Plane 转换从当前 Image Empty 创建普通 Plane 或 Depth Plane:普通 Plane 同步完成,Depth Plane 先取得 MoGe-2 Z Depth 文件再回到 Blender 创建对象。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
operators/convert_to_plane/
|
||||
├── __init__.py # 对外导出
|
||||
├── conversion.py # 两个入口 Operator 与 Depth Job
|
||||
├── build.py # 颜色、深度场、材质和对象导入
|
||||
├── mesh_plane.py # 基础四边形与 O Mesh Plane 修改器
|
||||
└── nodes.py # 运行时 O Image Depth Plane 节点图
|
||||
|
||||
server/
|
||||
├── jobs/generate_depth_plane.py
|
||||
├── geometry/generate_depth.py
|
||||
├── models/da3.py
|
||||
├── models/moge2.py
|
||||
└── geometry/projection.py
|
||||
```
|
||||
|
||||
## 总体流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Empty["Image Empty"] --> Kind{"转换类型"}
|
||||
Kind -- "Plane" --> Copy["复制 Image 与材质"]
|
||||
Copy --> Quad["创建四边形 + O Mesh Plane"]
|
||||
Kind -- "Depth Plane" --> Input["准备颜色与分析输入"]
|
||||
Input --> Job["generate-depth-plane"]
|
||||
Job --> Field["image.0001 + image_geometry.npz"]
|
||||
Field --> Anchor["按 Empty 范围锚定相机点"]
|
||||
Anchor --> Depth["创建深度 Image + 材质 + 节点修改器"]
|
||||
Quad --> Replace["替换源 Empty"]
|
||||
Depth --> Replace
|
||||
Kind -- "Plane" --> Color["复制 Color Image"]
|
||||
Color --> Plane["创建 Plane Object"]
|
||||
Kind -- "Depth Plane" --> Job["generate-depth-plane-geometry"]
|
||||
Job --> Result["Color Image + z-depth.exr + depth.json"]
|
||||
Result --> Import["直接加载并 Pack Depth Image"]
|
||||
Import --> Depth["创建 Depth Plane Object"]
|
||||
```
|
||||
|
||||
## 普通 Plane
|
||||
两条路径共用 Image Empty 的显示范围、颜色材质和基础 Plane。Depth Plane 多出一次 Server Job,并由节点根据相机元数据把 Z Depth 转换为局部位移。正式流程只使用 MoGe-2;DA3 只保留 Debug 入口。
|
||||
|
||||
`ConvertToPlane` 复制当前 Image 数据,保留 Movie / Sequence 的 Image User 设置,创建与 Image Empty 显示范围一致的四边形,再加载内置 `O Mesh Plane` 节点组。原始 Mesh 始终只有一个四边形;`Subdivide`、`Thickness` 和材质赋值由修改器执行。
|
||||
## 节点说明
|
||||
|
||||
对象继承源 Empty 的 `matrix_world`。转换完成后删除源 Empty,并让新 Plane 沿用对象名称。剪贴板的 Plane 导入复用同一构建函数,因此两种入口得到一致的基础网格与修改器。
|
||||
### 选择 Plane 或 Depth Plane
|
||||
|
||||
## Depth Plane
|
||||
`operators/convert_to_plane/__init__.py` 导出注册类型,实际入口在 `conversion.py`。`ConvertToPlane` 进入本地路径,`ConvertToDepthPlane` 检查静态图片和 AI 环境后启动 `GenerateDepthPlane`。
|
||||
|
||||
`ConvertToDepthPlane` 当前只接受静态图片。深度模型和分辨率来自扩展 Preferences:MoGe-2 使用 Resolution Level,DA3 使用按原图尺寸换算并对齐到模型 Patch 的处理分辨率。
|
||||
### 创建普通 Plane
|
||||
|
||||
`GenerateDepthPlane` 把当前 Image 随模型参数提交给 `generate-depth-plane`。`jobs/generate_depth_plane.py` 负责单图协议,`geometry/generate_depth.py` 负责 AI 深度生成;Server 将模型结果统一为 `GeometryFrame`,写出包含相机点、深度、内参、有效区域和参考深度的 `image_geometry.npz`。Blender 侧通过公共 `load_image_geometry()` 读取为 `ImageGeometry`,与 Cutout 使用同一协议校验。这一步不创建网格。`max_input_size` 同时传入 Job;Server 通过 `media/resolution.py` 在模型推理前限制分析图长边,默认 `2048`。颜色输入仍按当前 Image 的未缩放分辨率复制,受限分析图不会成为材质 Color。
|
||||
`conversion.py` 先调用 `object.create_color_image()` 复制当前 Image,再由 `object.create_plane_object()` 创建对象。`object.py` 使用 `mesh_plane.py` 生成与 Image Empty 显示范围一致的基础四边形,并通过 `nodes.py` 加载 `O Mesh Plane` 修改器。
|
||||
|
||||
Blender 响应阶段执行三件事:
|
||||
Movie 或 Sequence 的 Image User 设置会保留。转换完成后,新 Plane 替换源 Empty,并沿用原对象名称。
|
||||
|
||||
1. 根据 Image Empty 的平面范围、相机内参和参考深度,把相机点等比锚定到对象局部空间。
|
||||
2. 将锚定点的局部 Z 写入 Packed 浮点 `_depth.exr` Image,并创建颜色材质。
|
||||
3. 创建基础四边形和运行时 `O Image Depth Plane` 节点组,以 UV 采样深度并移动正面。
|
||||
### 生成 Z Depth
|
||||
|
||||
Depth 节点组先复用 `O Mesh Plane` 完成细分与材质,再生成背面厚度、限制正面向内穿透,最后在 Thickness 为零时删除背面和侧面。`Depth Amount` 控制位移强度;`Depth Image` 与 `Material` 是由插件填入的内部输入。
|
||||
Depth 路径中的 `GenerateDepthPlane` 位于 `conversion.py`。它从 Preferences 读取 **Depth & Normal Model**、**MoGe Resolution Level** 和 **Maximum AI Input Size**,提交 `generate-depth-plane-geometry` Job。
|
||||
|
||||
与 Cutout 的 Depth Surface 不同,Depth Plane 只使用锚定后的 Z 高度,不在 Geometry Nodes 中重建完整相机空间 XYZ。它强调一张图上的可编辑浮雕,而不是局部透视表面。
|
||||
`server/jobs/depth_plane.py` 编排任务,`server/geometry/prediction_artifacts.py` 调用 MoGe-2,写出 `z-depth.exr` 与 `depth.json`。EXR 的 RGB 重复保存相机 Z,Alpha 保存有效区;JSON 保存图片尺寸、相机内参与参考深度。AI 输入上限只影响模型分析图,颜色副本仍保留原始分辨率。
|
||||
|
||||
颜色材质、Normal 导入和结果对象激活分别复用 `create_image_material()`、`load_normal_result_image()` 与 `finalize_object_result()`;普通 Plane 和 Depth Plane 不再各自维护对象替换步骤。
|
||||
### 创建 Depth Plane
|
||||
|
||||
Job 返回后,`object.create_depth_plane_from_result()` 直接加载并 Pack `z-depth.exr`,数据块仍由 `depth_data_name()` 命名。`depth.json` 用于计算统一尺度,`O Image Depth Plane` 根据参考深度、统一尺度和用户的 Depth Amount 把相机 Z 转换为局部位移。
|
||||
|
||||
随后 `object.py` 创建颜色材质和基础四边形,`nodes.py` 加载 `O Image Depth Plane` 修改器。`conversion.py` 最后用一个 Undo 步骤替换源 Empty。
|
||||
|
||||
@@ -1,76 +1,91 @@
|
||||
# Cutout Tool
|
||||
|
||||
Cutout 由两个核心 Operator 组成:
|
||||
Cutout 从图片上的一个 Region 开始,可按需执行 Fit to Foreground、生成 Depth 或 Normal Map,最后在 Blender 中创建带材质与 Modifier 的 Mesh Object。
|
||||
|
||||
- `SelectCutoutRegion`(`select_region.py`)把 Viewport 手势转换为图片空间 Region,并弹出 Shape 菜单。
|
||||
- `CutoutRegionToShape`(`region_to_shape.py`)准备所需数据,再构建并创建 Shape。
|
||||
|
||||
路径约定:Blender 侧文件相对 `src/anyimage/operators/cutout_tool/`,Server 侧文件相对 `src/anyimage/server/`。
|
||||
|
||||
## 执行路径
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Select["圈定 Cutout Region<br/>选择 Shape"]
|
||||
Select["圈定 Region,选择 Shape"]
|
||||
Raster["栅格化 Region"]
|
||||
Route{"需要 AI 数据?"}
|
||||
Local["使用本地 Region 数据"]
|
||||
AI["生成 Refine / Depth / Normal"]
|
||||
Route{"需要后台生成数据?"}
|
||||
Local["沿用本地 RegionMask"]
|
||||
Job["执行 Fit to Foreground,生成 Depth / Normal 产物"]
|
||||
Ready["汇总 Shape 输入"]
|
||||
Build["构建基础 Shape"]
|
||||
Build["构建 BaseShape"]
|
||||
Create["创建 Blender 对象"]
|
||||
|
||||
Select --> Raster
|
||||
Raster --> Route
|
||||
Select --> Raster --> Route
|
||||
Route -- "否" --> Local --> Ready
|
||||
Route -- "是" --> AI --> Ready
|
||||
Route -- "是" --> Job --> Ready
|
||||
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/`。
|
||||
|
||||
## 节点说明
|
||||
|
||||
### 圈定 Cutout Region
|
||||
### 圈定 Region,选择 Shape
|
||||
|
||||
`SelectCutoutRegion` 将 Lasso 路径投射到图片像素坐标,形成 `RegionPath`,然后把 Region 和用户选择的 Shape 交给 `CutoutRegionToShape`。双击图片时,Region 使用完整图片范围。
|
||||
Cutout 工具由 `__init__.py` 注册,交互从 `main.py` 中的 `SelectCutoutRegion` 开始。它接收 Lasso 或双击整图手势,把图片空间路径保存为 `RegionPath`,然后调用 `interaction.py` 打开 Shape 饼菜单。
|
||||
|
||||
`RegionPath` 定义在 `operators/common/image_region.py`,包含图片空间路径点、反选状态和填充规则。它既供 Cutout 使用,也供 Image Tool 使用。
|
||||
`interaction.py` 在这里完成 Region 有效性检查、读取三个工具选项,并根据 **Mesh Sampling Spacing** 换算期望网格分辨率;它不定义 Operator。菜单中的 Surface、Balloon、Depth Balloon 和 Depth Surface,以及它们对应的节点分支索引,统一来自 `shape.py`。
|
||||
|
||||
### 栅格化 Region
|
||||
|
||||
`CutoutRegionToShape` 把 `RegionPath` 栅格化为 `RegionMask`。`RegionMask` 只包含局部像素权重 `values` 和它在源图中的 `bounds`,后续几何、颜色裁切和 AI 输入都以它为范围。
|
||||
用户选定 Shape 后,`main.py` 中的 `CutoutRegionToShape` 接过主线。它使用 `operators/common/image_region.py` 把 `RegionPath` 栅格化为 `RegionMask`:`values` 保存局部像素权重,`bounds` 保存它在源图中的位置。套索外和源图透明区域不会进入最终 Region。
|
||||
|
||||
Surface 或 Balloon 在未启用 Refine 与 Normal 时直接使用本地 Region 数据;选择 Depth Shape,或启用 Refine、Normal 时进入 AI 路径。两条路径最终都调用 `region_to_shape()`。
|
||||
此时也会应用 **Maximum Cutout Mesh Resolution**。它限制裁切区域的最长采样边,对四种 Shape 一视同仁,与是否使用 AI 无关。
|
||||
|
||||
### 生成 AI 数据
|
||||
### 需要后台生成数据?
|
||||
|
||||
`generate-region-data` Job(`jobs/generate_region_data.py`)根据请求生成所需数据:
|
||||
只有以下情况需要提交 Job:
|
||||
|
||||
- `generate_selection()`(`region/generate_selection.py`)使用 BEN2 收紧 Region;
|
||||
- `generate_depth(..., normal_mode=...)`(`geometry/generate_depth.py`)使用 MoGe-2 生成 Depth,并可从同一次 Prediction 派生 Tangent 或 Object Normal。
|
||||
- 开启 **Fit to Foreground**;
|
||||
- 选择 Depth Balloon 或 Depth Surface;
|
||||
- 开启 **Generate Normal Map**。
|
||||
|
||||
Blender 传入的已是带 Region Alpha 的局部 RGBA。Depth 与 Normal 同时启用时只运行一次 MoGe-2,颜色贴图仍使用 Region 的原始裁切分辨率。
|
||||
没有开启两个 AI 选项的 Surface 和 Balloon 会直接沿用本地 `RegionMask`。
|
||||
|
||||
### 构建基础 Shape
|
||||
### 执行 Fit to Foreground,生成 Depth / Normal 产物
|
||||
|
||||
`region_to_shape()` 汇总 Region、Depth 和 Normal 输入,再依次执行几何构建与 Blender 数据创建。
|
||||
`main.py` 把请求提交给 `server/jobs/cutout.py`。这个 Job 只生成本次 Shape 实际需要的产物:
|
||||
|
||||
`build_base_shape()` 从 `RegionMask` 构建纯内存 `BaseShape`:先由 `region_contours.py` 提取包含外轮廓与孔洞的 `RegionContours`,再由 `triangulation.py` 按 Point Spacing 采样并约束三角化,最后使用 `balloon.py` 计算 `o_balloon`。`depth_calibration.py` 负责把 AI Depth 标定为 Blender 中使用的深度基准与方向。四种 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 决定,不是单独的用户选项。
|
||||
|
||||
**Maximum AI Input Size** 只限制 BEN2 和 MoGe-2 看到的分析图长边。它不改变网格密度,也不降低最终颜色图分辨率。DA3 不进入这条正式路径,只保留 Debug 功能。
|
||||
|
||||
### 构建 BaseShape
|
||||
|
||||
Job 完成后,`main.py` 在 Blender 主线程读取可选的 RegionMask,直接加载并 Pack Depth 与 Normal 图片;本地路径则直接使用已有数据。两者最终都进入 `main.create_cutout_shape()`,再调用 `geometry.py` 中的 `build_base_shape()`:
|
||||
|
||||
1. 从最终 `RegionMask` 提取外轮廓和孔洞;
|
||||
2. 按 Mesh Sampling Spacing 生成轮廓与内部采样点;
|
||||
3. 进行约束三角化;
|
||||
4. 计算四种 Shape 共用的 `o_balloon`;
|
||||
5. 汇总顶点、三角面、UV 和 Balloon 权重,得到内存中的 `BaseShape`。
|
||||
|
||||
`geometry.py` 还提供 Depth 标定、采样和网格尺度计算,供后面的对象创建阶段使用。
|
||||
|
||||
### 创建 Blender 对象
|
||||
|
||||
`create_shape_object()` 创建裁切后的 Color Image、Material、Mesh Object 和统一的 `O Image Cutout` Modifier。Shape 的差异由 Modifier 中对应的几何分支表达:
|
||||
`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 会原样保留。
|
||||
|
||||
| Shape | 形成方式 | Shape 自身所需 AI 数据 |
|
||||
| Shape | Modifier 如何形成结果 | 必需后台产物 |
|
||||
| --- | --- | --- |
|
||||
| Surface | 保持基础 Shape 的平面轮廓,并可增加真实厚度 | 无 |
|
||||
| Balloon | 使用 `o_balloon` 从轮廓向内部平滑鼓起 | 无 |
|
||||
| Depth Balloon | 在 Balloon 上叠加相对基准面的图片深度,并沿 Depth Direction 形成浮雕 | MoGe-2 Depth |
|
||||
| Depth Surface | 使用完整相机点 XYZ 重建带透视位移的表面,并可增加厚度 | MoGe-2 Camera Points |
|
||||
| Surface | 保持基础平面轮廓,可增加真实厚度 | 无 |
|
||||
| Balloon | 使用 `o_balloon` 从边缘向内部鼓起 | 无 |
|
||||
| Depth Balloon | 在 Balloon 上叠加相对基准面的深度 | `z-depth.exr`、`depth.json` |
|
||||
| Depth Surface | 使用相机点 XYZ 重建透视表面 | `vector-depth.exr`、`depth.json` |
|
||||
|
||||
四种 Shape 共用 Region、基础三角面、UV、材质、Cleanup 和 Smooth。Cleanup 的 UI 数值放大 `100` 倍,节点内部乘以 `0.01` 还原,因此显示尺度不会改变实际清理阈值。
|
||||
Depth Shape 的 Base Plane Depth,以及 Depth Balloon 的 Direction,都由 `object.py` 调用 `geometry.py` 的标定函数,根据最终 Region Alpha 计算。透明像素达到 `5%` 时使用有效 Region 自适应标定,否则使用稳定的固定基准。
|
||||
|
||||
### Depth 与 Normal
|
||||
|
||||
Depth Shape 根据最终 Region Alpha 选择基准:透明像素比例达到 `5%` 时从有效内容自适应计算 Base Plane Depth;不足 `5%` 时使用固定基准。Depth Balloon 还会在自适应路径中拟合 Depth Direction。
|
||||
|
||||
Normal 是材质层的浮雕细节,与四种 Shape 都可组合。None 使用几何法线;Tangent 以完整图片平面为切线基准;Object 直接编码到 Cutout 对象局部轴。Geometry Nodes 负责大轮廓和深度,Normal 负责表面细节。
|
||||
Normal Map 是材质细节,不改变上述四种 Shape 的几何分类。关闭时材质使用几何法线;开启时,`object.py` 把生成的图片和已经确定的 Normal Space 交给材质节点。最后 `main.py` 提交 Undo,整条 Cutout 流程结束。
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
# Debug Operator
|
||||
|
||||
本页对应 `src/anyimage/operators/debug.py`。这些 Operator 为开发者直接验证 DA3、MoGe-2、BEN2 和 Upscale 的 Server 接口,不参与面向用户的对象创建流程。
|
||||
Debug Operator 从面板中的模型参数发起一次原始推理,把结果文件留在 Job 目录中供开发者检查,不创建用户场景对象。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
src/anyimage/
|
||||
├── operators/debug.py # 调试请求与结果目录打开
|
||||
├── panel.py # Debug 面板入口
|
||||
└── server/
|
||||
├── jobs/debug_predictions.py # 四种公开 Debug Job 的共享编排
|
||||
└── outputs/ # 调试产物写出
|
||||
```
|
||||
|
||||
## 主流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Panel["Debug 面板"] --> Operator["选择模型调试 Operator"]
|
||||
Operator --> Request["从 Scene 设置组装请求"]
|
||||
Request --> Job["提交对应 debug Job"]
|
||||
Panel["Debug 面板"] --> Operator["选择模型 Debug Operator"]
|
||||
Operator --> Request["读取 Scene 参数"]
|
||||
Request --> Job["提交对应 Debug Job"]
|
||||
Job --> Output["写出原始预测产物"]
|
||||
Output --> Directory["打开 Job 目录"]
|
||||
```
|
||||
|
||||
调试入口读取 Scene 中的输入路径、设备与模型参数,直接调用对应 Server Job。任务完成后只打开 Job 目录供检查,不把结果导入为 Blender Image、Mesh 或节点资产。因此它适合验证模型、设备和输出格式,不代表正式功能的用户流程。
|
||||
DA3、MoGe-2、BEN2 和 Upscale 都走这条调试路径。它验证模型、设备、请求参数和输出格式,但不代表正式功能的对象创建流程。
|
||||
|
||||
## 节点说明
|
||||
|
||||
### 从 Debug 面板进入
|
||||
|
||||
入口显示在 `src/anyimage/panel.py`,四个 Operator 定义在 `operators/debug.py`:`DebugDa3`、`DebugMoge2`、`DebugBen2` 和 `DebugUpscale`。它们读取 `Scene.anyimage_settings` 中的输入路径、设备、模型和分辨率参数,并检查 Environment 与模型是否可用。
|
||||
|
||||
### 提交原始推理
|
||||
|
||||
`debug.py` 分别提交 `debug-da3`、`debug-moge2`、`debug-ben2` 和 `debug-upscale` Job。Server 侧由 `server/jobs/debug_predictions.py` 接收请求,再调用相应模型适配器。
|
||||
|
||||
DA3 和 MoGe-2 的可视化与数组输出由 `server/outputs/debug_da3.py`、`server/outputs/debug_moge2.py` 写出;BEN2 与 Upscale 保留模型返回的图片结果。这里允许 DA3 继续存在,但它不会被 Plane、Depth Plane 或 Cutout 的正式 Operator 调用。
|
||||
|
||||
### 查看结果
|
||||
|
||||
任务完成后,`debug.py` 的 `_open_job_directory()` 调用 Blender 的路径打开操作,直接显示该 Job 的目录。响应阶段不导入 Image,不创建 Mesh、Material 或 Modifier,也不修改当前场景。
|
||||
|
||||
@@ -1,48 +1,45 @@
|
||||
# Image Tool
|
||||
|
||||
`operators/image_tool/` 对应工具栏中的 Box、Lasso、Line 与 Polyline。四个 WorkspaceTool 共用一个 `EditImageMask` Operator:手势先形成图片空间 Region,Region 栅格化为 Mask 后才修改图片 Alpha;只有 Box 与 Lasso 可以用 BEN2 执行 Refine Selection。
|
||||
Image Tool 从 Box、Lasso、Line 或 Polyline 手势得到一个图片 Region,再用它修改当前 Image Empty 的 Alpha。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
operators/image_tool/
|
||||
├── __init__.py # 类型清单与对外导出
|
||||
├── box.py # Box WorkspaceTool
|
||||
├── lasso.py # Lasso WorkspaceTool
|
||||
├── line.py # Line WorkspaceTool
|
||||
├── polyline.py # Polyline WorkspaceTool
|
||||
└── edit_mask.py # 本地编辑与 Refine Job 响应
|
||||
```
|
||||
|
||||
手势、坐标和像素能力由 `operators/common/` 提供,四点矫正则属于独立的 [`operators/perspective_tool/`](perspective-tool.md)。
|
||||
|
||||
## 编辑流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Tool["Box / Lasso / Line / Polyline"] --> Gesture["ImageRegionGesture"]
|
||||
Gesture --> Region["RegionPath"]
|
||||
Region --> Raster["栅格化 Region"]
|
||||
Raster --> Data["RegionMask"]
|
||||
Data --> Refine{"Refine Selection?"}
|
||||
Refine -- "否" --> Mask["Region Mask"]
|
||||
Refine -- "是" --> Input["带 Region Alpha 的裁切 RGBA"]
|
||||
Input --> Job["refine-image-mask"]
|
||||
Tool["Box / Lasso / Line / Polyline"] --> Gesture["采集图片空间手势"]
|
||||
Gesture --> Region["RegionPath → RegionMask"]
|
||||
Region --> Refine{"Fit to Foreground?"}
|
||||
Refine -- "否" --> Mask["使用本地 RegionMask"]
|
||||
Refine -- "是" --> Job["refine-image-region"]
|
||||
Job --> Mask
|
||||
Mask --> Alpha["源 Alpha × Mask"]
|
||||
Mask --> Alpha["源 Alpha × RegionMask"]
|
||||
Alpha --> Crop["紧裁切并写回 Empty"]
|
||||
```
|
||||
|
||||
`EditImageMask` 只接受静态图片。`ImageRegionGesture` 把屏幕路径投射为 `RegionPath`;`rasterize_region_path()` 再生成 `RegionMask`。未启用 Refine 时直接把 Region Mask 乘入源 Alpha;启用后,Operator 将 `RegionMask` 写成局部 RGBA 并提交 Job,响应阶段读取细化后的 Alpha 与 `bounds`,再映射回完整画布。
|
||||
四个工具共用 `EditImageMask`。Box 和 Lasso 可以执行 Fit to Foreground;Line 与 Polyline 始终保留几何边界,直接使用本地 `RegionMask`。
|
||||
|
||||
Box 和 Lasso 分别保存自己的 Refine Selection 状态。Line 与 Polyline 强制关闭 Refine,只使用本地 Region Mask;Line 将有向线扩展为半平面 Path,Polyline 显式闭合用户确认的 Path。
|
||||
## 节点说明
|
||||
|
||||
## 手势与预览
|
||||
### 选择工具并采集手势
|
||||
|
||||
四个工具使用相同的白色虚线轮廓和半透明填充。Lasso 按移动距离采点,并在线合并近似共线点;普通凹多边形使用三角剖分,自交路径使用 EVEN_ODD 扫描填充。预览缓存只在轨迹变化时更新。
|
||||
`operators/image_tool/__init__.py` 汇总注册类型;`box.py`、`lasso.py`、`line.py` 和 `polyline.py` 分别定义四个 WorkspaceTool。它们都把操作交给 `edit_mask.py` 中的 `EditImageMask`。
|
||||
|
||||
首次点击通过公共选择逻辑决定是切换 Active Image Empty,还是开始编辑当前图片。这样工具不需要替代 Blender 的普通对象选择。
|
||||
屏幕坐标投射、点击选择、轨迹预览和状态切换来自 `operators/common/image_interaction.py`。Lasso 按移动距离采点并合并近似共线点;Line 扩展为有向半平面;Polyline 在确认时闭合路径。
|
||||
|
||||
## 写回结果
|
||||
### RegionPath → RegionMask
|
||||
|
||||
最终像素通过公共 `image_pixels()` / `image_rgba()` 读取,保留源 RGB,只修改 Alpha,再按非零 Alpha 紧裁切。公共像素写回函数创建结果后,通过统一的 Image Empty 替换入口处理共享引用,并更新 `empty_display_size` 与 `empty_image_offset`,因此剩余像素继续对齐原图片平面,对象 `matrix_world` 不变。
|
||||
`EditImageMask` 通过 `operators/common/image_region.py` 把手势整理为 `RegionPath`,再栅格化为 `RegionMask`。凹多边形使用三角剖分,自交路径使用 `EVEN_ODD` 填充。预览缓存只在轨迹变化时更新。
|
||||
|
||||
Box 和 Lasso 分别读取自己的 **Fit to Foreground** 设置。Line 与 Polyline 强制关闭该选项,因此不会改变直线边界。
|
||||
|
||||
### Fit to Foreground
|
||||
|
||||
未开启 Fit to Foreground 时,`edit_mask.py` 直接使用本地 `RegionMask`。开启后,`RefineImageRegion` 把带 Region Alpha 的局部 RGBA 提交给 `server/jobs/refine_image_region.py`;Job 调用 `server/region/refine_region.py` 运行 BEN2,并返回收紧后的图片和 `bounds`。
|
||||
|
||||
响应阶段仍由 `edit_mask.py` 把局部结果映射回完整画布。
|
||||
|
||||
### 源 Alpha × RegionMask
|
||||
|
||||
`edit_mask.py` 保留源 RGB,只把最终 `RegionMask` 乘入源 Alpha,再按非零 Alpha 紧裁切。像素读取、结果 Image 创建和共享引用处理使用 `operators/common/image_data.py`。
|
||||
|
||||
公共 Image Empty 替换入口会同步更新 `empty_display_size` 和 `empty_image_offset`,因此裁切后的内容仍对齐原图片平面,对象 `matrix_world` 不变。Perspective 使用相同的像素写回能力,但属于独立工具和状态。
|
||||
|
||||
@@ -1,32 +1,40 @@
|
||||
# Perspective Tool
|
||||
|
||||
`operators/perspective_tool/` 对应独立的 Image Perspective WorkspaceTool。它采集四个图片角点,把透视四边形重采样为指定宽高比的矩形,不使用 Job Server。
|
||||
Perspective Tool 从图片上的四个角点建立透视四边形,把其中内容重采样为指定宽高比的矩形并写回当前 Image Empty。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
operators/perspective_tool/
|
||||
├── __init__.py # 类型清单与对外导出
|
||||
└── edit_perspective.py # 四点交互、预览、Homography 与写回
|
||||
```
|
||||
|
||||
图片坐标投射、Alpha 裁切和 Empty 写回复用 `operators/common/` 的基础能力;四点数据始终称为 Quad,不与 Image Region 或 Image Mask Operator 共享业务状态。
|
||||
|
||||
## 矫正流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Click["任意顺序的四个角点"] --> Quad["规范为凸四边形"]
|
||||
Quad --> Preview["生成一次 512 × 512 预览"]
|
||||
Preview --> Ratio["鼠标调整目标宽高比"]
|
||||
Click["点击四个角点"] --> Quad["规范为凸四边形"]
|
||||
Quad --> Preview["生成 512 × 512 预览"]
|
||||
Preview --> Ratio["调整目标宽高比"]
|
||||
Ratio --> Size["计算受限输出尺寸"]
|
||||
Size --> Warp["全分辨率 Homography"]
|
||||
Warp --> Crop["按可见 Alpha 紧裁切"]
|
||||
Crop --> Write["Pack 并写回当前 Empty"]
|
||||
Crop --> Write["Pack 并写回 Empty"]
|
||||
```
|
||||
|
||||
四点输入顺序不决定输出方向;规范化阶段依据源图 X/Y 方向得到不交错的凸四边形。第四点之后只创建一次低分辨率纹理,交互阶段改变 UI 宽高比,确认时才执行全分辨率重采样。
|
||||
预览只在第四点确认后生成一次;之后拖动鼠标只改变目标宽高比。用户确认时才执行全分辨率 Warp。整个流程在 Blender 进程内完成,不使用 Job Server。
|
||||
|
||||
Homography 使用预乘 Alpha 插值,避免透明边缘混入黑色。输出最长边限制为 8192 px,总像素限制为 16,777,216,并按 256 行分块计算,控制中间数组大小。
|
||||
## 节点说明
|
||||
|
||||
Perspective 是 deform 工具,不提供 Refine 或反选。它通过公共 `image_pixels()` 读取供预览与最终 Warp 共用的源像素,并与 Image Mask 共用像素结果创建和 Image Empty 替换入口。结果比例可能不同于原四边形的轴对齐范围,因此 Empty 写回保持中心和覆盖尺度近似一致,而不是假设当前 3D View 相机等于图片拍摄相机。
|
||||
### 采集并规范四个角点
|
||||
|
||||
`operators/perspective_tool/__init__.py` 导出注册类型,交互和计算集中在 `edit_perspective.py`。`ImagePerspectiveTool` 启动 `EditImagePerspective`,后者接受任意顺序的四个图片角点,再根据源图 X/Y 方向整理成不交错的凸 Quad。
|
||||
|
||||
图片坐标投射和首次点击选择复用 `operators/common/image_interaction.py`。Perspective 始终把四点称为 Quad,不使用 Image Tool 的 Region 或 Mask 状态。
|
||||
|
||||
### 预览并调整比例
|
||||
|
||||
第四点确定后,`edit_perspective.py` 创建一次 512 × 512 预览纹理。鼠标移动只更新目标宽高比和 HUD,可吸附到常用比例,不会重复重采样源图。
|
||||
|
||||
输出尺寸根据 Quad 边长和目标比例计算,最长边不超过 8192 px,总像素不超过 16,777,216。
|
||||
|
||||
### 执行 Homography
|
||||
|
||||
确认后,`edit_perspective.py` 计算 Homography,并按 256 行分块处理全分辨率像素。插值使用预乘 Alpha,避免透明边缘混入黑色。Perspective 只做形变,不提供 Fit to Foreground 或反选。
|
||||
|
||||
### 裁切并写回
|
||||
|
||||
Warp 结果按可见 Alpha 紧裁切,再通过 `operators/common/image_data.py` 创建 Packed Image 并替换当前 Empty。结果宽高比可能不同于原 Quad 的轴对齐范围,因此写回时保持中心和覆盖尺度近似一致,而不是复用原图片像素范围。
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
# Remove Background
|
||||
|
||||
本页对应 `src/anyimage/operators/remove_background.py`。该模块负责从 Image Empty 准备媒体输入、提交 BEN2 去背任务,并用结果 Image 替换当前图像;模型推理留在 Server 进程。
|
||||
Remove Background 从当前 Image Empty 准备单图或多帧输入,运行 BEN2 生成前景 Alpha,再用结果 Image 替换原图。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
src/anyimage/
|
||||
├── operators/
|
||||
│ ├── remove_background.py # Blender 入口、任务参数与结果替换
|
||||
│ └── common/image_data.py # 媒体输入准备与结果 Image 创建
|
||||
└── server/
|
||||
├── jobs/remove_background.py # 单图与多帧任务编排
|
||||
└── models/ben2.py # BEN2 前景适配
|
||||
```
|
||||
|
||||
## 主流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Empty["Image Empty"] --> Prepare["准备图片、视频或序列输入"]
|
||||
Prepare --> Operator["RunBackgroundRemoval"]
|
||||
Operator --> Job["remove-background Job"]
|
||||
Job --> Frames["生成 PNG 结果序列"]
|
||||
Frames --> Import["创建结果 Image"]
|
||||
Prepare --> Job["remove-background Job"]
|
||||
Job --> Frames["逐帧运行 BEN2"]
|
||||
Frames --> Result["写出 PNG 结果序列"]
|
||||
Result --> Import["创建结果 Image"]
|
||||
Import --> Replace["替换 Empty.data"]
|
||||
```
|
||||
|
||||
Packed 图片或内存中修改过的单图会先导出为临时输入;文件图片、视频和序列则沿用可读取的源路径。多帧输入由统一媒体层展开,结果保持连续帧命名,导入后继续沿用源 Image User 的帧起点、偏移与循环设置。
|
||||
Blender 负责媒体输入准备和结果导入,BEN2 推理留在 Server。Packed 图片和内存中修改过的单图会先导出临时文件;可直接读取的文件图片、视频和序列沿用原路径。
|
||||
|
||||
BEN2 推理前使用输入 Alpha 屏蔽透明区域,模型输出的前景 Alpha 再与源 Alpha 合成,RGB 保持为源图内容。响应阶段通过公共 Image Empty 替换入口导入结果;当旧 Image 没有其他用户和 Fake User 时,旧数据块会被清理并由结果继承名称。
|
||||
## 节点说明
|
||||
|
||||
### 准备媒体输入
|
||||
|
||||
入口是 `operators/remove_background.py` 中的 `RemoveImageBackground`。它检查当前对象、AI Environment 和帧数,再调用 `operators/common/image_data.py` 的 `prepare_image_input()`。多帧输入会先写入 Scene 中的抽帧设置。
|
||||
|
||||
准备完成后,内部 Operator `RunBackgroundRemoval` 保存输入路径、源对象名和临时文件清理标记。
|
||||
|
||||
### 运行 BEN2
|
||||
|
||||
`RunBackgroundRemoval` 提交 `remove-background` Job。`server/jobs/remove_background.py` 使用公共媒体输入层展开单图、视频或序列,并逐帧调用 `server/models/ben2.py`。
|
||||
|
||||
BEN2 推理前先用源 Alpha 屏蔽透明区域,模型输出的前景 Alpha 再与源 Alpha 合成,RGB 保持源图内容。多帧结果按连续文件名写入 Job 目录。
|
||||
|
||||
### 导入并替换结果
|
||||
|
||||
Job 返回后,`remove_background.py` 的 `apply_background_response()` 调用 `operators/common/image_data.py` 创建单图或序列 Image,并恢复源 Image User 的帧起点、偏移和循环设置。
|
||||
|
||||
同一公共入口随后替换 `Empty.data`。旧 Image 没有其他用户且未启用 Fake User 时会被清理,结果继承原名;否则保留旧数据块。最后提交一个 Remove Background Undo 步骤,并清理本次创建的临时输入。
|
||||
|
||||
@@ -1,37 +1,44 @@
|
||||
# Upscale
|
||||
|
||||
本页对应 `src/anyimage/operators/upscale.py`。该模块读取扩展首选项中的模型与全局 AI 输入长边上限,检查当前 Image 是否可处理,再提交 4× 高清任务。
|
||||
Upscale 从当前 Image Empty 读取单图或多帧媒体,在输入长边允许时生成 4× RGBA 结果并替换原图。
|
||||
|
||||
## 对应文件
|
||||
|
||||
```text
|
||||
src/anyimage/
|
||||
├── operators/
|
||||
│ ├── upscale.py # Blender 入口、任务参数与结果替换
|
||||
│ └── common/image_data.py # 媒体输入准备与结果 Image 创建
|
||||
└── server/
|
||||
├── jobs/upscale.py # 单图与多帧任务编排
|
||||
├── media/resolution.py # 共用长边限制与等比缩放
|
||||
├── models/upscale.py # 输入约束与 Alpha 合并
|
||||
└── models/onnx_upscale.py # 分块 4× ONNX 推理
|
||||
```
|
||||
|
||||
## 主流程
|
||||
## 执行过程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Empty["Image Empty"] --> Source["读取当前 Image"]
|
||||
Source --> Gate{"当前长边小于全局上限?"}
|
||||
Gate -- "否" --> Disabled["Upscale 置灰"]
|
||||
Empty["Image Empty"] --> Gate{"长边小于输入上限?"}
|
||||
Gate -- "否" --> Disabled["禁用或报告错误"]
|
||||
Gate -- "是" --> Prepare["准备媒体输入"]
|
||||
Prepare --> Job["upscale-image Job"]
|
||||
Job --> RGB["分块执行 4× RGB 推理"]
|
||||
Job --> Alpha["独立缩放 Alpha"]
|
||||
RGB --> Merge["合并 RGBA 结果"]
|
||||
RGB --> Merge["合并 RGBA"]
|
||||
Alpha --> Merge
|
||||
Merge --> Replace["导入并替换当前 Image"]
|
||||
```
|
||||
|
||||
模型以 256×256 分块处理 RGB,并带入相邻上下文以减弱块边界;Alpha 不进入模型,使用 Lanczos 独立放大后合并为 RGBA。`max_input_size` 来自全局 **Maximum AI Input Size**,默认 `2048`。Operator 只允许当前 Image 长边小于该值时执行,因此正式流程不会预缩放输入,4× 输出长边小于上限的四倍。Server 仍保留相同上限作为任务边界。
|
||||
模型只处理 RGB,Alpha 单独放大后再合并。Blender 侧在提交前检查 **Maximum AI Input Size**,Server 模型层也应用同一个输入上限。
|
||||
|
||||
菜单根据当前尺寸只显示预计的 4× 结果尺寸。结果通过与 Remove Background、Image Mask 和 Perspective 相同的 Image Empty 替换入口处理:原 Image 没有其他用户且未启用 Fake User 时,移除旧数据并让结果沿用原名;存在其他用户时保留原 Image,并只让当前 Empty 使用独立结果。结果不增加 Upscale 专属后缀,也不保存来源引用。后续 Upscale 与 Depth Plane 都读取当前 Image。模型与全局输入上限在每次执行时从 Preferences 读取,再写入可序列化的隐藏属性交给 Job。Provider 资源错误会释放当前 Upscale Session,并提示降低全局输入上限或改用 CPU。
|
||||
## 节点说明
|
||||
|
||||
### 检查尺寸并准备输入
|
||||
|
||||
入口位于 `operators/upscale.py`。`UpscaleImage.poll()` 读取 `preferences.py` 中的 **Maximum AI Input Size**;当前 Image 长边必须严格小于该值。菜单显示的预计尺寸来自同一文件的 `upscale_output_size()`。
|
||||
|
||||
执行时,`upscale.py` 冻结当前模型和输入上限,并通过 `operators/common/image_data.py` 准备单图、视频或序列输入。Packed Image 与内存修改结果会导出临时文件,多帧输入保留帧起点和抽帧设置。
|
||||
|
||||
### 分块放大 RGB
|
||||
|
||||
`UpscaleImage` 提交 `upscale-image` Job。`server/jobs/upscale.py` 展开媒体帧并逐帧调用模型;`server/models/upscale.py` 负责输入约束、RGB/Alpha 分离和结果合并,`server/models/onnx_upscale.py` 以 256 × 256 分块执行 4× ONNX 推理并带入相邻上下文。
|
||||
|
||||
`server/media/resolution.py` 统一解释输入长边上限。正式 Upscale 在 Blender 侧直接禁用超限图片,因此不会进入预缩放路径,输出长边小于上限的四倍;模型层仍保留同一限制作为任务边界。
|
||||
|
||||
### 合并 Alpha
|
||||
|
||||
Alpha 不进入模型,由 `server/models/upscale.py` 使用 Lanczos 放大到目标尺寸,再与 4× RGB 合并为 RGBA。Provider 资源不足时,Server 释放当前 Upscale Session,并返回降低输入上限或改用 CPU 的提示。
|
||||
|
||||
### 导入并替换结果
|
||||
|
||||
响应阶段回到 `operators/upscale.py`,通过 `operators/common/image_data.py` 读取 `upscale.*` 结果序列并替换当前 Empty。源 Image 没有其他用户且未启用 Fake User 时会被清理并由结果继承名称;存在其他用户时只替换当前 Empty 的引用。
|
||||
|
||||
结果不添加 Upscale 专属数据块后缀,也不保留来源引用。后续再次 Upscale 或转换 Depth Plane 时,读取的都是当前结果 Image。
|
||||
|
||||
@@ -1,72 +1,51 @@
|
||||
# Job 产物
|
||||
|
||||
Job 目录是 Server 与 Blender Operator 的交换边界。Server 写入普通图片、JSON 或 NPZ;Blender 只根据 Job 返回值读取需要的文件,并创建最终数据块。
|
||||
|
||||
## 产物流向
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Input["媒体输入"] --> Job["Server Job"]
|
||||
Job --> Color["PNG 颜色 / Alpha"]
|
||||
Job --> Field["NPZ 深度场"]
|
||||
Job --> Meta["JSON bounds"]
|
||||
Color --> Import["Blender response()"]
|
||||
Field --> Import
|
||||
Meta --> Import
|
||||
Import --> Data["Image / Mesh / Material"]
|
||||
```
|
||||
Job 目录是 Server 与 Blender Operator 的交换边界。Server 写入普通图片、JSON 或 Debug NPZ;Blender 只读取 Job 返回值明确声明的文件,再创建最终 Image、Mesh、Material 与 Object。
|
||||
|
||||
## 正式 Job
|
||||
|
||||
| Job | 主要文件 | 消费方 |
|
||||
| --- | --- | --- |
|
||||
| Job | 主要文件 | Blender 消费方式 |
|
||||
| | | |
|
||||
| `remove-background` | `image.0001.png` 起 | 替换 Image Empty 的颜色数据 |
|
||||
| `upscale-image` | `upscale.0001.png` 起 | 按共享引用情况替换当前 Image Empty 的颜色数据,并沿用原 Image 命名语义 |
|
||||
| `refine-image-mask` | `image.png`、`bounds.json` | Image Box / Lasso 读取细化 Alpha 与原图坐标 |
|
||||
| `generate-depth-plane` | `image.0001.*`、`image_geometry.npz` | 创建颜色图、深度图、材质和 Plane |
|
||||
| `generate-region-data` | 可选的 `region.png`、`region_bounds.json`、`image_geometry.npz`、`normal.png` | Blender 主线程构建 Cutout Shape 与贴图 |
|
||||
| `upscale-image` | `upscale.0001.png` 起 | 替换或新建高清颜色数据 |
|
||||
| `refine-image-region` | `image.png`、`bounds.json` | Image Box / Lasso 读取 Fit to Foreground 结果 |
|
||||
| `generate-depth-plane-geometry` | `image.0001.*`、`z-depth.exr`、`depth.json` | 创建 Depth Plane |
|
||||
| `generate-cutout-artifacts` | 可选 Region、Depth 与 Normal 文件 | 创建 Cutout Shape 与材质 |
|
||||
|
||||
两个几何 Job 都不输出 Blender 网格。`generate-depth-plane` 生成完整图片的颜色副本与深度场;`generate-region-data` 只生成请求的 AI 产物。轮廓提取、约束三角化以及 Mesh、Material 和 Geometry Nodes 创建都在 Blender 主线程完成。
|
||||
两个 Depth Job 都不输出 Blender 网格。Server 保存可由 Blender 直接加载的模型空间 EXR;轮廓提取、三角化、Depth 标定以及 Blender 数据创建仍在主线程完成。
|
||||
|
||||
## 深度场
|
||||
## Depth 与 Normal 文件
|
||||
|
||||
`image_geometry.npz` 是 Depth Plane、Depth Balloon 与 Depth Surface 共用的模型中间结果。Blender 侧统一通过 `operators/common/mesh_result.py` 的 `load_image_geometry()` 读取为 `ImageGeometry`,功能模块不分别解释字段:
|
||||
MoGe-2 Prediction 只存在于 Server 内存。`geometry/prediction_artifacts.py` 共享一次推理,并按请求写出以下文件:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| 文件 | 内容 |
|
||||
| --- | --- |
|
||||
| `points` | 每个模型像素的相机空间 XYZ |
|
||||
| `depth` | 相机深度 |
|
||||
| `intrinsics` | 像素坐标下的 3×3 相机内参 |
|
||||
| `valid` | 模型与数值检查后的有效区域 |
|
||||
| `calibration_valid` | 用于结果定位或深度基准的区域;Cutout 时与 Region 相交 |
|
||||
| `image_size` | 深度场宽高 |
|
||||
| `reference_depth` | 校准区域中的参考深度 |
|
||||
| `vector-depth.exr` | RGB 保存相机空间 XYZ,Alpha 保存有效区 |
|
||||
| `z-depth.exr` | RGB 重复保存相机 Z,Alpha 保存有效区 |
|
||||
| `depth.json` | 保存 `image_size`、3×3 `intrinsics` 与 `reference_depth` |
|
||||
| `tangent-normal.png` | Tangent Space Normal Map |
|
||||
| `object-normal.png` | Object Space Normal Map |
|
||||
|
||||
Server 保留模型空间数据,不提前换算 Blender 单位。Depth Plane 在导入时根据 Image Empty 平面范围和相机内参锚定点场;Cutout 深度形状则计算 `Uniform Scale` 和局部坐标,再把相机点写入 Packed 浮点 Image 供 Geometry Nodes 采样。
|
||||
Blender 通过 `operators/common/depth_data.py` 直接加载 EXR,设为 Non-Color 并 Pack;不会从 NumPy 点场再创建一张 Depth Image。Job 文件名不改变 Blender 数据块命名:Depth 与 Normal 仍分别使用 `depth_data_name()` 和 `normal_data_name()`。Blender 读取 Z 与 Alpha 只用于最终 Region 的本地标定,Geometry Nodes 直接采样已加载的 EXR。
|
||||
|
||||
## Cutout Region 产物
|
||||
|
||||
Blender 侧先把 `RegionPath` 栅格化为 `RegionMask`,再将 Region 裁切为带有效 Alpha 的临时 RGBA 输入。Server 不接收路径或 Mask 协议,只按需产生 AI 数据:
|
||||
Blender 先把 `RegionPath` 栅格化为 `RegionMask`,再把局部 RGBA 作为 Server 输入。Server 不接收 Path 或 Mask 对象协议:
|
||||
|
||||
- 启用 Refine 时,`region.png` 保存细化后的局部 RGBA,`region_bounds.json` 保存它在输入裁切图中的范围;
|
||||
- Depth Shape 使用 `image_geometry.npz`;
|
||||
- Tangent 或 Object Normal 使用 `normal.png`。
|
||||
- 开启 Fit to Foreground 时,`region.png` 保存 Fit to Foreground 后的局部 RGBA,`region_bounds.json` 保存它相对输入裁切图的范围;
|
||||
- 需要 Vector Depth 时请求 `vector-depth.exr` 与 `depth.json`;
|
||||
- 需要 Z Depth 时请求 `z-depth.exr` 与 `depth.json`;
|
||||
- Normal Map 按空间请求 `tangent-normal.png` 或 `object-normal.png`。
|
||||
|
||||
Blender 将局部范围与原始 `RegionMask.bounds` 合成回源图坐标,并直接从源 Image 创建最终 Color Image。未启用 Refine、Depth 或 Normal 时不提交 Job。
|
||||
未启用 Fit to Foreground,且不需要 Depth 或 Normal Map 时,Surface 与 Balloon 不提交 Job。最终颜色图仍由 Blender 从源 Image 裁切,并把 Alpha 乘以最终 `RegionMask`。
|
||||
|
||||
## Debug 产物
|
||||
|
||||
Debug Job 保留模型适配层的直接输出,不执行正式功能的 Blender 导入:
|
||||
|
||||
| Job | 文件 |
|
||||
| --- | --- |
|
||||
| | |
|
||||
| `debug-da3` | `prediction.npz` |
|
||||
| `debug-moge2` | `prediction*.npz` |
|
||||
| `debug-ben2` | `foreground*.png` |
|
||||
| `debug-upscale` | `prediction*.png` |
|
||||
|
||||
这些文件用于验证模型、Device 和适配层。正式 Job 会继续派生 Region、Alpha、深度场或可导入图片,因此两者的文件结构有意不同。
|
||||
|
||||
## 单图与序列
|
||||
|
||||
正式颜色序列从 `image.0001.*` 开始,Upscale 使用独立的 `upscale.0001.png` 前缀。Remove Background 与 Upscale 的动画结果继续引用 Job 目录;单图结果通常在 Blender 导入后 Pack 到 `.blend`。不要清理仍被工程引用的序列目录。
|
||||
Debug Job 只用于直接检查模型适配层,不参与正式对象创建流程。
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
# Job Runtime 与 Server
|
||||
|
||||
AnyImage 使用 BlendJob 管理独立 Python Environment、Server 进程和任务队列。Blender 侧只配置 Runtime 与提交参数;`server/` 是不依赖 `bpy` 的计算包,可以在独立解释器中导入。
|
||||
AnyImage 使用 BlendJob 管理独立 Python Environment、Server 进程与单 Worker 队列。Blender 侧只准备输入、提交普通字典参数并导入结果;`server/` 不依赖 `bpy`。
|
||||
|
||||
## 对应文件
|
||||
## 目录职责
|
||||
|
||||
```text
|
||||
src/anyimage/
|
||||
├── runtime.py # Environment 与 JobRuntime 配置
|
||||
└── server/
|
||||
├── app.py # Job 注册和共享资源
|
||||
├── app.py # 公开 Job 注册
|
||||
├── model_catalog.py # 模型声明
|
||||
├── model_download.py # 下载、校验与镜像回退
|
||||
├── model_manager.py # 模型目录与 Session 缓存
|
||||
├── media/input.py # 图片、视频和序列输入
|
||||
├── jobs/ # app.py 可提交的公开任务
|
||||
├── region/ # BEN2 Region 细化
|
||||
├── model_download.py # 下载与校验
|
||||
├── model_manager.py # 模型目录与 Session 生命周期
|
||||
├── jobs/ # 公开协议与流程编排
|
||||
├── media/ # 图片、视频、序列帧和尺寸处理
|
||||
├── region/ # 通用 BEN2 Region 细化
|
||||
├── geometry/ # Depth / Normal 文件产物与相机元数据
|
||||
├── models/ # 模型适配与 ONNX 推理
|
||||
├── geometry/ # 深度反投影与法线纹理编码
|
||||
└── outputs/ # Debug Prediction 序列化
|
||||
```
|
||||
|
||||
## 任务生命周期
|
||||
公开 Job 不互相导入实现。`jobs/` 只编排,稳定的原子能力放在对应领域目录中。
|
||||
|
||||
## 生命周期
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -32,56 +34,51 @@ flowchart TD
|
||||
Directory --> Response["Operator response()"]
|
||||
```
|
||||
|
||||
Runtime 在首次任务或显式启动时拉起 Server。任务在队列中串行执行,进度、取消和日志由 BlendJob 提供;AnyImage Job 在阶段边界调用 `context.check_cancelled()`,并把业务产物写入当前 Job 目录。Operator 完成响应后再清理 Blender 侧为 Packed Image 准备的临时输入。
|
||||
Job 在阶段边界调用 `context.check_cancelled()`,并把稳定产物写入当前 Job 目录。Blender 响应完成后,再由输入所有者清理临时 Packed Image 文件。
|
||||
|
||||
`server/app.py` 是任务清单的唯一入口:
|
||||
## 公开 Job
|
||||
|
||||
| Job | 主要用途 |
|
||||
| --- | --- |
|
||||
| `download-model`、`download-required-models` | 准备模型文件 |
|
||||
| `remove-background` | BEN2 透明前景 |
|
||||
| `remove-background` | 生成 BEN2 透明前景 |
|
||||
| `upscale-image` | 4× 图片或帧序列 |
|
||||
| `refine-image-mask` | 为 Image Box / Lasso 细化 Region |
|
||||
| `generate-depth-plane` | 为 Depth Plane 生成颜色副本与深度场 |
|
||||
| `generate-region-data` | 按需为 Cutout Region 生成 Refine、Depth 或 Normal |
|
||||
| `refine-image-region` | 为 Image Box / Lasso 执行 Fit to Foreground |
|
||||
| `generate-depth-plane-geometry` | 为 Depth Plane 复制颜色并生成 Z Depth 与相机元数据 |
|
||||
| `generate-cutout-artifacts` | 按需执行 Fit to Foreground,并生成 Depth 或 Normal 文件产物 |
|
||||
| `debug-*` | 保存模型适配层的直接输出 |
|
||||
|
||||
## 媒体输入
|
||||
`generate-depth-plane-geometry` 对应 `jobs/depth_plane.py`;`generate-cutout-artifacts` 对应 `jobs/cutout.py`。共享的 MoGe-2 推理编排位于 `geometry/prediction_artifacts.py`,Depth EXR 与元数据写入位于 `geometry/depth_texture.py`,Normal 编码位于 `geometry/normal_texture.py`,Fit to Foreground 的通用实现位于 `region/refine_region.py`。
|
||||
|
||||
`server/media/input.py` 把单图、视频和图片目录统一为有序帧路径,并用上下文管理器负责临时帧目录的生命周期。帧展开是媒体输入的内部能力,不再暴露没有业务消费者的独立 Job。`server/media/resolution.py` 提供默认 `2048` 的共用输入长边限制;Upscale Operator 只允许长边小于该值的当前 Image 进入正式任务,Depth Plane 与 Cutout 则只限制模型分析输入,不降低颜色贴图分辨率。
|
||||
## 尺寸约束
|
||||
|
||||
`generate-depth-plane` 与 `generate-region-data` 只接受一帧,因此 Depth Plane 与 Cutout 都是静态图工作流。Remove Background 与 Upscale 通过同一媒体入口处理单图、视频和序列帧。
|
||||
`server/media/resolution.py` 提供 **Maximum AI Input Size**,默认 `2048 px`。它限制 Upscale 的可提交源图长边,以及 Depth、Normal Map、Fit to Foreground 的模型分析图长边;不会降低材质颜色图分辨率。
|
||||
|
||||
公开 Job 按稳定的计算边界划分,不按界面入口机械映射。Depth Plane 使用 `jobs/generate_depth_plane.py`,Cutout 使用 `jobs/generate_region_data.py`,四个 Debug Job 共享 `jobs/debug_predictions.py`。Job 只负责协议和编排;可复用的输入、AI Region、模型与几何数据能力分别位于 `media/`、`region/`、`models/` 和 `geometry/`,Job 之间不互相导入实现。
|
||||
Cutout 另有 Blender 侧的 **Maximum Cutout Mesh Resolution**。它限制所有 Cutout Shape 的网格采样密度,包括完全不使用 AI 的 Surface 与 Balloon。两个设置没有隐式绑定。
|
||||
|
||||
## 模型层
|
||||
`generate-depth-plane-geometry` 与 `generate-cutout-artifacts` 只接受一帧,因此 Depth Plane 与 Cutout 是静态图工作流。Remove Background 与 Upscale 继续通过媒体入口处理单图、视频和序列帧。
|
||||
|
||||
Job 只编排流程,模型适配层把不同推理 API 统一为内存对象:
|
||||
## 模型边界
|
||||
|
||||
- DA3 适配为深度、置信度、相机内外参与相机点。
|
||||
- MoGe-2 适配为深度、法线、有效区域、相机内参与可选相机点。
|
||||
- BEN2 返回带 Alpha 的前景图。
|
||||
- Upscale 返回保留源 Alpha 的 4× RGBA 图。
|
||||
正式 Depth Plane、Cutout Depth 与 Normal Map 都只使用 MoGe-2。BEN2 用于 Remove Background 与 Fit to Foreground,Upscale 使用所选高清模型。DA3 只保留 `debug-da3` 及其 Debug 参数、模型下载与适配代码,不进入任何生产 Operator、Job 或自动回退。
|
||||
|
||||
`ModelManager` 管理下载目录和 ONNX Session。缓存按 BEN2、几何模型和 Upscale 三个族分开;每个族只保留最近一次使用的模型与 Device,切换同族模型时释放旧 Session。这样连续任务可以复用模型,同时避免同一类模型重复占用资源。
|
||||
`ModelManager` 按模型族管理下载目录与 ONNX Session,同一族只保留最近使用的模型和 Device,避免同类模型重复占用资源。
|
||||
|
||||
## Environment 与 Storage Root
|
||||
|
||||
`runtime.py` 声明 Python 3.12 环境和固定版本的 NumPy、Pillow、PyAV、trimesh、Hugging Face Hub 与 ONNX Runtime。Windows 安装 DirectML 版本,其他平台安装标准 ONNX Runtime。首次安装后依次下载默认 MoGe-2、BEN2 和 Real-ESRGAN WDN 模型。
|
||||
|
||||
Storage Root 默认是 `~/.anyimage`:
|
||||
`runtime.py` 声明独立 Python 3.12 环境和固定依赖。首次安装会准备默认 MoGe-2、BEN2 与 Real-ESRGAN WDN 模型。Storage Root 默认是 `~/.anyimage`:
|
||||
|
||||
```text
|
||||
~/.anyimage/
|
||||
├── .venv/ # 独立 Environment
|
||||
├── models/ # 模型目录
|
||||
├── jobs/ # Job 产物与 job.log
|
||||
├── .venv/
|
||||
├── models/
|
||||
├── jobs/
|
||||
├── environment.json
|
||||
├── manifest.json
|
||||
├── install.log
|
||||
└── server.log
|
||||
```
|
||||
|
||||
Storage Root 由扩展偏好设置提供给 Runtime。切换路径等同于切换整套 Environment、模型和任务数据,不会自动迁移旧目录。
|
||||
切换 Storage Root 等同于切换整套 Environment、模型与任务数据,不自动迁移旧目录。
|
||||
|
||||
各 Job 的稳定产物见 [Job 产物](outputs.md)。
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
| 入口 | 位置 | 输入 |
|
||||
| --- | --- | --- |
|
||||
| Paste Clipboard Image | 3D View / Node Editor 的 `Ctrl+V` 或 `Cmd+V` | 剪贴板静态图 |
|
||||
| Paste Clipboard Image | 3D View / oode Editor 的 `Ctrl+V` 或 `Cmd+V` | 剪贴板静态图 |
|
||||
| Convert to Plane | Image Empty 右键菜单 | 单图、Movie、Sequence |
|
||||
| Convert to Depth Plane | Image Empty 右键菜单 | 静态图 |
|
||||
| Remove Background | Image Empty 右键菜单 | 单图、Movie、Sequence |
|
||||
@@ -15,7 +15,7 @@
|
||||
| Image Perspective | 3D Viewport 工具栏 | 静态 Image Empty |
|
||||
| Cutout | 3D Viewport 工具栏 | 静态 Image Empty |
|
||||
|
||||
右键菜单只在当前对象是 Image Empty 时出现。AI 功能会在 Environment 或默认模型未就绪时转入安装流程;普通 Plane、非 Refine 的 Image Tools 与基础 Cutout Surface / Balloon 不依赖 Environment。
|
||||
右键菜单只在当前对象是 Image Empty 时出现。AI 功能会在 Environment 或默认模型未就绪时转入安装流程;普通 Plane、未启用 Fit to Foreground 的 Image Tools 与基础 Cutout Surface / Balloon 不依赖 Environment。
|
||||
|
||||
## 结果类型
|
||||
|
||||
@@ -34,7 +34,7 @@ Cutout 提供四种结果:
|
||||
| Depth Balloon | `O Image Depth Balloon` | MoGe-2 高度 |
|
||||
| Depth Surface | `O Image Depth Surface` | MoGe-2 相机点 |
|
||||
|
||||
四种 Shape 共用 `O Image Cutout` 修改器、规则三角基础面、UV 和 `o_balloon` 属性。Shape 菜单选择内部几何分支,Cleanup 在分支前执行且使用便于调节的百倍显示值,Smooth 在分支后执行;Depth Shape 根据 Region 透明比例选择固定或自适应 Base Plane Depth,Normal 可选 None、Tangent 或 Object,Refine Selection 按需启用 BEN2。
|
||||
四种 Shape 共用 `O Image Cutout` 修改器、规则三角基础面、UV 和 `o_balloon` 属性。Shape 菜单选择内部几何分支,Cleanup 在分支前执行且使用便于调节的百倍显示值,Smooth 在分支后执行;Depth Shape 根据 Region 透明比例选择固定或自适应 Base Plane Depth,Generate Normal Map 是启用开关:Depth Surface 自动使用 Object Space,其余 Shape 自动使用 Tangent Space;Fit to Foreground 按需启用 BEN2。
|
||||
|
||||
### 图片结果
|
||||
|
||||
@@ -43,7 +43,6 @@ Image Mask 和 Perspective 直接更新当前 Empty 的图片并 Pack。Remove B
|
||||
## 模型
|
||||
|
||||
- MoGe-2 ViT-S / ViT-B / ViT-L Normal
|
||||
- DA3 Small / Base
|
||||
- BEN2 Base
|
||||
- Real-ESRGAN General WDN x4v3
|
||||
- SAFMN Real x4
|
||||
|
||||
Reference in New Issue
Block a user