Add new tests and functionality for image processing and geometry handling

- Introduced color_image.py for preparing standalone color images for tests.
- Added hdr_image.py to create HDR textures for testing.
- Implemented test_image_depth_panorama.py to evaluate panorama topology, UVs, and depth discontinuities.
- Created test_shadeless.py to validate the opacity and HDR color endpoints of the Shadeless group.
- Developed moge3_export.py for exporting dynamic MoGe-3 backbone and ONNX graphs.
- Added material.py to inherit material slots onto generated geometry.
- Built image_depth_panorama.py to construct a quad panorama with depth separation and sampling.
This commit is contained in:
2026-09-10 14:42:17 +08:00
parent 27ca25224a
commit 489003c2cc
136 changed files with 5758 additions and 1083 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-09

View File

@@ -0,0 +1,86 @@
## Context
独立原型验证了 12 个透视视图的 MoGe2 推理、距离融合和 Quad Sphere。正式转换沿用 Image Empty 的异步转换流程。用户明确选择通过现有 Remove Background 预先处理背景,转换消费当前图片和 Alpha。
## Goals / Non-Goals
本次范围是静态 2:1 等距柱状全景的菜单转换、正式节点资产和 Split Threshold。沿用原型的 Subdivide、Depth Scale 和单张深度图片约定。
## Decisions
### 入口与对象生命周期
```mermaid
flowchart TD
A[Image Empty 右键 AnyImage] --> B[Convert to Panorama]
B --> C[检查静态图和 2 比 1 尺寸]
C --> D[读取当前 RGBA 和 Preferences]
D --> E[提交全景 Job]
E --> F[加载并打包颜色和深度]
F --> G[创建全景对象和节点修改器]
G --> H[替换源 Empty 并记录撤销]
```
新增 `operators/convert_to_panorama/`,`operators.py` 定义 `ConvertToPanorama` 与 `GeneratePanorama`,`object.py` 创建结果,`__init__.py` 导出注册清单。公开入口为 `anyimage.convert_to_panorama`,Job 为 `generate-panorama-geometry`。复用 `common` 的输入暂存、材质、深度加载、修改器赋值和对象收尾函数。
模型、推理级别和分析尺寸从 Preferences 读取,Job 参数为普通字典。Blender 数据只在主线程读取输入和处理响应。新对象中心对应原 Empty 原点,继承其世界变换;局部 +Z 为全景上方,U=0 朝向 +X,U 增加沿 +Y 转动。生成成功后替换源对象并激活结果;失败、取消或源对象已失效时清理本次临时资源。图片显示偏移只属于平面预览,球面方向由完整图片 UV 定义。
### 后端与数据协议
```mermaid
flowchart TD
A[当前 RGBA 全景] --> B[12 个重叠 90 度视图]
B --> C[MoGe2 与已知 FOV 的几何恢复]
C --> D[有效视图的径向距离]
D --> E[横向周期的对数梯度融合]
E --> F[尺度锚定与有限距离场]
A --> G[源 Alpha 对齐到深度尺寸]
F --> H[depth.exr]
G --> H
```
`server/jobs/panorama.py` 负责任务调度,`server/geometry/panorama.py` 负责投影与融合。将已知 FOV 接入已有 ONNX 后处理和模型会话生命周期,普通图片继续使用焦距估计。保留原分辨率颜色;视图分析尺寸遵循输入上限,首版目标视图为 512×512,融合网格最长边上限 512 且保持 2:1。Subdivide 独立控制最终网格密度。
源 Alpha 对齐、黑底模型输入及可见区域排除采用原型已验证的流程。全透明视图跳过推理,部分视图无效时继续融合其余有效观测;全局无有效几何时报错。逐视图及融合前后检查取消,释放模型资源。
| 字段 | 文件 | 内容 |
| --- | --- | --- |
| 颜色文件 | `image.0001.png` | 当前 RGBA,保留源 Alpha |
| `depth` | `depth.exr` | float32 RGB 重复保存径向距离,A 为融合 Mask × 源 Alpha |
| `depth_metadata` | `depth.json` | `projection: equirectangular`、`image_size`、`reference_distance` |
`reference_distance` 为满足 Alpha 阈值的有限正径向距离中位数,用于 Split Threshold 的尺度归一化。全景元数据按投影类型单独读取;复用现有 EXR 写入及 Non-Color、CHANNEL_PACKED、Pack 配置。颜色由材质采样,几何节点只有一个深度图片输入。
### Quad Sphere 与 Split Threshold
新增资产 `O Image Panorama`。Quad Sphere 与球面校正子组的构建定义归入本仓库节点构建模块,参考已检查的 `O Quad Sphere`,运行时从 `O_AnyImage.blend` 加载。面数为 `6 × 4^Subdivide`,默认 Subdivide=7;Depth Scale 默认 1,范围 0–1;Validity Threshold 默认 0.9;Split Threshold 默认 0,范围 0–1。深度图片、材质和参考距离作为数据输入。
```mermaid
flowchart TD
A[可调细分 Quad Sphere] --> B[固定单位射线与球面 UV]
B --> C[按深度 EXR Alpha 剔除无效面]
C --> D[相邻面径向距离变化判断]
D --> E[Split Edges 与条带面清理]
E --> F[分离面角沿原射线取所属面距离]
F --> G[Depth Scale 插值到重建表面]
G --> H[材质与临时属性清理]
```
提取并复用 `tools/nodes/common/depth_surface.py` 中的相邻面采样、内边判断、Split Edges、面角归属和条带面清理。共用逻辑消费明确的深度字段、基础面中心和归一化比例;Depth Plane 的调用同步适配,保持已有求值结果。
对全景,令相邻面距离为 rA/rB,单位球面上的面中心为 cA/cB,参考距离为 R。沿用现有 2.5 系数,以 `abs(rA-rB) / R × Split Threshold > 2.5 × distance(cA,cB)` 选择有两个邻面的内边。阈值为 0 时直接保留通过有效性剔除的原网格;阈值增大时选择更多断层边。
选中断层附近的面角使用其所属面的距离,未选中的顶点保持原采样;所有点沿原始球面射线定位。最终半径为 `1 + Depth Scale × (目标距离 - 1)`。条带面清理遵循当前 Depth Plane 的同一拓扑快照规则。
全景面中心采样由面中心方向重新计算 UV,横向循环采样;材质面角 UV 独立处理经度分支和极点。这样左右接缝与普通内边参与同样的判断。分裂后保留原射线及面角 UV,末尾清理专用临时属性。
### 验证与交付
正式模块从原型迁移有效算法及测试,运行时依赖正式模块与打包资产。此次实现运行相关单元测试、完整回归测试和独立 Blender 求值检查。节点资产更新走现有离线资产流程;扩展包及文档构建属于另行发布操作。
## Risks / Trade-offs
- 径向距离与平面 Z 深度的比较尺度不同 → 用参考距离归一化,并测试相同形状整体缩放后的分裂选择一致。
- 全景接缝和极点的 UV 有多种等价表示 → 用方向生成采样坐标,并验证接缝两侧的等价深度断层。
- 共享分裂代码近期增加了条带清理 → 保留现有 Depth Plane 回归结果,并覆盖全景分裂后孤立条带、Alpha 边缘和连续斜面。
- 天空及遮挡导致预测缺失 → 以当前源图 Alpha 和融合 Mask 确定有效几何,允许通过现有 Remove Background 预先处理。

