fix: GetInterface 数组版补 dUnit,与下标版统一单位

AecDbEwEquipment::GetInterface(AcArray<AecInterface>&) 里 ptPos 已经
transformBy(xform) 缩放过(米制 0.001),但 dSize1 / dSize2 直接取
pNoze->dVal1,没有乘 dUnit;下标版 GetInterface(int, ...) 是乘了的。
结果同一个接口经两个入口读出来尺寸差 1000 倍,出现"位置按米、尺寸按毫米"。

补 * dUnit。dV / dA 是电压电流(EarThwormDef.h:518),不是长度,不参与换算。

影响面:
- 数组版的 4 处内部调用(getOsnapPoints、subErase、DrawInfArrow、vtAdjust)
  只用 ptPos / vtDir,不受影响
- 外部消费 dSize1 的是 CoreCommand/pcf.cpp:1044 的 pcf_ewEquipment,
  米制图纸导出的 PCF 管径此前大了 1000 倍
- 毫米图纸 dUnit 为 1,行为不变

文档同步:3.7 补结论与影响面,3.12 标记确认不改,5.1 加第 16 项,
5.4 三项按结论更新。
This commit is contained in:
company-desktop committed 2026-10-25 11:58:00 +08:00
1 parent a72b38c4e5
commit d1f4d0b50b
2 files changed
+26 -11

No files matched your search

