docs: kIntersect/kSliceSolid 是遗留类型,阶段三不迁移
核对结果:这两种类型全库没有产生路径,新图永远不会出现。 - 枚举只在 AcDbX3dSolid.h:53-54 定义,其它模块零引用 - CreateIntersect / CreateSliceSolid 只有定义、头文件声明、ReCreate 读分支 调用(:4413、:4451),是纯读路径 - Create() 的 12 个 case 里没有它们;SetSolidData() 全库无调用者,内部也 没有对应 case - 没有 (Primitive)28/(Primitive)29 这类数字强转 文档相应调整: - 3.2 表格加「迁移」列,两种类型标为否,并补核对依据 - 4.3.1/4.3.2 把两处读写点移出迁移表,注明保持现状 - 4.3.3、4.3.6 的停写范围收敛为「迁移的 7 种类型」 - 12.5 降级表改为「不进容器,m_sScr 原样写出」 - 12.6 由「折线后缀待定」改写为「不参与迁移(已定)」,冲突不再存在 - 11.2 删掉折线后缀这条待定项,第 7 节验证清单同步
This commit is contained in:
1 parent
11bbf6dbf9
commit
4bc346640c
1 file changed
+35
-29
@@ -77,7 +77,7 @@ if (AcDbX3dSolid::kCurrentVersionNumber > 1) {
|
||||
|
||||
### 3.2 多 region 容器
|
||||
|
||||
9 种类型里,6 种只有 region(5 种单 region、1 种双 region),2 种是 region + 折线,1 种(`kLoft`)N 个 region。容器只装 region,折线部分不进容器:
|
||||
9 种 region 类型里,**只有 7 种参与迁移**:5 种单 region、1 种双 region(`kConePipe`)、1 种 N region(`kLoft`)。`kIntersect`(28) / `kSliceSolid`(29) 是遗留类型,全库没有产生路径,不参与迁移(见下)。容器只装 region:
|
||||
|
||||
```cpp
|
||||
// 16 字节头
|
||||
@@ -96,22 +96,31 @@ struct RegionBlobHeader {
|
||||
|
||||
对应关系(按当前代码核对):
|
||||
|
||||
| 类型 | `m_sScr` 实际内容 | nRegions |
|
||||
| --- | --- | --- |
|
||||
| `kExtrude2`(27) / `kSlicePipe`(26) / `kRevolve`(21) / `kRevolve2`(38) / `kSweep`(40) | 单个 region 的 SAT | 1 |
|
||||
| `kConePipe`(30) | `外环SAT` + `\|` + `内环SAT` | 2 |
|
||||
| `kIntersect`(28) / `kSliceSolid`(29) | `regionSAT` + `\|` + **折线文本** | 1 |
|
||||
| `kLoft`(41) | N 个 region SAT,`@region@` 连接 | N |
|
||||
| 类型 | `m_sScr` 实际内容 | nRegions | 迁移 |
|
||||
| --- | --- | --- | --- |
|
||||
| `kExtrude2`(27) / `kSlicePipe`(26) / `kRevolve`(21) / `kRevolve2`(38) / `kSweep`(40) | 单个 region 的 SAT | 1 | 是 |
|
||||
| `kConePipe`(30) | `外环SAT` + `\|` + `内环SAT` | 2 | 是 |
|
||||
| `kLoft`(41) | N 个 region SAT,`@region@` 连接 | N | 是 |
|
||||
| `kIntersect`(28) / `kSliceSolid`(29) | `regionSAT` + `\|` + 折线文本 | — | **否**,遗留类型,`m_sScr` 保持原样 |
|
||||
|
||||
几点必须注意:
|
||||
|
||||
- `kIntersect` / `kSliceSolid` 的第二个分量是 `CoreTools::CurveToString` 产出的折线文本,**不是 region**。写端 `:2130`/`:2184`,读端用 `StringToPolyline`(`:4403`、`:4441`)。原文档把它们当成「外 + 内」两个 region 是错的,按那样装容器,解包时第二个 `acisIn` 必然失败
|
||||
- `kIntersect` / `kSliceSolid` 不参与迁移:不进容器、不停止写 `m_sScr`,读写路径保持原样。它们的老格式是 `regionSAT|折线文本`,第二个分量是 `CoreTools::CurveToString` 产出的折线(`:2130`/`:2184`),**不是 region**;读端用 `StringToPolyline`(`:4403`、`:4441`)。原文档把它们当成「外 + 内」两个 region 是错的
|
||||
- 切分统一取第一个 `|`,且 `sScr2 = m_sScr.Mid(nPos)` 保留了分隔符本身,靠 `StringToRegion` / `StringToPolyline` 内部找 ACIS 头容错
|
||||
- `kSweep` 的路径存在 `m_sszPoint2ds`(`AcDbCurveToString`,`:5088`/`:5103`),不在 `m_sScr`
|
||||
- 将来做降级导出时也要按这张表拼回,`kIntersect` / `kSliceSolid` 的折线文本要原样保留
|
||||
- 降级导出按这张表拼回:迁移的 7 种走容器,遗留的 2 种原样保留 `m_sScr`
|
||||
|
||||
`magic` 是**必需**的,不是可选项:`m_pSatBuffer` 是公共字节池,当前已有 4 种语义(`kFenceExtrude` 点数组、`kFrom3JS` SubDMesh、`kLoftReducer` 宽字符串、SAT 导入原始字节),必须自校验。
|
||||
|
||||
**`kIntersect` / `kSliceSolid` 为什么排除在外**(2026-10-22 核对):
|
||||
|
||||
- 枚举只在 `inc/AcDbX3dSolid.h:53-54` 定义,其它模块零引用
|
||||
- `CreateIntersect` / `CreateSliceSolid` 只有三个出现点:定义(`:2050`、`:2136`)、头文件声明、`ReCreate` 的读分支调用(`:4413`、`:4451`)—— 是纯读路径,只为重建图纸里已有的对象
|
||||
- `Create()` 的 12 个 case 里没有它们;`SetSolidData()` 全库无调用者,内部也没有对应 case
|
||||
- 没有 `(Primitive)28` / `(Primitive)29` 这类数字强转
|
||||
|
||||
结论:新图永远不会产生这两种对象,阶段三不必为它们设计容器格式。
|
||||
|
||||
### 3.3 编解码
|
||||
|
||||
```cpp
|
||||
@@ -201,8 +210,6 @@ void EnsureCreated() { if (m_bNeedCreate) { m_bNeedCreate = false; ReCreate(); }
|
||||
| `:1371` | `kExtrude2` | `RegionToString(pReg, m_sScr)` |
|
||||
| `:1436`、`:1439` | `kConePipe` | 外/内 → `sScr1`/`sScr2` → 拼 `m_sScr` |
|
||||
| `:2041` | `kSlicePipe` | → `m_sScr` |
|
||||
| `:2127` | `kIntersect` | → `sScr1` → `m_sScr` |
|
||||
| `:2181` | `kSliceSolid` | → `sSrc1` → `m_sScr` |
|
||||
| `:2211` | `kRevolve` | → `m_sScr` |
|
||||
| `:2242` | `kRevolve2` | → `m_sScr` |
|
||||
| `:5029` | `kLoft` | `strAll`(`@region@` 拼接)→ `m_sScr` |
|
||||
@@ -211,14 +218,14 @@ void EnsureCreated() { if (m_bNeedCreate) { m_bNeedCreate = false; ReCreate(); }
|
||||
| `:5135`、`:5155`、`:5176`、`:5206` | `SetExturd2Data` / `SetRevolve2Data` / `SetSweepData` / `SetLoftData` | `m_sScr = sReg` |
|
||||
| `:5516`、`:5528`、`:5542`、`:5562`、`:5589` | `TransformBy` | 变换后重新导出 |
|
||||
|
||||
`kIntersect`(`:2127`) 与 `kSliceSolid`(`:2181`) 不迁移,写入保持现状(见 3.2)。
|
||||
|
||||
#### 4.3.2 读取点(`StringToRegion(m_sScr)` → `UnpackRegions`)
|
||||
|
||||
| 行 | 类型 / 函数 |
|
||||
| --- | --- |
|
||||
| `:4366` | `kSlicePipe` |
|
||||
| `:4378` | `kExtrude2` |
|
||||
| `:4402` | `kIntersect` |
|
||||
| `:4440` | `kSliceSolid` |
|
||||
| `:4468` | `kRevolve` |
|
||||
| `:4488`、`:4489` | `kConePipe` |
|
||||
| `:4563` | `kRevolve2` |
|
||||
@@ -227,11 +234,13 @@ void EnsureCreated() { if (m_bNeedCreate) { m_bNeedCreate = false; ReCreate(); }
|
||||
| `:5321`、`:5345`、`:5370`、`:5453` | `ToJson` |
|
||||
| `:5512`、`:5524`、`:5538`、`:5558`、`:5584` | `TransformBy` |
|
||||
|
||||
`kIntersect`(`:4402`) 与 `kSliceSolid`(`:4440`) 的读分支保留原样,不改成 `UnpackRegions`。
|
||||
|
||||
#### 4.3.3 序列化
|
||||
|
||||
**不改**。`m_pSatBuffer` 的 `writeUInt32` + `writeBytes` 已经在 `:4822-4829`,`dwgInFields` 有对称读。
|
||||
|
||||
只改一件事:region 类型写入时**不再写 `m_sScr`**(保持空字符串),管廊脚本类型不受影响。
|
||||
只改一件事:迁移的 7 种 region 类型写入时**不再写 `m_sScr`**(保持空字符串)。`kIntersect` / `kSliceSolid` 例外,继续按老格式写;管廊脚本类型不受影响。
|
||||
|
||||
#### 4.3.4 兼容判断
|
||||
|
||||
@@ -322,7 +331,7 @@ void SetSweepData(const CString& sReg, const AcDbCurve* pCurve);
|
||||
|
||||
功能(必须在 CAD 内实测):
|
||||
|
||||
1. **新建 + 存盘 + 重开**:9 个 region 类型的几何与改前一致(对比 `getArea`、体积、`getGeomExtents`)
|
||||
1. **新建 + 存盘 + 重开**:迁移的 7 个 region 类型的几何与改前一致(对比 `getArea`、体积、`getGeomExtents`);`kIntersect` / `kSliceSolid` 不迁移,只需确认老图仍能打开
|
||||
2. **老图纸兼容**:打开改动前保存的图,走 `m_sScr` 路径,几何正确
|
||||
3. **移动 / 旋转**:`kExtrude2`、`kRevolve`、`kRevolve2`、`kLoft`、`kSweep` 变换后几何跟着动(`TransformBy` 的 5 处往返)
|
||||
4. **复制粘贴 / 撤销**:验证 `Clone()` 路径(`AecDbXDraw::add3DCache`)不崩、不丢几何
|
||||
@@ -397,7 +406,6 @@ void SetSweepData(const CString& sReg, const AcDbCurve* pCurve);
|
||||
|
||||
1. `TransformBy`、`ToJson` 是否一起改——这两处在运行时会反复导出/解析 SAT,是阶段三改动量的大头
|
||||
2. 老图纸里 region 类型的实际占比——占比低的话体积收益有限,可以永久搁置
|
||||
3. `kIntersect` / `kSliceSolid` 的折线后缀怎么存(12.6)——阶段三动 `m_sScr` 之前必须先定,否则折线文本会丢
|
||||
|
||||
### 11.3 实施时的技术前提(已核对)
|
||||
|
||||
@@ -480,22 +488,20 @@ if (pSatOut != NULL)
|
||||
| --- | --- | --- |
|
||||
| `kExtrude2` / `kSlicePipe` / `kRevolve` / `kRevolve2` / `kSweep` | 1 个 region | region 的 SAT 文本 |
|
||||
| `kConePipe` | 2 个 region(外、内) | `外环SAT` + `\|` + `内环SAT` |
|
||||
| `kIntersect` / `kSliceSolid` | 1 个 region | `regionSAT` + `m_sScr`(折线后缀,见 12.6) |
|
||||
| `kIntersect` / `kSliceSolid` | 不进容器 | 不涉及,`m_sScr` 原样写出 |
|
||||
| `kLoft` | N 个 region | N 段 SAT 用 `@region@` 连接 |
|
||||
|
||||
读端能容忍 `|` 留在第二段:`kConePipe` 用 `StringToRegion(sScr2)`(`:4489`)、`kIntersect` / `kSliceSolid` 用 `StringToPolyline(sScr2)`(`:4403`、`:4441`),两者内部都靠找 ACIS 头 / 数值容错。
|
||||
`kConePipe` 的读端用 `StringToRegion(sScr2)`(`:4489`),`sScr2` 带着开头的 `|`,靠 `StringToRegion` 内部找 ACIS 头容错,所以拼回时照原样加 `|` 即可。
|
||||
|
||||
### 12.6 阶段三必须先把折线后缀的位置定下来
|
||||
### 12.6 `kIntersect` / `kSliceSolid` 不参与迁移(已定)
|
||||
|
||||
`kIntersect` / `kSliceSolid` 的老格式是 `regionSAT|折线文本`,折线文本不是 region,不进容器。而 4.3.6 要求 region 类型停写 `m_sScr`——这两条冲突。
|
||||
这两种是遗留类型,全库没有产生路径(核对见 3.2),只可能出现在早期版本写出的图纸里。因此:
|
||||
|
||||
**建议**:这两种类型继续写 `m_sScr`,但只写老格式的第二段(含开头的 `|`,即原来的 `sScr2`)。理由:
|
||||
- 阶段三不为它们设计容器格式,`m_sScr` 继续按老格式写
|
||||
- 降级导出对它们无事可做——本来就没进容器
|
||||
- 老图打开时仍走 `ReCreate` 的 `StringToRegion` + `StringToPolyline` 重建,读路径保留
|
||||
|
||||
- 体积上只多了折线文本,region 那部分照常减半
|
||||
- 读端 `sScr2 = m_sScr.Mid(nPos)` 的既有切分逻辑不用改
|
||||
- 降级导出直接 `regionSAT + m_sScr`,不需要额外字段
|
||||
|
||||
不这么做的话,折线只能塞进容器做第二个 section,容器格式要加类型标签,复杂度和风险都上一个台阶。
|
||||
之前设想的「折线后缀与 4.3.6 停写 `m_sScr` 冲突」因此不成立:停写范围只覆盖迁移的 7 种类型。
|
||||
|
||||
### 12.7 命令
|
||||
|
||||
@@ -525,11 +531,11 @@ void SaveLegacyDwg()
|
||||
|
||||
### 12.9 验证清单
|
||||
|
||||
- 9 种类型各建一个样本,导出后装到老版本插件里打开,几何、面积、位置都正确
|
||||
- 迁移的 7 种类型各建一个样本,导出后装到老版本插件里打开,几何、面积、位置都正确
|
||||
- 老版本打开导出的图 → 另存 → 回新版打开,几何仍正确(回环)
|
||||
- 导出前后,当前文档自身存盘仍是新格式(开关已复位)
|
||||
- 容器被人为改坏(magic 对、region 段截断)时,`MakeLegacyScr` 返回 false,导出退回新格式并打日志,不产出空几何
|
||||
- `kIntersect` / `kSliceSolid` 的折线后缀原样保留,读回后截面边界正确
|
||||
- 遗留的 `kIntersect` / `kSliceSolid`(若老图里有)打开、另存、再打开,截面仍能重建
|
||||
|
||||
### 12.10 成本与时机
|
||||
|
||||
@@ -540,4 +546,4 @@ void SaveLegacyDwg()
|
||||
| 导出命令 + 文件选择 | ~40 行 |
|
||||
| 主要风险 | 老格式规则核对不全,导出的图在老版本里读不出来 |
|
||||
|
||||
依赖 12.6 的折线后缀方案先定。与阶段三的先后关系:两者最好一起上——阶段三一旦合入、`m_sScr` 停写,没有降级导出的那段时间里,新图在老版本插件上就是缺几何的。
|
||||
12.6 的结论已经定:遗留类型不参与迁移,阶段三不必为它们设计容器格式。与阶段三的先后关系:两者最好一起上——阶段三一旦合入、`m_sScr` 停写,没有降级导出的那段时间里,新图在老版本插件上就是缺几何的。
|
||||
Reference in new issue
Block a user