Files
envi-code/SourceCode/Code2026/cad_mcp_aec/cmakelists.txt
T
company-desktop 132615af42 feat: 新增 cad_mcp_aec 插件,让 agent 直接建/改 Envi3D 自定义实体
现象:cad_mcp_frame 的插件机制只能挂"纯 AcDb 层"的只读工具
(cad_mcp_plugins 不链接 CoreCommand,拿不到 AecDbEwPipe / AecDbXWall /
AecDbXSlab / AecDbColumn / AecDbBeam 这些类的实现),agent 没法改仓库的自定义实体。

改动:新建 SourceCode/Code2026/cad_mcp_aec,仍是普通 DLL(由 frame 运行时
LoadLibrary),但链接 CoreCommand_BAL_REMOTE(内含静态库 CoreLibrary),
因此可以 new / 修改这五类实体。cmake 照 PipelineCmd 的写法,并在顶层
cmakelists.txt 里挂在 cad_mcp_frame 同一处(C++11+ 才编,R180/R190 跳过)。

12 个工具(每个实体一个 create + 一个 update,外加 list/get):
  list_aec_entities / get_aec_entity
  create_aec_pipe   / update_aec_pipe
  create_aec_wall   / update_aec_wall
  create_aec_slab   / update_aec_slab
  create_aec_column / update_aec_column
  create_aec_beam   / update_aec_beam

单位约定:坐标与建筑尺寸用图纸单位;管道的 dn_mm / od_mm /
wall_thickness_mm 用毫米,内部按 AS_MUNIT 转米(与 BZGDDlg、AecPipeLineTool 一致)。
update_* 只改传入字段;管道只给一个端点时另一端沿用实体现有值。

实现上撞到三个坑,都已修:
1. MCP 工具在主线程消息里跑、不在命令上下文,写库必须先
   acDocManager->lockDocument(),否则 appendAcDbEntity 返回
   eLockViolation(0x140)。用 DocLock RAII 包起来。
2. 只读实体上取专业数据必须 GetSpecialtyData(AcDb::kForRead):
   该函数缺省参数是 kForWrite,第一次实现没注意,直接把 acad 崩了
   (%TEMP%\acminidump.dmp)。
3. SetSection() 会清掉 PIPE_THICK 等派生字段("只改 DN"会把壁厚清成 0);
   AecDbXSlab::SetRegionSlab(AcGePoint2dArray&) 内部连线不补闭合点,
   传点串必须自己首尾闭合。两处都按实测结果处理了。

验证方式:
- R230 Debug、Z2026 Debug 两个 preset 编译通过并自动部署
  (cad_mcp_aec.dll,12 个工厂函数 + g_mcpPluginApiVersion 都在导出表里)。
- AutoCAD 2020 实测(临时把工具合进部署目录的 cad-mcp-frame.json,测完还原):
  tools/list 返回 30 个工具;pcf_1.dwg 上 list 出 20 根管道;
  五种实体各建一次并用 get 读回参数一致;管道改 DN+单端点后壁厚保留;
  板改厚/标高生效;类型不匹配与非法 handle 返回 -32004 / -32002。
  详见 cad-mcp-aec.md 第 5 节的用例表。

已知限制:只支持这五类实体;新建实体要等一次 REGEN 才有 bbox;
工具没有事务包装;运行期工具描述需要把 cad-mcp-aec.json 的 tools 追加到
部署目录的 cad-mcp-frame.json(插件侧的 private_description 已内置同样的文案)。
2026-10-29 21:52:05 +08:00

42 lines
1.2 KiB
CMake

cmake_minimum_required(VERSION 3.16)
project(CadMcpAec)
set(SOURCES
"mcp_aec.cpp"
"aec_mcp_common.cpp"
"aec_mcp_entity_tools.cpp"
"aec_mcp_query.cpp"
"StdAfx.cpp"
)
add_library(CadMcpAec SHARED ${SOURCES})
target_precompile_headers(CadMcpAec PRIVATE StdAfx.h)
target_set_name_and_suffix(CadMcpAec "cad_mcp_aec" ".dll")
target_link_objectarx(CadMcpAec CADMCPAEC_EXPORT)
# Unlike cad_mcp_plugins (read-only AcDb review, no CoreCommand link), this plugin
# must new/modify the repo's custom entities (AecDbEwPipe, AecDbXWall, ...).
# Their implementation lives in CoreCommand.arx (which contains the static
# CoreLibrary), so link it - same as PipelineCmd does.
#
# Do NOT define EARTHWORM_EXPORT / AECRXBASE_EXPORT here: those macros are for
# CoreLibrary/AecRxBase themselves when they export these classes; we import
# them, so keep the default dllimport from the headers.
target_link_libraries(CadMcpAec PRIVATE
AecRxBase
CoreCommand_BAL_REMOTE
)
if (IS_ZWCAD)
target_compile_definitions(CadMcpAec PRIVATE SUB_ARX=0)
else()
target_compile_definitions(CadMcpAec PRIVATE SUB_ARX=${CAD_SDK_SUBVERSION})
endif()
set_debug_post_build(CadMcpAec "cad_mcp_aec" ".dll")