Merge pull request 'docs: 阶段三暂缓,补兼容取舍与已核对的技术前提' (#35) from company-desktop-computer/docs/x3dsolid-stage3-deferred into main
Reviewed-on: #35
This commit was merged in pull request #35.
This commit is contained in:
commit
266deb16ae
1 file changed
+85
-36
@@ -4,7 +4,7 @@
|
|||||||
>
|
>
|
||||||
> 范围:`SourceCode/Code2026/CoreLibrary/AcDbX3dSolid.cpp`(5596 行)、`inc/AcDbX3dSolid.h`、`CoreCommand/CoreTools.cpp`。
|
> 范围:`SourceCode/Code2026/CoreLibrary/AcDbX3dSolid.cpp`(5596 行)、`inc/AcDbX3dSolid.h`、`CoreCommand/CoreTools.cpp`。
|
||||||
>
|
>
|
||||||
> 原则:**老图纸必须能读**;写入统一新格式;不改对象模型(`AcDbX3dSolid` 仍是可平凡复制的数据类)。
|
> 原则:**单向兼容——新版必须能读老图纸,老版不保证能显示新图的 region 类型几何**(见 11.1);写入统一新格式;不改对象模型(`AcDbX3dSolid` 仍是可平凡复制的数据类)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ AcDbRegion* ──RegionToString()──► %TEMP%\Region1.sat ──读文件
|
|||||||
`m_pSatBuffer` 的读写通道**已经打通并持久化**:
|
`m_pSatBuffer` 的读写通道**已经打通并持久化**:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// dwgOutFields :4808-4814
|
// dwgOutFields :4822-4829
|
||||||
if (AcDbX3dSolid::kCurrentVersionNumber > 1) {
|
if (AcDbX3dSolid::kCurrentVersionNumber > 1) {
|
||||||
pFiler->writeUInt32(m_nSatLen);
|
pFiler->writeUInt32(m_nSatLen);
|
||||||
if (m_pSatBuffer != NULL)
|
if (m_pSatBuffer != NULL)
|
||||||
@@ -107,20 +107,28 @@ struct RegionBlobHeader {
|
|||||||
### 3.3 编解码
|
### 3.3 编解码
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// AcDbX3dSolid.cpp 内部 static
|
// AcDbX3dSolid.cpp 匿名 namespace
|
||||||
static bool PackRegions(const AcArray<AcDbRegion*>& regs, void*& pBuf, Adesk::UInt32& nLen);
|
bool PackRegions(const AcArray<AcDbRegion*>& regs, void*& pBuf, Adesk::UInt32& nLen);
|
||||||
static bool UnpackRegions(const void* pBuf, Adesk::UInt32 nLen, AcArray<AcDbRegion*>& regs);
|
bool UnpackRegions(const void* pBuf, Adesk::UInt32 nLen, AcArray<AcDbRegion*>& regs);
|
||||||
|
|
||||||
// 单 region 的 SAT 字节(CoreTools 新增,与 RegionToString 共用临时文件逻辑)
|
|
||||||
bool CoreTools::RegionToBuffer(const AcDbRegion* pReg, void*& pBuf, Adesk::UInt32& nLen);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`UnpackRegions` 内部用**已存在**的 `CoreTools::StringToRegion(Adesk::UInt64 nLen, char* pszReg)`(`CoreTools.cpp:3525`),读端无需新代码。
|
单 region 的 SAT 字节**不需要新函数**,直接复用已有的两个重载:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 输出 SAT 的 ASCII 字节,返回长度,pszTxt 由调用方 delete[]
|
||||||
|
Adesk::UInt64 CoreTools::RegionToString(const AcDbRegion* pReg, char*& pszTxt); // CoreTools.cpp:3114
|
||||||
|
// 从字节重建 region
|
||||||
|
AcDbRegion* CoreTools::StringToRegion(Adesk::UInt64 nLen, char* pszReg); // CoreTools.cpp:3581
|
||||||
|
```
|
||||||
|
|
||||||
|
`RegionToString(char*&)` 内部已经用 `MakeTempSatPath()` + `DeleteFile`,`StringToRegion` 内部已经过 `fixACISFormat`,阶段一、二落地后这两条链路都是现成的。`PackRegions` 负责把拿到的字节拷进容器并 `delete[]`。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. 改动清单
|
## 4. 改动清单
|
||||||
|
|
||||||
|
> 阶段一、二已合并;阶段三暂缓,取舍与前提见第 11 节。以下保留完整方案,供重启时参考。
|
||||||
|
|
||||||
### 阶段一:临时文件唯一化(纯 bug 修复)
|
### 阶段一:临时文件唯一化(纯 bug 修复)
|
||||||
|
|
||||||
**位置**:`CoreCommand/CoreTools.cpp`
|
**位置**:`CoreCommand/CoreTools.cpp`
|
||||||
@@ -178,40 +186,42 @@ void EnsureCreated() { if (m_bNeedCreate) { m_bNeedCreate = false; ReCreate(); }
|
|||||||
|
|
||||||
#### 4.3.1 写入点(`RegionToString` → `PackRegions`)
|
#### 4.3.1 写入点(`RegionToString` → `PackRegions`)
|
||||||
|
|
||||||
| 行 | 类型 | 现状 |
|
行号为当前 main(阶段一、二落地后),实施时以函数名定位。
|
||||||
|
|
||||||
|
| 行 | 类型 / 函数 | 现状 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `:1364` | `kExtrude2` | `RegionToString(pReg, m_sScr)` |
|
| `:1371` | `kExtrude2` | `RegionToString(pReg, m_sScr)` |
|
||||||
| `:1429-1432` | `kConePipe` | 外/内两个 → `sScr1`/`sScr2` → 拼 `m_sScr` |
|
| `:1436`、`:1439` | `kConePipe` | 外/内 → `sScr1`/`sScr2` → 拼 `m_sScr` |
|
||||||
| `:2034` | `kSlicePipe` | `RegionToString(pRegion, m_sScr)` |
|
| `:2041` | `kSlicePipe` | → `m_sScr` |
|
||||||
| `:2120` | `kIntersect` | → `sScr1` → `m_sScr` |
|
| `:2127` | `kIntersect` | → `sScr1` → `m_sScr` |
|
||||||
| `:2174` | `kSliceSolid` | → `sSrc1` → `m_sScr` |
|
| `:2181` | `kSliceSolid` | → `sSrc1` → `m_sScr` |
|
||||||
| `:2204` | `kRevolve` | → `m_sScr` |
|
| `:2211` | `kRevolve` | → `m_sScr` |
|
||||||
| `:2235` | `kRevolve2` | → `m_sScr` |
|
| `:2242` | `kRevolve2` | → `m_sScr` |
|
||||||
| `:5020` | `kLoft` | `strAll`(`@region@` 拼接)→ `m_sScr` |
|
| `:5029` | `kLoft` | `strAll`(`@region@` 拼接)→ `m_sScr` |
|
||||||
| `:5073`、`:5087` | `kSweep` | → `m_sScr` |
|
| `:5087`、`:5101` | `kSweep` | → `m_sScr` |
|
||||||
| `:4868`、`:4881` | `SetSolidData` | `m_sScr = srcRegion` |
|
| `:4882`、`:4895` | `SetSolidData` | `m_sScr = srcRegion` |
|
||||||
| `:5121`、`:5141`、`:5162`、`:5192` | `SetExturd2Data` / `SetRevolve2Data` / `SetSweepData` / `SetLoftData`(`:5192` 所属函数实施时核对) | `m_sScr = sReg` |
|
| `:5135`、`:5155`、`:5176`、`:5206` | `SetExturd2Data` / `SetRevolve2Data` / `SetSweepData` / `SetLoftData` | `m_sScr = sReg` |
|
||||||
|
| `:5516`、`:5528`、`:5542`、`:5562`、`:5589` | `TransformBy` | 变换后重新导出 |
|
||||||
|
|
||||||
#### 4.3.2 读取点(`StringToRegion(m_sScr)` → `UnpackRegions`)
|
#### 4.3.2 读取点(`StringToRegion(m_sScr)` → `UnpackRegions`)
|
||||||
|
|
||||||
| 行 | 类型 |
|
| 行 | 类型 / 函数 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `:4364` | `kSlicePipe` |
|
| `:4366` | `kSlicePipe` |
|
||||||
| `:4376` | `kExtrude2` |
|
| `:4378` | `kExtrude2` |
|
||||||
| `:4400` | `kIntersect` |
|
| `:4402` | `kIntersect` |
|
||||||
| `:4438` | `kSliceSolid` |
|
| `:4440` | `kSliceSolid` |
|
||||||
| `:4466` | `kRevolve` |
|
| `:4468` | `kRevolve` |
|
||||||
| `:4486-4487` | `kConePipe` |
|
| `:4488`、`:4489` | `kConePipe` |
|
||||||
| `:4561` | `kRevolve2` |
|
| `:4563` | `kRevolve2` |
|
||||||
| `:4585` | `kLoft` |
|
| `:4587` | `kLoft`(循环) |
|
||||||
| `:4599` | `kSweep` |
|
| `:4601` | `kSweep` |
|
||||||
| `:5307`、`:5331`、`:5356`、`:5439` | `ToJson` |
|
| `:5321`、`:5345`、`:5370`、`:5453` | `ToJson` |
|
||||||
| `:5500`、`:5512`、`:5526`、`:5542`、`:5571` | `TransformBy` |
|
| `:5512`、`:5524`、`:5538`、`:5558`、`:5584` | `TransformBy` |
|
||||||
| `:5111`、`:5129`、`:5154` | `GetExturd2Data` / `GetRevolve2Data` / `GetSweepData` |
|
|
||||||
|
|
||||||
#### 4.3.3 序列化
|
#### 4.3.3 序列化
|
||||||
|
|
||||||
**不改**。`m_pSatBuffer` 的 `writeUInt32` + `writeBytes` 已经在 `:4808-4814`,`dwgInFields` 有对称读。
|
**不改**。`m_pSatBuffer` 的 `writeUInt32` + `writeBytes` 已经在 `:4822-4829`,`dwgInFields` 有对称读。
|
||||||
|
|
||||||
只改一件事:region 类型写入时**不再写 `m_sScr`**(保持空字符串),管廊脚本类型不受影响。
|
只改一件事:region 类型写入时**不再写 `m_sScr`**(保持空字符串),管廊脚本类型不受影响。
|
||||||
|
|
||||||
@@ -235,7 +245,7 @@ else if (!m_sScr.IsEmpty())
|
|||||||
|
|
||||||
写入:只写新格式。
|
写入:只写新格式。
|
||||||
|
|
||||||
**不升 `kCurrentVersionNumber`**。理由:字段都在,靠"哪个非空"即可判别;升版本会让老版本 CAD 读新图时走 `eMakeMeProxy`。
|
**不升 `kCurrentVersionNumber`**。理由:字段都在,靠"哪个非空"即可判别;升版本会让老版本 CAD 读新图时走 `eMakeMeProxy`,新图在所有老版本上彻底不可编辑。代价是老版本看不到 region 类型的几何,这是已定的取舍,见 11.1。
|
||||||
|
|
||||||
#### 4.3.5 `kLoftReducer` 纳入统一容器
|
#### 4.3.5 `kLoftReducer` 纳入统一容器
|
||||||
|
|
||||||
@@ -354,3 +364,42 @@ void SetSweepData(const CString& sReg, const AcDbCurve* pCurve);
|
|||||||
| 1 | `kLoftReducer`(22) 是否纳入统一容器 | **纳入**(4.3.5),老数据回退 `0x00c1` 切分 |
|
| 1 | `kLoftReducer`(22) 是否纳入统一容器 | **纳入**(4.3.5),老数据回退 `0x00c1` 切分 |
|
||||||
| 2 | `kSHEarthWorm`(23) 是否仍在使用 | **已废弃**,但 `m_sScr` 字段本次保留不删,仅停止写入(4.3.6) |
|
| 2 | `kSHEarthWorm`(23) 是否仍在使用 | **已废弃**,但 `m_sScr` 字段本次保留不删,仅停止写入(4.3.6) |
|
||||||
| 3 | 公开 `CString` 接口 | **签名不变**,内部转换,外部调用方零改动(第 5 节) |
|
| 3 | 公开 `CString` 接口 | **签名不变**,内部转换,外部调用方零改动(第 5 节) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 阶段三暂缓(2026-10-22)
|
||||||
|
|
||||||
|
**决定:暂不实施。** 阶段一(临时文件唯一化、越界读)、阶段二(懒重建)已合并,主要痛点已经解决;阶段三剩下的收益只有「region 部分 DWG 体积减半」,代价是新图在老版本插件里 region 几何不可见。当前时机未到。
|
||||||
|
|
||||||
|
### 11.1 兼容方向(已定)
|
||||||
|
|
||||||
|
**单向兼容**:新版插件完整读取旧版图纸(`m_sScr` 老路径永久保留);旧版插件打开新图时,region 类型的 `AcDbX3dSolid` 几何不可见。
|
||||||
|
|
||||||
|
不可见不等于丢数据:`m_pSatBuffer` 老版本也会原样读写(版本 > 1 的通道一直都在),所以旧版打开后另存、再回新版打开,几何仍能恢复。非 region 类型(`m_sszPoint2ds` 点串、SubDMesh、管廊脚本)不受影响。
|
||||||
|
|
||||||
|
| 选项 | 后果 | 结论 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 不升版本号,接受老插件缺几何 | 老插件能开图、参数都在,region 类型几何不显示;换新版可恢复 | **已定,选这个** |
|
||||||
|
| 升到 5,老插件显式 proxy | 不会静默缺几何,但新图在所有老版本上彻底不可编辑,且不可回退 | 不选 |
|
||||||
|
| 保留双写(`m_sScr` 仍写老格式) | 体积变成 2N + N,比现状更差 | 否决 |
|
||||||
|
|
||||||
|
### 11.2 重启前还要定的事
|
||||||
|
|
||||||
|
1. `TransformBy`、`ToJson` 是否一起改——这两处在运行时会反复导出/解析 SAT,是阶段三改动量的大头
|
||||||
|
2. 老图纸里 region 类型的实际占比——占比低的话体积收益有限,可以永久搁置
|
||||||
|
|
||||||
|
### 11.3 实施时的技术前提(已核对)
|
||||||
|
|
||||||
|
- `kCurrentVersionNumber` 当前是 **4**。`m_pSatBuffer` 的读写通道在 `dwgOutFields:4822` / `dwgInFields:4754`,版本 > 1 即生效,阶段三不需要动序列化
|
||||||
|
- **不需要**新增 `CoreTools::RegionToBuffer`:`RegionToString(const AcDbRegion*, char*&)`(`CoreTools.cpp:3114`)已经输出 SAT 的 ASCII 字节和长度,内部用 `MakeTempSatPath` + `DeleteFile`
|
||||||
|
- 读端 `StringToRegion(Adesk::UInt64, char*)`(`CoreTools.cpp:3581`)已经过 `fixACISFormat`
|
||||||
|
- `m_pSatBuffer` 当前有 4 种语义:`kFenceExtrude` 点数组(`:1514`)、`kFrom3JS` SubDMesh(`:1019`/`:1048`)、`kLoftReducer` 宽字符串(`:3132`/`:5405`)、SAT 导入原始字节(`:2872`)。容器头的 magic 是必需的
|
||||||
|
- 拷贝构造对 `m_pSatBuffer` 做了深拷贝(`:274-280`),`Clone()` 不会共享指针
|
||||||
|
|
||||||
|
### 11.4 当前状态
|
||||||
|
|
||||||
|
| 阶段 | 状态 | PR |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 一:临时文件唯一化 | 已合并 | #22、#26 |
|
||||||
|
| 二:懒重建 | 已合并 | #25、#27 |
|
||||||
|
| 三:region 二进制化 | 暂缓 | — |
|
||||||
Reference in new issue
Block a user