Files
bim_engine/.sisyphus/plans/clipping-api-migration.md
yuding 4a09d52283 feat(clipping): implement hide/recover toggle for all section dialogs
Update all three section dialogs to support hide/show toggle:

SectionAxisDialogManager:
- onHideToggle now calls hideSection()/recoverSection()

SectionBoxDialogManager:
- onHideToggle now calls hideSection()/recoverSection()

SectionPlanePanel:
- Add isHidden state tracking
- Change onHide to onHideToggle(isHidden)
- Add setHiddenState/getHiddenState methods
- Update button to toggle active state

SectionPlaneDialogManager:
- Switch to onHideToggle callback
- Call hideSection()/recoverSection() based on toggle state

Behavior: Click hide button to hide section, click again to recover.
2026-02-02 16:36:17 +08:00

493 lines
14 KiB
Markdown
Raw Permalink 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.

# Clipping API Migration Plan
## TL;DR
> **Quick Summary**: 将剖切功能迁移到新的底层 API `engine.clipping.xxx`,对外只暴露统一入口 `activeSection(mode)` 和 `deactivateSection()`,移除旧的分散方法。
>
> **Deliverables**:
> - Engine 组件清理:移除残留的旧状态变量
> - EngineManager 同步更新:新增 `activeSection(mode)`,移除旧方法
> - 三个 Dialog Manager 适配新 API
> - 文档更新
>
> **Estimated Effort**: Small (Engine 已完成大部分)
> **Parallel Execution**: YES - 2 waves
> **Critical Path**: Task 1 → Task 2 → Task 3/4/5 → Task 6 → Task 7
## Pre-work Completed (by user)
Engine 组件已完成重构:
-`activeSection(mode: 'x' | 'y' | 'z' | 'box' | 'face')` - 已实现
-`getCurrentSectionMode()` - 已实现
-`setSectionBoxRange()` - 已使用 `updateClippingValue`
-`deactivateSection()` - 已实现
- ✅ 旧方法 `activateSectionAxis/Box` 等已移除
---
## Context
### Original Request
用户提供了新的底层剖切 API
```javascript
engine.clipping.active("x" | "y" | "z" | "box" | "face")
engine.clipping.disActive()
engine.clipping.disabled()
engine.clipping.recover()
engine.clipping.updateClippingValue({x:{min,max}, y:{min,max}, z:{min,max}})
engine.clipping.clippingModel(model)
```
需要将 Engine wrapper 和 EngineManager 的公开 API 统一到新入口。
### Interview Summary
**Key Discussions**:
- 公开 API 策略:只保留统一新入口,不保留旧方法名作为兼容层
- 统一激活方法命名:`activateClipping(mode)`
- Box range update不自动激活 box 模式
- SectionPlane 面板hide 接 `disabled()`reverse/reset 暂不接入
- SectionBox fit/reset不再保留统一用 `updateClippingValue()`
- 测试策略:手动验收,无自动化测试
**Research Findings**:
- 旧 API 分布在 Engine 组件和 EngineManager 中
- 三个 Dialog Manager 分别管理 axis/box/plane 剖切
- 文档 `docs/引擎API对接.md``docs/API调用链.md` 需要同步更新
---
## Work Objectives
### Core Objective
将剖切功能的公开 API 统一为 `activateClipping(mode)``deactivateSection()`,内部实现迁移到新的 `engine.clipping.xxx` API。
### Concrete Deliverables
- `src/components/engine/index.ts`:重构剖切相关方法
- `src/managers/engine-manager.ts`:同步更新公开 API
- `src/managers/section-axis-dialog-manager.ts`:适配新 API
- `src/managers/section-box-dialog-manager.ts`:适配新 API
- `src/managers/section-plane-dialog-manager.ts`:接入 hide 功能
- `docs/引擎API对接.md`:更新 API 文档
- `docs/API调用链.md`:更新调用链文档
### Definition of Done
- [x] `npm run build` 编译通过
- [x] `npm run dev:demo` 启动后,点击工具栏剖切相关按钮能正常工作
- [x] 轴向剖切 (X/Y/Z) 可切换,关闭对话框时停止剖切
- [x] 剖切盒可打开/关闭,滑块可调整范围
- [x] 拾取面剖切可打开hide 按钮可隐藏剖切面
### Must Have
- 新的统一 API`activateClipping(mode)``deactivateSection()`
- 剖切盒范围更新使用 `updateClippingValue()`
- 拾取面剖切的 hide 功能使用 `disabled()`
### Must NOT Have (Guardrails)
- 不保留旧方法名作为公开 API`activateSectionAxis``activateSectionBox` 等)
- 不自动激活 box 模式(只有用户点击剖切盒按钮才激活)
- 不实现 SectionPlane 的 reverse/reset底层暂无 API
- 不实现 SectionBox 的 fit/reset统一用百分比范围
---
## Verification Strategy (MANDATORY)
### Test Decision
- **Infrastructure exists**: NO
- **User wants tests**: NO (手动验收)
- **QA approach**: Manual verification
### Manual Verification Procedures
每个 TODO 完成后,需在 demo 环境中验证:
```bash
npm run dev:demo
```
然后在浏览器中进行以下操作验证。
---
## Execution Strategy
### Parallel Execution Waves
```
Wave 1 (Start Immediately):
└── Task 1: Engine 组件清理(仅移除残留状态变量)
Wave 2 (After Wave 1):
└── Task 2: EngineManager 适配
Wave 3 (After Wave 2):
├── Task 3: SectionAxisDialogManager 适配
├── Task 4: SectionBoxDialogManager 适配
└── Task 5: SectionPlaneDialogManager 适配
Wave 4 (After Wave 3):
└── Task 6: 文档更新
Wave 5 (Final):
└── Task 7: 集成验证
```
### Dependency Matrix
| Task | Depends On | Blocks | Can Parallelize With |
|------|------------|--------|---------------------|
| 1 | None | 2 | None |
| 2 | 1 | 3, 4, 5 | None |
| 3 | 2 | 6 | 4, 5 |
| 4 | 2 | 6 | 3, 5 |
| 5 | 2 | 6 | 3, 4 |
| 6 | 3, 4, 5 | 7 | None |
| 7 | 6 | None | None |
---
## TODOs
- [x] 1. Engine 组件清理(残留状态变量)
**What to do**:
- 移除旧状态变量:`currentSectionAxis` (第48行)、`isSectionBoxActive` (第52行)
**Must NOT do**:
- 不修改已完成的 `activeSection()` / `deactivateSection()` 等方法
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`coding-standards`]
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 1
- **Blocks**: Task 2
- **Blocked By**: None
**References**:
- `src/components/engine/index.ts:48-52` - 需要移除的旧状态变量
**Acceptance Criteria**:
**Automated Verification**:
```bash
npx tsc --noEmit -p tsconfig.json
# Assert: Exit code 0
```
**Commit**: YES
- Message: `refactor(engine): remove legacy clipping state variables`
- Files: `src/components/engine/index.ts`
---
- [x] 2. EngineManager 适配
**What to do**:
- 新增 `activeSection(mode)` 方法,转发到 Engine 的 `activeSection(mode)`
- 保留 `deactivateSection()` 方法(已存在)
- 保留 `setSectionBoxRange()` 方法(已存在)
- 移除旧方法:`activateSectionAxis()`、`deactivateSectionAxis()`、`getCurrentSectionAxis()`、`activateSectionBox()`、`deactivateSectionBox()`、`fitSectionBoxToModel()`、`resetSectionBox()`
**Must NOT do**:
- 不添加向后兼容的别名方法
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`coding-standards`]
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 2
- **Blocks**: Tasks 3, 4, 5
- **Blocked By**: Task 1
**References**:
- `src/managers/engine-manager.ts:261-338` - 现有剖切相关方法位置(需移除)
**Acceptance Criteria**:
**Automated Verification**:
```bash
npx tsc --noEmit -p tsconfig.json
# Assert: Exit code 0
```
**Commit**: YES
- Message: `refactor(engine-manager): update clipping API to unified activeSection`
- Files: `src/managers/engine-manager.ts`
---
- [x] 3. SectionAxisDialogManager 适配
**What to do**:
- 修改 `onAxisChange` 回调:将 `activateSectionAxis(axis)` 改为 `activeSection(axis)`
- 修改 `onDialogCreated`:将 `activateSectionAxis('x')` 改为 `activeSection('x')`
- 确认 `onBeforeDestroy` 已使用 `deactivateSection()`(之前已改过)
**Must NOT do**:
- 不修改 UI 组件 (section-axis-panel)
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`coding-standards`]
**Parallelization**:
- **Can Run In Parallel**: YES
- **Parallel Group**: Wave 3 (with Tasks 4, 5)
- **Blocks**: Task 6
- **Blocked By**: Task 2
**References**:
**Pattern References**:
- `src/managers/section-axis-dialog-manager.ts:67-88` - onAxisChange 和 onDialogCreated 位置
**Acceptance Criteria**:
**Automated Verification**:
```bash
npx tsc --noEmit -p tsconfig.json
# Assert: Exit code 0
```
**Manual Verification (via demo)**:
```
1. npm run dev:demo
2. 点击工具栏"轴向剖切"按钮
3. 预期:对话框打开,模型显示 X 轴剖切效果
4. 切换到 Y/Z 轴
5. 预期:剖切面随之切换
6. 关闭对话框
7. 预期:剖切效果消失
```
**Commit**: YES (groups with 4, 5)
- Message: `refactor(section-managers): adapt to unified clipping API`
- Files: `src/managers/section-axis-dialog-manager.ts`, `src/managers/section-box-dialog-manager.ts`, `src/managers/section-plane-dialog-manager.ts`
---
- [x] 4. SectionBoxDialogManager 适配
**What to do**:
- 修改 `onDialogCreated`:将 `activateSectionBox()` 改为 `activeSection('box')`
- 确认 `onBeforeDestroy` 已使用 `deactivateSection()`
- 确认 `onRangeChange` 使用 `setSectionBoxRange()`(保持不变)
- 移除 `onFitToModel` 和 `onReset` 的回调实现(不再支持)
**Must NOT do**:
- 不修改 UI 组件 (section-box-panel) 的按钮显示fit/reset 按钮保留但功能暂停)
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`coding-standards`]
**Parallelization**:
- **Can Run In Parallel**: YES
- **Parallel Group**: Wave 3 (with Tasks 3, 5)
- **Blocks**: Task 6
- **Blocked By**: Task 2
**References**:
**Pattern References**:
- `src/managers/section-box-dialog-manager.ts:55-79` - createContent 和回调设置位置
- `src/managers/section-box-dialog-manager.ts:82-85` - onDialogCreated 位置
**Acceptance Criteria**:
**Manual Verification (via demo)**:
```
1. npm run dev:demo
2. 点击工具栏"剖切盒"按钮
3. 预期:对话框打开,模型显示剖切盒效果
4. 拖动 X/Y/Z 滑块
5. 预期:剖切范围随之变化
6. 关闭对话框
7. 预期:剖切效果消失
```
**Commit**: YES (groups with 3, 5)
---
- [x] 5. SectionPlaneDialogManager 适配
**What to do**:
- 修改 `onDialogCreated`:添加 `activeSection('face')` 调用
- 修改 `onBeforeDestroy`:添加 `deactivateSection()` 调用
- 修改 `onHide` 回调:调用 `engine.clipping.disabled()`(隐藏剖切面)
- 保留 `onReverse` 和 `onReset` 为日志输出(暂不接入)
**Must NOT do**:
- 不实现 reverse/reset 功能
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`coding-standards`]
**Parallelization**:
- **Can Run In Parallel**: YES
- **Parallel Group**: Wave 3 (with Tasks 3, 4)
- **Blocks**: Task 6
- **Blocked By**: Task 2
**References**:
**Pattern References**:
- `src/managers/section-plane-dialog-manager.ts:47-75` - createContent 和回调位置
**Acceptance Criteria**:
**Manual Verification (via demo)**:
```
1. npm run dev:demo
2. 点击工具栏"拾取面剖切"按钮
3. 预期:对话框打开,进入面拾取模式
4. 点击"隐藏"按钮
5. 预期:剖切面隐藏
6. 关闭对话框
7. 预期:剖切效果消失
```
**Commit**: YES (groups with 3, 4)
---
- [x] 6. 文档更新
**What to do**:
- 更新 `docs/引擎API对接.md`
- 移除旧方法的文档
- 添加新方法 `activateClipping(mode)` / `hideClipping()` / `showClipping()` 的说明
- 更新调用链示例
- 更新 `docs/API调用链.md`
- 更新剖切功能的流程图
- 反映新的 API 名称
**Must NOT do**:
- 不删除整个章节,只更新方法名和示例
**Recommended Agent Profile**:
- **Category**: `writing`
- **Skills**: []
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 4
- **Blocks**: Task 7
- **Blocked By**: Tasks 3, 4, 5
**References**:
**Documentation References**:
- `docs/引擎API对接.md` - 完整的 API 对接文档
- `docs/API调用链.md` - 调用链流程图
**Acceptance Criteria**:
**Manual Verification**:
- [ ] 文档中不再出现 `activateSectionAxis` / `activateSectionBox` 等旧方法名
- [ ] 新方法 `activateClipping(mode)` 有清晰的说明和示例
**Commit**: YES
- Message: `docs: update clipping API documentation`
- Files: `docs/引擎API对接.md`, `docs/API调用链.md`
---
- [x] 7. 集成验证
**What to do**:
- 运行完整构建:`npm run build`
- 启动 demo 环境:`npm run dev:demo`
- 依次测试所有剖切功能:
- 轴向剖切 (X/Y/Z 切换)
- 剖切盒 (打开/关闭/范围调整)
- 拾取面剖切 (打开/隐藏)
- 确认无控制台错误
**Must NOT do**:
- 不修改任何代码(仅验证)
**Recommended Agent Profile**:
- **Category**: `quick`
- **Skills**: [`playwright`]
**Parallelization**:
- **Can Run In Parallel**: NO
- **Parallel Group**: Wave 5 (final)
- **Blocks**: None
- **Blocked By**: Task 6
**References**: None (verification only)
**Acceptance Criteria**:
**Automated Verification**:
```bash
npm run build
# Assert: Exit code 0
```
**Manual Verification (comprehensive)**:
```
1. npm run dev:demo
2. 打开浏览器控制台
[轴向剖切测试]
3. 点击"轴向剖切"按钮 → 对话框打开X轴剖切生效
4. 切换 Y → 剖切面切换
5. 切换 Z → 剖切面切换
6. 关闭对话框 → 剖切消失
[剖切盒测试]
7. 点击"剖切盒"按钮 → 对话框打开,剖切盒生效
8. 拖动 X min 滑块 → 剖切范围变化
9. 拖动 Y max 滑块 → 剖切范围变化
10. 关闭对话框 → 剖切消失
[拾取面剖切测试]
11. 点击"拾取面剖切"按钮 → 对话框打开
12. 点击"隐藏"按钮 → 剖切面隐藏(控制台无错误)
13. 关闭对话框 → 剖切消失
14. 检查控制台:无错误信息
```
**Commit**: NO (verification only)
---
## Commit Strategy
| After Task | Message | Files | Verification |
|------------|---------|-------|--------------|
| 1 | `refactor(engine): migrate clipping to unified activateClipping API` | src/components/engine/index.ts | tsc --noEmit |
| 2 | `refactor(engine-manager): update clipping API to unified entry points` | src/managers/engine-manager.ts | tsc --noEmit |
| 3, 4, 5 | `refactor(section-managers): adapt to unified clipping API` | section-*-dialog-manager.ts | tsc --noEmit |
| 6 | `docs: update clipping API documentation` | docs/*.md | manual review |
---
## Success Criteria
### Verification Commands
```bash
npm run build # Expected: exit 0, no errors
npm run dev:demo # Expected: server starts, no runtime errors
```
### Final Checklist
- [x] 新 API `activeSection(mode)` 可用
- [x] 旧 API 已移除(`activateSectionAxis` 等)
- [x] 轴向剖切功能正常
- [x] 剖切盒功能正常
- [x] 拾取面剖切的 hide 功能正常
- [x] 文档已更新
- [x] 无 TypeScript 编译错误
- [x] 无运行时控制台错误