Files
cad-agent/ai.memory/reference_environment.md
T
gjm 1e5bff268a feat(review): 截屏前最大化绘图区 + 空瓦片过滤覆盖回退路径
新增 MCP 工具 set_drawing_area(mode="max"|"restore"):最大化主窗口 + CLEANSCREENON
(隐藏功能区/命令行/面板)。实测绘图区 2110x462 -> 3310x1084(面积 3.68x),
restore 精确回位(窗口矩形/最大化态/绘图区尺寸全部还原)。

坑:CLEANSCREENOFF 是异步命令,AutoCAD 会按「进入干净屏幕时的布局」重设窗口几何,
把同步的 SetWindowPlacement 覆盖掉(表现为窗口停在最大化)。解法是插件内
SetTimer 延迟 700ms 再压回;实测窗口在 0.5~1.0s 之间收敛,故调用方等待取 1.5s。

取证层:
- 新增 maximized_drawing_area(ctx) 上下文管理器,__main__ 用它包住整个取证循环
  (多图框只进出一次);受 DRAWING_AREA_MAXIMIZE 控制,工具缺失/调用失败静默降级,
  restore 失败不掩盖业务异常。
- 内容过滤统一到规划与回退两条路径,共用同一谓词;过滤后为空则退回原集合。
- 判定改用「实体 bbox」而非「占用格」:格子量化会把跨界内容算进相邻格,反而更粗
  (实测实体 bbox 正好压象限边界时 4 个象限全判有内容)。heatmap.occupied_boxes 随之删除。

实测(真实图纸 A0/A1/A2 三图框):截图张数 12/8/4 -> 8/5/4;pytest 296 passed。
新增 verify_drawing_area.py 作为该工具的验收脚本。
2026-10-15 23:44:32 +08:00