View File

@@ -0,0 +1,25 @@
## Why
全景原型已验证 Quad Sphere、径向深度和单张深度 EXR 的可行性。现在需要把生成流程接入 Image Empty 的常用入口,并通过 Depth Plane 的 Split Threshold 机制处理前后景连接处的拉伸。
## What Changes
- 在 Image Empty 的 AnyImage 右键菜单增加 `Convert to Panorama`,通过后台 Job 将静态 2:1 全景转换成可编辑的全景表面。
- 将原型的多视图 MoGe2 推理、距离融合和深度 Alpha 导出接入正式 Server。
- 新增 `O Image Panorama` 节点资产,提供 Quad Sphere 细分、Depth Scale、Validity Threshold 和 Split Threshold。
- 复用 Depth Plane 的分边、面角深度重定位和条带面清理机制,按全景径向距离适配判断。
- 延续单深度图片输入:`depth.exr` 的 Alpha 在导出时合成模型 Mask 与当前源图 Alpha。
## Capabilities
### New Capabilities
- `panorama-conversion`: Image Empty 菜单、异步转换、对象替换与撤销。
- `panorama-geometry-generation`: 全景多视图推理、融合与文件产物。
- `panorama-surface`: Quad Sphere、球面 UV、深度有效性剔除与 Split Threshold。
### Modified Capabilities
## Impact
涉及 `menu.py`、类型注册、新增 `operators/convert_to_panorama/`、Server Job 与全景几何模块、共享深度表面节点构建函数,以及对应测试。生产节点组由资产构建流程写入 `O_AnyImage.blend`,运行时按名称加载。使用现有 MoGe2、ONNX Runtime、NumPy 与 SciPy 环境。

