Files
AnyImage/docs/development.md
nan 13ef705226 Add operators for model downloading and surface generation
- Implemented `DownloadModel` and `DownloadRequiredModels` operators for downloading models.
- Created `ClearModels` operator to clear model resources.
- Added `ConvertToSurface` operator for converting image empties into textured surfaces.
- Introduced `GenerateDa3Surface` and `GenerateMoge2Surface` operators for generating surfaces using DA3 and MoGe-2 models respectively.
- Developed utility functions for handling image mesh data, assigning attributes, and managing geometry nodes.
- Established runtime configuration and post-installation model downloading in `runtime.py`.
2026-08-20 01:56:04 +08:00

9.2 KiB
Raw Blame History

程序设计、开发与许可证

程序设计

SnapForm 分成 Blender 主进程与独立 Job Server 两侧。Blender 侧只负责界面、任务参数和 .blend 数据修改;模型下载、媒体准备、ONNX 推理和文件输出都在 Python 3.12 Environment 中运行。两侧由随扩展分发的 BlendJob wheel 连接,避免把 FastAPI、ONNX Runtime 等计算依赖载入 Blender Python。

flowchart LR
    User["Image Empty / Debug Panel"] --> Operator["Blender Operator"]
    Operator --> Runtime["JobRuntime"]
    Runtime --> Server["JobServer FIFO Queue"]
    Server --> Handler["SnapForm Job Handler"]
    Handler --> Model["ModelManager / ONNX"]
    Handler --> JobFiles["Job Directory"]
    JobFiles --> Response["Operator response"]
    Response --> Scene["Blender Scene"]

核心边界如下:

  • src/snapform/__init__.py 是注册入口,集中注册 Blender 类型、Scene.snapform_settings、右键菜单与 Runtime
  • menu.py 与 panel.py 是同级 Blender UI 入口;preferences.py、properties.py 分别保存插件配置和 RNA 状态,它们都不直接导入 Server 模型实现
  • runtime.py 创建唯一 JobRuntime,配置 Environment、Storage Root、Server 入口与首次安装后的推荐模型下载
  • operators/ 按功能组织 Blender 操作。Depth Plane、Surface、Background 与 Balloon 各自包含入口 Operator、Job 请求和结果回写,不设置跨功能的 results.py
  • operators/common.py 只保留跨 Job Operator 共用的参数校验、模型就绪检查、临时输入清理和请求参数构造;operators/image.py 与 operators/material.py 提供各功能 Operator 共用的 Image Empty、序列和材质操作,三者同层但不互相混合职责
  • operators/models.py 与 operators/debug.py 分别承载模型管理和 Debug 操作
  • operators/balloon/ 以持续 BalloonLasso 控制器分发单次、可独立 Redo/Undo 的 ExtractBalloon;geometry.py 负责共用拓扑,poisson.py 与 teddy.py 分别计算两种厚度场
  • operators/depth_plane/ 将转换入口、Job 请求、响应回写、深度数据和网格构建收拢在同一功能包;operators/surface.py 与 operators/background.py 采用相同的功能内聚原则
  • server/__init__.py 创建 JobServer、注册公开 Job,并把 ModelManager 注册为 Resource
  • server/jobs/ 按任务组织完整流程;DA3、MoGe-2、BEN2 Debug 各自拥有独立模块和 Job,不用模型分支总控函数
  • server/models/ 包含三个模型适配器及其 ONNX 实现,只负责模型载入、推理和 Prediction;不接收 Job Context、不写文件
  • server/geometry/ 包含投影、像素网格和唯一 Surface Builder,均为纯数据转换;不负责 Debug 或文件输出
  • server/outputs/ 只负责 Depth、Surface 与各模型 Debug 的序列化;Debug writer 原样保存 API 字段,不构建派生几何
  • server/media/input.py 只处理图片、序列和视频输入;共享的可选前景流程保留在 jobs/foreground.py
  • 根目录 model_catalog.py 供 Blender UI 与本地就绪检查使用;server/model_catalog.py 独立声明下载与推理所需模型,二者的模型键、目录名和 ready_patterns 由测试约束一致
  • server/__init__.py 只注册 Job 与 Resource;jobs/background.py、jobs/frames.py 分别实现去背景和帧提取
  • 所有任务产物写入 Runtime 分配的 opaque-ID Job 目录

功能细节继续按主题维护:Depth Plane、Surface、输出格式 和 Job Server。

项目结构

.
├── AGENTS.md
├── README.md
├── pack.py
├── sync_models.py
├── docs/
├── src/
│   └── snapform/
│       ├── __init__.py
│       ├── blender_manifest.toml
│       ├── runtime.py
│       ├── menu.py
│       ├── panel.py
│       ├── preferences.py
│       ├── properties.py
│       ├── model_catalog.py
│       ├── assets/
│       │   └── O_SnapForm.blend
│       ├── operators/
│       │   ├── common.py
│       │   ├── image.py
│       │   ├── material.py
│       │   ├── models.py
│       │   ├── debug.py
│       │   ├── background.py
│       │   ├── surface.py
│       │   ├── depth_plane/
│       │   │   ├── operator.py
│       │   │   ├── data.py
│       │   │   └── build.py
│       │   └── balloon/
│       │       ├── operator.py
│       │       ├── geometry.py
│       │       ├── poisson.py
│       │       └── teddy.py
│       ├── server/
│       │   ├── __init__.py
│       │   ├── jobs/
│       │   ├── geometry/
│       │   ├── media/
│       │   ├── models/
│       │   └── outputs/
│       └── wheels/
│           └── blendjob-*.whl
├── tests/
└── tools/

