Add specifications for two-times upscale and unified depth plane features

- Introduced the two-times upscale specification detailing requirements for unified output, fixed model presets, arbitrary dimensions, and consistent job behavior.
- Added scenarios for existing models, repeated upscale, and handling of alpha preservation.
- Created the unified depth plane specification outlining geometry modes, stable interface, and asset evaluation.
- Defined scenarios for mode switching, relief and camera preservation, and validation of delivered assets.
This commit is contained in:
2026-09-17 17:19:05 +08:00
parent 2811c7bf3a
commit 076a8c90f1
524 changed files with 6514 additions and 3 deletions

View File

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

View File

@@ -0,0 +1,91 @@
## Context
当前图片选区业务横跨 Blender 侧数据结构、Viewport 手势、Image Tool、Cutout Tool 和 Server Job,但统一使用 `region`;与此同时 Blender API 也用 Region 表示编辑器窗口区域。两种含义出现在同一调用链中,增加了阅读和查找成本。
当前工作树已将 Blender 侧共享模块整理为 `common/region.py` 与 `common/viewport.py`。本次变更以该结构为迁移起点,并遵守项目不保留旧入口或兼容层的约束。Server 仍保持独立包边界,不能引用上级共享模块。
## Goals / Non-Goals
**Goals:**
- 让图片选区从数据类型到 Job 产物全程只使用 `selection`。
- 明确区分图片 Selection 与 Blender Viewport Region。
- 用面向用户的 Mesh Detail 代替实现导向的像素采样间距。
- 一次性迁移所有内部调用方、测试和文档,不留下混合术语。
**Non-Goals:**
- 不修改路径栅格化、Mask 运算、BEN2 细化或 Normal Map 生成算法。
- 不增加新的网格采样密度,也不改变四个既有间距的几何结果。
- 不重命名 Blender API 规定的 Region 概念,也不替换与图片选区无关的普通区域表达。
- 不改变 AI 可用性门控、Shape 候选项或 Normal Space 规则。
## Decisions
### 1. 按业务含义迁移,不做全局文本替换
业务选区主链统一采用以下名词:
| 当前表达 | 目标表达 |
| --- | --- |
| `common/region.py` | `common/selection.py` |
| `RegionPath` / `RegionMask` / `RegionContours` | `SelectionPath` / `SelectionMask` / `SelectionContours` |
| `region_path` / `region_mask` / `region_contours` | `selection_path` / `selection_mask` / `selection_contours` |
| `ImageRegionGesture` | `ImageSelectionGesture` |
| `SelectCutoutRegion` / `CutoutRegionToShape` | `SelectCutoutSelection` / `CutoutSelectionToShape` |
| `RefineImageRegion` / `refine-image-region` | `RefineImageSelection` / `refine-image-selection` |
| `refine_region` | `refine_selection` |
| `region_image` / `region_bounds` | `selection_image` / `selection_bounds` |
| `server/region/refine_region.py` | `server/selection/refine_selection.py` |
同一规则应用于相关函数、属性、序列化字段、进度消息、临时文件和测试名称。由于项目不保留兼容层,旧模块、Operator ID、Job 类型和字段在迁移完成后直接删除。
不纳入迁移的名称包括 `context.region`、`context.region_data`、`event.mouse_region_x/y`、Viewport Region 指针与尺寸,以及算法中确实表示一般连通区域而非用户 Selection 的术语。相比机械替换,按语义清单迁移可以避免破坏 Blender API,并使残留检查具有明确判断标准。
### 2. Selection 是业务名词,Refine 是动作
属性工厂和三个工具设置分别改为 `refine_selection_property`、`cutout_refine_selection`、`image_box_refine_selection` 与 `image_lasso_refine_selection`,Operator 参数使用 `refine_selection`。界面统一显示 **Refine Selection**,描述说明使用 BEN2 将手势产生的 Selection 收紧到前景。
相较只改界面文案,此方案让代码与界面保持同一概念;相较继续使用 `fit`,`refine` 更准确地表达已有 AI 操作,并与原名称一致。
### 3. Normal Map 只缩短用户界面名称
Cutout 布尔选项显示名从 **Generate Normal Map** 改为 **Normal Map**。`generate_normal` 等执行层标识继续表达“是否生成”这一布尔动作,不为追求表面一致而改成含义更弱的 `normal_map`。
### 4. Mesh Detail 映射到既有采样间距
Cutout 设置从 `cutout_point_spacing` 整数属性迁移为 `cutout_mesh_detail` 枚举属性,显示名为 **Mesh Detail**。枚举标识使用稳定字符串 `"LOW"`、`"MEDIUM"`、`"HIGH"`、`"ULTRA"`,使代码标识与界面档位直接对应;创建 Shape 前通过单一映射转换为实际采样间距:
| Mesh Detail | Sampling Spacing |
| --- | --- |
| Low | 32 px |
| Medium | 16 px |
| High | 8 px |
| Ultra | 4 px |
默认值为 Low,与当前默认 32 px 保持一致。转换函数放在使用网格间距的 Cutout 业务边界,后续几何代码仍接收明确的像素间距,不让 UI 档位渗入采样算法。
相比保留 4–32 的任意整数输入,四档枚举只暴露实际支持和测试的密度;相比直接把 Level 数值传入几何代码,显式映射保留了算法参数的物理含义。
### 5. Server 协议与文件产物同步切换
Blender 和 Server 在同一次变更中切换 Job 类型、参数、结果字段及产物文件名。建议的细化产物为 `selection.png` 与 `selection_bounds.json`;独立 Image Selection Job 的通用输出仍可沿用 `image.png` 与 `bounds.json`,但结果字典键使用 `selection_image` 与 `selection_bounds`。
协议不做双读或双写。这样符合项目移除旧路径的规则,也避免长期维护两套字段;代价是旧会话中尚未完成的 Job 结果不能由新代码恢复。
## Risks / Trade-offs
- [遗漏某个业务 `region` 导致混合术语或运行时字段不匹配] → 按模块清单迁移,并用定向 `rg` 结合人工语义复核;测试覆盖 Blender 调用与 Server 返回值两端。
- [机械重命名误伤 Blender Viewport Region] → 将 Blender API 名称列入明确保留清单,重点运行手势绘制、投影和 Perspective 相关测试。
- [与当前 `reorganize-common-modules` 工作树重叠] → 以其整理后的 `common/selection.py` 目标结构为准,不恢复已删除的旧模块。
- [旧 `.blend` 中保存的工具设置名失效] → 接受该迁移成本,不增加兼容属性;工具设置回到新属性的默认值。
- [Mesh Detail 顺序与采样间距方向写反] → 使用单一常量映射,并对 Low、Medium、High、Ultra 四档添加参数化测试。
- [旧 Job 或临时结果不可恢复] → 同版本同步发布 Blender 与 Server 代码,并接受更新时终止中的旧 Job。
## Migration Plan
1. 先迁移 Selection 数据模块、类型和纯函数,再更新 Blender 侧所有导入与调用。
2. 迁移 Viewport 手势、工具属性和 Operator,同时切换 Mesh Detail 枚举与间距映射,更新注册与逆序注销。
3. 同步迁移 Server 包、Job 类型、参数、结果字段和产物文件名。
4. 更新测试与内部文档,使用搜索确认剩余 `region` 均属于保留语义。
5. 运行相关测试后运行全部测试;若失败,整体回退本次重命名,不引入临时兼容层。