View File

@@ -0,0 +1,33 @@
## ADDED Requirements
### Requirement: Image Empty panorama conversion entry
系统 SHALL 在 Image Empty 的 AnyImage 右键菜单展示 `Convert to Panorama`,调用 `anyimage.convert_to_panorama`。
#### Scenario: Select panorama conversion
- **WHEN** 用户选中静态 2:1 Image Empty 并选择 Convert to Panorama
- **THEN** 提交当前图片及 Alpha 的全景生成任务,使用 Preferences 中的模型、推理级别和分析尺寸
#### Scenario: Unsupported image
- **WHEN** 输入是动画、视频或非 2:1 图片
- **THEN** 提示输入限制并保留源对象
### Requirement: Consume current image alpha
转换 SHALL 直接使用当前源图及 Alpha。背景处理由用户通过现有 Remove Background 完成。
#### Scenario: Already removed background
- **WHEN** 源 Empty 的天空已透明
- **THEN** 当前 Alpha 进入全景任务,转换过程中只运行几何模型
### Requirement: Complete conversion transaction
系统 SHALL 在主线程加载结果、打包贴图并创建节点对象,成功后替换源 Empty,并提供完整撤销。
#### Scenario: Successful conversion
- **WHEN** Job 返回有效产物
- **THEN** 创建使用 O Image Panorama 的对象,继承源 Empty 世界变换并以其原点为拍摄中心,激活结果并支持撤销恢复源对象
#### Scenario: Cancelled or failed conversion
- **WHEN** 任务失败、取消或响应时源对象已失效
- **THEN** 清理本任务暂存及未使用数据块,不应用部分转换结果

View File

@@ -0,0 +1,33 @@
## ADDED Requirements
### Requirement: Generate panoramic radial distance
Server SHALL 从当前 RGBA 全景生成 12 个重叠的 90 度透视视图,使用已知 FOV 恢复 MoGe2 几何并融合为横向周期的径向距离场。
#### Scenario: Continuous panorama
- **WHEN** 输入包含跨越 U=0/1 的连续表面
- **THEN** 两侧使用同一周期求解,产出有限正距离且无额外拼接断层
#### Scenario: Invalid views and cancellation
- **WHEN** 部分视图全透明或模型无有效预测
- **THEN** 利用其余有效观测完成融合,全局无有效几何时返回明确错误,并在视图与融合阶段响应取消
### Requirement: Export combined depth alpha
系统 SHALL 返回颜色文件、`depth.exr` 与 `depth.json`。深度 RGB 保存径向距离,Alpha 在导出时一次合成融合 Mask × 源 Alpha;元数据 SHALL 标明等距柱状投影、深度图尺寸和参考距离。
#### Scenario: Transparent background
- **WHEN** 源图某区域 Alpha 为零
- **THEN** 该区域深度 EXR Alpha 为零,颜色文件保留源 Alpha
#### Scenario: Fractional alpha
- **WHEN** 有效模型 Mask 为 1 且源 Alpha 为 0.5
- **THEN** 深度导出 Alpha 为 0.5,几何端直接消费该值
### Requirement: Use managed production runtime
全景生成 SHALL 使用现有模型会话、Preferences 配置和 Job 生命周期;Job 参数可序列化,Server 与 Blender 数据保持进程边界。
#### Scenario: Configured inference
- **WHEN** 用户修改模型或推理分辨率级别后发起转换
- **THEN** 新任务采用配置值,最终网格细分仍由独立 Subdivide 参数控制

View File

