From 4bc346640c1f14b9b8e9bd0215af4d2f06d441a2 Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Thu, 22 Oct 2026 13:52:13 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20kIntersect/kSliceSolid=20=E6=98=AF?= =?UTF-8?q?=E9=81=97=E7=95=99=E7=B1=BB=E5=9E=8B=EF=BC=8C=E9=98=B6=E6=AE=B5?= =?UTF-8?q?=E4=B8=89=E4=B8=8D=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 核对结果:这两种类型全库没有产生路径,新图永远不会出现。 - 枚举只在 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 节验证清单同步 --- AcDbX3dSolid-refactor-plan.md | 64 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/AcDbX3dSolid-refactor-plan.md b/AcDbX3dSolid-refactor-plan.md index ea1edf7..de97297 100644 --- a/AcDbX3dSolid-refactor-plan.md +++ b/AcDbX3dSolid-refactor-plan.md @@ -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` 停写,没有降级导出的那段时间里,新图在老版本插件上就是缺几何的。