Add comprehensive tests for edge depth extension, empty image edits, and material view adaptation

- Introduced `test_edge_depth.py` to validate the functionality of edge depth extension, ensuring core alpha preservation, proper depth handling, and edge padding behavior.
- Created `test_empty_image_edits.py` to verify the behavior of image edits in Blender, focusing on shared edits, preservation of image properties, and handling of failed operations.
- Developed `test_material_view_adaptation.py` to test material adaptation preferences, ensuring color space and alpha settings are correctly applied and preserved across various scenarios.
This commit is contained in:
2026-09-06 21:43:47 +08:00
parent 1994d38ccd
commit 7e55af6722
58 changed files with 3607 additions and 200 deletions

View File

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

View File

@@ -0,0 +1,61 @@
## Context
`common/material.py` 通过 `scene.view_settings.view_transform` 选择颜色空间,随后调用 `configure_color_alpha()` 固定设置 PREMUL。当前映射包含 ACES 1.3、ACES 2.0、AgX、Filmic 和 Khronos PBR Neutral;Standard 及未匹配视图返回 sRGB。剪贴板 Mesh 材质使用独立构建入口。
`common/image.py` 的 Alpha 配置服务于普通编辑结果。此次策略集中作用于材质 Color Image,并复用已有像素读取和恢复机制。
## Goals
- 提供一个全局着色偏好,作为材质颜色贴图适配状态的唯一控制来源。
- 保证实际 inverse 空间搭配 STRAIGHT,实际 sRGB 搭配 PREMUL。
- 保留 Color 的业务 RGB、Alpha、透明区域 RGB 和共享源图片。
## Decisions
### 偏好与生效时间
在 `AnyImagePreferences` 添加布尔属性 `adapt_material_to_view_transform`,UI 名称为 `Adapt to Scene View Transform`,放入独立 Shading 分组。默认值采用 `False`,让用户主动启用适配;这是本提案的默认选择。读取入口放在 `preferences.py`,通过 `addon_preferences()` 获取;偏好不可用时采用相同默认值。
新建材质时读取当前偏好,已创建的材质 Color Image 保留原配置。切换偏好只决定后续创建的材质贴图策略。创建操作、源图片状态和场景 View Transform 都只能参与贴图配置,不能改写适配开关。View Transform 用于开启适配时选择对应颜色空间,回退到 sRGB 后偏好仍保持开启。
### 颜色空间与 Alpha 一起决策
```mermaid
flowchart TD
A[新建材质 Color] --> B{Preferences 开启视图适配}
B -->|是| C[按当前场景选择颜色空间]
B -->|否| D[设置 sRGB]
C --> E{对应 inverse 空间可用}
E -->|是| F[设置 inverse 空间]
E -->|否| D
F --> G[设置 STRAIGHT]
D --> H[设置 PREMUL]
G --> I[绑定材质颜色贴图]
H --> I
```
沿用 `VIEW_TRANSFORM_COLOR_SPACES` 中的准确名称。Standard、未匹配的 View Transform、缺失 scene 以及不支持的 inverse 空间统一使用 sRGB + PREMUL;这属于颜色空间解析结果,适配开关仍由 Preferences 保持。Alpha 模式以实际成功应用的颜色空间为准。如果连 sRGB 也无法设置,配置明确报错并保留该贴图之前的有效配置。
### 公共配置边界
在 `common/material.py` 集中配置材质 Color 的颜色空间和 Alpha。公共材质与剪贴板 Mesh 材质创建入口调用同一配置函数,在 Blender 主线程处理,颜色空间映射采用创建时当前场景的 View Transform。审查 Plane、Depth Plane、Cutout 调用链,保证加载、复制或 Pack 步骤保持偏好决定的配置。
材质专属配置函数负责设置 STRAIGHT 或 PREMUL;普通图片编辑继续使用现有 `configure_color_alpha()`。复用 `common` 中的像素读取函数处理数据保留。
颜色空间和 Alpha 都属于 Image 数据块属性。配置作用于本次新建材质专用的 Color Image;当源图还被 Empty、普通图片编辑或已有材质引用时,先复制并仅绑定本次新建材质的 Color 节点。复用 `image_pixels()` 读取业务像素,对 generated、dirty、packed 和文件来源验证两项设置先后变化后的内容保留。
### 与已有 Alpha 变更的协调
活动变更 `enable-image-alpha-blending-and-premul` 中 `Mesh Color images use PREMUL independently of data textures` 的材质规则由本变更细化为颜色空间配对策略。实施时调整对应材质断言,归档时保证最终主规格采用此规则。普通编辑结果默认 PREMUL、Empty Alpha Blending、Depth 与 Normal 数据解释继续按各自规格执行。
## Risks / Trade-offs
- inverse + STRAIGHT 的边缘优势来自用户观察,需使用实际半透明边缘在 Blender 中复核;属性断言只能验证策略落地。
- Image 颜色空间或 Alpha 切换可能改变像素读取解释,需覆盖 Pack、保存重载以及重新作为编辑源的行为。
- 新建材质使用共享源图片时,需要隔离本次 Color 配置,保障已有材质及图片的其他用途。
## Validation
测试偏好默认值、UI、注册与逆序注销;覆盖各视图映射、关闭状态、Standard 和 inverse 不可用的回退,并断言创建及回退前后偏好值保持一致。对 Plane、Depth Plane、Cutout、剪贴板材质验证切换偏好后已有 Color 保持原值、新建 Color 使用当前设置及共享图片隔离。回归验证 Empty、普通编辑结果、Depth、Normal 和非目标材质保持原值。对 byte、float、generated、dirty、packed 材质图片验证业务 RGB/Alpha 保留及保存重载;在实际 Blender 中比较半透明边缘并记录结果。
实施完成后运行 `uv run pytest`。本次实施仅修改实现和测试。