@@ -0,0 +1,41 @@
## ADDED Requirements
### Requirement: Editable Quad Sphere surface
系统 SHALL 提供资产 `O Image Panorama`,使用全四边面 Quad Sphere,并提供 Subdivide、Depth Scale、Validity Threshold 和 Split Threshold。几何节点 SHALL 只有一个深度图片输入。
#### Scenario: Sphere and depth endpoints
- **WHEN** 所有样本有效且 Split Threshold 为 0
- **THEN** Subdivide=n 产生 6×4^n 个四边面,Depth Scale=0 为单位球,Depth Scale=1 为预测径向距离表面
#### Scenario: Validity culling
- **WHEN** 深度 EXR Alpha 低于 Validity Threshold
- **THEN** 按 Depth Plane 的点域布尔字段与面域删除方式剔除对应区域
### Requirement: Depth Plane split semantics
全景 SHALL 复用 Depth Plane 的相邻面深度差判断、内边分裂、面角深度重定位和条带面清理机制,并使用参考距离归一化的径向距离适配球面。
#### Scenario: Disabled splitting
- **WHEN** Split Threshold 为 0
- **THEN** 分裂与条带清理完全旁路,有效性剔除保持生效
#### Scenario: Foreground depth discontinuity
- **WHEN** 相邻有效面的归一化距离跳变达到分裂条件
- **THEN** 分离选中的内边,断层附近面角沿原球面射线使用所属面的距离,未选中顶点保持原始深度采样
#### Scenario: Threshold and scale consistency
- **WHEN** 增大 Split Threshold 或对所有距离与参考距离同时乘以相同正比例
- **THEN** 增大阈值不会减少被选中的断层边,等比例距离变化不会改变断层边选择
#### Scenario: Seam and strip cleanup
- **WHEN** 深度断层跨越全景经度接缝或分裂产生孤立条带
- **THEN** 经度接缝采用周期采样,面角 UV 保持正确,条带面按 Depth Plane 的同一拓扑快照规则清理
### Requirement: Packaged node assets
生产节点组及 Quad Sphere 子组 SHALL 包含在 `O_AnyImage.blend` 中,通过现有加载入口使用。
#### Scenario: Reopen converted object
- **WHEN** 在新 Blender 进程重新打开转换后的文件
- **THEN** 无需访问原型目录或外部参考库即可求值,贴图、细分、Depth Scale 和 Split Threshold 均正常工作

View File

@@ -0,0 +1,24 @@
## 1. 全景后端
- [x] 1.1 将原型的投影、周期距离融合和参考距离计算迁移到正式 Server 模块,保留解析几何测试
- [x] 1.2 为现有 MoGe2 ONNX 推理增加已知 FOV 的几何恢复,复用模型会话并验证普通图片回归
- [x] 1.3 实现 generate-panorama-geometry Job、尺寸和有效性检查、取消与清理,导出当前颜色、深度及全景元数据
- [x] 1.4 验证源 Alpha 与 Mask 仅在深度导出合成一次,覆盖透明视图、全局无有效数据和跨经度接缝
## 2. 全景节点资产
- [x] 2.1 在本仓库实现 Quad Sphere 及校正子组的资产构建,创建 O Image Panorama 的细分、球面 UV 和 Depth Scale
- [x] 2.2 复用深度 EXR 加载与 Alpha 剔除,保持几何节点单深度图片输入
- [x] 2.3 提取共享 Split Threshold 机制并同步适配现有调用,将径向距离判断、面角重定位和条带清理接入全景
- [x] 2.4 覆盖阈值旁路、断层强度、尺度不变性、连续斜面、经度接缝、极点及条带清理,并运行现有深度表面回归
## 3. 菜单与对象转换
- [x] 3.1 实现 ConvertToPanorama 与 GeneratePanorama,接入 Preferences、输入暂存、Job 参数与注册清单
- [x] 3.2 在 Image Empty 的 AnyImage 菜单添加 Convert to Panorama,验证静态 2:1 输入限制及当前 Alpha 传递
- [x] 3.3 实现主线程结果加载、材质、全景对象和修改器,覆盖源变换继承、替换、撤销及失败清理
## 4. 集成验证
- [x] 4.1 通过既有离线节点资产流程更新 O_AnyImage.blend,验证新进程加载和打包后独立求值
- [x] 4.2 使用已去天空的真实全景与解析样本检查正式菜单流程和 Split Threshold,运行完整测试并检查最终差异