+22 -9
View File
@@ -361,15 +361,24 @@ return (nCount - nCoundPre); // :12762 顺序反了
建议:`HLR_CALC` 这类纯运行时标志不要进 `m_mapSpecXData`,或序列化时按 key 白名单/黑名单过滤。
### 3.7 P1:`GetInterface` 两个重载单位不一致
### 3.7 P1:`GetInterface` 两个重载单位不一致(已修复)
| 重载 | 位置 | 是否乘 `dUnit`(米制 0.001) |
| --- | --- | --- |
| `GetInterface(int, AecInterface&)` | `:3285` | 是(`inf.dSize1 = pNoze->dVal1 * dUnit`) |
| `GetInterface(AcArray<AecInterface>&)` | `:3224` | **否**(直接 `pNoze->dVal1`) |
| `GetInterface(int, AecInterface&)` | `:3323` | 是(`inf.dSize1 = pNoze->dVal1 * dUnit`) |
| `GetInterface(AcArray<AecInterface>&)` | `:3262` | **否**(直接 `pNoze->dVal1`) |
米制图纸里,同一份数据经两个入口读出来的接口尺寸差 1000 倍。`Draw*Vlv2d` 用下标版,`subErase` / `PreprocessForHlr` 用数组版,两边算出来的东西对不上。
**已修复**:数组版补 `* dUnit`,与下标版一致。
- 数组版里 `ptPos` 本来就 `transformBy(xform)` 缩放过,只有尺寸没缩,属于「位置按米、尺寸按毫米」的自相矛盾
- `dV` / `dA` 是电压电流(`EarThwormDef.h:518`),不是长度,不参与换算
- 影响面:数组版的 4 处内部调用(`getOsnapPoints`、`subErase`、`DrawInfArrow`、`vtAdjust`)只用 `ptPos` / `vtDir`;外部消费 `dSize1` 的是 `CoreCommand/pcf.cpp:1044` 的 `pcf_ewEquipment`,米制图纸导出的 PCF 管径此前大了 1000 倍
- 只在米制图纸(`INSUNITS == kUnitsMeters`)里有差异,毫米图纸 `dUnit` 为 1,行为不变
**顺带发现(未改)**:同一函数里 `inf.bSizeUnLock = true;` 写在 `:3283`,循环内的 `memset(&inf, 0, sizeof(AecInterface))`(`:3294`)每次都把它清成 false,所以数组版返回的接口实际一直是「锁定」。下标版由调用方传入 `inf`,不经过 memset。修这个要确认下游怎么用 `bSizeUnLock`,单独评估。
### 3.8 P1:`copyFrom` 漏拷字段(已修复)
`:2174` 只拷了 `m_mapSpecXData` / `m_nInfActive` / `m_ptInsert` / `m_vtDir` / 几何单元,**没有拷 `m_bVert`、`m_idDash`、`m_idCenter`**。复制粘贴一个竖放阀门,粘贴出来是横放的;两个图层软指针也丢了(虚线和中心线会跑到默认图层)。
@@ -421,7 +430,7 @@ p->m_pData = new PVOID[br._len]; // 按 PVOID 个数分配
**已修复**:加 16MB 上限(`kMaxXPrimDataSize`),超限 `setFilerStatus(Acad::eInvalidInput)` 让整个 `dwgInFields` 退出;`readBytes` 检查返回值,失败时释放并清零。`m_Combins` 的递归深度上限未加,损坏图纸仍可能打爆栈,优先级低。
### 3.12 P2:`PreprocessForHlr` 的"对面"被变换了两次
### 3.12 P2:`PreprocessForHlr` 的"对面"被变换了两次(确认不改)
```cpp
AcGeMatrix3d mat4(mat3.inverse()); // mat3 = 沿截面法向平移 -H/2
@@ -433,7 +442,9 @@ for (...) {
}
```
原实体在 `-H/2` 位置,克隆体被移到 `+H` 位置(两次 `+H/2`),两侧不对称。除非这是刻意做的"厚度补偿",否则应只乘一次。建议拿一个剖切样例对照确认。
原实体在 `-H/2` 位置,克隆体被移到 `+H` 位置(两次 `+H/2`),两侧不对称。
**2026-10-25 结论:是故意的,不改。** `mat3` 只移动半个设备高度,乘两次正好凑成一个设备高度,剖切体的前后两面本来就该相距一个完整高度。
### 3.13 P2:`GetBodyBox` 恒返回 `TRUE`(已修复)
@@ -580,6 +591,7 @@ Draw3dSolid(&dc, nColor); // :3062 拖拽时每帧都走到这里
| 13 | `byJson` 按字节长度分配 `m_pData` | 低 | 已完成 |
| 14 | `dwgInFieldsForXPrim` 加尺寸上限与读失败处理 | 低 | 已完成 |
| 15 | `GetBodyBox` 返回实际结果 | 低 | 已完成 |
| 16 | `GetInterface` 数组版补 `dUnit` | 低(仅米制图纸有差异) | 已完成 |
另外补做的 4 处内存修复(2.6、2.7、2.9、2.10、2.11、`GetDraw3dables` 合并泄漏、`dwgInFields` 的 `RemoveAll`)见 2.13。
@@ -609,9 +621,9 @@ Draw3dSolid(&dc, nColor); // :3062 拖拽时每帧都走到这里
1. ~~`booleanOper` 是否删除入参(3.15)~~ —— 2026-10-23 按「不删除入参」处理,理由见 3.15
2. ~~`GetSectionDraw` 的返回值调用方到底期望什么(3.5)~~ —— 2026-10-25 核实全库调用点都忽略返回值,已按「返回新增个数」修正
3. ~~`kCombination` 单元的实际存量(5.2)~~ —— 2026-10-25 确认仍在用,见 3.1
4. `PreprocessForHlr` 的 `mat4` 双次变换是否刻意(3.12)
5. `HLR_CALC` 是否从 `m_mapSpecXData` 的序列化里排除(3.6):要动 `AecDbObjXDataMap` 公共类,且 `AecDbEwPipe` / `AecDbEwFitting` / `AecDbOpening` / `AecDbPipeHanger` 都在用它,需逐个确认有没有依赖它跨会话保持的地方
6. `GetInterface` 数组版是否补 `dUnit`(3.7):补了之后米制图纸里所有走数组版的尺寸会放大 1000 倍,需确认 `subErase`、`PreprocessForHlr`、`Draw*Vlv2d` 的下游计算不受影响
4. ~~`PreprocessForHlr` 的 `mat4` 双次变换是否刻意(3.12)~~ —— 2026-10-25 确认是故意的:`mat3` 移动半个设备高度,两次正好一个设备高度,不改
5. `HLR_CALC` 是否从 `m_mapSpecXData` 的序列化里排除(3.6):只有在剖切过程中出意外(保存、崩溃、取消)才会写进 dwg,目前没碰到,先放一放
6. ~~`GetInterface` 数组版是否补 `dUnit`(3.7)~~ —— 2026-10-25 确认是 bug,已补;数组版内部 4 处调用不消费 `dSize`,外部只有 PCF 设备导出受影响,见 3.7
7. `AecDbEwFitting.cpp:16523` / `AecDbECFitting.cpp:8751` 的 `GetSectionDraw` 同样写反,是否一起改
---
@@ -634,6 +646,7 @@ Draw3dSolid(&dc, nColor); // :3062 拖拽时每帧都走到这里
| `MakeBlockRefSet` | 剖切/2D 导出生成的块,插入点位于设备中心而不是原点 |
| `byJson` | JSON 导入设备,几何与参数正确 |
| `subErase` 的 `Find` | 删除普通设备后,相邻管线不被合并 |
| `GetInterface` 单位 | 米制图纸(`INSUNITS` = 6)里插入设备,接口尺寸与下标版一致;PCF 导出的管径不再大 1000 倍 |
| 拖拽优化 | 拖夹点 10 秒,内存不涨、帧率稳定;松手后几何位置正确 |
| 2D bbox | 各阀门 2D 符号方向、手柄位置与改前一致 |
@@ -654,5 +667,5 @@ Draw3dSolid(&dc, nColor); // :3062 拖拽时每帧都走到这里
1. ~~第一批 1~5(内存),单独一个 PR,可独立验证~~ —— 已完成,范围扩到 2.1~2.11 全部内存项,见 2.13
2. ~~第二批(`m_Combins` 存盘清空)~~ —— 已完成(PR #48),见 3.1、5.2
3. ~~第一批 6~11(逻辑)~~ —— 已完成,范围扩到 3.2~3.14 共 10 项,见 5.1
4. 确认 5.4 剩下的问题(3.6 `HLR_CALC` 序列化、3.7 `GetInterface` 单位、3.12 `mat4` 双次变换)
4. ~~确认 5.4 剩下的问题~~ —— 3.7 已改(见 3.7),3.12 确认是故意的、不改,3.6 暂缓
5. 第三批按 4.7 度量结果排序,一项一个 PR
@@ -3297,8 +3297,10 @@ bool AecDbEwEquipment::GetInterface(AcArray<AecInterface>& arInfs) const
ptGe.transformBy(xform);
inf.ptPos = ptGe;
inf.vtDir = vtDir;
inf.dSize1 = pNoze->dVal1;
inf.dSize2 = pNoze->dVal2;
//ptPos 上面已经按 0.001 缩放过,尺寸也必须一起换算。
//原来只有下标版乘了 dUnit,同一个接口经两个入口读出来差 1000 倍
inf.dSize1 = pNoze->dVal1 * dUnit;
inf.dSize2 = pNoze->dVal2 * dUnit;
if (pNoze->nType == 0 || pNoze->nType == 2)
{