docs: VTK 三维分类视图重构 spec + 三维体归属层级修订
- 新增 spec: 按数据类型大类(电阻率/视电阻率/瞬变电磁/三维体/切片)分组视图; 对象树 GS 三态双开关联动 + 项目根固定; 装置类型(arrayType)/采集时间(collectTime)筛选; VTK 画布工具条; createVolume/createSlice 组装真实请求体 DTO(走 mock) - vtk-3d-openapi.json v0.5-draft: 三维体归属由 TM 改为 GS/项目根(structParentConfType=1) - 经 opus 子代理评审并据评审修订(GS 三态停用 AutoTristate 改手动/properties 两接口形态澄清/帘面勾选链承接等)
This commit is contained in:
parent
509ba35a47
commit
eceb964aa1
|
|
@ -2,8 +2,8 @@
|
||||||
"openapi": "3.0.3",
|
"openapi": "3.0.3",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "Geopro3 三维视图 API(三维体 / 切片 / 异常 三件套)",
|
"title": "Geopro3 三维视图 API(三维体 / 切片 / 异常 三件套)",
|
||||||
"version": "0.4.0-draft",
|
"version": "0.5.0-draft",
|
||||||
"description": "VTK 三维视图后端接口。归属结构(2026-06-23 定稿):**TM → 三维体(dd_voxel) → 切片(dd_slice)**,异常挂在三维体上(remarkSourceId=三维体 dsObjectId)。\n\n**总原则:实体无关的契约一律复用存量;只为各自特有、存量装不下的部分扩展。**\n- 三维体/切片对后端 = 纯元数据 dsObject:增删改查/属性复用存量 dsObject 面,各加 1 个登记端点;体素字节/切面数据全在客户端(算+存+取+渲染),后端零数据端点。\n- 异常复用整套存量 /business/exception 端点(端点不限实体类型,三维体 id 直接塞 remarkSourceId);**异常体(consortium)分组也是存量已有**(consortiumId/Name/Type)。3D 仅扩展两处:location 加 worldPts+plane(三维几何)、加截图(R88)。\n\n响应统一信封 `{ code:int, msg:string, data:object|array }`,code==200 成功;列表/集合放 data.value。\n\n依赖前提:异常 remarkSourceId 指向三维体,须等三维体登记出真 dsObjectId 后,3D 异常才能接真端点。"
|
"description": "VTK 三维视图后端接口。归属结构(2026-06-24 修订):**GS/项目根 → 三维体(dd_voxel) → 切片(dd_slice)**(三维体由空间容器节点生成,非 TM;TM 单线不成体),异常挂在三维体上(remarkSourceId=三维体 dsObjectId)。\n\n**总原则:实体无关的契约一律复用存量;只为各自特有、存量装不下的部分扩展。**\n- 三维体/切片对后端 = 纯元数据 dsObject:增删改查/属性复用存量 dsObject 面,各加 1 个登记端点;体素字节/切面数据全在客户端(算+存+取+渲染),后端零数据端点。\n- 异常复用整套存量 /business/exception 端点(端点不限实体类型,三维体 id 直接塞 remarkSourceId);**异常体(consortium)分组也是存量已有**(consortiumId/Name/Type)。3D 仅扩展两处:location 加 worldPts+plane(三维几何)、加截图(R88)。\n\n响应统一信封 `{ code:int, msg:string, data:object|array }`,code==200 成功;列表/集合放 data.value。\n\n依赖前提:异常 remarkSourceId 指向三维体,须等三维体登记出真 dsObjectId 后,3D 异常才能接真端点。"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{ "url": "/", "description": "业务网关根(各路径已含 /business 前缀)" }
|
{ "url": "/", "description": "业务网关根(各路径已含 /business 前缀)" }
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"post": {
|
"post": {
|
||||||
"tags": ["dsObject-reuse"],
|
"tags": ["dsObject-reuse"],
|
||||||
"summary": "[复用] 分页查询某父节点下的数据集行",
|
"summary": "[复用] 分页查询某父节点下的数据集行",
|
||||||
"description": "存量端点(loadRowsAsync)。查三维体:structParentId=tmObjectId、structParentConfType=2;查某三维体下切片:structParentId=该三维体 dsObjectId。返回行 ddCode=dd_voxel / dd_slice。",
|
"description": "存量端点(loadRowsAsync)。查三维体:structParentId=容器节点 id(GS/项目根)、structParentConfType=1;查某三维体下切片:structParentId=该三维体 dsObjectId。返回行 ddCode=dd_voxel / dd_slice。",
|
||||||
"operationId": "dsObjectDataPage",
|
"operationId": "dsObjectDataPage",
|
||||||
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DsPageRequest" } } } },
|
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DsPageRequest" } } } },
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
"post": {
|
"post": {
|
||||||
"tags": ["voxel-new"],
|
"tags": ["voxel-new"],
|
||||||
"summary": "[新增] 登记三维体记录",
|
"summary": "[新增] 登记三维体记录",
|
||||||
"description": "在 tmObjectId 下登记一条 dd_voxel dsObject(名称 + 构建参数写入 attachedParameters.voxelParams),返回新 dsObjectId。只建记录、不触发后端计算——体素插值/落盘/渲染全在客户端。",
|
"description": "在容器节点(GS/项目根)下登记一条 dd_voxel dsObject(名称 + 构建参数写入 attachedParameters.voxelParams),返回新 dsObjectId。只建记录、不触发后端计算——体素插值/落盘/渲染全在客户端。",
|
||||||
"operationId": "registerVoxel",
|
"operationId": "registerVoxel",
|
||||||
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VoxelGenerateRequest" } } } },
|
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VoxelGenerateRequest" } } } },
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
@ -303,8 +303,8 @@
|
||||||
"required": ["projectId", "structParentId", "structParentConfType", "classifyTypeList", "pageNo", "pageSize"],
|
"required": ["projectId", "structParentId", "structParentConfType", "classifyTypeList", "pageNo", "pageSize"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"projectId": { "type": "string" },
|
"projectId": { "type": "string" },
|
||||||
"structParentId": { "type": "string", "description": "查三维体填 tmObjectId;查切片填所属三维体 dsObjectId" },
|
"structParentId": { "type": "string", "description": "查三维体填容器节点 id(GS/项目根);查切片填所属三维体 dsObjectId" },
|
||||||
"structParentConfType": { "type": "integer", "description": "父节点配置类型:TM=2(三维体场景)" },
|
"structParentConfType": { "type": "integer", "description": "父节点配置类型:GS/项目根=1(三维体场景);查切片时=三维体所在层级" },
|
||||||
"classifyTypeList": { "type": "array", "items": { "type": "integer" }, "description": "数据类别过滤(dd_voxel/dd_slice 的 classify code 由后端定义)" },
|
"classifyTypeList": { "type": "array", "items": { "type": "integer" }, "description": "数据类别过滤(dd_voxel/dd_slice 的 classify code 由后端定义)" },
|
||||||
"pageNo": { "type": "integer", "default": 1 },
|
"pageNo": { "type": "integer", "default": 1 },
|
||||||
"pageSize": { "type": "integer", "default": 20 }
|
"pageSize": { "type": "integer", "default": 20 }
|
||||||
|
|
@ -321,7 +321,7 @@
|
||||||
"id": { "type": "string" }, "dsName": { "type": "string" },
|
"id": { "type": "string" }, "dsName": { "type": "string" },
|
||||||
"ddCode": { "type": "string", "enum": ["dd_voxel", "dd_slice"] },
|
"ddCode": { "type": "string", "enum": ["dd_voxel", "dd_slice"] },
|
||||||
"typeName": { "type": "string", "example": "三维体" },
|
"typeName": { "type": "string", "example": "三维体" },
|
||||||
"parentId": { "type": "string", "nullable": true, "description": "三维体=tmObjectId;切片=所属三维体 dsObjectId" }
|
"parentId": { "type": "string", "nullable": true, "description": "三维体=容器节点 id(GS/项目根);切片=所属三维体 dsObjectId" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DsObjectDetail": {
|
"DsObjectDetail": {
|
||||||
|
|
@ -382,10 +382,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"VoxelGenerateRequest": {
|
"VoxelGenerateRequest": {
|
||||||
"type": "object", "required": ["projectId", "tmObjectId", "name", "sourceDatasetIds"],
|
"type": "object", "required": ["projectId", "structParentId", "structParentConfType", "name", "sourceDatasetIds"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"projectId": { "type": "string" },
|
"projectId": { "type": "string" },
|
||||||
"tmObjectId": { "type": "string", "description": "归属 TM —— 三维体挂在 TM 下(structParentConfType=2)" },
|
"structParentId": { "type": "string", "description": "归属容器节点 id —— 三维体挂在 GS/项目根下" },
|
||||||
|
"structParentConfType": { "type": "integer", "default": 1, "description": "父节点配置类型:GS/项目根=1(项目根本质亦为 GS)" },
|
||||||
"name": { "type": "string" },
|
"name": { "type": "string" },
|
||||||
"sourceDatasetIds": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
|
"sourceDatasetIds": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
|
||||||
"interpModel": { "$ref": "#/components/schemas/InterpModel" },
|
"interpModel": { "$ref": "#/components/schemas/InterpModel" },
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
# VTK 三维分析视图重构设计(按数据类型分组 + 对象树联动)
|
||||||
|
|
||||||
|
> 日期 2026-06-24 · 分支 `feat/vtk-3d-view` · 状态:设计待评审
|
||||||
|
> 配套后端契约见 [`HANDOFF-vtk-3d-backend-api.md`](../HANDOFF-vtk-3d-backend-api.md);持久化定论见记忆 `vtk-3d-persistence-structure`。
|
||||||
|
|
||||||
|
## 1. 背景与目标
|
||||||
|
|
||||||
|
现状 VTK 视图左侧 `ColumnDrawer` 是三个固定 tab(三维数据集 / 二维数据集 / 三维分析),`splitByDimension` 仅按 `ddCode` 把数据集分到 3 个维度桶。
|
||||||
|
|
||||||
|
新需求:把「三维数据集」并入「三维分析」,改成**按数据类型大类分组**的视图(电阻率 / 视电阻率 / 瞬变电磁 / 三维体 / 切片),每类有各自的筛选条与操作;对象树勾选与 VTK 列表联动,且支持 GS / 项目层级直挂的数据集;全局视图控制移到 VTK 画布工具条。
|
||||||
|
|
||||||
|
**目标**:在保持现有渲染/交互能力的前提下,完成上述信息架构与交互重构,分类与筛选数据全部走已查实的真实字段,不引入臆测。
|
||||||
|
|
||||||
|
## 2. 范围
|
||||||
|
|
||||||
|
**含**:
|
||||||
|
- 「三维数据集 + 三维分析」合并为按大类分组的「三维分析」tab。
|
||||||
|
- 分类层由 `ddCode`(3 维)改为 `dsTypeCode`(大类)映射表驱动。
|
||||||
|
- 对象树联动改造:非根 GS 三态复选框 + 右键 ds/tm;项目根直挂数据固定显示;按 `structParentConfType` 分流拉取。
|
||||||
|
- 装置类型 / 采集时间筛选落地(客户端可做,不依赖后端补字段)。
|
||||||
|
- 全局视图控制(坐标轴 / 比例 / 快捷视图 / 缩放)移到中央 VTK 画布工具条。
|
||||||
|
- 三维体/切片生成(`createVolume/createSlice`)按契约 DTO 组装出**真实 `VoxelGenerateRequest`/`SliceGenerateRequest` 请求体结构**(仍走 mock 存储、假 id),供后端联调、并为将来切真实端点铺序列化路径。
|
||||||
|
|
||||||
|
**不含**:
|
||||||
|
- 「二维分析」tab(现 `Column2DDataset`)本次不改。
|
||||||
|
- 三维体 / 切片 / 异常的持久化切真实(仍走 `Api3dRepository` mock,后端就绪后另行切换,见配套 handoff)。
|
||||||
|
- 后端接口改动(装置类型值→中文字典源待坐实,见 §11)。
|
||||||
|
|
||||||
|
## 3. 实测依据(关键事实,已通过真实接口核实)
|
||||||
|
|
||||||
|
后端基址 `http://tenant.geomative.cn/pop-api`,样本项目「演示项目(高密度+瞬变)」`1438889436225536`。
|
||||||
|
|
||||||
|
1. **大类必须按 `dsTypeCode` 分**,不能按 `ddCode`——电阻率 / 视电阻率 / 瞬变电磁反演剖面**三者 `ddCode` 同为 `dd_inversion_data`**,仅 `dsTypeCode`/`name` 不同:
|
||||||
|
|
||||||
|
| 大类 | ds 行 `name` | `dsTypeCode` |
|
||||||
|
|---|---|---|
|
||||||
|
| 电阻率数据 | 电阻率数据 | `ERT platform inversion data` |
|
||||||
|
| 视电阻率数据 | 视电阻率数据 | `visual resistivity data` |
|
||||||
|
| 瞬变电磁数据 | 瞬变电磁反演剖面 | `DD TRANSIENT ELECTROMAGNETIC INVERSION` |
|
||||||
|
|
||||||
|
2. **装置类型与采集时间是 ds 的结构化属性**:`dsObject/dynamicForm/{id}` 的 `formList` 定义字段 `arrayType`(装置类型,下拉)、`collectTime`(采集时间);ds 行 `properties` 按 confFieldId 携带其值。装置类型只 ERT 类(电阻率/视电阻率)有,瞬变电磁没有。
|
||||||
|
3. **装置类型枚举**:`GET /business/script/arrayTypeList` → `[{itemValue,name}]`(温纳排列(α)…施伦贝谢尔…共 15 项)。
|
||||||
|
4. **层级拉取**:`dsObject/data/page` 按 `structParentId` + `structParentConfType`(1=GS/项目,2=TM)查;客户端 `loadRowsAsync` 第 3 参即 `parentConfType`,现状写死 2。
|
||||||
|
5. **遗留**:`arrayType` 值是 id(如 `1429468249448449`),实测**不在**该字段 `optionsObject`(另一套 id 体系)里,value→中文字典源待坐实(§11)。
|
||||||
|
|
||||||
|
## 4. 整体架构
|
||||||
|
|
||||||
|
`ColumnDrawer` 改为两 tab:「三维分析」「二维分析」。二维分析不动。
|
||||||
|
|
||||||
|
**「三维分析」tab = `QScrollArea` 纵向堆叠 5 个类型段:**
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─ 三维分析 ──────────── 二维分析 ─┐
|
||||||
|
│ ▼ 电阻率数据 [日期▾][装置类型▾]│ 段头:类型级筛选
|
||||||
|
│ ▸ 演示项目(根·直挂ds固定·无复选框) │
|
||||||
|
│ ▾ ☑ ERT1 (GS·三态) [右键:生成体]│
|
||||||
|
│ ☑ ERT1-WN (数据行·勾选=渲染)│
|
||||||
|
│ ☑ ERT1-WS │
|
||||||
|
│ ▾ ☐ ERT2 (GS) [右键:生成体]│
|
||||||
|
│ ▼ 视电阻率数据 [日期▾][装置类型▾]│
|
||||||
|
│ ▼ 瞬变电磁数据 [日期▾] │ 无装置类型筛选
|
||||||
|
│ ▼ 三维体 [日期▾] │ 已生成体(+正在生成态)+异常
|
||||||
|
│ ▼ 切片 [日期▾] │ 已保存切片(挂父体下)
|
||||||
|
└──────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**全局视图控制移到中央 VTK 画布竖排工具条:** 设置(⚙→坐标轴设置对话框) / 快捷视图(前后上下左右) / 放大·缩小·复位(=现"适配")。
|
||||||
|
|
||||||
|
## 5. 数据模型与分类层
|
||||||
|
|
||||||
|
**`DsRow` 扩展**(`RepoTypes.hpp`):现解析 `id/dsName/typeName(=name)/ddCode/createTime/parentId/file*`,新增:
|
||||||
|
- `dsTypeCode` —— 大类分类主键。
|
||||||
|
- `arrayType` —— 装置类型值(从 ds 行 `properties[]` 按 confFieldId 取)。
|
||||||
|
- `collectTime` —— 采集时间(同上)。
|
||||||
|
|
||||||
|
`NavDto::parseDsRows` 补这三个字段的解析。**两接口 `properties` 形态不同(实测)**:`dsObject/data/page` 的 ds 行 `properties` 是 **`[{confFieldId,value}]` 数组**(按 confFieldId 取值);`dsObject/dynamicForm/{id}` 的 `properties` 是 **`{fieldCode:value}` map**(现 `parseDynamicForm` 用 fieldCode 取值,正确、不冲突)。DsRow 解析的是前者,故需配合 §10 的 confFieldId↔fieldCode 映射定位 arrayType / collectTime。
|
||||||
|
|
||||||
|
**分类配置表 `CategoryConfig`**(新文件,集中一处,开闭原则)——每段一条,带元数据:
|
||||||
|
|
||||||
|
| 段序 | 段名 | 识别键 | 可生成三维体 | 装置类型筛选 |
|
||||||
|
|---|---|---|:--:|:--:|
|
||||||
|
| 1 | 电阻率数据 | `dsTypeCode = ERT platform inversion data` | ✓ | ✓ |
|
||||||
|
| 2 | 视电阻率数据 | `dsTypeCode = visual resistivity data` | ✓ | ✓ |
|
||||||
|
| 3 | 瞬变电磁数据 | `dsTypeCode = DD TRANSIENT ELECTROMAGNETIC INVERSION` | ✓ | ✗ |
|
||||||
|
| 4 | 三维体 | `ddCode = dd_voxel` | — | ✗ |
|
||||||
|
| 5 | 切片 | `ddCode = dd_slice` | — | ✗ |
|
||||||
|
|
||||||
|
**`splitByCategory(rows) -> CategoryBuckets`**:替代 `splitByDimension`,按配置表把 `DsRow` 分入有序大类桶;不在表内的 dsTypeCode(接地电阻/原始数据/白化/坐标等)丢弃。
|
||||||
|
|
||||||
|
## 6. 对象树联动(`ObjectTreePanel` 改造)
|
||||||
|
|
||||||
|
**节点交互模型:**
|
||||||
|
|
||||||
|
| 节点 | 复选框 | 右键新增项 |
|
||||||
|
|---|---|---|
|
||||||
|
| 项目根 | 无(不可勾,直挂 ds 固定显示) | 生成三维体 |
|
||||||
|
| 非根 GS | 三态 | 选择 ▸ ds / tm(带对号)、生成三维体 |
|
||||||
|
| TM 叶子 | 普通二态 | — |
|
||||||
|
|
||||||
|
**GS 三态语义**(标准 tristate 聚合):GS 复选框 = `[GS 自身 ds]` + `[所有子 TM 勾选]` 的聚合;都有=Checked,都无=Unchecked,部分=PartiallyChecked。
|
||||||
|
- 右键「选择 ▸ ds」= 切换「GS 自身 ds」开关(GS 自身 ds 在树中无独立复选框载体,故必须由此控制)。
|
||||||
|
- 右键「选择 ▸ tm」= 一键全选/全不选所有子 TM(子 TM 仍可单独勾,此项是批量便捷)。
|
||||||
|
- 点 GS 复选框:任一开 → 全关;全关 → 全开。
|
||||||
|
- 菜单项按有无动态禁用(无直挂 ds 禁 ds 项,无 TM 禁 tm 项)。
|
||||||
|
- **实现约束(必须)**:**停用现有 `Qt::ItemIsAutoTristate`**(`ObjectTreePanel.cpp:123`)——它只聚合子项 checkState、看不到「GS 自身 ds 开关」这第二维度,直接套用会产出错误聚合态。改为:用一个 `UserRole` 在 GS 节点存「自身 ds 开关」布尔,`itemChanged` 里手动按「ds 开关 ∨ 子 TM 勾选」计算父三态并 `setCheckState`(复用现有 0ms 合并防重入 pattern,避免级联多次触发)。
|
||||||
|
|
||||||
|
**信号扩展**:`checkedTmsChanged(QStringList)` → `checkedSourcesChanged(QList<DataSource>)`,每个 `DataSource = {id, confType}`:
|
||||||
|
- 勾选 TM → `{tmId, 2}`;GS 自身 ds 开关开 → `{gsId, 1}`;项目根直挂(固定)→ `{rootId, 1}`。
|
||||||
|
- 集合为**按 `{id,confType}` 去重的并集**:一条 TM 既被 GS 聚合又被单独勾时只算一次;`confType=1`(GS/项目)拉该节点**直挂 ds**、`confType=2`(TM)拉 TM 下 ds,二者物理数据不重叠,不会重复进桶。
|
||||||
|
|
||||||
|
**数据流**(`main.cpp` 接线):
|
||||||
|
```
|
||||||
|
checkedSourcesChanged
|
||||||
|
→ 对每源 loadRowsAsync(projId, src.id, src.confType, classify=3, …) // 第3参按源传(1/2)
|
||||||
|
→ 汇总 DsRow[] → splitByCategory → 各 CategorySection.setDatasets
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. 类型段组件 `CategorySection`
|
||||||
|
|
||||||
|
一个可参数化的类型段(单一职责,高内聚),由 `CategoryConfig` 一条配置驱动:
|
||||||
|
- **段头**:标题 + 折叠开关 + 日期范围筛选 + 装置类型下拉(仅 `装置类型筛选=✓` 的段显示)。
|
||||||
|
- **段体**:项目根 / GS / TM 树 + 数据行,复用 `DatasetListPanel::populateDatasetList`(按 parentId 建树)与卡片委托;数据行可勾选 = 渲染。
|
||||||
|
- **渲染勾选链承接(必须)**:CategorySection 暴露 `checkedDatasetsChanged`,**接管退役的 `Column3DDataset` 原有「剖面勾选→帘面渲染」主链**——main.cpp 把 5 段(电阻率/视电阻率/瞬变=帘面,三维体/切片=体素/切片)的勾选并集后下发 `pushChecked`(沿用现有 `checkedProfiles`/`checkedAnalysis` 并集模型),否则帘面渲染整体失联。
|
||||||
|
- **生成三维体入口**:仅 `可生成三维体=✓` 的段(电阻率/视电阻率/瞬变电磁),在段内**项目根 / GS 节点**右键提供「生成三维体」——用该容器下本段类型的剖面生成体,类型由段决定、空间范围由容器节点决定。TM 节点不提供(单线不成体)。生成的 `sourceDatasetIds` 须按「**本段 dsTypeCode ∩ 本容器归属**」双重过滤,杜绝跨物理量插值(现 `Column3DDataset::showListContextMenu` 仅按 ddCode 白名单收集、不分 dsTypeCode,会把电阻率+瞬变混入同体;重构后入口移入段内天然隔离,但仍须按段类型+容器双重圈定源)。
|
||||||
|
- **筛选**:复用并扩展 `applyDatasetFilter`,日期比较字段由 `createTime` 改为 `collectTime`(§10)。
|
||||||
|
|
||||||
|
「三维分析」tab 容器(替代原 Column3DDataset/Column3DAnalysis 在 tab 中的位置):`QScrollArea` + 垂直布局,按配置表实例化 5 个 `CategorySection`。
|
||||||
|
|
||||||
|
## 8. 三维体 / 切片 / 异常段
|
||||||
|
|
||||||
|
复用现有 `Api3dRepository`(mock)与 `refreshAnalysis` 合并注入机制,仅重新组织到段:
|
||||||
|
|
||||||
|
> 三维体归属 **GS / 项目根**(非 TM)。后端契约 `docs/api/vtk-3d-openapi.json` 已同步至 v0.5-draft(`structParentConfType=1`);客户端 `createVolume` 接真实端点时需补 `structParentId/structParentConfType`,并新增按三维体 id 查异常的 `queryException/{remarkSourceId}` 调用。
|
||||||
|
- **三维体段**:列已生成的体(客户端 mock + 后端 `dd_voxel`),按归属(项目/GS)分组。(**「正在生成…」状态**:现 `createVolume` 同步登记、首次 `loadVolume` 惰性插值,本期**不引入异步生成态机**、体即时出行;如需占位仅作纯展示文案、不做进度。)异常挂三维体(记忆 `vtk-3d-persistence-structure`):现 `Column3DAnalysis` 的 3D 异常列表 / 显示过滤档位 / 单条显隐,迁入三维体段内(随当前活动体展示)。
|
||||||
|
- **切片段**:列已保存切片(`dd_slice`),按父体分组(`parentId` = 所属体)。
|
||||||
|
|
||||||
|
体素 / 切片 / 异常的渲染、生成、保存路径不变(`VtkSceneController` / `InteractionManager` / `Api3dRepository`),只改列表的承载位置。
|
||||||
|
|
||||||
|
**请求体组装(本次新增)**:`createVolume` 扩参为 `(projectId, structParentId, structParentConfType, params, name)`——归属来自生成入口的 GS/项目根节点;`createSlice` 补 `projectId`。两者内部按新增客户端 DTO `VoxelGenerateRequest`/`SliceGenerateRequest`(对齐 `docs/api/vtk-3d-openapi.json` schema)组装出**完整请求体**并提供 `toJson` 序列化;mock 路径存内存 +(debug)打印请求体,将来切真实端点只把「存」改「发」、组装逻辑原样复用。如此重构一落地即可从 UI 真实产出请求体(值为 mock、结构与字段为真)。`createSlice` 补 `projectId` 会波及 main.cpp 切片保存调用点(切片右键/列表保存路径),须一并传 `nav.currentProjectId()`。
|
||||||
|
|
||||||
|
## 9. VTK 画布工具条 `VtkViewToolbar`
|
||||||
|
|
||||||
|
从 `Column3DDataset` 抽出全局视图控制,做成中央 VTK 画布上的竖排工具条(新组件):
|
||||||
|
- **设置(⚙)** → 弹「坐标轴设置」对话框 `AxesSettingsDialog`:X 轴 / Y 轴 / 深度(m) 各带「显示」开关 + 最小值 / 最大值,取消 / 应用。
|
||||||
|
- **快捷视图**:前、后、上、下、左、右(按钮文字即此六字,沿用现有 `ViewDir` 与功能)。
|
||||||
|
- **缩放**:放大 / 缩小 / 复位(复位 = 现「适配」)。
|
||||||
|
|
||||||
|
信号沿用现有 `Column3DDataset` 已接的控制器槽(`axesModeChanged`/`verticalExaggerationChanged`/`viewRequested`/`zoom*`/`fitRequested` 等),仅迁移承载控件。水平/垂直比例的承载位置随工具条一并迁移(或并入坐标轴设置对话框,实现时取最贴合者);`setVerticalExaggeration` 默认值回灌(main.cpp:902)也要迁到新工具条,避免默认夸张值不同步。
|
||||||
|
|
||||||
|
## 10. 装置类型 / 采集时间筛选落地
|
||||||
|
|
||||||
|
**字段映射服务 `DatasetFieldDictionary`**(新组件,按 dsType 缓存)——**为何必要**:ds 列表行 `properties` 只给 `[{confFieldId,value}]`(数字 confFieldId、无字段名),要判定哪个 confFieldId 是 arrayType/collectTime,必须从 `dynamicForm` 的 `formList`(含 confFieldId↔fieldCode 对应)取映射。
|
||||||
|
- 对每个 dsType 拉一次 `dsObject/dynamicForm`,缓存:① `arrayType` / `collectTime` 字段的 `confFieldId`(用于从 ds 行 `properties` 取值);② 装置类型选项字典(value→中文)。
|
||||||
|
- 列表行装置类型 = ds 行 `properties` 中 `confFieldId == arrayType 的 confFieldId` 那项的 value,经字典翻中文展示与分组。
|
||||||
|
- 段头装置类型下拉 = 该段当前数据出现过的装置类型集合;选中按值过滤。
|
||||||
|
|
||||||
|
**采集时间**:日期筛选按 `collectTime`;三维体 / 切片段无此字段 → 回退 `createTime`。
|
||||||
|
|
||||||
|
## 11. 待坐实 / 风险
|
||||||
|
|
||||||
|
- **装置类型 value→中文字典源**:实测 `arrayType` 值不在该字段 `optionsObject` 里(另一套 id),`parseDynamicForm` 也不翻译;但客户端属性面板据称显中文。需在实现前坐实正确字典源(候选:`fieldConfigJsonObject.fieldDataRadius` 指向的全局字典 / `script/arrayTypeList`)——**请提供客户端数据集属性面板截图**以最快定位现有翻译路径。不阻塞其余设计。
|
||||||
|
- **三维体 / 切片 / 异常仍 mock**:后端就绪后切真实(接口 `I3dSceneRepository` 留缝),见配套 handoff。
|
||||||
|
- **跨 GS 生成体**:本次以「单容器(项目根/GS)范围」为主;跨多 GS 拼大体暂不做。
|
||||||
|
|
||||||
|
## 12. 组件 / 文件边界
|
||||||
|
|
||||||
|
| 类别 | 组件 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| 新增 | `CategoryConfig` | dsTypeCode/ddCode→大类映射表 + 段元数据 |
|
||||||
|
| 新增 | `splitByCategory` | 替代 `splitByDimension` |
|
||||||
|
| 新增 | `CategorySection` | 单个类型段(段头筛选/操作 + 段体树) |
|
||||||
|
| 新增 | 三维分析 tab 容器 | QScrollArea 堆叠 5 段 |
|
||||||
|
| 新增 | `VtkViewToolbar` + `AxesSettingsDialog` | VTK 画布工具条 + 坐标轴设置 |
|
||||||
|
| 新增 | `DatasetFieldDictionary` | 按 dsType 缓存 arrayType/collectTime 映射 + 装置字典 |
|
||||||
|
| 改造 | `ObjectTreePanel` | GS 三态 + 右键 ds/tm + 信号扩展为带 confType 源集合 |
|
||||||
|
| 改造 | `DsRow` + `NavDto::parseDsRows` | 补 dsTypeCode/arrayType/collectTime |
|
||||||
|
| 改造 | `ColumnDrawer` | 三 tab → 两 tab |
|
||||||
|
| 改造 | `main.cpp` | 数据流按 confType 分流拉取 + 段接线 + 生成入口传容器归属 |
|
||||||
|
| 新增 | `VoxelGenerateRequest`/`SliceGenerateRequest` DTO + `toJson` | 对齐 openapi schema 的客户端请求体结构 + 序列化 |
|
||||||
|
| 改造 | `Api3dRepository::createVolume/createSlice` | 扩参带归属/projectId,内部组装请求体 DTO(mock 存 / 将来发) |
|
||||||
|
| 复用 | `DatasetListPanel` | populateDatasetList / 卡片委托 / applyDatasetFilter |
|
||||||
|
| 复用 | `Api3dRepository` / `refreshAnalysis` | 三维体/切片/异常 mock 与合并注入 |
|
||||||
|
| 复用 | `Column2DDataset` | 二维分析 tab,不动 |
|
||||||
|
| 退役 | `Column3DDataset` / `Column3DAnalysis` | 功能拆分到 CategorySection / VtkViewToolbar / 三维体段 |
|
||||||
|
|
||||||
|
## 13. 非目标
|
||||||
|
|
||||||
|
- 不改二维分析。
|
||||||
|
- 不改后端接口、不新增后端字段(装置类型走客户端已有数据)。
|
||||||
|
- 不切换三维体/切片/异常持久化为真实后端。
|
||||||
|
- 不做跨 GS 拼体、不做装置类型以外的新筛选维度。
|
||||||
Loading…
Reference in New Issue