现象:mcp_config.json 里配了 40 个工具,但仓库的 cad_mcp_plugins 只有 16 个工厂,
add_line / add_text / add_mtext / add_polyline / add_leader_annotation /
draw_revision_cloud / delete_entities / set_entity_properties / find_collisions /
set_drawing_area 这 10 个在 tools/list 里被静默丢掉(实测只有 30 = 18 + 12)。
来源:d:\new-start\CadProject\src\cad_mcp_plugins(pull 之后新增的
dwg_annotate_*、dwg_review_ui、find_collisions、bvh.h),整体搬到本仓库。
改动:
- 新增 bvh.h、dwg_annotate_common.cpp/h、dwg_annotate_draw.cpp、
dwg_annotate_edit.cpp、dwg_review_ui.cpp、find_collisions.cpp;
- cad_mcp_plugins/cmakelists.txt 的 SOURCES 补上这 6 个 cpp;
- 移植差异两处(都在本仓库编译/运行才暴露):
1. `#include "cadsdk.h"` -> `#include "KTCad.h"`(本仓库没有 cadsdk.h);
2. 上游 cadsdk.h 带 NOMINMAX,本仓库 KTCad.h 没有,`std::min/std::max`
被 windows.h 的宏顶掉(C2589/C2059)→ 在 dwg_annotate_common.cpp、
dwg_annotate_draw.cpp、find_collisions.cpp 里 `#undef min / #undef max`。
- 上游的写库工具没有文档锁:MCP 工具跑在主线程消息里、不在命令上下文,
kForWrite 打开块表记录直接拿到 eLockViolation(0x140),报
"cannot open target space for write"。补了 `dwg_annotate::DocLock`
(acDocManager->lockDocument/unlockDocument 的 RAII),并在
dwg_annotate_draw / dwg_annotate_edit 的 8 个 Execute 开头构造。
这一条是上游在新环境下的真 bug,不修这批工具在本仓库根本用不了。
- 所有新增文件转 UTF-8 with BOM(仓库红线)。
验证:
- R230 Debug / Z2026 Debug 编译通过并部署;dumpbin 显示
cad_mcp_plugins.dll 导出 26 个 Create*Tool + 26 个 Destroy_*。
- AutoCAD 2020 实测(部署目录放仓库的 mcp_config.json,frame 优先读它):
tools/list = **40**,配置里没有一个工具缺失;
add_line / add_text / add_polyline / add_mtext / add_leader_annotation /
draw_revision_cloud 全部返回 created[handle](图层 AI_REVIEW);
set_entity_properties 改图层+颜色、delete_entities 删两个句柄都成功;
find_collisions / find_zero_length 正常返回结构。
84 lines
3.3 KiB
C++
84 lines
3.3 KiB
C++
#pragma once
|
||
// ============================================================================
|
||
// dwg_annotate_common.h
|
||
// 图纸批注工具集 - 公共辅助层
|
||
//
|
||
// 供 dwg_annotate_draw / dwg_annotate_edit 共用,避免重复实现:
|
||
// - 批注图层自动创建(默认 AI_REVIEW)
|
||
// - 以 kForWrite 打开目标空间
|
||
// - UTF-8 <-> 宽字符、点/窗口参数解析
|
||
// - 图层/颜色设置、实体 append 与关闭
|
||
// - 统一创建结果构造
|
||
//
|
||
// 依赖 dwg_review_common(复用其 handleOf / makeJsonResult / makeError /
|
||
// objectIdFromHandle / kErr* 等)。
|
||
// ============================================================================
|
||
|
||
#include "KTCad.h"
|
||
#include "dwg_review_common.h"
|
||
#include <string>
|
||
#include <vector>
|
||
#include <nlohmann/json.hpp>
|
||
|
||
namespace dwg_annotate
|
||
{
|
||
|
||
// 默认批注图层名
|
||
extern const char* kDefaultAnnotLayer;
|
||
|
||
// 写数据库前必须拿文档锁:MCP 工具是在主线程的消息里跑的,**不在命令上下文**,
|
||
// 不锁的话 kForWrite 打开块表记录 / appendAcDbEntity 会返回 Acad::eLockViolation(0x140),
|
||
// 表现为 "cannot open target space for write"。
|
||
// (与 cad_mcp_aec 的 DocLock 同一套办法;各 Execute 开头构造一个,析构自动解锁。)
|
||
class DocLock
|
||
{
|
||
public:
|
||
DocLock();
|
||
~DocLock();
|
||
bool ok() const { return m_bLocked; }
|
||
|
||
private:
|
||
DocLock(const DocLock&);
|
||
DocLock& operator=(const DocLock&);
|
||
|
||
bool m_bLocked;
|
||
AcApDocument* m_pDoc;
|
||
};
|
||
|
||
// 确保图层存在(不存在则以给定 ACI 颜色创建)
|
||
bool ensureLayer(AcDbDatabase* pDb, const std::string& name, int aciColor);
|
||
|
||
// 以 kForWrite 打开指定空间的块表记录(成功返回的对象需调用者 close)
|
||
AcDbBlockTableRecord* openWriteSpace(AcDbDatabase* pDb, const std::string& space);
|
||
|
||
// UTF-8 -> 宽字符
|
||
std::wstring utf8ToWStr(const std::string& s);
|
||
|
||
// ---------- 参数解析 ----------
|
||
// 点:[x,y] / [x,y,z] / {"x":..,"y":..,"z":..}
|
||
bool parsePoint(const nlohmann::json& j, AcGePoint3d& out);
|
||
bool parsePoints(const nlohmann::json& arr, std::vector<AcGePoint3d>& out);
|
||
// 窗口:window 对象 或 min_x/min_y/max_x/max_y 或 p1/p2 两角点
|
||
bool parseWindow(const nlohmann::json& args, double& x1, double& y1, double& x2, double& y2);
|
||
// 句柄列表:handle / handles
|
||
std::vector<std::string> collectHandlesArg(const nlohmann::json& args);
|
||
|
||
// ---------- 公共参数默认值 ----------
|
||
std::string getLayerArg(const nlohmann::json& args); // 默认 AI_REVIEW
|
||
int getColorArg(const nlohmann::json& args, int def = 256); // 默认 ByLayer
|
||
std::string getSpaceArg(const nlohmann::json& args); // 默认 Model
|
||
|
||
// ---------- 实体写入 ----------
|
||
void applyLayerColor(AcDbEntity* pEnt, const std::string& layer, int aciColor);
|
||
// append 到空间并 close 实体,返回 ObjectId(kNull = 失败)
|
||
AcDbObjectId appendToSpace(AcDbBlockTableRecord* pSpace, AcDbEntity* pEnt);
|
||
std::string handleOfId(AcDbDatabase* pDb, const AcDbObjectId& id);
|
||
|
||
// ---------- 结果构造 ----------
|
||
nlohmann::json makeCreatedItem(AcDbDatabase* pDb, const AcDbObjectId& id,
|
||
const std::string& type, const std::string& layer);
|
||
// 包装为 MCP 文本信封:{"ok":true,"count":N,"created":[...]}
|
||
nlohmann::json createdResult(const std::vector<nlohmann::json>& created);
|
||
|
||
} // namespace dwg_annotate
|