company-desktop
|
ecb8436720
|
feat: 移植 cad_mcp_plugins,并对齐中望平台的符号与依赖
插件工程在 CadProject/src/cad_mcp_plugins(8 个 cpp/h),本次一并整合进 code2026。
移植改动:
- 源码拷到 SourceCode/Code2026/cad_mcp_plugins/;cadsdk.h -> KTCad.h
- 输出是普通 DLL(.dll),由 cad_mcp_frame 运行时 LoadLibrary,不注册 ARX 命令
- 新增 cad_mcp_plugins/cmakelists.txt:按 code2026 惯例
(target_set_name_and_suffix ".dll" / target_link_objectarx / 预编译头 / SUB_ARX)
- mcp_plugin_api.h 从 cad_mcp_frame/inc 上移到 SourceCode/Code2026/inc:
frame 与 plugins 共用,且在 ShsGlobalIncludes 的 include 路径里两边都可见;
frame 的 CMake 去掉已删除的本地 inc 目录
- 顶层在同一个 C++11+ 条件里挂载 add_custom_module_2(cad_mcp_plugins CadMcpPlugins)
- 中望适配:源码里的 #pragma comment(lib,"rxapi.lib") 在中望下没有这个库(叫 ZwRx.lib),
该 pragma 与导出名都按 #ifdef ZWCAD 分开(中望导出 zcrxGetApiVersion);
frame 里 GetProcAddress 查插件版本号的函数名同样按平台分
验证:
- R230:cad_mcp_frame.arx 826 KB + cad_mcp_plugins.dll 866 KB,已自动部署
- Z2026:cad_mcp_frame.zrx 825 KB + cad_mcp_plugins.dll 864 KB,已自动部署
- 配置里 16 个 c++_dll 工具的工厂函数(CreateXxxTool)全部出现在 dll 导出表里
- 所有 .cpp/.h 为 UTF-8 with BOM
未做:没有在 CAD 里实跑。另外配置文件本身没有随构建部署(set_debug_post_build 只拷产物),
需要把 cad-mcp-frame.json(或改名 mcp_config.json)与 LISP 目录放到部署目录,
否则 frame 起来后 LoadAndRegister 失败会直接自关。详见 cad_mcp_frame-review.md。
|
2026-10-29 00:16:37 +08:00 |
|
company-desktop
|
facf14699b
|
fix: AecDbX3dPart 记住"已尝试建过",避免 Hide 构件被反复重建
现象:开图时 X3dPart 的 EnsureCreated 命中率只有 10.1%,1914 次重建里
721 次产出 NULL(38%),单个对象最多被重建 544 次。
根因:EnsureCreated 的命中条件是 !m_bNeedCreate && m_pSolid != NULL,
而 Rebuild() 里对 Hide 构件是"故意不建几何、直接 return true"——
m_pSolid 按设计就是 NULL,于是每次访问都重新走一遍 Rebuild,永远不可能命中。
子项全为空的构件同理。
修复:
- 新增 m_bCreated 标记"已经尝试建过"(无论是否产出实体)
- EnsureCreated 命中条件改为 !m_bNeedCreate && (m_bCreated || m_pSolid != NULL)
- Rebuild 入口置 m_bCreated = true;所有设 m_bNeedCreate = true 的 setter
同时置 m_bCreated = false,保证参数变化后仍会重建
- 重建后仍无实体时打一条日志(限前 5 条,带 m_sName),方便定位是哪些构件
实测(big1.dwg / R230 Debug):
X3dPart 命中率 10.1% -> 41.4%
重建次数 1914 -> 1248(-666)
rebuild_null 721 -> 55
单对象最多重建 544 -> <=3
开图墙钟 93 s -> 93 s(无变化)
注意:这 666 次空转没有带来可测的提速,因为 Rebuild 里 Hide 的早退分支在
布尔运算之前,每次只有几微秒。所以这是正确性/整洁度修复,不是性能修复;
但消除了"个别构件被重试几百次"这种病态行为,也暴露了"哪些构件建不出实体"。
顺带新增诊断(Debug + AEC_PERF_COUNTER=1 才生效,Release 无开销):
- SectionPerf::NoteEnsure():按 tag 统计"延迟建几何"的命中/重建,
并给出对象维度直方图与重建次数最高的对象
- AecDbX3dPart::Rebuild / AcDbX3dSolid::EnsureCreated / AecDbGuardBar::Draw3d 打点
- tools/run_acad_perf.ps1 增加 -CpuTrace:用 xperf 采 CPU 采样并 merge 成 etl,
可直接喂 tools/perf_diagsession.py(VS 的 VSDiagnostics 在这台机器上会卡住,
wpr -stop 有 COM 线程模式 bug,故用 xperf)
验证:R230 Debug 编译通过并部署,自动开图取数;截面缓存与回写仍为 0/正常。
|
2026-10-28 22:51:01 +08:00 |
|
company-desktop
|
b981fe930a
|
perf: 护栏/爬梯等构件的管道副本改为"只存参数",消除开图期 1140 次截面回写
现象:开图期间 AecDbEwPipeBase::RegionAcisoutDwgOutFields 被调用 1140 次、耗时 2.38 s,
把截面写成临时 SAT 文件。用 AEC_WRITEBACK_TRACE 抓栈 + tools/resolve_rva.ps1 解符号,
定位到 AecDbZLineStair::DrawGuarBar3d 里的 pipe.clone():
clone 走 AcDbObject → AecDbEwPipeBase::copyFrom → CopyObject(整实体 dwgOutFields/dwgInFields
往返),于是截面被写成临时文件再读回。
这些 clone 的唯一用途是存进 m_pipes,供 ToJson() 导出 __pipes__,而截面参数在
SetSection 时已经写进 spec XData(KEY_SECSHAPE / KEY_SIZE1 / KEY_SIZE2 / PIPE_THICK /
KEY_SECCEN),完全可以按参数重建。因此把"建几何"推迟到导出时:
- AecDbEwPipeBase::BuildSectionFromXData():按 XData 参数重建截面(圆形/矩形;
自定义截面返回 NULL,那种只能存在于 SAT 里)
- AecDbEwPipeBase::CloneParamsOnly():生成只带参数(XData、放样线、实体属性、GUID、
Breaks)、不含截面几何的副本,不触发任何序列化
- AecDbEwPipeBase::ToJson():GetSection() 为空时回退到 BuildSectionFromXData(),
保证 __section__ / __section2__ 仍然导出
- 30 处 m_pipes.push_back((AecDbEwPipe*)pipe.clone()) 改为 pipe.CloneParamsOnly():
ClimbStair(10)、ZLineStair(6)、BossHolder(4)、MRPLineStair(4)、Hanger(3)、Holder(3)
过程:先只改楼梯两个文件,回写从 1140 降到 960;再抓栈解析出剩余 960 全部来自
AecDbClimbStair::DrawLadderH3d,于是把其余 20 处一并改掉,最终归零。
实测(big1.dwg / AutoCAD 2020 / R230 Debug):
开图墙钟 初始 108~113 s -> 缓存后 98 s -> 本次 93 s
开图期回写 1140 次/2.38 s -> 1140 次 -> 0
RegionAcisIn 3082 次 -> 3082 次 -> 1942 次
临时文件 6773/9.34MB -> 2694/3.34MB -> 1733/2.34MB
截面恢复总耗时 22.4 s -> 9.87 s -> 9.4 s
另外把 SectionPerf::TraceCallStack 的输出改写到独立的 aec_writeback_trace.txt,
不再写进 ENVIPERFDUMP 的报告文件(否则脚本会把"栈写出来了"误判成"开图完成")。
验证:R230 Debug 编译通过并部署;用 tools/run_acad_perf.ps1 自动开图取数。
待验证:JSON 导出。m_pipes 里现在是不含几何的参数副本,ToJson 靠
BuildSectionFromXData() 重建,需要实际触发一次导出,确认 __pipes__ 里每条仍有
__section__ / __section2__ 且与改动前一致。
|
2026-10-28 21:57:31 +08:00 |
|
company-desktop
|
7038a98441
|
diag: 用 PDB 解析栈帧,定位到 AecDbEwPipeBase::copyFrom 里的多余序列化
上一版只给了"模块+RVA"的栈,我据此先后推断成
AecDbCurveBase::subGetTransformedCopy 和 AecDbEntityCommon::base_DeepClone,两者都是错的
(用户在那里下断点不命中;新加的 PerfTraceMark 打点也没有触发)。本次用符号解析定死。
本次改动:
- 新增 inc/PerfTraceMark.h:inline 的"某函数被调用过"打点,Debug 且 AEC_WRITEBACK_TRACE=1
才生效。AecRxBase.arx 不链接 CoreLibrary(静态库只被 CoreCommand 链接),拿不到 SectionPerf,
所以做成 header-only。
- 在 5 个候选入口打点:AecDbCurveBase::subGetTransformedCopy / subDeepClone、
AecDbEntityBase::subDeepClone、AecDbEntityCommon::base_DeepClone、CKTCadUtility::CloneObject。
跑一次开图,5 个都没触发 —— 这些候选被排除。
- 新增 tools/resolve_rva.ps1:用 dbghelp 的 SymLoadModuleEx / SymFromAddr 配本地 PDB,
把"模块+RVA"解析成函数名。Windows 没有自带 symbolizer,这个脚本很轻,可反复用。
解析结果(CoreCommand.arx):
0x58f051 AecDbEwPipeBase::copyFrom+0x41
0x7e1300 AecDbZLineStair::DrawGuarBar3d+0x2c0
0x7e09d0 AecDbZLineStair::DrawSteep3d+0xbe0
0x7ddcef AecDbZLineStair::Draw3d+0x34f
真实成因:Z 型楼梯画护栏(DrawGuarBar3d)时 copyFrom 一份管道实体,
而 AecDbEwPipeBase::copyFrom 用通用的 CopyObject(inc/AecDbEntityCommon.h:331)
做"整实体 dwgOutFields/dwgInFields 往返"来拷字段,于是截面被写成临时 SAT 文件再读回来。
而且这次序列化是多余的:copyFrom 随后把所有字段又用内存级方式拷了一遍
(曲线 clone/copyFrom、截面 clone/copyFrom、XData CopyFrom、m_arUserInfs append、
标志位/图层/线型/Breaks 逐项赋值),WriteUserInterface 写的也只是 m_arUserInfs。
所以最小修改是把那句 CopyObject 去掉,并补上源为 NULL 时清空目标的分支
(目前这个"清空"是 CopyObject 顺带完成的)。
本次只做定位与记录(分析写进 pipe-section-region-performance-plan.md 并纠正了上一版的误判),
不改 copyFrom 的行为——它影响所有管系实体的复制粘贴/块内拷贝,需要单独验证。
|
2026-10-28 21:28:00 +08:00 |
|
company-desktop
|
6d6f9ddaff
|
diag: 统计回写的实体类,定位到 AecDbEwPipeBase 基类实例
上一版只抓到"绘制期深拷贝"的调用栈,还没回答"是哪个类的实体在回写"。
现在 SectionPerf 增加按类统计的写回计数(NoteWriteBackClass),
在 RegionAcisoutDwgOutFields 里记一次 isA()->name()。
实测(big1.dwg,开图一次):
---- write-backs by entity class ----
1140 AecDbEwPipeBase
全部 1140 次都是 AecDbEwPipeBase 基类实例,不是 AecDbEwPipe 也不是具名子类,
与属性 key 统计里 AecDbEwPipeBase 的 1172 次几乎一一对应——
说明图纸里约有 1172 个基类实例(由 AecDbAssembleWell.cpp 的装配井代码创建,
多为矩形截面段),绘制期每个被深拷贝一次。
完整链路(已写入计划文档):
base_ViewportDraw -> AecDbCurveBase::subGetTransformedCopy
(AecRxBase/AecDbCurveBase.cpp:307 里的 clone())
-> AecDbEntityCommon::base_DeepClone(AecDbEntityCommon.cpp:1232,dwgOut 在 1265)
-> AecDbEwPipeBase::dwgOutFields(AecDbEwPipeBase.cpp:1440)
-> AecDbEwPipeBase::RegionAcisoutDwgOutFields(AecDbEwPipeBase.cpp:1275)
顺带发现:AecDbEwPipeBase::copyFrom(:1605)复制截面用的是 m_pRegion->copyFrom(),
是内存级 ACIS 拷贝,比"写文件再读回"便宜得多。所以最局部的修法可能是给管系实体
加 subGetTransformedCopy 重载,用 isA()->create()+copyFrom() 代替 clone(),
绕开整条序列化链路;但 clone 与 copyFrom 语义不完全等价,需先核对。
本次只记录分析,不改行为。
验证:R230 Debug 编译通过并部署,脚本自动开图一次得到上述分类统计。
|
2026-10-28 21:06:22 +08:00 |
|
company-desktop
|
67d6545e6c
|
diag: 增加调用栈抓取,定位开图期 1140 次截面回写的成因
现象:开图期间 EwPipe::RegionAcisout 被调用 1140 次、耗时 2.38 s,
把几何又序列化回 SAT。之前只知现象不知来源。
新增 SectionPerf::TraceCallStack():用 RtlCaptureStackBackTrace + GetModuleHandleExW
把栈帧解析成 "模块名 + RVA" 并写进报告文件。正式代码里不开启,
只在 AEC_WRITEBACK_TRACE=1 时于 RegionAcisoutDwgOutFields 首次调用处抓一次。
结论(栈已定位):
subViewportDraw -> base_ViewportDraw -> ... -> base_DeepClone
-> AcDbObject::dwgOut -> AecDbEwPipeBase::dwgOutFields -> RegionAcisout
即:不是保存,而是绘制期的深拷贝。AecDbEntityCommon::base_DeepClone
(AecRxBase/AecDbEntityCommon.cpp:1265)用
AcDbDeepCloneFiler filer; GetMe()->dwgOut(&filer); pClone->dwgIn(&filer);
实现拷贝,于是每次克隆实体,截面都要写一个临时 SAT 文件再读回来。
读的那一半现在已被 kText 缓存吃掉,剩下 acisOut 写文件这半(2.38 s)。
顺带修正一个文档缺陷:inc/SectionPerfCounter.h 里 %TEMP%\aec_section_perf.txt
的注释之前被转义吃掉变成了 %TEMP%<BEL>ec_section_perf.txt。
修法(跳过深拷贝期的区域序列化 / 直接写缓存里的 SAT 原文)都需要动
AecDbEntityCommon 的拷贝契约或先审计 m_pRegion 的写操作,风险面不一致,
只把分析与三种方案写进 pipe-section-region-performance-plan.md,本次不改行为。
验证:R230 Debug 编译通过并部署;AEC_WRITEBACK_TRACE=1 跑图一次,栈如文档所示。
|
2026-10-28 20:49:42 +08:00 |
|
company-desktop
|
f8d10d5a3b
|
perf: 增加截面 Region 缓存,开图恢复耗时降 56%
一次开图要做 5641 次截面恢复(22.4 s),其中大量内容重复,
而每次恢复都是"写临时 SAT 文件 + 从盘 acisIn + 删文件",单次 2.7~5.5 ms,
还要过一次杀软。本提交加一级母体缓存,命中直接 clone 返回。
新增 CoreLibrary/SectionRegionCache.{h,cpp},三个通道按 key 的正确性强度分开:
- kParam:纯参数 hash,用于 AecDbEwFitting::GetSection 的两个重载
(key = dD/dt/HLR 标志 或 W/H/dt/HLR 标志,同参数必同几何)
- kAttr:类名 + spec XData(排除编号,并跳过 Id/点/向量/矩阵/二进制类型),
只给 AecDbEwPipe 用。AecDbEwPipeBase 是很多类的基类,其余派生类实例间的
区别就是截面,不满足"同数据必同截面",所以一律走内容 hash
- kText:SAT 文本内容 hash,用于 RegionAcisInDwgInFields 的其它类
与 CoreTools::StringToRegion 的两个重载
约定:母体由缓存持有、永不外泄,Acquire/Put 都返回 clone,调用方拥有返回值;
母体不入库;每条通道 4096 条上限(AEC_SECTION_CACHE_MAX 可调),超出按 FIFO 淘汰;
AEC_SECTION_CACHE=0 可整体关闭做 A/B;卸载时 ClearAll() 释放,避免 DLL 析构顺序问题。
关键发现:SAT 文本第 2 行带存盘时间戳
16 Autodesk AutoCAD 19 ASM 219.0.0.5600 NT 24 Thu Oct 22 10:19:20 2026
同一几何存盘时间不同,整份文本就不同(采样里两份 2596 字节的文本只差
10:19:20 与 10:19:16),这正是内容 hash 命中率只有 54% 的原因,与截面无关。
因此新增 HashSatText():算 hash 时跳过第 2 行,仅当该行含 "Autodesk" 时才跳过。
计数器也改用同一口径,避免两套统计互相矛盾。
实测(big1.dwg / AutoCAD 2020 / R230 Debug,AEC_SECTION_CACHE 关 vs 开):
开图墙钟 108~113 s -> 98 s
截面恢复总耗时 22.4 s -> 9.87 s(-56%)
StringToRegion 14.05 s -> 7.73 s
RegionAcisIn 8.38 s -> 2.14 s
临时文件 6773 次/9.34MB -> 2875 次/3.61MB
命中率 text 65.5% / attr 84.1% / param 88.8%
clone 开销 命中 58us、未命中 73us(合计 0.37 s,可忽略)
顺带:
- tools/run_acad_perf.ps1 增加 -CacheOff 开关,用于同一构建上的 A/B 对比
- SectionPerfCounter 增加 AppendReport(),让缓存统计也写进同一份报告文件
- 诊断口子 AEC_SAT_SAMPLE=n 可导出未命中的 SAT 原文,用于定位这类差异
验证:R230 Debug 编译通过并部署;用脚本自动开图各跑一次(缓存关/开),
数据已写入 pipe-section-region-performance-plan.md。
尚未做:R190 编译(本机缺 v100 工具集)、Release 构建的收益复测、
开图期间 1140 次 RegionAcisout 回写(与本缓存无关,需单独立项)。
|
2026-10-28 20:41:05 +08:00 |
|
company-desktop
|
764e544db4
|
perf: 增加属性 key 命中率统计(Phase 0 补充)
意图:内容 hash 只看到 54% 命中率,但业务上"同数据的管子/管件截面必然相同",
所以要用实体属性做 key 再量一次,决定 Phase 1 到底用哪种缓存键。
新增 SectionPerf::AttrKey(RAII):
- 构造时按类名(isA()->name())初始化 hash 与统计桶,析构时记一次
- Add() 增量喂字节,调用方决定哪些字段参与 key
- 统计按实体类分开(total / unique / hits / hit_rate)
接入 AecDbEwPipeBase::RegionAcisInDwgInFields:key = 类名 + 全部 spec XData,
但排除编号("No.",每根管子唯一)并跳过 Id / 点 / 向量 / 矩阵 / 二进制类型
(与截面无关或随实体变化)。只在 AEC_PERF_COUNTER=1 时构建,Release 无开销。
实测(big1.dwg,AutoCAD 2020 / R230 Debug,113 s 开图):
属性 key 合计 3082 次 / 2672 命中 = 86.7%
AecDbEwPipe 1088 次 173 唯一 84.1%
AecDbEwPipeBase 1172 次 3 唯一 99.7%
(其余类 43%~99%)
内容 hash 54.0%
结论:属性 key 显著优于内容 hash,但只覆盖 3082/5641 次恢复
(另 2559 次走 CoreTools::StringToRegion,拿不到 spec 数据,只能用内容 hash)。
混合策略预计省 14.9 s / 22.6 s 恢复开销,约占 113 s 开图的 13%。
数据已写入 pipe-section-region-performance-plan.md,并标注一个未验证点:
属性 key 命中时两份 SAT 文本是否真的相同(决定 Phase 1 是否需要 textHash 兜底校验)。
验证:R230 Debug 编译通过并部署,用 tools/run_acad_perf.ps1 自动跑图取数。
|
2026-10-28 20:06:06 +08:00 |
|
company-desktop
|
3afc2dd7c1
|
perf: 增加截面恢复路径的 Phase 0 计数器(Debug 探针)
按 pipe-section-region-performance-plan.md 的 Phase 0 落地。目的不是提速,而是先拿到
三个决定性数字,再判断截面缓存(Phase 1)到底值不值得做:
1) 每次截面恢复多贵(µs),一次开图共多少次;
2) 同一份 SAT 文本被重复恢复多少次(唯一 hash 数 / 模拟命中率)——直接决定缓存收益上限;
3) 临时文件写入次数与字节数(杀软扫描影响面),以及打开图纸时的回写次数。
改动:
- 新增 inc/SectionPerfCounter.h + CoreLibrary/SectionPerfCounter.cpp
- Scope(QPC 计时)+ NoteRegionText(FNV-1a 64 位 hash,统计唯一数与模拟命中)
+ NoteTempFile + NoteWriteBack + Dump/Reset
- 计数器实例放在函数内 static:CoreLibrary 是静态库且只被 CoreCommand 链接,
所以 CoreCommand.arx 里只有一份,两个入口共用
- AecDbEwPipeBase.cpp:RegionAcisInDwgInFields / RegionAcisoutDwgOutFields 接入
- CoreTools.cpp:StringToRegion 两个重载 / RegionToString 接入
- EarthWorm.cpp:注册 ENVIPERFDUMP / ENVIPERFRESET(仅 Debug)
- CoreLibrary/cmakelists.txt 加一个源文件
- 计划文档的 Phase 0 补上实际命令与采集项
开关:启动 CAD 前 set AEC_PERF_COUNTER=1;命令 ENVIPERFDUMP 打印并追加到
%TEMP%\aec_section_perf.txt,ENVIPERFRESET 清零。
Release 下 Enabled() 恒为 false,调用点只剩一次 bool 判断。
不改任何几何逻辑与存盘格式。
验证:R230 Debug 编译通过(CoreLibrary_BAL_REMOTE、CoreCommand_BAL_REMOTE,无新增 warning),
产物已自动部署到 c:\ShangHuaSoft\Envi3D-2026-M\R230\。
R190 未在本机编译(缺 v100 工具集);代码刻意只用 C++98 特性,控制台输出改走 %hs,
避开了 &wstring[0] 这类老 STL 上的写法问题。
尚未做 CAD 实测:需要开图后跑 ENVIPERFDUMP 才看得到数据。
|
2026-10-28 19:31:27 +08:00 |
|
home-laptop
|
75819c0b72
|
修复 XEquipment 外壳/Impl 分离机制的 M1-M7 缺陷
- M1 createParamEquImpl 成功替换前释放旧 impl,消除 inplace 编辑泄漏
- M2 copyFrom2 先克隆成功再替换,避免旧 impl 泄漏或被置空
- M3 copyFrom 补基类深拷贝并兜底重建 impl,修复 clone/复制得到空壳
- M4 在 XEquipmentImplBase 注明 impl 不拥有 xdata 的所有权契约
- M5 draw3dByImp 改用临时数组,绘制失败时保留旧 3D 缓存并提示
- M6 抽出 makeTempClone(),集中 ToJson 的克隆/补数据/拷 part 流程
- M7 getUniqueName 的 %s 统一传 LPCTSTR、修正 sizeof,XL 的 %d 改 %f
|
2026-10-26 22:36:28 +08:00 |
|
company-desktop
|
41397130e2
|
refactor: 统一 XPrimData::m_pData 为字节数组,releaseData 只保留 delete[]
releaseData() 原来按 m_eType 分两路(8 种 delete[],其余 delete),但同一类型
在内存里可能是对象也可能是字节数组:开图、JSON 导入、深拷贝都分配 new byte[],
而对话框里 setData<T> 的 default 分支和几处直接 new 分配的是对象。按类型判断
必然有一半场景不匹配。
- 13 处对象形式分配统一改成 new unsigned char[sizeof(T)],后续 (T*)m_pData
的用法不变
- releaseData() 去掉 switch,只保留 delete[];~XPrimData() 改为先调 releaseData(),
顺带修掉 m_Combins 子单元的 m_pData 泄漏
- AecDbEwEquipment::FreeSubPrimData() 取代 FreeBuffer(CPtrArray&),改成成员函数,
不再需要参数
- 另外三个文件作用域的 FreeBuffer/FreeBuffer2/FreeBuffer3 改名为 FreeEntityArray/
FreeComplexCurveArray/FreeFaceplanArray,并加 static 收回内部链接
- 删除 ReleaseXPrimData,直接 releaseData() + DELETE_PTR
|
2026-10-23 10:29:31 +08:00 |
|
company-desktop
|
8ca9519320
|
refactor: X3dPart 的懒加载标志改名 m_bNeedCreate 并加 mutable
与 AcDbX3dSolid::m_bNeedCreate 对齐:同一个语义(派生几何缓存失效,
首次使用时再算),用同一个名字,避免 m_bDirty 被理解成"参数没写完"。
声明为 mutable,与 AcDbX3dSolid 一致;清标志仍在 Rebuild() 里做。
|
2026-10-22 15:41:14 +08:00 |
|
company-desktop
|
5a5cd08721
|
perf: X3dPart 布尔结果改为按需重建,开图不再逐件建体
方案 A(见 AcDbX3dSolid-refactor-plan.md 第 13 节)。开图慢的瓶颈是
AecDbX3dPartEntity::dwgInFields 无条件调 m_pPart->Create(),每个 part 都要
N 次建体 + N 次布尔。
A1:引入 m_bDirty
- AecDbX3dPart 增加 m_bDirty,构造/拷贝构造置 true
- 15 个改参数的接口置脏:AddX3dSolid、RemoveAt、RemoveAll3dSolidRec、
SetOrgPoint、SetAxis、SetBoolOperFor、SetHide、SetActive、PeelOffTheSkin、
AddMove×2、ResetMove、AddRotate、ResetRotate、CopyFrom
- 新增 Rebuild()(protected):清标志后无条件重建,原 Create() 的函数体
- 新增 EnsureCreated():m_bDirty 或 m_pSolid 为空时才 Rebuild
Create() 保持「显式调用一律重建」的语义,内部转调 Rebuild()。原因是外部
有 10 处先取 GetX3dSolid(0) 直接改(如 AecDbBDPipeBase:941 调 TransformBy)
再调 Create(),部件感知不到这类改动,做成幂等会漏掉重建。
A2:开图不建几何
- AecDbX3dPartEntity::dwgInFields 去掉 m_pPart->Create(),由
AecDbX3dPart::dwgInFields 结尾置脏
- 读入口统一先 EnsureCreated:CreateDraw3dSolid、Draw3d、getOsnapPoints、
GetForHouseSubtract
收益:关闭/冻结图层、视口外、XREF/审核/发布等不绘制的场景完全省掉建体与
布尔;全图可见时开图时间下降、首次 regen 补回。
|
2026-10-22 15:07:18 +08:00 |
|
company-desktop
|
4e658a8ae9
|
refactor: 水池截面中转文件改用 CoreTools::getTempFilePath
删除 Pool3dCmd/PoolSectionTemp.h,JMDBDlg、JMSJDlg、HZQTDlg 共 7 处
改为 CoreTools::getTempFilePath(_T("JMSJ_"), _T(".sat"), 目录)。
同时修 getTempFilePath 自身的问题:
- 传了有效父目录时 sParentPath 没有赋值,会拼出 "\JMSJ_xxx.sat"
- 父目录为空时仍对 pszParentPath 调 _taccess,参数可能是 NULL
- return sPath(); 语法错误
- objId 用 %lu 格式化 Adesk::ULongPtr,64 位下会截断,改 %I64u
temp-file-naming.md 同步改为介绍这个通用函数。
|
2026-10-22 10:06:51 +08:00 |
|
company-desktop
|
8941246b16
|
refactor: 管道截面统一存 SAT,曲线写路径退役
SectionRegionDwgOutFields 不再 explode 后按曲线写,改为固定写 nLen=0 +
RegionAcisoutDwgOutFields。读取端 nLen==0 本来就识别 SAT 通道,因此
kCurrentVersionNumber 保持 7,新图在老插件上仍可还原。
同时修 SAT 通道自身缺陷:
- RegionAcisoutDwgOutFields:临时文件名加进程号;new char[nLen] 补 +1 并
清零;检查短读,短读或空文件退回原生写法,不再把未初始化内存写进 DWG;
acisOut/Open 失败分支补 DeleteFile;两个重复的 errorfile 分支合并为
WriteRegionNativeFallback,顺带修掉 7 字节泄漏
- RegionAcisInDwgInFields:临时文件名只取纯文件名,拒绝 DWG 里夹带的路径
成分和盘符;errorfile 分支补 delete[];create/dwgInFields/acisIn 失败
分支加日志并正确释放;acisIn 返回的非 region 实体不再泄漏
- 删除 RegionExplodeDwgOutFields(写路径退役后无调用者)
|
2026-10-21 22:15:49 +08:00 |
|
company-desktop
|
f80ec56189
|
fix: AcDbX3dSolid 正确性小修(失败留痕/缓存失效/GSMarker/死代码)
- StringToRegion 两个重载在 fixACISFormat 拒绝时打印长度与 SAT 首行,
原来完全静默,现场只表现为构件消失,无法定位
- ReCreate 统一失效绘制缓存:清 m_pSolidDraw、m_arRegionFaces、
m_pSubDMeshDraw。原来只有 AddMove/ResetMove/AddRotate/ResetRotate 清,
TransformBy/SetSolidData/SetOrgPoint 调完 ReCreate 后 Draw3d 仍画旧几何
- GSMarker 改用独立成员 m_nGSMarker,不再借用 m_sszPoint2ds。
后者在 kExtrude/kLoft/kSweep 里存断面/路径串,SetGSMarkerID 会覆盖成数字,
导致 ReCreate 静默失败、几何丢失
- 删除 GetDrawSubDMesh 中 return 之后的 28 行不可达代码
- GetDraw2d / ByJson 补注释说明现状
|
2026-10-21 15:31:27 +08:00 |
|
company-desktop
|
81215c8fe1
|
perf: AcDbX3dSolid 几何改为懒重建
- 新增 m_bNeedCreate 标志与 EnsureCreated():dwgInFields 与拷贝构造
不再立即 ReCreate,延迟到首次访问几何时重建
- 开图时不再对每个单元逐个走 SAT 临时文件(acisOut/acisIn),
显著降低开图耗时;Clone 也省掉一次重建
- 所有读取 m_pSolid/m_pSubDMesh 的入口统一走 EnsureCreated:
GetNative3dSolid / GetDraw3dSolid / GetNativeSubDMesh /
GetDrawSubDMesh / GetDrawSubDMesh2D / GetCentoridPoint
- GetDrawSubDMesh 补 m_pSubDMesh 空指针保护
- TransformBy 保持原有行为(参数变更后必须重建)
|
2026-10-21 10:01:17 +08:00 |
|
gjm
|
c84bc78869
|
重构底层
重构AecDbEntityBase,AecDbCurveBase
|
2026-10-19 09:19:05 +08:00 |
|
company-desktop
|
199abb989c
|
重构: AecDbObjXDataMap 解耦 UI,并统一 SetAt/数组实现
- AecXData 的 ctor/Free/CopyFrom 由头部 inline 移入 .cpp,结构体加
AECDLLIMPEXP 导出,修复其它模块构造 AecXData 时的 LNK2019。
- 抽出私有 SetXData(pszKey, xdata) 助手,替换各 SetAt 中重复的
find/Free+覆盖/insert 逻辑,并接管 xdata 所有权。
- 数组二进制块统一为 [kArrayMagic][元素类型][元素个数][数据...],元素类型
复用 AecXData::EType;新增元素类型无需再加魔数或类型标签。
- 矩阵/数组魔数集中到 .cpp 顶部常量,便于维护。
- List(CListCtrl*, int) 改为 List(std::vector<CString>&):去掉 MFC 控件与
nImage 依赖,每个元素输出 key/value 两项;CCKSXDlg::ListXDataMap 相应改为
构造 vector 后填充两列列表。
|
2026-10-13 15:28:19 +08:00 |
|
company-desktop
|
0467086e65
|
重构: AecXData 类型标签改用枚举 AecXData::EType
- 在 AecXData 内新增 enum EType,取值直接采用 wtypes.h 的 VARENUM(VT_*),
与原实现逐位一致(nVt 会序列化进 DWG/DXF/XData,数值必须保持不变)。
- 各模块共 303 处 nVt 判断由裸 VT_* 改为 AecXData::kTypeXxx,涉及 18 个文件;
仅调试打印用的字符串字面量保持原样。
- AecDbObjXDataMap.h 增加 #include <wtypes.h>(EType 引用 VT_*)。
|
2026-10-13 09:55:42 +08:00 |
|
gjm
|
164968b62e
|
chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
|
2026-10-04 00:04:20 +08:00 |
|
gjm
|
345044cb46
|
初始化提交
|
2026-09-28 15:28:50 +08:00 |
|