102 lines
6.1 KiB
Markdown
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.
---
name: 环境与外部资源
description: CadProject 的构建/运行要点、CAD SDK 路径、测试分层(pytest 快层 + verify_* 慢层)等外部资源指引
type: reference
---
# 环境与外部资源
## 构建
- 系统:**CMake + vcpkg + Visual Studio 生成器**,通过 CMake Presets 区分 CAD 版本。
- 产物:`bin/<Config>-<TAG>/` 与 `lib/<Config>-<TAG>/`。
- 命令:`cmake --preset R230` → `cmake --build --preset R230 --config Debug`。
- 可用 preset:`R180`–`R260`(AutoCAD,ARX 18–26)、`Z2023`–`Z2026`(ZWCAD,ZRX)。
- 前置:需要 `VCPKG_ROOT`;必需 cache 变量 `CAD_SDK_ROOT`、`DEP_LIB_ROOT`、`DEP_INC_ROOT`、
`CAD_SDK_VERSION`(AutoCAD 还需 `CAD_SDK_SUBVERSION`)。
## CAD SDK 路径
- AutoCAD:仓库同级 `../envi-code/Arx`
- ZWCAD:仓库同级 `../envi-code/Zrx`
- 在 `cmakepresets.json` 的 `CAD_SDK_ROOT` 中配置。
## 运行 / 联调
- 先启动 **已加载插件的 CAD**,确认 `127.0.0.1:8080` 在监听。
- 脚本通过 TCP 连接 `127.0.0.1:8080` 收发 JSON-RPC。
## 测试(两层,互不替代)
**快层 —— pytest 离线单元测试**(`tests/`,假 LLM + 假基座,无需 CAD、不联网、秒级):
- `pip install -r requirements-dev.txt` → `python -m pytest`。
- 配置:`pytest.ini`(`testpaths = tests`)、根 `conftest.py`(加 `sys.path` + `RENDER_WAIT=0` / `REPORT_DIR=tmp` fixture)。
- 陷阱:`dwg_review.config` 常量导入期定值,改 `os.environ` 无效,须 `monkeypatch.setattr(config, ...)`。
**慢层 —— 端到端冒烟脚本**(根目录 `verify_*.py`,需 CAD 在线且 `127.0.0.1:8080` 监听):
| 脚本 | 作用 |
| --- | --- |
| `verify_mcp_frame.py` | 基座最小集:分帧 / id / isError 映射 |
| `verify_mcp_tcp_hardening.py` | TCP 收发路径加固(超长帧 / 粘包 / 半关闭) |
| `verify_mcp_fault_injection.py` | 工具异常保护(类型错误不再崩 CAD) |
| `verify_stdio_bridge.py` | stdio ↔ TCP 桥(协议协商 / 转发 / 通知) |
| `verify_annotate.py` | 批注工具运行时验证(绘制/校验/改属性/清理);`--keep` 保留批注 |
| `verify_heatmap.py` | 实体分布热力图(占用网格 + 聚类 + PNG),**不耗 token**,缓存 bbox JSON 供离线调参 |
| `verify_vlm_resolution_offline.py` | **离线**(纯 PIL 合成)标定 VLM 读图下限 `R_text`/`R_line`,`--dry-run` 只出图 |
| `verify_text_resolution.py` | **CAD 实测**标定(临时加字 + 平行线,测完 `delete_entities` 清理);`--keep` 保留 |
| `verify_drawing_area.py` | 绘图区最大化验收:基线 → `set_drawing_area(max)` → `restore`,断言窗口矩形/最大化态/绘图区尺寸全回位(实测 3.68×) |
> 历史:根目录 `test.py` / `test_autoagent.py` / `countOfCircle.py` / `agent_loop.py` /
> `dwg_review_agent.py` 五个遗留调试脚本已于 2026-10-14 删除(前三个含硬编码 API Key,
> 后两个是重复实现)。`test_screenshot.png` 是 `test_autoagent.py` 的残留产物。
## 两个构建目标
| 目标 | 产物 | 作用 |
| --- | --- | --- |
| `src/cad_mcp_frame` | `cad_mcp_frame.arx`(ZWCAD 下 `.zrx`) | MCP **基座**:起 TCP、解析配置、路由执行 |
| `src/cad_mcp_plugins` | `cad_mcp_plugins.dll` | 示例 **C++ 工具插件**,ABI 动态加载 |
## 三种工具后端(`backend.type`)
- `lisp_inline`:`{占位符}` 替换后 `sendStringToExecute`(**异步**)。
- `lisp_file`:`(load "文件" nil)` 后执行 `call_template`。
- `c++_dll`:`LoadLibrary`(**同一 DLL 只加载一次**)+ 工厂/销毁函数(**同步**,可返回图像)。
版本校验与「写库需文档锁」两个坑见 [MCP 基座 c++_dll 加载与执行的坑](project_mcp_frame_dll_loader.md)。
## 工具语义坑:`query_entities` 的两个 filter(2026-10-15 实测)
- **`type_filter` 必须是「数组」**(精确类型名列表,如 `["TEXT"]`)。
传**字符串**会被**静默忽略**——`typeMatches` 对「非数组」一律 `return true`(全通过),
于是你以为筛了文字,实际把 LINE 等全带回来了(踩过:标定脚本因此把窗口中心算到无文字处)。
- **`layer_filter` 是「字符串 + 通配」**(`wildcardMatch`),**不是**列表。
传列表会被忽略 → 通配为空 → **匹配所有图层**(清理类操作慎用)。
- 另有 `space`(模型/图纸空间)、`limit`(**硬钳 1..1000**)、`offset`(分页)。
- 相关工具返回体:`add_text` / `add_line` 等返回 `{"ok":true,"count":1,"created":[{handle,layer,type}]}`
—— 句柄在 **`created`** 键下(不是 `items`)。
## 远程仓库
- 现状(2026-10-08 起):`CadProject` 已从「某仓库的子目录」**独立为单独仓库**。
- `origin` = `ssh://git@39.107.55.179:222/gjm/cad-agent.git`
- 当前分支 `home-ai-dev`;服务器只保留 `main`,采用 **PR 流程**
(`home-ai-dev` → `main`,合并后源分支被删除,故本地 `home-ai-dev` 的 upstream 显示 `[gone]`)。
- 历史已被重写/重新初始化(哈希全新)。
- 历史参考(旧):`new-start.git` = `ssh://gjm@47.93.46.28:1216/srv/git/new-start.git`
- **SSH 密钥(2026-10-08 变更)**:服务器已改用新密钥
`~/.ssh/id_ed25519_guojianming`(注释 `guojianming.go@gmail.com`);
旧密钥 `~/.ssh/id_ed25519`(`deploy@aly-db`)已被服务器移除,会 `Permission denied (publickey)`。
本仓库已设置 `git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_guojianming -o IdentitiesOnly=yes"`。
换机器时需补该配置或加入 `~/.ssh/config`。
## 真实测试图纸(2026-10-15)
- 图纸:`e:\desktop\agent_test.dwg`(用户制作的真实 Plant 3D 图纸:3 个图框 A0/A1/A2,
86 个实体:`AECDBEWFITTING` 40 / `AECDBEWPIPE` 29 / `AECDBEWEQUIPMENT` 14 / `INSERT` 3)。
- **启动方式**:`acad.exe /p SHS-ENVI2026 e:\desktop\agent_test.dwg`
—— 必须带 `/p SHS-ENVI2026` profile,否则**自定义实体无法显示**(该 profile 自动加载
用户写的显示插件)。
- 实测:`python -m dwg_review --frames 1` 端到端可跑通并出报告。