2026-05-24-19-17-13 补齐位姿精度并隐藏自动拉伸成功提示

This commit is contained in:
2026-05-24 19:24:26 +08:00
parent b6e6ace233
commit e380a19acb
9 changed files with 174 additions and 14 deletions

View File

@@ -13,7 +13,7 @@
当前 Docker 构建会同步包含以下能力: 当前 Docker 构建会同步包含以下能力:
- 二维逆向分割映射按实体填充显示rib、skin 等薄壳或细长构件会做局部实体化兜底,导出的分割 Label Map 也按填充区域写入。 - 二维逆向分割映射按实体填充显示rib、skin 等薄壳或细长构件会做局部实体化兜底,导出的分割 Label Map 也按填充区域写入。
- 模型位姿支持以模型中心沿 X/Y/Z 轴镜像翻转,平移和缩放支持 `0.001` 级微调,保存、项目库预览和导出均沿用该位姿。 - 模型位姿支持以模型中心沿 X/Y/Z 轴镜像翻转,平移和缩放支持 `0.001` 级微调,保存、项目库预览和导出均沿用该位姿;自动拉伸完成后不再在位姿区保留成功提示
- “构件分别导出”会把所有构件 NIfTI 文件集中到导出包内的 `segmentation-parts/` 目录。 - “构件分别导出”会把所有构件 NIfTI 文件集中到导出包内的 `segmentation-parts/` 目录。
- 项目库 DICOM 首页支持滚轮缩放、拖拽平移和位置重置。 - 项目库 DICOM 首页支持滚轮缩放、拖拽平移和位置重置。
- 项目库与工作区的 DICOM 切片编号按医学影像顺序显示,滑条使用非进度条样式。 - 项目库与工作区的 DICOM 切片编号按医学影像顺序显示,滑条使用非进度条样式。

View File