View File

@@ -0,0 +1,29 @@
## Why
用户实测材质颜色贴图在 inverse 类颜色空间下使用 STRAIGHT 边缘更好,在 sRGB 下使用 PREMUL 效果合适。当前材质入口自动适配场景 View Transform 并统一设置 PREMUL,需要提供着色偏好,让用户选择适配方式并配套正确的 Alpha 模式。
## What Changes
- Preferences 新增 Shading 分组和 Adapt to Scene View Transform(适配场景视图变换)开关,默认关闭。
- 开启时根据当前场景选择对应 inverse 颜色空间,并设置 STRAIGHT。
- 关闭时使用 sRGB + PREMUL;开启适配但实际回退到 sRGB 时也使用 PREMUL。
- Preferences 是适配开关的唯一控制来源;新建材质读取当前设置,已创建的材质贴图保留原配置。
- Plane、Depth Plane、Cutout 和剪贴板 Mesh 材质的 Color Image 统一应用该策略,保留业务像素和源图片独立性。
## Capabilities
### New Capabilities
- `material-view-adaptation`: 材质视图适配偏好、颜色空间与 Alpha 配对、应用时机和像素保留。
### Modified Capabilities
无。当前主规格目录为空;与活动变更 `enable-image-alpha-blending-and-premul` 的 Mesh Color 默认值重叠部分,在实施和归档时按本变更的配对策略协调。
## Impact
- `src/anyimage/preferences.py`:偏好属性、统一读取入口和 Shading UI。
- `src/anyimage/common/material.py`:颜色空间选择与材质 Color 配置。
- `src/anyimage/common/image.py`:复用现有业务像素读取能力;材质专属策略由 `common/material.py` 承担。
- `src/anyimage/operators/clipboard_image/actions.py`:接入公共材质 Color 配置。
- Blender 偏好注册、材质配置、Alpha 数据保留和转换入口测试。

View File

