Files
envi-code/SourceCode/Code2026/cad_mcp_plugins/dwg_annotate_common.h
T
company-desktop c10f5b0083 feat: 补齐 cad_mcp_plugins 的批注/编辑/干涉工具(26 个工具齐了)
现象: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 正常返回结构。
2026-10-29 22:45:14 +08:00

84 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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