@@ -155,6 +155,12 @@ const defaultModelPose: ModelPoseValue = {
flipY: false, flipY: false,
flipZ: false, flipZ: false,
}; };
const modelPoseValuePrecision: Partial<Record<keyof ModelPoseValue, number>> = {
translateX: 3,
translateY: 3,
translateZ: 3,
scale: 3,
};
interface DicomAttributes { interface DicomAttributes {
patientName: string; patientName: string;
@@ -442,9 +448,11 @@ function defaultModelPoses(): ModelPoseRecord[] {
function normalizeModelPoseValue(value: Partial<ModelPoseValue> | undefined): ModelPoseValue { function normalizeModelPoseValue(value: Partial<ModelPoseValue> | undefined): ModelPoseValue {
const read = (key: keyof ModelPoseValue, fallback: number, min: number, max: number) => { const read = (key: keyof ModelPoseValue, fallback: number, min: number, max: number) => {
const nextValue = value?.[key]; const nextValue = value?.[key];
return typeof nextValue === 'number' && Number.isFinite(nextValue) const clampedValue = typeof nextValue === 'number' && Number.isFinite(nextValue)
? clampNumber(nextValue, min, max) ? clampNumber(nextValue, min, max)
: fallback; : fallback;
const precision = modelPoseValuePrecision[key];
return typeof precision === 'number' ? Number(clampedValue.toFixed(precision)) : clampedValue;
}; };
const readBoolean = (key: keyof ModelPoseValue, fallback: boolean) => ( const readBoolean = (key: keyof ModelPoseValue, fallback: boolean) => (
typeof value?.[key] === 'boolean' ? Boolean(value?.[key]) : fallback typeof value?.[key] === 'boolean' ? Boolean(value?.[key]) : fallback

View File

@@ -3027,15 +3027,10 @@ export default function ReverseWorkspace({
dicomSize.y / (Math.max(rotatedSize.y, 1e-6) * baseScale), dicomSize.y / (Math.max(rotatedSize.y, 1e-6) * baseScale),
dicomSize.z / (Math.max(rotatedSize.z, 1e-6) * baseScale), dicomSize.z / (Math.max(rotatedSize.z, 1e-6) * baseScale),
); );
const limitedByVolume = axisFitScale > containmentScale + 1e-6;
const nextScale = clampPoseValue('scale', Math.min(axisFitScale, containmentScale)); const nextScale = clampPoseValue('scale', Math.min(axisFitScale, containmentScale));
const nextPose = { ...modelPose, scale: nextScale }; const nextPose = { ...modelPose, scale: nextScale };
updateModelPose({ scale: nextScale }, { markCustom: !options.silentInitial, keepStatus: true }); updateModelPose({ scale: nextScale }, { markCustom: !options.silentInitial, keepStatus: true });
setPoseImportStatus( setPoseImportStatus('');
limitedByVolume
? `已按 ${axis.toUpperCase()} 方向拉伸,并限制在 DICOM 体范围内`
: `已按 ${axis.toUpperCase()} 方向进行三维等比例拉伸`,
);
if (options.silentInitial) { if (options.silentInitial) {
savedWorkspaceSnapshotRef.current = createWorkspaceSnapshot({ savedWorkspaceSnapshotRef.current = createWorkspaceSnapshot({
modelPose: nextPose, modelPose: nextPose,

View File

@@ -14,6 +14,7 @@
- `WebSite/src/components/ReverseWorkspace.tsx` - `WebSite/src/components/ReverseWorkspace.tsx`
- `WebSite/src/components/ProjectLibrary.tsx` - `WebSite/src/components/ProjectLibrary.tsx`
- `WebSite/server.ts`
- `Docker部署/README.md` - `Docker部署/README.md`
- `工程分析/经验记录.md` - `工程分析/经验记录.md`
@@ -22,6 +23,7 @@
- 检查现有 `poseStepConfig`、项目库位姿控件数组和格式化函数。 - 检查现有 `poseStepConfig`、项目库位姿控件数组和格式化函数。
-`translateX/translateY/translateZ/scale``step`、按钮文案、快捷 delta 调整为 `0.001` -`translateX/translateY/translateZ/scale``step`、按钮文案、快捷 delta 调整为 `0.001`
- 为平移字段补充三位小数精度处理,避免浮点累积或显示截断。 - 为平移字段补充三位小数精度处理,避免浮点累积或显示截断。
- 服务端保存和读取模型位姿时,对平移和缩放执行三位小数归一化。
- 保持旋转字段不变。 - 保持旋转字段不变。
## 执行步骤 ## 执行步骤
@@ -29,10 +31,11 @@
1. 定位所有平移和缩放步进配置。 1. 定位所有平移和缩放步进配置。
2. 修改逆向工作区位姿控件。 2. 修改逆向工作区位姿控件。
3. 修改项目库位姿控件。 3. 修改项目库位姿控件。
4. 更新 Docker 部署说明与经验记录 4. 修改服务端位姿归一化精度
5. 运行类型检查和构建 5. 更新 Docker 部署说明与经验记录
6. 重新部署并验证服务 6. 运行类型检查和构建
7. 提交并推送到 Gitea 7. 重新部署并验证服务
8. 提交并推送到 Gitea。
## 兼容性与回滚方案 ## 兼容性与回滚方案
@@ -43,6 +46,7 @@
## 预计文件变更 ## 预计文件变更
- 2 个前端组件文件。 - 2 个前端组件文件。
- 1 个服务端文件。
- 1 个 Docker 部署说明文件。 - 1 个 Docker 部署说明文件。
- 3 个工程分析当次文档。 - 3 个工程分析当次文档。
- 1 个经验记录追加。 - 1 个经验记录追加。

View File

@@ -0,0 +1,48 @@
# 实现方案-2026-05-24-19-17-13
## 实现方案文档路径
`工程分析/实现方案-2026-05-24-19-17-13.md`
## 修改目标
- 自动拉伸成功后不再写入“已按 X/Y/Z 方向进行三维等比例拉伸”类持久状态。
- 保留 `stretchingAxis` 按钮加载状态与 `fusionError` 错误提示。
## 涉及路径
- `WebSite/src/components/ReverseWorkspace.tsx`
- `Docker部署/README.md`
- `工程分析/经验记录.md`
## 技术路线
- 定位 `applyModelStretchByAxis` 中成功分支的 `setPoseImportStatus`
- 成功更新 `scale` 后清空 `poseImportStatus`,避免残留成功文案。
- 不修改 `catch` 与前置校验中的 `setFusionError`
## 执行步骤
1. 检查自动拉伸按钮与状态提示的调用路径。
2. 修改自动拉伸成功后的状态处理。
3. 运行类型检查与构建。
4. 重新部署并验证服务。
5. 作为自动拉伸提示的后续界面微调单独提交并推送。
## 兼容性与回滚方案
- 只影响成功提示文案,不影响位姿计算和保存数据。
- 如需恢复提示,可回滚本次 commit 或重新加入成功状态文案。
## 预计文件变更
- 1 个前端组件文件。
- 1 个 Docker 部署说明文件。
- 3 个工程分析当次文档。
- 1 个经验记录追加。
## 提交与部署策略
- Commit message 包含 `2026-05-24-19-17-13` 和自动拉伸提示调整说明。
- 构建通过后重启 `tmux` 会话 `revoxelseg-dicom`
- 验证本机和公网入口。

View File

@@ -0,0 +1,44 @@
# 测试方案-2026-05-24-19-17-13
## 测试方案文档路径
`工程分析/测试方案-2026-05-24-19-17-13.md`
## 静态检查
- 执行 `cd WebSite && npm run lint`
- 搜索自动拉伸成功提示,确认不再输出“已按 Z 方向进行三维等比例拉伸”。
## 构建检查
- 执行 `cd WebSite && npm run build`
- 确认生产构建成功。
## 关键业务场景验证
- 点击 X/Y/Z 自动拉伸时,按钮仍显示加载态。
- 自动拉伸成功后模型缩放位姿更新,但页面下方不残留成功提示。
- 数据未加载或角度不满足条件时,仍显示错误提示。
## 医学影像数据相关边界验证
- 本次不修改 DICOM/STL 读取、切片排序、分割映射和导出算法。
- 自动拉伸后的位姿仍参与融合视图、保存和导出。
## 部署验证
- 重启 `tmux` 会话 `revoxelseg-dicom`
- 验证 `http://127.0.0.1:4000/api/health`
- 验证 `http://127.0.0.1:4000/`
- 验证 `https://revoxel.huijutec.cn/api/health``https://revoxel.huijutec.cn/`
## Git/Gitea 备份验证
- 暂存本次相关源码、Docker 说明和工程分析文档。
- 提交 message 包含本次时间戳。
- 推送到 Gitea `main` 后确认本地分支与远端同步。
## 风险与回归关注点
- 不能隐藏失败提示。
- 自动拉伸成功后不应影响 `markCustom` 和工作区保存状态判断。

View File

@@ -1775,7 +1775,25 @@ B. 原因分析
逆向工作区和项目库各自维护位姿控件步进;平移、缩放曾使用 `0.005``0.05``0.25` 等不同粒度。若只改按钮步进,不同步滑杆 step、显示精度和归一化取整保存后的位姿可能看起来或实际不是 0.001 级别。 逆向工作区和项目库各自维护位姿控件步进;平移、缩放曾使用 `0.005``0.05``0.25` 等不同粒度。若只改按钮步进,不同步滑杆 step、显示精度和归一化取整保存后的位姿可能看起来或实际不是 0.001 级别。
C. 处理方式 C. 处理方式
将逆向工作区 `poseStepConfig` 中平移 X/Y/Z 与缩放步进统一为 `0.001`,项目库位姿控件的按钮 delta、range step 也统一为 `0.001`。同时为项目库平移字段补充三位小数归一化,保证按钮、滑杆、显示、保存和导出使用同一精度。 将逆向工作区 `poseStepConfig` 中平移 X/Y/Z 与缩放步进统一为 `0.001`,项目库位姿控件的按钮 delta、range step 也统一为 `0.001`。同时为项目库和服务端平移/缩放字段补充三位小数归一化,保证按钮、滑杆、显示、保存和导出使用同一精度。
D. 后续建议 D. 后续建议
后续调整位姿控件时,要把步进、按钮 delta、range step、数字显示、状态归一化和导出数据一起检查;不要只改单个页面或单个控件,否则会出现项目库与逆向工作区微调精度不一致。 后续调整位姿控件时,要把步进、按钮 delta、range step、数字显示、前端状态归一化、服务端保存归一化和导出数据一起检查;不要只改单个页面或单个控件,否则会出现项目库与逆向工作区微调精度不一致。
## 2026-05-24-19-17-13 自动拉伸成功提示不要长期占位
A. 具体问题
用户点击 `Z拉伸` 后,页面保留“已按 Z 方向进行三维等比例拉伸”提示。该提示不是错误,也不需要长期显示,容易占用界面注意力。
B. 产生问题原因
自动拉伸成功分支复用了位姿导入/保存状态 `poseImportStatus`,并在每次成功后写入持久成功文案;按钮本身已经有 `stretchingAxis` 加载态,成功后的额外文字反馈并非必要。
C. 解决问题方案
自动拉伸成功后仍更新模型 `scale` 并保持工作区脏状态判断,但立即清空 `poseImportStatus`。前置校验和异常分支继续写入 `fusionError`,确保数据未加载、角度不满足条件或计算失败时仍有明确错误提示。
D. 后续如何避免问题
后续新增操作反馈时,要区分“处理中反馈”“成功反馈”和“错误反馈”。短操作可以只保留按钮加载态和错误提示,避免把普通成功信息写入长期占位区域;如果确实需要成功提示,应设计为短暂 toast 或局部临时状态。

View File

@@ -23,6 +23,7 @@
- `WebSite/src/components/ReverseWorkspace.tsx`:逆向工作区位姿控件步进。 - `WebSite/src/components/ReverseWorkspace.tsx`:逆向工作区位姿控件步进。
- `WebSite/src/components/ProjectLibrary.tsx`:项目库模型位姿控件步进。 - `WebSite/src/components/ProjectLibrary.tsx`:项目库模型位姿控件步进。
- `WebSite/server.ts`:服务端位姿归一化精度。
- `Docker部署/README.md`:同步说明位姿微调精度。 - `Docker部署/README.md`:同步说明位姿微调精度。
- `工程分析/经验记录.md`:记录位姿步进和精度同步经验。 - `工程分析/经验记录.md`:记录位姿步进和精度同步经验。

View File

@@ -0,0 +1,42 @@
# 需求分析-2026-05-24-19-17-13
## 开始时间
2026-05-24-19-17-13
## 原始需求摘要
用户反馈点击 `Z拉伸` 后不需要显示“已按 Z 方向进行三维等比例拉伸”,或者只在“自动拉伸”区域短暂显示后隐去。
## 业务目标
- 自动拉伸操作完成后不在页面下方残留成功提示。
- 保留按钮自身的加载反馈,让用户能知道当前正在拉伸。
- 保留拉伸失败、数据未加载、角度不满足条件等错误提示。
## 输入与输出
- 输入:用户点击逆向工作区融合视角中的 X/Y/Z 自动拉伸按钮。
- 输出:成功后只更新模型缩放位姿,不显示持久成功提示;失败时仍显示明确错误原因。
## 影响范围
- `WebSite/src/components/ReverseWorkspace.tsx`:自动拉伸成功后的状态提示处理。
- `Docker部署/README.md`:同步说明容器部署包含该界面行为。
- `工程分析/经验记录.md`:记录成功提示与错误提示的分离经验。
## 关键约束
- 不改变自动拉伸计算逻辑。
- 不改变保存、导出、模型位姿字段结构。
- 不隐藏失败提示,避免用户无法判断拉伸为什么没有生效。
## 风险点
- 如果直接清空所有状态,可能把错误提示也隐藏。
- 如果保留 `keepStatus` 但不清空成功状态,旧的“已按 Z 方向...”仍可能残留。
## 待确认问题或默认假设
- 默认本次只去掉自动拉伸成功后的持久提示,不新增单独的临时 toast。
- X/Y 方向自动拉伸成功提示也同步按同一规则处理,保证交互一致。