@@ -0,0 +1,108 @@
## ADDED Requirements
### Requirement: Preferences expose material view adaptation
AnyImage SHALL 在 Preferences 的 Shading 分组提供 `Adapt to Scene View Transform` 布尔选项,默认关闭。扩展设置及读取入口 SHALL 位于 `preferences.py`,并通过 `addon_preferences()` 读取。
#### Scenario: Preferences use the default
- **WHEN** 用户尚未设置该选项或读取不到扩展偏好
- **THEN** 材质颜色贴图 SHALL 使用关闭适配的行为
### Requirement: Material color space determines alpha presentation
开启适配时,AnyImage SHALL 按当前场景 View Transform 选择既有映射中的 inverse 颜色空间,并使用 STRAIGHT。关闭适配时 SHALL 使用 sRGB + PREMUL。实际回退为 sRGB 时 SHALL 使用 PREMUL,并保持 Preferences 中的适配开关原值。
#### Scenario: A supported view is adapted
- **WHEN** 适配开启,当前场景为 AgX,且 `AgX Base sRGB` 可用
- **THEN** 材质 Color Image SHALL 使用 `AgX Base sRGB` + STRAIGHT
#### Scenario: Other mapped views are adapted
- **WHEN** 适配开启,场景使用 ACES 1.3、ACES 2.0、Filmic 或 Khronos PBR Neutral,且对应空间可用
- **THEN** Color Image SHALL 分别使用 `ACES 1.3 sRGB`、`ACES 2.0 sRGB`、`Filmic sRGB` 或 `Khronos PBR Neutral sRGB`
- **AND** Alpha 模式 SHALL 为 STRAIGHT
#### Scenario: Adaptation is disabled
- **WHEN** 适配关闭,创建任意受支持入口的材质
- **THEN** Color Image SHALL 使用 sRGB + PREMUL
#### Scenario: The scene resolves to sRGB
- **WHEN** 适配开启,但场景为 Standard、视图未匹配、场景不可用或 inverse 空间不被支持
- **THEN** Color Image SHALL 使用 sRGB + PREMUL
#### Scenario: The fallback color space is unavailable
- **WHEN** 所需颜色空间及 sRGB 均无法应用
- **THEN** 配置 SHALL 明确报错并保留贴图之前的有效配置
- **AND** Preferences 中的适配开关 SHALL 保持原值
### Requirement: Material entry points apply the same policy
AnyImage SHALL 在 Plane、Depth Plane、Cutout 和剪贴板 Mesh 材质创建时统一配置 Color Image。最终模式 SHALL 在后续绑定及交付步骤中保留。Depth 与 Normal SHALL 保留各自的数据解释约定。
#### Scenario: A material is created from an edited color result
- **WHEN** 一个 PREMUL 编辑结果进入开启适配的 inverse 材质
- **THEN** 最终材质 Color Image SHALL 为 STRAIGHT
- **AND** 材质交付后 SHALL 保留该模式
#### Scenario: Shadeless material is created
- **WHEN** 用户通过支持 Shadeless 的入口创建材质
- **THEN** Color Image SHALL 应用相同颜色空间与 Alpha 配对策略
### Requirement: Configuration preserves business pixels and source ownership
材质 Color 配置 SHALL 保留原有业务 RGB、Alpha 和完全透明区域 RGB,并在 Pack、保存重载和再次编辑后保持可读取。配置 SHALL 作用于材质专用 Color Image 或独立 Color 副本。
#### Scenario: The source image has other users
- **WHEN** 源 Image 同时被其他对象引用
- **THEN** 配置 SHALL 作用于独立 Color 结果
- **AND** 原 Image 的颜色空间、Alpha 模式和业务像素 SHALL 保持原值
#### Scenario: A color result is packed and reopened
- **WHEN** byte、float、generated、dirty 或 packed 来源的 Color 完成配置并保存重载
- **THEN** 业务 RGB/Alpha SHALL 在既有编码精度内保留
- **AND** 结果 SHALL 保持所选颜色空间和 Alpha 模式
### Requirement: Preferences exclusively control material adaptation
Preferences SHALL 是适配开关的唯一控制来源。新建材质 SHALL 读取当前偏好;已创建的材质颜色贴图 SHALL 保留原配置。创建操作和颜色空间解析 SHALL 保持偏好值。
#### Scenario: The preference changes
- **WHEN** 用户在 Preferences 开启或关闭适配
- **THEN** AnyImage 已创建的材质颜色贴图 SHALL 保持原颜色空间、Alpha 模式和像素
- **AND** 后续新建材质 SHALL 使用新的偏好设置
#### Scenario: A new material shares its source with an existing material
- **WHEN** 切换偏好后,使用已被现有材质引用的源 Image 创建新材质
- **THEN** 新材质 SHALL 使用独立 Color Image 并应用当前偏好
- **AND** 已有材质的贴图及其配置 SHALL 保持原值
#### Scenario: A material is created or an inverse space is unavailable
- **WHEN** 创建材质或颜色空间解析发生回退
- **THEN** Preferences 中的适配开关 SHALL 保持操作前的值
### Requirement: Adaptation affects only material color textures
本选项 SHALL 仅配置 AnyImage 材质的 Color 贴图。Empty、普通图片编辑结果、Depth、Normal 和非目标材质 SHALL 保持原有行为与数据。
#### Scenario: A material color image is shared with an Empty
- **WHEN** 新建材质的源 Color Image 同时被 Empty 引用
- **THEN** 系统 SHALL 为材质 Color 创建独立副本并重新绑定目标节点
- **AND** Empty 引用的原 Image 的颜色空间、Alpha 模式与业务像素 SHALL 保持原值
#### Scenario: Ordinary image editing runs with adaptation enabled
- **WHEN** 开启适配后执行 Mask、Frame、Rectify 或图片编辑 Job
- **THEN** 编辑结果 SHALL 沿用各自已有颜色空间与 Alpha 规则