常见命令

在项目根目录使用 Git Bash:

uv sync
uv run pytest
uv run pytest tests/test_addon.py tests/test_manifest.py tests/test_pack.py -v
uv run python pack.py

.github/workflows/test.yml 在 main push、Pull Request 与手动触发时使用 Python 3.11 和锁定依赖运行完整测试。.github/workflows/build.yml 只响应 v* tag,在再次通过完整测试后运行 pack.py,并把生成的 ZIP 上传到该 tag 对应的 Gitea Release。pack.py 从 pyproject.toml 的默认 dependencies 读取 Extension wheel 需求,按 Manifest 平台从 PyPI 下载 wheel,并把各平台对应的 wheel 列入包内 Manifest;src/snapform/wheels/ 只保留本地资产,不作为 uv source。.github/workflows/docs.yml 在 main 的文档内容、MkDocs 配置或自身 Workflow 变化时部署,也可手动触发;它只使用 docs 依赖组,因此不安装默认依赖。Server Environment 与测试依赖声明在 dev 组,文档工具声明在 docs 组;新增依赖后应更新锁文件,不要在 Workflow 中另行维护下载清单。

本地预览用户文档:

uv run mkdocs serve

构建静态文档或使用 Mike 发布版本化文档:

uv run mkdocs build
uv run mike deploy <version> -p
uv run mike set-default <version> -p

文档部署

.github/workflows/docs.yml 在 main 分支的文档相关文件变化后运行,也可从 Gitea Actions 手动触发。工作流使用锁定的 Python 依赖严格构建 site/,将其放入与站点 URL 对应的 public/snapform/,再通过 Wrangler 部署为 Cloudflare Workers Static Assets。

在 Gitea 仓库的 Settings > Actions 中配置:

  • Secret CLOUDFLARE_ACCOUNT_ID:Cloudflare Account ID
  • Secret CLOUDFLARE_API_TOKEN:限制到目标账号的 Cloudflare API Token,使用 Edit Cloudflare Workers 模板
  • Variable CLOUDFLARE_WORKER_NAME:承载文档的 Worker 名称

API Token 不写入仓库。Workflow 只在 main 上部署生产文档,不在 Pull Request 中读取 Cloudflare Secret。

目标 Worker 必须专门用于 SnapForm,并把 docs.omoolab.xyz/snapform/* 路由到该 Worker。每次 Wrangler 部署都会更新目标 Worker 的整套静态资源;如果一个 Worker 同时承载多个项目,应改由中央文档仓库聚合全部站点后统一部署,不能从各项目仓库分别覆盖它。

Mike 不依赖 GitHub API;mike deploy --branch <branch> --push 也可以向 Gitea 保存版本化静态站点。当前自动部署先发布 mkdocs build 生成的单版本站点,等确定版本 URL 规则后再启用 Mike 分支,避免在 Cloudflare 上提前固化不合适的路径结构。

pack.py 根据 blender_manifest.toml 分别生成 Windows、macOS 和 Linux 扩展包,例如 dist/SnapForm.v0.12.14.windows-x64.zip。更换 src/snapform/wheels/ 中随扩展分发的 wheel 后,先刷新锁文件再测试:

uv lock --refresh
uv run pytest

资产构建与验证

tools/ 脚本依赖 bpy,必须由 Blender 执行。设置本机 Blender 可执行文件后,可以重建或验证 O_SnapForm.blend:

BLENDER_BIN="/c/Program Files/Blender Foundation/Blender 4.5/blender.exe"

"$BLENDER_BIN" --background --python tools/build_geometry_nodes_asset.py
"$BLENDER_BIN" --background --python tools/validate_depth_plane_asset.py
"$BLENDER_BIN" --background --python tools/validate_geometry_nodes_asset.py
"$BLENDER_BIN" --background --python tools/validate_moge_depth_plane.py
"$BLENDER_BIN" --background --python tools/validate_moge_surface.py

验证脚本会自动把 src/snapform/wheels/ 中的 BlendJob wheel 加入 Blender Python 路径,因此可在 --factory-startup 的干净环境中直接运行。

只改 Python、文档或打包逻辑时不需要重建 .blend 资产;修改节点组、材质组或其接口时,应运行相应资产验证脚本,并再次运行完整测试。

上游与许可证

  • Depth Anything 3 代码采用 Apache 2.0
  • BEN2 ONNX 模型采用其仓库声明的 Apache 2.0 License
  • SnapForm Extension 代码采用 GPL-3.0-or-later
  • 模型权重许可证由所选 Hugging Face 模型仓库决定,Extension 下载前会在界面显示