View File

@@ -0,0 +1,28 @@
## Why
当前代码把用户圈定的图像选区称为 `region`,容易与 Blender 的 Viewport Region 混淆,也与界面中的选择概念不完全对应;Cutout 还直接暴露像素采样间距,用户难以判断数值与细节的关系。统一业务术语并改用 Mesh Detail 后,代码、公开协议和界面可以使用更直观且彼此对应的表达。
## What Changes
- **BREAKING**:将表示图像选区的模块、类型、函数、属性、Operator、Job 参数、返回字段和文件名从 `region` 重命名为 `selection`,不保留兼容别名或转发入口。
- 保留 Blender API 固有的 `context.region`、`region_data`、`mouse_region_x` 等名称,以及与选区业务无关的普通空间区域表达。
- 将界面选项 **Fit to Foreground** 恢复为 **Refine Selection**,并同步对应的代码标识。
- 将界面选项 **Generate Normal Map** 缩写为 **Normal Map**;其布尔语义和生成行为不变。
- **BREAKING**:将 Cutout 的连续整数选项 **Mesh Sampling Spacing** 改为四档 **Mesh Detail**;Low、Medium、High、Ultra 分别使用 32、16、8、4 px 的采样间距。
- 同步测试和内部文档,使术语、界面名称与当前实现一致。
## Capabilities
### New Capabilities
- `image-selection`: 规定图像工具和 Cutout 工具对选区的统一表达,以及选区细化、Normal Map 与 Cutout Mesh Detail 选项。
### Modified Capabilities
无。
## Impact
- 影响 `common` 的选区数据与 Viewport 交互、Image Tool、Cutout Tool、Server Job、属性定义、注册入口和相关文件布局。
- 影响 Blender 内部 Operator ID、Job 类型、序列化参数与结果字段;旧名称不再可用。
- 需要同步相关测试与 `docs/internals` 文档;不新增依赖,不改变选区栅格化、AI 细化、Normal Map 生成或既有四种网格采样密度。

View File