View File

@@ -0,0 +1,32 @@
## 1. 着色偏好
- [x] 1.1 在 `preferences.py` 增加默认关闭的 `adapt_material_to_view_transform`、统一读取入口和 Shading 分组。
- [x] 1.2 补充偏好默认值、读取回退、UI 展示测试,并检查 `__init__.py` 注册和逆序注销。
## 2. 材质配置
- [x] 2.1 在 `common/material.py` 集中颜色空间与 Alpha 配对:inverse + STRAIGHT,sRGB + PREMUL;实现映射、回退和设置失败处理。
- [x] 2.2 在材质专属配置入口设置 Alpha,复用现有业务像素读取能力,验证颜色空间与 Alpha 连续切换的数据完整性。
- [x] 2.3 接入公共材质与剪贴板 Mesh 入口,审查 Plane、Depth Plane、Cutout 的独立 Color 所有权及最终交付模式。
- [x] 2.4 确保新建材质使用独立 Color 图片,隔离共享源对已有材质及其他用途的影响。
## 3. 验证
- [x] 3.1 覆盖开关两种状态、全部既有视图映射、Standard、场景缺失、inverse 不可用及 sRGB 设置失败。
- [x] 3.2 覆盖各材质入口及 Shadeless,验证切换偏好后已有材质 Color 保持原值,新建材质读取当前设置,创建和回退均保持偏好值。
- [ ] 3.3 更新现有材质 PREMUL 断言,验证 byte、float、generated、dirty、packed Color 的 RGB/Alpha、透明 RGB、Pack、保存重载和再次编辑。
- [x] 3.4 在实际 Blender 中用半透明边缘复核 inverse + STRAIGHT 与 sRGB + PREMUL 的效果,并记录验证结果。
- [x] 3.5 运行 `uv run pytest`,修复相关回归。
- [x] 3.6 验证仅材质 Color 受影响:共享源、Empty、Mask/Frame/Rectify、图片编辑 Job、Depth、Normal 和非目标材质保持原有行为与数据。
## 4. 规格收敛
- [ ] 4.1 归档时协调 `enable-image-alpha-blending-and-premul` 的 Mesh Color 需求,使最终主规格统一采用本变更的颜色空间与 Alpha 配对。
## 验证记录
2026-09-05:`uv run --no-sync pytest -q --tb=short`:562 passed、2 xfailed、56 subtests passed。`--no-sync` 使用本轮已同步的项目环境。OpenSpec strict 校验通过。
Blender 4.5.3 LTS / Cycles CPU、AgX、16 samples:渲染 64×64 橙色圆形贴图的渐变 Alpha 边缘,192×192 输出。sRGB + PREMUL 和 AgX Base sRGB + STRAIGHT 均正常显示连续半透明边缘;后者中心色更接近输入橙色。该检查确认两种策略可用。
3.3 部分完成:byte、generated byte、dirty、文件和 packed 图片的业务像素及保存重载通过;原生浮点图片在保存重载后的 RGB 不满足原值断言,两种设置均可复现,已用严格 xfail 保留检查。即时配置和共享源保留通过。此项尚未解决,因此保留未完成状态。4.1 留待归档阶段处理。