From d1f4d0b50b577ab89140c69bbbc8264bd103e28e Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Sun, 25 Oct 2026 11:58:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20GetInterface=20=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E7=89=88=E8=A1=A5=20dUnit=EF=BC=8C=E4=B8=8E=E4=B8=8B=E6=A0=87?= =?UTF-8?q?=E7=89=88=E7=BB=9F=E4=B8=80=E5=8D=95=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AecDbEwEquipment::GetInterface(AcArray&) 里 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 三项按结论更新。 --- AecDbEwEquipment-analysis.md | 31 +++++++++++++------ .../Code2026/CoreLibrary/AecDbEwEquipment.cpp | 6 ++-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/AecDbEwEquipment-analysis.md b/AecDbEwEquipment-analysis.md index 806e372..c87fb60 100644 --- a/AecDbEwEquipment-analysis.md +++ b/AecDbEwEquipment-analysis.md @@ -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&)` | `:3224` | **否**(直接 `pNoze->dVal1`) | +| `GetInterface(int, AecInterface&)` | `:3323` | 是(`inf.dSize1 = pNoze->dVal1 * dUnit`) | +| `GetInterface(AcArray&)` | `: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 diff --git a/SourceCode/Code2026/CoreLibrary/AecDbEwEquipment.cpp b/SourceCode/Code2026/CoreLibrary/AecDbEwEquipment.cpp index c22becb..e3a4811 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbEwEquipment.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbEwEquipment.cpp @@ -3297,8 +3297,10 @@ bool AecDbEwEquipment::GetInterface(AcArray& 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) {