feat: Introduce Balloon Lasso Tool for mesh extraction

- Added BalloonTool workspace tool to facilitate the extraction of balloon meshes in the 3D viewport.
- Implemented ActivateBalloonTool operator to activate the Balloon Lasso Tool.
- Refactored BalloonLasso operator into ExtractBalloon for better clarity and functionality.
- Enhanced properties for balloon extraction, including mode, thickness, resolution, and material reuse options.
- Updated SnapFormSettings to include new balloon-related properties.
- Improved material and image handling for balloon extraction, ensuring compatibility and reusability.
- Added tests to validate the registration and functionality of the new balloon tools and properties.
This commit is contained in:
2026-08-20 11:33:19 +08:00
parent 13ef705226
commit 4e1231790b
18 changed files with 864 additions and 851 deletions

View File

@@ -1,120 +1,49 @@
# 功能参考
本页记录完整功能行为和实现边界,主要供开发、测试与故障排查使用。第一次使用 SnapForm 时,请从
[安装与首次配置](installation.md)或[五分钟上手](quick-start.md)开始。
本页概览 SnapForm 的能力。安装步骤见[安装与首次配置](installation.md),实际操作见[工作流选择](workflows.md)与各使用指南。
`SnapForm` 是一套从图片快速构建空间结构的 Blender Extension。目前以
[Depth Anything 3](https://github.com/ByteDance-Seed/Depth-Anything-3)
作为首个 AI 能力,在独立 Environment 中运行 DA3,可将模型 API Prediction 保存在独立 job 目录,
也可把 Image Empty 转换成带几何与材质置换的立体面片。MoGe-2 作为独立深度来源,保留其 metric depth、normal、mask 与 intrinsics 输出,不复用 DA3 Prediction 后处理。Debug 面板还可运行
[BEN2](https://github.com/PramaLLC/BEN2) 背景剔除功能测试。
## 工作流
## 当前功能
| 工作流 | 适合 | 输入 | 结果 |
| --- | --- | --- | --- |
| Depth Plane | 快速制作可调节的立体图片 | 单图、视频、序列帧 | 带颜色、深度与 Geometry Nodes 的面片 |
| Surface | 从单张图片恢复透视空间 | 单图 | 相机空间网格、材质与可选匹配相机 |
| Remove Background | 提取透明前景 | 单图、视频、序列帧 | 透明图片或透明序列 |
| Balloon | 沿轮廓绘制鼓起造型 | 静态 Image Empty | 带原图 UV 的封闭网格 |
| Debug | 检查模型原始输出 | 模型支持的图片或帧序列 | 保存在 Job 目录中的原始 Prediction |
- 使用 Blender Extension manifest,可通过 `Install from Disk` 安装
- 在独立 Environment 中通过常驻 Server 运行 ONNX Runtime;MoGe-2、DA3 与 BEN2 的模型执行及后处理完全不使用 PyTorch,避免污染 Blender Python 进程
- Server 的深度模型缓存只保留 DA3 或 MoGe-2 其中一个,切换时主动释放前一个;BEN2 使用独立缓存,
可与当前深度模型共存
- Blender 使用内置 `urllib.request` 访问仅监听 `127.0.0.1` 的 Server;连接由随机端口与 Instance ID 归属当前 Runtime
- 常驻 Server 复用 ONNX Runtime session、BEN2 与最近使用的深度模型,连续执行时不再重复加载
- 每个 Blender 实例持有自己的 Job Server;`Job Server` 面板显示状态与模型缓存,并提供安装、启动、清理、重启和停止控制
- Environment、模型和任务结果默认保存在 `~/.snapform`,可由多个 Blender 版本共享
- 当前仅启用 FP32 DA3 Small 和 Base;它们不随首次安装下载,Giant 1.1 与 Nested Giant Large 1.1 暂停使用
- 支持 BEN2 Base 单图背景剔除测试,输出透明 PNG 与推理耗时
- 支持单张 JPG、JPEG、PNG、WEBP 图片或常见视频文件输入
- 视频按顺序截取前若干帧,可设置参与重建的最大帧数
- `Models` panel 默认折叠,展开后可逐项查看和下载所有可用模型
- Environment 已安装时不额外占用面板空间;模型列表每个模型只占一行
- `Debug` 默认折叠,内部的 `DA3`、`MoGe-2` 与 `BEN2` 也分别默认折叠
- DA3、MoGe-2 与 BEN2 分别使用独立 Debug Job,直接保存各自 API 返回,不共享按模型分支的总控函数
- DA3 Debug 保存 Prediction NPZ;MoGe-2 Debug 保存逐帧原始预测 NPZ;BEN2 Debug 保存直接返回的透明前景
- Debug 与 Convert to Depth Plane 的模型选项直接显示下载状态;未下载模型带
`(Missing)`,已下载模型保持原名
- Debug 不运行点云、Surface、深度预览、置信度 percentile 或坐标变换等 SnapForm 后处理
- Image Empty 右键菜单提供单一 Balloon 套索提取,并可在 Last Operation 中切换 Poisson 与 Teddy / Chordal Axis Mode;无需 Environment 或模型,源 Empty 保留
- Image Empty 右键菜单可直接运行 DA3,根据 `mini_npz` 深度生成面片
- Image Empty 右键菜单可直接运行 BEN2,保留原图并换用新建的透明背景图片
- 缺少必需的 `MoGe-2 ViT-S Normal` 或 `BEN2 Base` 时,Image Empty 的 `SnapForm`
右键子菜单显示 `Download Required Models`;单次任务只下载缺失项,并在补齐前禁用
`Convert to Depth Plane`、`Convert to Surface` 和 `Remove Background`。Environment 未安装时,
同一位置改为显示 `Install Environment` 与 `Install Environment (Mirror)`,三个禁用的功能入口仍然可见
- 菜单、模型面板和转换对话框直接检查 Storage Root 的 `models/` 必需文件,显示模型状态时不会启动 Job Server
- Image Empty 支持视频与序列帧输入:`Convert to Depth Plane` 逐帧估计深度,
`Remove Background` 逐帧抠图,入口保持不变。DA3 转换时每帧独立执行 ONNX 推理并复用模型 Session;
DA3 Debug 多帧任务继续联合推理;MoGe-2 与 BEN2 Debug 按单图 API 逐帧运行
- 视频生成的序列帧以外部文件引用保留在 job 目录(Blender 无法整体 Pack 序列帧);
Geometry Nodes 与材质 Image Texture 均可按场景帧播放序列帧
- 使用浮点深度贴图、`O DA3 Depth Plane` Geometry Nodes 和原图 Bump 构建立体面片
- 转换对话框选择推理模式、处理分辨率与背景移除;细分和置换方式在 Geometry Nodes 修改器中调整
- Debug 的 DA3 输出或 BEN2 背景剔除完成后只打开对应 job 文件夹,不修改当前场景
- Debug 完整保留模型 API 返回的数组字段,不混入 SnapForm 派生几何
- 安装和模型下载使用后台子进程;推理提交给常驻 Server,状态栏实时显示阶段、百分比进度条与取消按钮
- 后台任务运行时,Install、Download 和 Export 按钮保持原位置并变灰,任务完成后恢复
Depth Plane 与 Surface 可使用 DA3 或 MoGe-2。DA3 提供相对深度和相机信息;MoGe-2 还提供 metric depth、法线与有效区域。BEN2 为去背景和可选前景处理提供 Alpha。
## 使用
## Blender 交互
1. 运行 `uv run python pack.py`,分别构建 `windows-x64`、`macos-arm64`、
`linux-x64` 三个平台的 Extension ZIP(如 `SnapForm.v0.12.17.macos-arm64.zip`)。
安装包不携带 uv 或 AI 项目源码;首次安装 Environment 时下载固定版本 uv,并校验固定 SHA-256。官方安装按钮使用 GitHub、uv 默认 Python 下载源和 PyPI;镜像按钮使用 CNB uv Release、CNB Python 解释器镜像和清华 PyPI。
2. 在 Blender 的 `Preferences > Extensions` 中选择 `Install from Disk`。
3. 在 Extension Preferences 中确认 Storage Root 与 Device。Device 是正式功能
(Image Empty 右键菜单)使用的推理设备。Windows 默认取 DirectML,否则 CPU;Apple M4 或更新芯片列出 MPS/CoreML 与 CPU,Intel、M1–M3 和无法识别的 Mac 只列出 CPU。
4. 在 `Job Server` 选择 `Install Environment` 或 `Install Environment (Mirror)`。首次安装会下载 Python、ONNX Runtime、FastAPI、Uvicorn;
uv 由 Job Runtime 的 Environment 安装器下载并校验,DA3、BEN2 与 MoGe 不安装源码包,
并在 Environment 安装后自动下载 `MoGe-2 ViT-S Normal` 和 FP16 `BEN2 Base` 推荐模型。首次安装
Environment Bootstrap 的 0–100% 只包含 uv、Python 与 packages:三阶段显示 `1/3`、`2/3`、`3/3`,范围分别为 1–20%、20–50%、50–98%,最终验证使用 98–100%。下载占各阶段的 84–87%;开始与验证不显示编号,单阶段状态不显示 `1/1`。
两个默认模型由普通的 `post_install(runtime)` 发起正式 Server Job。
安装完成后直接写入 Environment Manifest,不再额外导入全部组件进行验证;`DA3 Base` 等其他模型可稍后在 `Models` 面板按需下载。
Environment packages 使用固定的 Resolving、Downloading 与 Installing 状态,原始 uv 输出写入 `install.log`。模型下载显示速度,例如
`Downloading DA3 Small 14.2 MB/s`;镜像来源显示为
`Downloading DA3 Small (mirror) 14.2 MB/s`。下载按字节连续推进,重试或切换镜像时进度不会倒退。
Environment 安装阶段与 `Models` 面板单独下载使用相同的模型名称格式,不会改写为通用的 `Downloading packages`。
Environment 安装后即使模型下载中断也仍会保留,但 `Install Environment` 会以失败结束并显示模型下载错误。
可稍后在 Image Empty 的 `SnapForm` 右键菜单用 `Download Required Models` 一次补齐缺失的
MoGe-2 ViT-S 与 BEN2,也可在 `Models` 面板单独补下。
安装不做启动网络预检;每个模型都先尝试 Hugging Face,失败后尝试 OmooLab R2,两者都失败时当前 Job 失败。
官方安装固定使用 GitHub、uv 默认 Python 下载源和 PyPI;镜像安装固定使用 CNB uv Release、`python-build-standalone` 镜像和清华 PyPI。两种方式都不测速、不竞速、不自动切换,镜像配置只注入当前安装子进程。模型仍按自身的 Hugging Face 与 OmooLab R2 逻辑下载。
5. 在 3D View 按 `N`,打开 `SnapForm` 页签。
6. 如需其他模型,展开 `Models` panel,找到模型并点击该行的 `Download`。
7. 展开默认收起的 `Debug`,在 DA3、MoGe-2 或 BEN2 区域选择模型与输入,然后直接运行对应 API。
8. 选择一张图片或一个视频文件。视频可设置从头截取的帧数,然后点击 `Generate Output`。
9. 测试背景剔除时,确认 `Models` panel 中的 `BEN2 Base` 已就绪,然后在 `Debug` 的
`BEN2` 区域选择单张图片并点击 `Remove Background`。
完成后会打开 job 文件夹,其中的 `foreground.png` 带透明 Alpha;状态栏显示
BEN2 推理、模型加载与任务总耗时。当前测试固定关闭较慢的 foreground refinement。
主要功能位于 Image Empty 的 `SnapForm` 右键菜单。菜单会显示 Environment 和必需模型的就绪状态,并在缺少内容时提供安装或下载入口。
## Extract Balloon
转换任务完成后,SnapForm 在一个 Undo 步骤中创建网格、图片、材质和修改器。源 Image Empty 是否保留由转换选项决定。
`Balloon Mesh (Lasso)` 是纯 Blender 侧入口,不提交 Job,也不调用 BEN2、深度模型或其他 AI,仅支持静态 Image Empty。它启动不进入 Undo/Redo 历史的持续 `BalloonLasso` 控制器;按住左键绘制套索,松开时控制器调用一次独立的 `ExtractBalloon` Operator 并立即完成,随后继续等待下一次圈选。`Esc` 结束控制器,右键只清除当前未完成轨迹。屏幕轨迹通过视图射线与 Empty 图片平面求交,再结合图片宽高比、Display Size、Image Offset 与 Object Transform 映射为原图像素坐标。
Balloon 是 Blender 内部工具,无需 Environment 或模型。它支持连续绘制,每次 Stroke 都生成一个可单独 Undo/Redo 的结果。Tool Settings 提供模式、厚度、采样距离与材质复用设置。
Operator 的 `Mode` 保留两种厚度算法:
## 动画
- `Poisson` 在共用二维网格上组装 cotangent Laplacian 与面积载荷,求解零边界 Poisson 场;高度取场值平方根并按 `Thickness` 缩放
- `Teddy / Chordal Axis` 依据 [Teddy: A Sketching Interface for 3D Freeform Design](https://www.cs.princeton.edu/courses/archive/fall00/cs597b/papers/teddy-siggraph99.pdf) 的思路,仅对平滑轮廓做约束 Delaunay,形成袖段、分叉和端点轴,并用轴半径生成局部圆/椭圆式截面。当前实现将厚度场映射到共用均匀网格,并非逐面复刻论文的专用缝合拓扑
Depth Plane 和 Remove Background 支持 Movie 与 Image Sequence。它们按 Image Empty 的帧范围处理素材,并生成与场景帧对应的颜色或深度序列。
每次释放都会把该次套索、源对象名称和启动时的完整 Matrix World 传给一个带 `REGISTER`、`UNDO` 的 `ExtractBalloon`。它完成后立即成为 Last Operation,即使持续 Lasso 仍在运行,也可在左下角修改当前结果的 `Mode`、`Thickness` 和 `Resolution`;每次提取分别拥有 Undo 步骤。重建后会重新把源 Image Empty 设为选中和 Active,便于继续圈选,结果也不会跳回原点。Modal 对中键、滚轮、触控板、NDOF、Alt+左键、HUD 和其他未处理事件返回 `PASS_THROUGH`,所以持续状态不阻断 3D View 导航或参数面板交互。`Thickness` 默认 `1.0`、软上限 `5.0` 且无硬上限。`Resolution` 是 subtype 为 `DISTANCE` 的长度属性,直接表示相邻采样点的目标世界空间距离,默认 `0.1 Blender unit`;数值越小网格越密,不再使用密度倍率换算。
Blender 无法整体 Pack 图片序列,因此动画结果会继续引用 Job 目录。保存或移动 `.blend` 时,应同时保留这些外部文件。详见[动画与序列帧](animation.md)。
两种模式共用轮廓平滑、按弧长等距重采样和二维约束 Delaunay。边界与内部点以 `Resolution` 的世界距离采样,不随图片分辨率、Display Size 或对象 Scale 改变目标间距。前后表面在同一条零厚度边缘共享顶点,不生成直立侧壁,结果为封闭网格。UV 保持原图坐标;材质使用独立的 `O Texture Layer`,并复制源 Image datablock、按 Convert 系列相同规则命名为 `.color`。创建 Object 与 Mesh 时直接使用源 Image Empty 名称,不主动追加 Balloon 后缀;同一 Blender datablock 集合已有重名时仍由 Blender 自动追加数字编号。源 Image Empty 保持不变,Undo 可移除提取结果。
## 运行环境
当前不提供添加/减去选区、边缘羽化和视频跟踪。
## Image Empty 去背景
AI 任务在独立 Python Environment 中通过 ONNX Runtime 执行。Blender 负责界面、任务提交和结果导入,Job Server 负责模型与文件处理。
1. 确认 `Models` panel 中的 `BEN2 Base` 已就绪;首次安装 Environment 时会默认下载。
2. 在 3D View 选中 Image Empty,右键打开 `SnapForm` 子菜单并选择 `Remove Background`。
3. 完成后以 Fake User 保留原 Image datablock,新建并 Pack 一张透明 PNG 到当前 `.blend`,然后只把
当前 Empty 的 `data` 换成新图;Empty 的 Transform、显示尺寸、Offset 及其他设置保持不变。
4. 新 Image 使用原图去掉格式后再追加 `.color` 的名称。例如 `img.png` 生成
`img.color`,`img.png.001` 生成 `img.001.color`。已有同名 datablock 时由
Blender 自动追加编号。
默认 Storage Root 为 `~/.snapform`,其中保存 Environment、模型、日志和 Job 结果。连续任务会复用已加载的模型 Session;DA3 与 MoGe-2 共享一个深度模型缓存位置,BEN2 可同时保留。
原图已 Pack 时会先写出临时 PNG 交给 BEN2,任务结束后删除临时输入;原 Image 仍保持 Pack
状态和原始内容。正式任务的 `color.0001.png` 也会保留在对应 job 目录中。
安装、下载和推理都在后台运行,并通过状态栏提供进度与取消操作。详细设计见[Job Server](server.md)。
Image Empty 引用视频或序列帧时,Remove Background 直接执行,默认取 Empty 的 Image Frames
数值(未设置时为完整帧数,显式设为 1 时只处理 1 帧),起始帧跟随 Empty 的 Offset;若 Offset 加 Frames 超出视频长度,
会把窗口整体收进视频内(保证实际处理 Frames 帧数),Offset 过小时从第 1 帧开始。输出
`color.0001.png` 等透明序列帧(帧号从 0001 开始,与 Blender 场景帧一一对应),并把
关闭去背景时,原始颜色帧同样以 `color.0001.*` 起始的统一名称写入 job 目录。替换 Empty 的 Image 为
加载这些帧的 SEQUENCE Image,从原 Empty 的 Start 位置开始播放(Start 原样保留)。图片类型只取决于源 Empty:普通单图的单个 `color.0001.*` 仍作为 `IMAGE`,Movie/Sequence 即使只导出一帧也作为 `SEQUENCE`;`.depth` 同样遵循该规则。
Cyclic 沿用原 Empty 的设置。序列帧无法被 Blender 整体 Pack,因此保持外部引用 job 目录;
请保留对应 job 目录,否则序列会失效。
## 模型与调试
正式功能使用以下 ONNX 模型:
- MoGe-2 ViT-S、ViT-B、ViT-L Normal
- DA3 Small、DA3 Base
- BEN2 Base
首次安装会准备 MoGe-2 ViT-S Normal 与 BEN2 Base,其他模型可从 Models 面板按需下载。
Debug 工作流保存模型 API 的直接返回,适合验证模型、设备与输入。Depth Plane 和 Surface 则在模型结果之上继续生成 Blender 可用的贴图与几何。文件字段见[输出格式](outputs.md)。