# 经验记录 本文件用于记录项目修改过程中的关键问题与解决方案。每条经验使用四段式结构。 ## 2026-05-04-02-38-48 建立代码编纂工作流 A. 具体问题 当前项目尚无统一的需求分析、实现方案、测试方案、经验沉淀和备份提交流程,后续修改容易缺少可追溯记录。 B. 产生问题原因 项目仍处于早期建设阶段,已有前端工程和医学影像数据资产,但尚未建立工程治理文档与固定执行规范。 C. 解决问题方案 创建 `工程分析/` 目录,新增工程整体分析、代码编纂工作流、本次需求分析、实现方案、测试方案和经验记录文档。后续项目修改必须先写文档,并在实现方案和测试方案阶段等待用户二次人工审核确认。 D. 后续如何避免问题 每次项目修改前先记录时间戳并阅读 `工程分析/工程整体分析.md` 与 `工程分析/经验记录.md`。修改前写入需求、实现和测试文档,确认后再执行,完成后追加经验记录并提交 Gitea 备份。 ## 2026-05-04-02-38-48 Gitea 推送后的本地凭据清理 A. 具体问题 使用带账号信息的一次性推送地址完成 Gitea push 后,本地 `branch.main.remote` 曾记录为带账号信息的 URL。 B. 产生问题原因 `git push -u main` 会把该 `` 记录为当前分支上游,而不是只使用已配置的 `origin` 名称。 C. 解决问题方案 将 `origin` 保持为不含账号信息的仓库地址,并把 `branch.main.remote` 改回 `origin`、`branch.main.merge` 改为 `refs/heads/main`。 D. 后续如何避免问题 后续推送时优先使用已配置好的 `origin`。如果必须临时带认证信息推送,推送后立即检查 `git config --get-regexp 'branch\\.main|remote\\.origin'`,确保本地配置中没有保存账号密码。 ## 2026-05-04-02-38-48 开发服务端口占用 A. 具体问题 本项目默认 Vite 端口 `3000` 已被 `/home/wkmgc/Desktop/Seg_Server` 的 node 服务占用,无法直接作为本项目部署端口。 B. 产生问题原因 同一机器上已有其他项目服务监听 `0.0.0.0:3000`。 C. 解决问题方案 不停止既有服务,改用 `3001` 端口启动当前项目的 Vite 服务,并通过 `curl -I http://127.0.0.1:3001/` 验证返回 `HTTP/1.1 200 OK`。 D. 后续如何避免问题 部署前先使用 `ss -ltnp` 检查目标端口。如果默认端口被占用,优先选择相邻可用端口并在测试方案执行结果中记录实际访问地址。 ## 2026-05-04-02-38-48 后台部署进程托管 A. 具体问题 使用普通 `nohup` 后台启动 Vite 时进程会静默退出,无法稳定保留服务。 B. 产生问题原因 当前命令执行环境会回收普通后台子进程,导致 `nohup` 方式没有形成稳定部署。 C. 解决问题方案 使用 `tmux new-session -d -s revoxelseg-dicom` 托管 Vite 服务,使开发服务脱离当前命令执行会话独立运行。 D. 后续如何避免问题 需要保留长时间运行的开发服务时,优先使用 `tmux` 会话托管,并用 `tmux capture-pane -pt ` 查看启动日志,用 `curl` 验证 HTTP 响应。 ## 2026-05-04-03-08-20 附件 logo 落盘与静态资源引用 A. 具体问题 用户要求将 title 图标、登录页 logo 和左上角 logo 都替换为对话中提供的图片,需要把附件图片变为前端可稳定访问的静态资源。 B. 产生问题原因 前端组件不能直接引用对话附件,必须先将图片保存到项目静态资源目录,再通过固定 URL 引用。 C. 解决问题方案 确认 `/tmp/logo_check.png` 与用户提供的 logo 一致后,将其复制到 `WebSite/public/logo.png`。`index.html` favicon、登录页和侧边栏统一通过 `/logo.png` 引用。 D. 后续如何避免问题 后续涉及用户上传图片替换项目资源时,先在本地确认附件是否已落盘;优先放入 `WebSite/public/` 并使用根路径引用,避免组件间重复存放资源。 ## 2026-05-04-03-08-20 指定端口重新部署 A. 具体问题 用户要求将项目部署到 `http://192.168.3.11:4000/`,需要从原先 `3001` 端口切换到 `4000`。 B. 产生问题原因 项目早前使用 `tmux` 会话 `revoxelseg-dicom` 托管在 `3001`,本次需求指定了新的访问端口。 C. 解决问题方案 先检查 `4000` 端口是否空闲,然后关闭旧 `revoxelseg-dicom` 会话,使用同名 `tmux` 会话启动 Vite:`node ./node_modules/vite/bin/vite.js --host 0.0.0.0 --port 4000 --strictPort`。随后用本机地址和内网地址分别验证 HTTP 200。 D. 后续如何避免问题 每次调整部署端口前先检查端口占用和现有 `tmux` 会话;部署后同时验证 `127.0.0.1` 与目标内网 IP,并把实际访问地址写入测试方案执行结果。 ## 2026-05-04-03-21-40 从纯前端演示升级为前后端协调系统 A. 具体问题 原系统登录、项目列表、用户列表、出厂重置和导出都是前端静态假数据,不同浏览器之间无法共享状态。 B. 产生问题原因 项目初始形态是 Vite/React 前端演示,没有后端 API、共享状态存储和统一部署入口。 C. 解决问题方案 新增 Express 后端 `server.ts`,用同一 `4000` 端口服务 API 和前端页面。后端通过 `WebSite/data/state.json` 维护演示状态,前端通过 `/api/session` 轮询同步登录状态,并将项目、用户、概况、重置和导出功能全部接入 API。 D. 后续如何避免问题 新增跨浏览器共享功能时,默认先判断状态是否必须由后端维护;涉及多浏览器一致性的功能不要放在组件静态数组或浏览器本地状态中。 ## 2026-05-04-03-21-40 默认医学数据项目载入 A. 具体问题 项目列表需要默认载入 `Head_CT_DICOM` 和 `Head_CT_ReConstruct`,恢复演示环境出厂设置后也必须恢复这两个默认数据目录。 B. 产生问题原因 旧项目列表使用硬编码医疗项目示例,和当前仓库中的 DICOM/STL 数据资产没有建立关系。 C. 解决问题方案 后端启动和读取状态时扫描 `Head_CT_DICOM` 的 `.dcm` 数量与 `Head_CT_ReConstruct` 的 `.stl` 文件列表,生成默认项目 `head-ct-demo`。`POST /api/demo/reset` 使用同一逻辑重建默认项目。 D. 后续如何避免问题 演示数据入口统一放在后端默认项目构建函数中,避免多个页面分别硬编码 DICOM/STL 路径或数量。 ## 2026-05-04-03-21-40 NIfTI 导出闭环 A. 具体问题 逆向工作区需要最终生成 `nii` 或 `nii.gz` 格式的分割 mask,而旧界面只有导出按钮,没有后端文件生成能力。 B. 产生问题原因 项目尚未实现真实 STL 到 DICOM 空间的体素化算法,也没有文件导出 API。 C. 解决问题方案 新增 `POST /api/projects/:projectId/export-mask`,后端生成 NIfTI-1 单文件 mask,并按请求输出 `.nii` 或 `.nii.gz`。`.nii.gz` 使用 Node `zlib.gzipSync` 压缩,并通过 `Content-Disposition` 触发下载。 D. 后续如何避免问题 导出类功能需要先定义后端接口、文件格式和校验命令。后续实现真实体素化时,可替换当前演示 mask 生成函数,但保留 API 和下载流程。 ## 2026-05-04-03-21-40 Vite 中间件 HMR 端口冲突 A. 具体问题 Express + Vite 中间件启动时,默认 HMR WebSocket 端口 `24678` 被其他服务占用,日志出现端口冲突。 B. 产生问题原因 同一机器同时运行多个 Vite 服务,默认 HMR 端口可能重复。 C. 解决问题方案 在 `createViteServer` 中指定 `server.hmr.port = 24679`,使本项目后端服务使用独立 HMR 端口。 D. 后续如何避免问题 多项目并行部署时,除了业务端口外,也检查 Vite HMR 端口;发现冲突时为每个项目分配独立 HMR 端口。 ## 2026-05-04-03-50-07 概况统计语义误导 A. 具体问题 项目总数只有 1 时,“已处理项目总数”也显示 1,容易让用户误解为系统已经完成真实处理。 B. 产生问题原因 旧统计把 `status === completed` 直接当作已处理项目,而默认演示项目为了表示数据可用被标记为 `completed`。 C. 解决问题方案 将概况卡片语义改为“已导出 Mask 项目”,后端按 `exportedMaskCount > 0` 统计;默认项目初始为 0,只有实际触发 mask 导出后才计入。 D. 后续如何避免问题 统计卡片必须反映明确业务事件,不要把演示数据可用状态和处理完成状态混在一起。 ## 2026-05-04-03-50-07 DICOM 预览解析 A. 具体问题 项目库 DICOM 影像页看不到真实影像,只显示占位图形。 B. 产生问题原因 前端没有读取 DICOM 像素数据,后端也没有提供切片预览 API。 C. 解决问题方案 新增 `GET /api/projects/:projectId/dicom-preview`,后端解析当前 Little Endian DICOM 的 Rows、Columns、Window、Rescale 和 Pixel Data,返回 base64 灰度像素,前端用 canvas 绘制真实切片。 D. 后续如何避免问题 医学影像可视化应优先验证真实像素是否进入浏览器。后续扩展更多 DICOM 传输语法时,应把解析器替换为成熟 DICOM 库或 Python 预处理服务。 ## 2026-05-04-03-50-07 STL 模型真实渲染 A. 具体问题 项目库 3D 模型页显示的是占位立方体,不是 `Head_CT_ReConstruct` 中的真实 STL。 B. 产生问题原因 前端没有 STLLoader,后端也没有安全暴露 STL 文件。 C. 解决问题方案 新增 `GET /api/projects/:projectId/models/:fileName`,仅允许读取项目 STL 列表中的文件;前端使用 Three.js `STLLoader`、`Bounds` 和 `Center` 加载并自动居中显示模型。 D. 后续如何避免问题 三维模型视图必须加载真实模型文件,不能长期使用占位几何体;后端文件服务要限制文件名和项目白名单,避免任意路径读取。 ## 2026-05-04-03-50-07 Recharts 容器尺寸警告 A. 具体问题 控制台出现 Recharts 警告:图表宽高为 `-1`,需要检查容器尺寸。 B. 产生问题原因 图表在布局尚未稳定时渲染,`ResponsiveContainer` 从父容器拿到异常宽高。 C. 解决问题方案 为图表外层设置 `min-w-0`、固定高度和 `min-h`,并在 chartData 存在后再渲染 `ResponsiveContainer`,高度使用明确数值 `300`。 D. 后续如何避免问题 使用 Recharts 时保证父容器有稳定尺寸;在异步数据未到达前不要提前渲染响应式图表。 ## 2026-05-04-03-50-07 Python 环境引入边界 A. 具体问题 用户提出如果需要 Python 可新建 conda 环境,但本次需求可以在现有 Node/React/Three.js 技术栈中完成。 B. 产生问题原因 DICOM/STL/Mask 功能既可以由前端演示链路实现,也可能进入 Python 医学影像算法链路,需要判断当前阶段是否真的需要 Python。 C. 解决问题方案 本次不创建 conda 环境,避免增加不必要复杂度;README 中说明当前构建方式和后续真实体素化阶段的 conda 环境建议。 D. 后续如何避免问题 只有当需要真实 DICOM 空间解析、STL 体素填充、NIfTI 精确写入或批处理算法时,再引入 Python/conda,并把环境文件纳入项目文档。 ## 2026-05-04-04-12-34 DICOM 三方向预览 A. 具体问题 项目库 DICOM 影像只能看横断面,且右侧切片控制显示为 `NAV` 和 `#0`,不符合医学影像浏览习惯。 B. 产生问题原因 旧前端只把 DICOM 序列当成单一轴向切片数组浏览,后端 DICOM preview API 只返回单张横断面。 C. 解决问题方案 后端 DICOM preview API 增加 `plane=axial|sagittal|coronal` 参数。横断面读取单张 DICOM,矢状面和冠状面从 DICOM 序列逐张采样重建灰度平面。前端增加方向切换,并把右侧控制改为 `第 n / 总数` 的切片语义。 D. 后续如何避免问题 医学影像浏览控件应按方向、当前切片和总切片数表达,不使用模糊的导航标签;多方向重建后续可加入缓存或 Python 预处理优化性能。 ## 2026-05-04-04-12-34 STL 多模型样式控制 A. 具体问题 3D 模型视图只显示单个 STL,右侧状态点无实际意义,用户需要不同 STL 有独立颜色和透明度,并由整体眼睛统一控制显示。 B. 产生问题原因 旧实现把 STL 列表当成选择器,只加载当前选中的一个模型;侧栏状态点只是装饰,没有绑定模型材质。 C. 解决问题方案 前端为每个 STL 建立 `visible`、`color`、`opacity` 状态,同时加载所有可见 STL;每个模型材质绑定对应颜色和透明度,右侧整体眼睛统一切换所有 STL 可见性,删除无意义状态点。 D. 后续如何避免问题 三维列表中的视觉控件必须和真实渲染状态绑定;颜色、透明度、可见性等控件不应只是静态装饰。 ## 2026-05-04-04-12-34 项目管理交互 A. 具体问题 创建项目输入框常驻在项目列表中占空间;项目编辑需要手动保存按钮;项目缺少删除入口和二次确认。 B. 产生问题原因 项目管理功能初版偏向快速可用,没有区分高频浏览和低频管理操作。 C. 解决问题方案 创建项目改为点击 `+` 后弹窗输入;项目名编辑改为失焦或回车自动保存;项目右侧增加删除按钮,点击后必须在确认弹窗中再次确认。 D. 后续如何避免问题 列表页面应减少常驻表单噪声;破坏性操作必须二次确认;轻量编辑可采用失焦保存,但需要避免空名称提交。 ## 2026-05-04-04-58-36 项目列表按钮布局 A. 具体问题 项目列表标题旁的 `+` 创建按钮和侧栏收缩按钮靠得太近,视觉上发生重叠。 B. 产生问题原因 两个操作都放在项目列表标题区右侧,且侧栏宽度固定,未给低频收缩操作独立位置。 C. 解决问题方案 保留 `+` 在标题区,收缩按钮移动到项目列表侧栏中线外侧,并调整容器为 `overflow-visible`,避免按钮被卡片裁剪。 D. 后续如何避免问题 同一区域的高频操作和布局控制应分区放置;绝对定位按钮如果超出容器,要同步检查父容器裁剪策略。 ## 2026-05-04-04-58-36 DICOM 三方向缓存与显示模式 A. 具体问题 矢状面和冠状面切换后图像变化慢或不明显,且 DICOM 只能用单一窗宽窗位显示。 B. 产生问题原因 每次重建非横断面都要重新读取 DICOM 序列,前后端没有把显示模式作为预览参数,也没有复用已解析的体数据。 C. 解决问题方案 后端按显示模式缓存 DICOM 体数据和预览结果,API 增加 `mode=default|bone|soft|contrast`;前端切换方向时重置到对应方向中间层,并提供显示模式分段按钮。 D. 后续如何避免问题 DICOM 多平面重建应优先设计缓存键和窗宽窗位参数;后续接入真实医学影像库时继续保留 plane、slice、mode 的稳定 API 契约。 ## 2026-05-04-04-58-36 STL 大文件预览 A. 具体问题 3D 模型页容易空白,直接加载 9 个原始 STL 总量约 240MB,浏览器解析慢且缺少可靠进度反馈。 B. 产生问题原因 前端承担了原始 STL 解析和渲染的全部工作,大体积二进制模型会阻塞交互并放大 WebGL 环境差异。 C. 解决问题方案 后端新增 STL 二进制采样预览 API,只返回抽样三角面顶点;前端用原生 Three.js 按采样顶点生成 BufferGeometry,并显示加载进度。WebGL 不可用时改用二维 canvas 投影预览兜底。 D. 后续如何避免问题 大模型浏览应区分“预览网格”和“原始精度文件”;列表/项目库优先加载轻量预览,进入精修或导出阶段再读取完整 STL。 ## 2026-05-04-04-58-36 逆向工作区项目上下文与融合视图 A. 具体问题 逆向工作区没有明确显示当前项目,融合视图没有展示 DICOM 与 STL 归一化中心对齐的效果。 B. 产生问题原因 工作区初版更多是流程面板,缺少从项目库传入项目后继续呈现项目上下文和影像/模型叠加结果的状态。 C. 解决问题方案 工作区进入后读取当前项目详情,顶部显示项目名、DICOM 数量、STL 数量和路径;融合视图加载 DICOM 软组织窗切片,并叠加中心对齐的模型轮廓、十字参考线和切片滑块。 D. 后续如何避免问题 跨页面工作流必须在目标页面重新显示当前操作对象;医学影像配准类视图至少应具备影像层、模型层、对齐标识和当前切片控制。 ## 2026-05-04-05-20-16 DICOM 三平面预览与下载 A. 具体问题 DICOM 切片长按不能连续移动,三平面不能旋转,矢状面/冠状面存在大量黑边导致主体像只显示一半,同时缺少当前 PNG 和整套 DICOM 压缩包下载。 B. 产生问题原因 前端切片控制只有原生 range 输入,缺少连续步进逻辑;canvas 绘制没有旋转参数;后端重建平面直接输出完整矩阵,没有对非黑内容边界做裁切;下载链路只覆盖了分割 Mask。 C. 解决问题方案 前端新增上下箭头长按定时步进、左/右 90 度旋转和与显示一致的 PNG 导出;后端 DICOM 文件按自然文件名排序,对重建平面做内容裁切并做轻量边缘增强;新增 `dicom-archive` 接口生成 `tar.gz` 压缩包。 D. 后续如何避免问题 医学影像预览的显示状态应统一由平面、切片、窗宽窗位、旋转角度组成;下载当前视图时复用同一套 canvas 绘制逻辑,避免屏幕显示和导出结果不一致。 ## 2026-05-04-05-20-16 3D 模型加载完成但画布空白 A. 具体问题 项目库 3D 模型页提示加载完成,但用户界面仍可能看不到模型。 B. 产生问题原因 STL 抽样顶点仍保留原始模型坐标,先给 group 位置减中心再缩放时,模型可能被缩放后的坐标体系推离相机视野;WebGL 不可用时二维兜底 canvas 尺寸也依赖容器测量,可能拿到过小尺寸。 C. 解决问题方案 模型加载完成后先计算整体包围盒,将中心偏移直接平移到每个 mesh 的 geometry 顶点,再统一缩放 group 和设置相机;二维兜底 canvas 在容器尺寸不可用时使用父容器尺寸或默认尺寸,保证兜底预览可见。 D. 后续如何避免问题 三维预览应在模型坐标归一化后再设置相机;验证时要覆盖 WebGL 正常路径和 WebGL 不可用兜底路径,并做 canvas 尺寸和非背景像素检查。 ## 2026-05-04-05-20-16 逆向工作区路径信息噪声 A. 具体问题 逆向工作区标题中显示 `Head_CT_DICOM ↔ Head_CT_ReConstruct`,对用户当前操作帮助不大。 B. 产生问题原因 早期为了证明项目数据源接入,将数据目录路径直接放进了页面副标题。 C. 解决问题方案 副标题改为只显示当前项目名称;DICOM 数量和 STL 数量保留在上下文标签中。 D. 后续如何避免问题 工作区首屏应优先显示“当前正在处理哪个项目”和“下一步操作”,底层路径只在诊断、详情或设置区域出现。 ## 2026-05-04-05-41-22 STL 实体化程度与位姿控制 A. 具体问题 3D 模型虽然可以显示,但抽样三角面过少时视觉上偏稀疏,用户希望更接近白色实体 STL 拼装效果,并且能够手动调整整体模型位姿。 B. 产生问题原因 项目库为了避免大体积 STL 造成浏览器卡顿,使用固定低抽样量预览;同时模型 group 只有自动旋转,没有暴露旋转、平移、缩放等用户控制。 C. 解决问题方案 新增“预览/标准/精细”实体化程度,后端 STL preview 抽样上限提升到 `36000`;前端新增白色实体模式、自动旋转开关、旋转 X/Y/Z、平移 X/Y/Z、缩放和重置位姿控制,所有位姿变换作用在整体 group 上。 D. 后续如何避免问题 大模型预览应提供性能档位,而不是在“速度”和“实体感”之间固定取舍;位姿控制必须作用于整体模型容器,避免破坏各 STL 构件的相对拼装关系。 ## 2026-05-04-05-41-22 DICOM 长按切片反馈 A. 具体问题 长按切片上下箭头时,编号会变化,但用户希望图像也有连续变化的运动感。 B. 产生问题原因 前端连续修改 `sliceIndex` 后依赖异步 API 返回更新图像,缺少请求乱序保护和切片切换中的视觉反馈。 C. 解决问题方案 将长按步进间隔缩短到 `95ms`,为 DICOM preview 请求加入递增序号,只允许最新请求更新画面;切片切换时给 canvas 容器增加轻微缩放、亮度和状态提示。 D. 后续如何避免问题 连续浏览医学影像时,必须同时处理“状态连续变化”“图像异步返回”和“旧请求覆盖新请求”三个问题;前端应保留上一帧并提供明确切换反馈。 ## 2026-05-04-05-41-22 逆向工作区标题去重 A. 具体问题 逆向工作区同时出现全局标题和页面内标题,也重复显示“当前项目”。 B. 产生问题原因 页面局部标题和全局 header 没有统一职责,项目上下文既出现在副标题,也出现在标签行。 C. 解决问题方案 保留全局 header 的“逆向工作区”,删除页面内重复标题和副标题;保留并放大当前项目、DICOM 数量、STL 数量标签。 D. 后续如何避免问题 页面级标题应由全局导航或内容区二选一承担;当前对象信息只保留在最醒目的单一位置,减少重复文本造成的噪声。 ## 2026-05-04-05-56-34 DICOM 多平面物理比例 A. 具体问题 矢状面和冠状面只按像素矩阵重建,没有考虑切片间距与单张图像内像素间距,导致图像观感过扁。 B. 产生问题原因 后端重建平面时直接使用 `切片数 x 行/列数` 作为输出尺寸,默认把切片方向和像素方向当成等距网格。 C. 解决问题方案 解析 `PixelSpacing`、`SliceThickness`、`SpacingBetweenSlices` 和 `ImagePositionPatient`;优先用相邻 `ImagePositionPatient` 距离估计真实切片间距,并按 `sliceSpacing` 与像素间距做最近邻重采样,返回 spacing 与 physicalSize。 D. 后续如何避免问题 医学影像任意重建平面都必须带着物理 spacing 计算,不应只看像素数量;当 DICOM tag 缺失时要明确 fallback 来源。 ## 2026-05-04-05-56-34 DICOM 信息面板 A. 具体问题 前端缺少 DICOM 详细信息查询,用户无法看到像素间距、切片间距等判断空间比例的关键信息。 B. 产生问题原因 原有 API 只服务于灰度预览,没有暴露 DICOM 元数据和序列级空间统计。 C. 解决问题方案 新增 `GET /api/projects/:projectId/dicom-info`,返回患者、检查、序列、图像矩阵、窗宽窗位、spacing、物理尺寸和首尾切片位置;前端增加“信息”按钮和 DICOM 详细信息弹窗。 D. 后续如何避免问题 影像显示功能旁应提供可审计的元数据入口,特别是任何影响几何比例、配准和导出的空间参数。 ## 2026-05-04-05-56-34 3D 模型交互控制简化 A. 具体问题 3D 模型页存在不需要的白色实体模式和自动旋转,同时缺少更高细节档位;鼠标拖拽、滚轮等画布操作不能同步到右侧位姿控件。 B. 产生问题原因 前一版位姿控制主要依赖右侧滑块,画布本身只负责渲染;显示开关也偏演示型,没有完全贴近用户的实际浏览习惯。 C. 解决问题方案 移除白色实体和自动旋转;新增“超精细”档,后端 STL 抽样上限提升到 `72000`;画布监听左键旋转、右键或 Shift 平移、滚轮缩放,并回写整体位姿 state。 D. 后续如何避免问题 三维浏览默认应遵循常见交互习惯,UI 控件与鼠标操作必须共享同一份状态;演示型开关要及时剔除,避免干扰核心工作流。 ## 2026-05-07-16-20-46 3D 默认位姿 A. 具体问题 网页端 3D 模型默认位姿看起来不像用户参考图中的正常位姿,打开后更像斜向观察。 B. 产生问题原因 默认 Three.js 相机使用 `(4.5, 3.5, 5)` 斜向等距视角,而用户期望的是接近俯视/轴向的标准视角。 C. 解决问题方案 将默认相机改为俯视方向:`camera.up=(0,1,0)`、`camera.position=(0,0,6)`、`lookAt(0,0,0)`;保留默认位姿滑块为旋转 0、平移 0、缩放 1,重置位姿也回到同一基准。 D. 后续如何避免问题 默认位姿应该由相机预设和模型位姿共同定义;如果用户提供标准视图截图,应优先匹配相机视角,再决定是否需要固定模型 Z 轴校正。 ## 2026-05-07-16-35-52 3D 位姿重置与旋转中心 A. 具体问题 整体位姿只有一个重置按钮,无法分别恢复旋转和平移缩放;同时用户感觉模型旋转中心不在模型正中间,缺少右下角 XYZ 方位参考。 B. 产生问题原因 前端位姿状态虽包含旋转、平移和缩放,但重置操作仍使用单一 `defaultModelPose`;Three.js 预览也使用单 group 同时承载旋转、平移和缩放,层级职责不够清晰;画布缺少固定的方位提示。 C. 解决问题方案 抽出统一的位姿 clamp 方法;新增 `重置旋转位姿` 与 `重置平移缩放位姿`;旋转项增加 ±90° 快捷按钮,平移和缩放增加正负方向快捷步进;Three.js 渲染拆为 `poseGroup` 负责平移、`pivotGroup` 负责围绕整体包围盒中心旋转和缩放;右下角增加 X/Y/Z 方位与旋转角度 overlay。 D. 后续如何避免问题 三维位姿控制应按旋转、平移、缩放分开管理;模型加载后必须先基于所有 STL 的整体包围盒做中心化,再把旋转和缩放应用到中心 pivot 上;涉及交互状态时,滑块、按钮和鼠标操作必须共享同一份 clamp 逻辑。 ## 2026-05-07-16-53-23 STL 抽样中心漂移与动态坐标轴 A. 具体问题 用户旋转模型后切换 `预览/标准/精细/超精细`,模型位置会明显偏移;鼠标拖拽旋转时也感觉旋转中心没有落在模型内部;右下角坐标轴不随旋转位姿变化。 B. 产生问题原因 前端用当前抽样出来的 STL 顶点计算整体包围盒,不同细节档位的抽样集合不同,导致中心点和缩放基准随档位变化;右下角坐标轴是固定 HTML/CSS 图形,没有基于当前旋转矩阵更新。 C. 解决问题方案 后端 STL preview 在遍历完整二进制 STL 时同步计算全量 `bounds`,前端加载时使用所有可见 STL 的全量包围盒合成稳定中心和尺寸,再把抽样 geometry 平移到该中心;右下角坐标轴改为 SVG,根据 `rotateX/Y/Z` 生成 Three.js 旋转矩阵并投影 X/Y/Z 三轴。 D. 后续如何避免问题 任何用于配准、视角稳定、旋转中心的几何参数都必须来自全量模型或稳定元数据,不能来自随性能档位变化的抽样数据;坐标系、状态文字和模型实际位姿应共用同一份 pose 状态。