插件工程在 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。
79 lines
3.0 KiB
C++
79 lines
3.0 KiB
C++
#pragma once
|
||
// ============================================================================
|
||
// dwg_review_frame.h
|
||
// 图纸审查 - 图框识别模块
|
||
//
|
||
// 目标:从 DWG 中识别出"图框"(图纸边界),为后续「按图框逐张审查 / 分图」
|
||
// 提供基准。图框在 DWG 中通常以三种形态存在(参考主流分图软件做法):
|
||
// 1) 块参照 (Block Reference) —— 最常见,图框被封装为块
|
||
// 2) 闭合多段线 (Closed Polyline) —— 独立图层上的闭合矩形
|
||
// 3) 直线组 (Line Loop) —— 四条直线围成的矩形(老旧图纸)
|
||
//
|
||
// 识别特征:轴对齐矩形 + 长宽比接近 ISO A 系列(√2≈1.414,含加长图)
|
||
// + 可选的图层/块名关键词(图框/TK/FRAME/BORDER/TITLE/A0-A4)。
|
||
// ============================================================================
|
||
|
||
#include <string>
|
||
#include <vector>
|
||
#include <nlohmann/json.hpp>
|
||
|
||
namespace dwg_review
|
||
{
|
||
|
||
// 图框的几何来源形态
|
||
enum class FrameKind
|
||
{
|
||
Block, // 块参照
|
||
Polyline, // 闭合多段线
|
||
LineLoop // 直线组
|
||
};
|
||
|
||
// 一个被识别出的图框
|
||
struct DrawingFrame
|
||
{
|
||
std::string handle; // 代表图元句柄(块 INSERT / 多段线 / 首条线)
|
||
FrameKind kind = FrameKind::Polyline;
|
||
std::string layer; // 所在图层
|
||
std::string blockName; // 仅 Block 有值
|
||
|
||
// 外框范围(WCS 坐标)
|
||
double minX = 0.0, minY = 0.0, maxX = 0.0, maxY = 0.0;
|
||
|
||
// 外框尺寸(图纸单位)
|
||
double width = 0.0, height = 0.0;
|
||
double longSide = 0.0, shortSide = 0.0;
|
||
|
||
int orientation = 0; // 0 = 横向(宽>=高),1 = 纵向
|
||
std::string sheetSize; // 推测图幅 "A0".."A4" / "A?-加长";无法判定为空串
|
||
double sheetScale = 0.0; // 由比例反推命中的出图比例(如 100.0),未命中为 0
|
||
double confidence = 0.0; // 置信度 0~1
|
||
int lineCount = 0; // LineLoop 时的线段数
|
||
};
|
||
|
||
// 识别选项
|
||
struct FrameDetectOptions
|
||
{
|
||
std::string space = "Model"; // "Model" 或布局名
|
||
std::string layerFilter; // 图层通配符,空 = 不过滤
|
||
std::string blockNameFilter; // 块名通配符,空 = 自动启发式判定
|
||
bool useWindow = false; // 是否限定扫描范围
|
||
double winMinX = 0.0, winMinY = 0.0, winMaxX = 0.0, winMaxY = 0.0;
|
||
|
||
double minSide = 0.0; // 最小短边过滤(图纸单位),过滤小方块
|
||
double ratioTol = 0.06; // 长宽比容差
|
||
double axisTol = 1.0; // 轴对齐 / 矩形顶点判定容差(图纸单位)
|
||
bool detectLineLoops = false;// 是否做直线组配对(成本较高,默认关闭)
|
||
double minConfidence = 0.0; // 最低置信度过滤
|
||
};
|
||
|
||
// 主入口:识别当前文档指定空间中的图框
|
||
std::vector<DrawingFrame> detectFrames(const FrameDetectOptions& opt);
|
||
|
||
// 转为 JSON(供 MCP 工具直接返回给 LLM)
|
||
nlohmann::json framesToJson(const std::vector<DrawingFrame>& frames);
|
||
|
||
// 形态名("block" / "polyline" / "line_loop")
|
||
const char* frameKindName(FrameKind k);
|
||
|
||
} // namespace dwg_review
|