Files
AnyImage/openspec/changes/archive/2026-09-17-match-polyline-gesture-interaction/design.md
nan 076a8c90f1 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.
2026-09-17 17:19:05 +08:00

67 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
`ImageGesture` 已在屏幕空间维护 Polyline 的已提交顶点与移动光标,并在三个顶点后允许点击起点 8 px 范围完成。当前闭合圈只在进入命中范围后以固定尺寸出现,缺少接近过程反馈;Modal 也不处理 `DOUBLE_CLICK`。Mask 使用单一 WorkspaceTool 承载 Lasso、Brush 与 Polyline,当前未声明工具光标。
Blender 的 Polyline Gesture 将实际点击半径与更大的视觉提示范围分开:实际命中半径为 `15 × UI Scale`,鼠标进入约为该半径平方的提示距离后,起点圈从 `1 × UI Scale` 平滑放大到实际命中半径。Polyline modal keymap 将左键双击作为 Confirm;Sculpt 的 Box、Lasso、Line 与 Polyline Mask/Hide 工具统一使用 `PAINT_CROSS`。
## Goals / Non-Goals
**Goals:**
- 让 Polyline 起点闭合提示具有与 Blender 一致的渐进接近反馈和命中范围。
- 支持双击完成有效 Polyline,并保留现有完成、回退和取消方式。
- 让统一 Mask Tool 使用适合区域编辑的十字光标。
- 将距离、缩放与事件判定保持为易单测的屏幕空间逻辑。
**Non-Goals:**
- 不调用或包装 Blender 内建 Polyline Operator。
- 不改变 Polyline 顶点投影、Selection 栅格化或 Alpha 合成。
- 不加入起点吸附、自动修改最后一个顶点或新的用户设置。
- 不拆分现有单一 Mask Tool。
## Decisions
### 1. 分离闭合命中半径与视觉提示距离
定义 15 px 基础闭合半径,并使用操作开始时读取的 UI Scale 得到实际命中半径。视觉提示距离沿用 Blender 的 `scaled_radius²`;只有已提交至少三个点且鼠标位于该范围内时才绘制起点圈。
提示圈半径使用 smoothstep 随距离插值:鼠标位于提示范围边缘时接近 `1 × UI Scale`,位于起点时等于实际闭合半径。绘制使用一明一暗的相邻轮廓,使提示在亮、暗图片上都可辨认。
选择独立的纯计算 Helper,而不是在 Draw Handler 内直接散落公式,以便精确测试边界、单调性和 UI Scale。
### 2. 点击只使用实际闭合半径
渐进提示范围只控制视觉反馈,不扩大可点击区域。普通左键按下仍先判断是否已有三个点且光标位于实际闭合半径内;命中时直接完成并且不提交新顶点,否则沿用现有最小点距规则添加顶点。
不使用整个提示范围作为命中范围,避免鼠标离起点较远时意外闭合。
### 3. Modal 同时处理原生双击与连续按下
`ImageGesture._modal_polyline()` 在普通左键按下分支之前处理 `LEFTMOUSE` 的 `DOUBLE_CLICK`。同时记录最近一次左键按下的位置与时间:当 Blender 只向 Python Modal 连续发送两个 `PRESS` 时,使用用户设置中的双击间隔和 `5 px × UI Scale` 位移范围识别第二击。当已提交至少三个点时复用 `_confirm_polyline()`;点数不足时保持 Modal,不应用 Selection。
Blender 内建 Gesture 依靠 Modal Keymap 将双击转换为 Confirm,但当前 Python Operator 没有该映射,因此不能只依赖 `DOUBLE_CLICK` 事件。不为 WorkspaceTool 增加第二个启动 keymap 项,因为双击发生时 Operator 已处于 Modal,连续按下判定可以避免再次启动 Operator 或复制完成逻辑。双击只完成现有已提交路径,第二击不得添加重复顶点。
### 4. 统一 Mask Tool 使用 PAINT_CROSS
在 `MaskTool` 上声明 `bl_cursor = "PAINT_CROSS"`。这会覆盖 Lasso、Brush 与 Polyline,符合 Blender 对 Sculpt Mask/Hide 区域手势的统一光标约定,也避免根据 Gesture 动态设置和恢复 Window cursor。
### 5. 保留当前项目已有控制
Enter、Numpad Enter、Backspace、RMB、Esc、工具切换取消和至少三个已提交点的完成门槛保持不变。状态文本补充双击完成,但不改变 Mode 或 Brush Radius 的展示。
## Risks / Trade-offs
- [提示距离按半径平方后明显大于实际命中范围] → 圆圈在远处保持接近 1 px,并通过连续放大表达接近程度;点击仍严格限制在实际半径内。
- [UI Scale 与 Region 坐标可能在不同平台产生取整差异] → 全程使用浮点屏幕坐标,只在比较和绘制中复用同一个缩放值,并对 1.0 与非 1.0 Scale 建立单测。
- [Python Modal 可能收到原生 `DOUBLE_CLICK`,也可能只收到连续 `PRESS`] → 同时支持两种事件链;连续按下仅在用户双击时间和小范围位移内成立,第二击不追加点。
- [`PAINT_CROSS` 同时影响非 Polyline Gesture] → Blender 的 Box、Lasso 与 Polyline Mask/Hide 本身采用同一光标,因此统一行为优先于引入动态 cursor 生命周期。
## Migration Plan
先替换闭合提示计算与绘制,再加入双击事件和 Tool cursor,随后更新状态文本、测试与内部文档。此变更不迁移持久数据;回滚只需恢复旧的固定半径提示、事件分支与默认 cursor。
## Open Questions
无。交互常量、光标范围和双击完成语义均以 Blender 当前 Polyline Gesture 为准。