Refactor Cutout Tool to Use World Space Edge Length
- Replaced the Mesh Detail parameter with a new Edge Length property to define cutout sampling in physical units. - Introduced Minimum Relative Edge Length preference to control effective spacing based on the bounding box of the cutout content. - Updated tests to validate the new edge length functionality and ensure consistent behavior across different resolutions and canvas sizes. - Removed deprecated parameters and adjusted related properties to align with the new edge length implementation. - Enhanced geometry sampling logic to utilize effective world spacing for both standard and fine outline modes.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-12
|
||||
@@ -0,0 +1,38 @@
|
||||
## Context
|
||||
|
||||
当前工具栏以 Mesh Detail 枚举映射像素间距,Operator 按裁切像素长边和 Maximum Cutout Mesh Resolution 限制间距。普通几何随后将像素间距换算到世界度量,Fine Outline 在像素空间生成网格。两条路径需要统一为物理长度驱动。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
本变更负责 Cutout 的目标采样长度、场景单位换算、相对密度限制,以及普通轮廓和 Fine Outline 的一致性。实施范围为工具属性、偏好、几何采样链和相关测试。
|
||||
|
||||
## Decisions
|
||||
|
||||
### 参数与单位
|
||||
|
||||
工具栏使用 `cutout_edge_length`,标签 Edge Length,正值 FloatProperty,使用 Blender 长度单位显示;通过公共属性工厂提供一致的 Operator 参数。初始物理默认值为 0.1 m。内部明确区分 Blender 世界单位与米:世界长度乘 `scene.unit_settings.scale_length` 得到米。场景属性以米存储,通过读写回调转换 Blender 世界单位;Operator 使用原生长度属性接收菜单传入的世界单位值,确保 Blender 复制参数时保留输入。属性初始化和显示遵循 Blender 的长度属性语义,避免重复换算;用实际 Blender 测试覆盖非默认 Unit Scale 下的初始值与输入值。无单位场景按 Unit Scale 换算,默认比例 1。
|
||||
|
||||
### 有效间距
|
||||
|
||||
在裁切内容确定后,使用参与建网的内容范围计算局部包围盒,将其图像平面两条轴向边向量应用世界变换,取较长者作为 L。该定义包含非均匀缩放,旋转前后保持一致;多块内容共用整体包围盒,孔洞不改变外部范围。范围依据有效 Alpha 与选区的交集;透明留白不扩大基准。
|
||||
|
||||
Preferences 增加 `min_cutout_relative_edge_length`,标签 Minimum Relative Edge Length,百分比显示,Blender 百分比属性保存百分数(默认 1,范围 0.001 到 100),preferences.py 读取入口换算为比例(默认 0.01)。
|
||||
|
||||
以相同长度单位计算 `effective_edge_length = max(edge_length, L * min_relative_edge_length)`。这里限制的是目标点间距;相对限制生效时,界面可见反馈使用场景长度格式显示 Effective Edge Length。操作前尚无有效内容范围时,在执行得到范围后通过 Operator 报告显示有效值。用户请求值和实际值分别保存,避免执行改写工具参数。
|
||||
|
||||
### 采样链
|
||||
|
||||
普通轮廓与 Fine Outline 共用同一有效世界间距和世界平面度量。轮廓读取继续使用 Alpha 数据;基础内部采样、边界重采样及相关容差统一从有效间距派生。Fine Outline 将轮廓变换到世界平面度量后,按有效间距归一化为目标间距 32 的计算坐标,统一既有轮廓容差和约束采样尺度。非均匀缩放下距离判断保持一致;Alpha 宽度样本使用最小奇异值保守换算,仅辅助细枝支撑判断,输出映射回像素坐标用于 UV。沿现有真实调用链检查清理容差等间距消费者。
|
||||
|
||||
同步与 AI 异步路径使用相同解析入口,在 Blender 主线程读取场景和对象数据,后台参数保持普通可序列化值。AI 内容返回后根据实际建网内容范围解析最终有效间距。
|
||||
|
||||
### 替换与验证
|
||||
|
||||
删除旧 Mesh Detail 枚举、档位映射、以源像素为单位的 Operator 间距参数,以及 Maximum Cutout Mesh Resolution 属性和读取函数。相关保存属性直接使用新默认值,不保留转发或兼容层。更新注册清单检查与相关测试。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- 相对限制生效后,放大对象可能提高实际间距 → 展示有效长度,并测试限制两侧的行为。
|
||||
- Fine Outline 和三角剖分会产生短边,1% 不等同于严格顶点预算 → 保留细轮廓语义,验证整体采样密度与细小部件存活。
|
||||
- Alpha 像素化使不同分辨率的边界略有差异 → 分辨率不影响目标间距,测试比较几何密度容差而非要求任意图片顶点完全相同。
|
||||
- 单位换算或非均匀缩放可能导致两条采样路径分歧 → 使用不同 Unit Scale、旋转和非均匀缩放的几何用例验证。
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
Cutout 的 Mesh Detail 使用源图像像素间距,用户难以从 Image Empty 的外观预判生成密度。改用场景物理长度,让网格密度由明确的目标边长控制,并通过裁切区域的相对尺寸限制生成成本。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **BREAKING**:将 Mesh Detail 枚举替换为带长度单位的 Edge Length 浮点参数,初始默认值为 0.1 m。
|
||||
- 按世界变换和场景 Unit Scale 计算采样间距,图片分辨率与画布大小不参与密度定义。
|
||||
- Preferences 使用 Minimum Relative Edge Length 百分比替换 Maximum Cutout Mesh Resolution,默认 1%;实际间距取用户长度与裁切包围盒世界长边乘比例的较大值。
|
||||
- 普通轮廓与 Fine Outline 共用有效间距语义;相对限制作用于目标采样间距,轮廓适配允许更短的边。
|
||||
- 限制生效时展示实际采用的目标长度。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `cutout-edge-length`: Cutout 的物理目标边长、相对密度限制及一致的采样与界面行为。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
无。当前 openspec/specs 下无已归档能力规范。
|
||||
|
||||
## Impact
|
||||
|
||||
涉及 properties.py、preferences.py、cutout_tool 的交互、Operator、几何与 Fine Outline 采样链,以及相关注册、偏好与几何测试。移除旧枚举映射、像素间距协议和旧密度上限入口;无需新增依赖。
|
||||
@@ -0,0 +1,65 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Physical edge length control
|
||||
|
||||
系统 SHALL 提供正值浮点长度参数 Edge Length,初始物理默认值为 0.1 m,遵循 Blender 场景单位显示与换算。
|
||||
|
||||
#### Scenario: Default length
|
||||
- **WHEN** 用户首次使用 Cutout
|
||||
- **THEN** Edge Length 的初始值表示 0.1 m,并可连续调整
|
||||
|
||||
#### Scenario: Scene unit conversion
|
||||
- **WHEN** 场景 Unit Scale 为 0.01,用户输入 0.1 m 且相对限制未触发
|
||||
- **THEN** 建网目标间距为 10 个 Blender 世界单位
|
||||
|
||||
### Requirement: Relative spacing floor
|
||||
|
||||
系统 SHALL 在 Preferences 提供 Minimum Relative Edge Length 百分比,默认 1%,并使用 `max(请求边长, 有效裁切包围盒世界长边 × 最小比例)` 计算有效目标间距。包围盒 SHALL 来自参与建网的有效内容,包含所有组件,采用图像平面轴向边经过世界变换后的较长边。
|
||||
|
||||
#### Scenario: Floor is applied
|
||||
- **WHEN** 包围盒长边为 1 m,最小比例为 1%,请求边长为 0.001 m
|
||||
- **THEN** 有效目标间距为 0.01 m
|
||||
|
||||
#### Scenario: Requested spacing is retained
|
||||
- **WHEN** 包围盒长边为 1 m,最小比例为 1%,请求边长为 0.1 m
|
||||
- **THEN** 有效目标间距为 0.1 m
|
||||
|
||||
#### Scenario: Preference changes
|
||||
- **WHEN** 用户将最小比例改为 2%,包围盒长边为 1 m,请求边长为 0.001 m
|
||||
- **THEN** 有效目标间距为 0.02 m
|
||||
|
||||
### Requirement: Stable world density
|
||||
|
||||
系统 SHALL 根据有效世界间距驱动普通轮廓与 Fine Outline 的基础采样。图片分辨率与有效内容外的画布 SHALL 不参与目标间距定义;对象世界变换 SHALL 参与空间长度计算。
|
||||
|
||||
#### Scenario: Resolution and canvas changes
|
||||
- **WHEN** 相同物理尺寸和轮廓的主体更换图像分辨率或增加透明画布,参数保持一致
|
||||
- **THEN** 两种建网模式采用相同的有效目标间距
|
||||
|
||||
#### Scenario: Object scaling below the floor threshold
|
||||
- **WHEN** 用户放大 Image Empty 且相对限制仍未触发
|
||||
- **THEN** 目标边长保持一致,放大的区域获得更多采样点
|
||||
|
||||
#### Scenario: Rotation and nonuniform scale
|
||||
- **WHEN** 对象旋转或非均匀缩放
|
||||
- **THEN** 两种建网模式在世界平面度量中应用有效间距,旋转不改变包围盒长边基准
|
||||
|
||||
### Requirement: Detail preserving spacing semantics
|
||||
|
||||
系统 SHALL 将长度限制解释为基础采样目标,允许轮廓适配和三角剖分产生更短的边,并保持 Fine Outline 的细小部件支持。
|
||||
|
||||
#### Scenario: Thin outline feature
|
||||
- **WHEN** Fine Outline 处理宽度小于有效间距的可用细小轮廓
|
||||
- **THEN** 建网可增加局部采样并生成较短边,以保留该轮廓
|
||||
|
||||
### Requirement: Effective length feedback and parameter replacement
|
||||
|
||||
系统 SHALL 在相对限制生效后显示有效目标长度,并保留用户请求长度。系统 SHALL 使用新长度属性和相对偏好替换旧 Mesh Detail 枚举与最大网格分辨率设置。
|
||||
|
||||
#### Scenario: Visible clamp result
|
||||
- **WHEN** 用户请求 0.1 m,但实际采用 0.2 m
|
||||
- **THEN** 界面反馈显示有效长度 0.2 m,用户设置仍为 0.1 m
|
||||
|
||||
#### Scenario: Consistent execution paths
|
||||
- **WHEN** 用户通过同步或 AI 异步路径生成 Cutout
|
||||
- **THEN** 系统依据最终建网内容采用同一套有效边长规则
|
||||
17
openspec/changes/use-world-space-cutout-edge-length/tasks.md
Normal file
17
openspec/changes/use-world-space-cutout-edge-length/tasks.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## 1. 参数与偏好
|
||||
|
||||
- [x] 1.1 将 Mesh Detail 替换为 Edge Length 长度属性,接通工具栏、菜单与 Operator,验证默认 0.1 m 和场景单位语义。
|
||||
- [x] 1.2 将最大网格分辨率偏好替换为默认 1% 的 Minimum Relative Edge Length,统一 preferences.py 读取入口,更新属性注册与相关测试。
|
||||
|
||||
## 2. 世界空间采样
|
||||
|
||||
- [x] 2.1 从有效裁切内容求世界平面轴向包围盒长边,实现包含 Unit Scale 的有效间距计算,覆盖比例限制、旋转、非均匀缩放与透明留白。
|
||||
- [x] 2.2 将普通轮廓的重采样、内部采样和间距衍生容差接入有效世界间距,移除源像素密度换算链。
|
||||
- [x] 2.3 将 Fine Outline 的密度判断接入统一世界度量,保持 Alpha 取样、UV 和细小轮廓支持,验证非均匀缩放下的目标间距。
|
||||
- [x] 2.4 同步与 AI 异步执行路径使用最终内容范围计算有效间距;保持 Blender 数据读取在主线程,分别保留请求值和有效值。
|
||||
|
||||
## 3. 反馈与验证
|
||||
|
||||
- [x] 3.1 相对限制生效时使用场景长度格式反馈有效值,补充设置值保持不变的交互测试。
|
||||
- [x] 3.2 更新相关几何测试,覆盖分辨率和画布变化、缩放、两种轮廓模式及细小部件;补充实际 Blender 非默认 Unit Scale 的长度输入与初始化验证。
|
||||
- [x] 3.3 检查并移除旧档位、像素间距参数和旧偏好引用,运行相关测试并确认正常退出,检查最终差异。
|
||||
Reference in New Issue
Block a user