@@ -0,0 +1,37 @@
## Purpose
统一 Image Tool 与 Cutout Tool 对图片选区的用户表达和外部协议,并以简洁一致的名称呈现选区细化、Normal Map 与 Cutout 网格细节选项。
## ADDED Requirements
### Requirement: Image selection uses one business term
系统 SHALL 在 Image Tool、Cutout Tool 及其对外 Job 协议中使用 Selection 表示用户在图片上圈定并栅格化的范围。
#### Scenario: Selection passes through a tool workflow
- **WHEN** 用户使用图片手势圈定范围并提交工具操作
- **THEN** 工具状态、Job 参数和 Job 结果中表示该范围的字段使用 Selection 术语
### Requirement: Selection refinement option is named Refine Selection
支持 AI 选区细化的工具 SHALL 将对应布尔选项显示为 **Refine Selection**,且开启后只细化当前 Selection 中的前景内容。
#### Scenario: User enables selection refinement
- **WHEN** 用户在 Image Box、Image Lasso 或 Cutout 中开启 **Refine Selection**
- **THEN** 系统使用 AI 将当前 Selection 收紧到其中的前景内容
### Requirement: Cutout normal option is named Normal Map
Cutout Tool SHALL 将控制法线贴图生成的布尔选项显示为 **Normal Map**,并保持现有 Normal Map 生成行为。
#### Scenario: User enables Normal Map
- **WHEN** 用户在 Cutout 中开启 **Normal Map** 并选择可执行该功能的 Shape
- **THEN** 系统按该 Shape 的既定 Normal Space 生成并应用 Normal Map
### Requirement: Cutout mesh detail uses named presets
Cutout Tool SHALL 使用 **Mesh Detail** 档位选择控制网格采样密度,并将 Low、Medium、High、Ultra 分别映射为 32、16、8、4 px 的采样间距。
#### Scenario: User chooses mesh detail
- **WHEN** 用户选择任一 **Mesh Detail** 档位并创建 Cutout Shape
- **THEN** 系统使用该档位对应的采样间距构建网格,且从 Low 到 Ultra 逐档增加采样密度
#### Scenario: User keeps the default mesh detail
- **WHEN** 用户未修改 **Mesh Detail**
- **THEN** 系统使用 Low 对应的 32 px 采样间距

View File

@@ -0,0 +1,22 @@
## 1. 迁移 Selection 基础类型
- [x] 1.1 将 `common/region.py` 迁移为 `common/selection.py`,把图片选区类型、函数、参数与返回值统一重命名为 Selection,并运行 `uv run pytest tests/test_cutout_geometry.py tests/test_cutout_objects.py` 验证栅格化和几何行为不变
- [x] 1.2 更新 `common/image.py` 与 `common/viewport.py` 的选区输入、手势基类、设置辅助函数和所有调用方,同时保留 Blender Viewport Region API 名称,并运行相关 image data、clipboard 和手势测试验证交互与投影行为
## 2. 迁移 Blender 工具
- [x] 2.1 将属性工厂、三个工具设置和 Operator 参数统一为 `refine_selection`,把显示名改为 **Refine Selection**,把 Cutout 法线选项显示名改为 **Normal Map**,并运行属性与工具设置测试验证名称、独立设置和 AI 门控
- [x] 2.2 将 `cutout_point_spacing` 迁移为默认 Low 的 `cutout_mesh_detail` 四档枚举,在 Cutout 业务边界将 Low、Medium、High、Ultra 映射为 32、16、8、4 px,并用参数化测试验证全部映射及采样密度顺序
- [x] 2.3 将 Image Tool 的 Selection 数据流、细化 Operator、Operator ID、Job 类型和注册入口迁移到新名称,并运行 Image Tool 与注册测试验证本地和 AI 两条路径
- [x] 2.4 将 Cutout Tool 的 Selection Operator、交互传参、Mask/Contour 使用和结果读取迁移到新名称,并运行 `uv run pytest tests/test_cutout_interaction.py tests/test_cutout_geometry.py tests/test_cutout_objects.py` 验证 Shape 菜单、Mesh Detail 与对象构建行为
## 3. 迁移 Server 协议
- [x] 3.1 将 `server/region/` 与 Image Selection Job 文件迁移到 Selection 命名,更新 `refine-image-selection` 注册、参数、进度消息、结果字段和细化产物文件名,并运行 Server runtime 测试验证 Job 输出
- [x] 3.2 同步 Blender 与 Server 两端的 `selection_image`、`selection_bounds` 和 `refine_selection` 协议,更新打包断言,并运行 `uv run pytest tests/test_server_runtime.py tests/test_extension_packaging.py tests/test_blender_addon.py` 验证跨进程契约和扩展内容
## 4. 同步文档与完整验证
- [x] 4.1 更新 `docs/internals`、getting started 与相关索引,将图片业务范围正面描述为 Selection,并确认 **Refine Selection**、**Normal Map**、**Mesh Detail** 档位映射和新 Job/产物协议一致
- [x] 4.2 使用 `rg` 检查源码、测试和文档中的 `region`,逐项确认剩余结果仅为 Blender Viewport Region 或与图片选区无关的一般区域表达,且不存在旧模块、旧类型、旧 Operator、旧 Job、旧字段或兼容转发
- [x] 4.3 运行 `uv run pytest`,确认全部测试通过且 Selection 重命名未改变现有功能