官方插件指南
文档:
vjcad/doc/plugin/plugin-annotation.md、vjcad/doc/plugin/plugin-architecture.md示例:vjcad/example/plugin/05architecture.js
vjcad 自带几个官方插件,理解它们就掌握了"标准插件长什么样"。
| 插件 | 包名 | 功能 | 主要扩展点 |
|---|---|---|---|
| 批注 | vcad-plugin-annotation |
云线 / 箭头 / 矩形 / 文字 / 引线 / 自由线 / 图章 / 高亮 / 显隐 / 清除 / 列表 | Ribbon 「审阅」标签、命令 ANNOTATION、ANNO_* 系列 |
| 建筑 | vcad-plugin-architecture |
轴网 / 柱 / 墙 / 门窗 / 楼梯 / 阳台 / 房间 / 标高 / 剖切 / 指北针 | Ribbon 「建筑」标签、命令 BIN*、window.vjcadArchEntities 暴露实体类 |
| 三维视图 | vcad-plugin-view3d |
三维查看 | 命令 VIEW3D,标准 PluginManager 用法的最小骨架 |
| 插入 / 图片矢量化 | vcad-plugin-insert |
插入图片(内部 VectroizeService 矢量化)、插入/提取表格 |
插件自己注册命令 INSERTIMAGE / INSERTTABLE / EXTRACTTABLE(核心库无这些命令),挂到 Ribbon insert 标签 |
| AI 助手 | vcad-plugin-aiassist |
AI 对话面板 | 命令 AIASSISTANT2 |
| 网络图 | vcad-plugin-network-graph |
网络拓扑图 | 命令 DRAWNETWORKGRAPH / GENERATENETWORK / MERGENODES / BREAKBRANCH / REVERSEBRANCH |
1. 批注插件(annotation-plugin)
命令一览
| 工具 | 命令 |
|---|---|
| 主面板 | ANNOTATION |
| 云线 | ANNO_CLOUD |
| 箭头(单/双/折) | ANNO_ARROW |
| 矩形 / 椭圆 | ANNO_RECT / ANNO_ELLIPSE |
| 文字 / 引线 | ANNO_TEXT / ANNO_LEADER |
| 自由线 | ANNO_FREEHAND |
| 图章 | ANNO_STAMP(1=批准 2=驳回 3=审核 4=修改 5=作废 6=草稿) |
| 高亮 | ANNO_HIGHLIGHT |
| 显示 / 隐藏 / 清除 / 列表 | ANNO_SHOW / ANNO_HIDE / ANNO_CLEAR / ANNO_LIST |
设计要点
- 专属图层
_ANNOTATION:所有批注实体落入此图层,颜色 ACI 1(红) - 自适应线宽:批注用多段线
globalWidth(不是lineWeight),按 WCS 对角线/500计算 - 自适应弧长:云线弧长 = WCS 对角线
/30 - 命令委托:
ANNO_TEXT/ANNO_LEADER通过setTimeout异步调度委托给MTEXT/MLEADER,避免命令嵌套
加载
const pm = PluginManager.getInstance();
await pm.loadFromUrl('./plugins/vcad-plugin-annotation.js');
// 或
await pm.loadByName('vcad-plugin-annotation');
激活后:
await Engine.editor.executerWithOp('ANNOTATION'); // 打开浮动工具栏
2. 建筑插件(architecture-plugin)
命令分类
| 分类 | 命令 |
|---|---|
| 轴网 | BINDRAWAXISGRID / BINLABELAXIS |
| 柱子 | BINDRAWCOLUMN / BINCOLUMNTOAXIS |
| 墙体 | BINDRAWWALL / BINWALLFROMAXIS / BINEDITWALL |
| 门窗 | BININSERTDOOR / BININSERTWINDOW |
| 楼梯 / 阳台 | BINDRAWSTAIR / BINDRAWBALCONY |
| 房间 | BINSEARCHROOM / BINLABELROOM |
| 符号 | BINELEVMARK / BINSECTIONMARK / BINNORTHARROW / BININDEXMARK |
| 标注 | BINARCHDIM / BINAXISDIM |
| 工具 | BINARCHTOOLBAR / BINDEMOFLOORPLAN |
加载与 SDK API
const pm = PluginManager.getInstance();
await pm.loadByName('vcad-plugin-architecture');
const {
AxisGridEnt, ColumnEnt, WallEnt,
DoorEnt, WindowEnt, StairEnt, BalconyEnt,
ElevationMarkEnt, SectionMarkEnt
} = window.vjcadArchEntities;
// 例:建轴网
const grid = AxisGridEnt.create(
new Point2D(0, 0),
[3600, 3900, 5700], // 横向间距
[4200, 2100, 4200] // 纵向间距
);
Engine.addEntities([grid]);
// 例:墙体(厚 240,中线对齐)
const wall = WallEnt.create(new Point2D(0, 0), new Point2D(13200, 0), 240);
Engine.addEntities([wall]);
// 例:门 + 关联墙
const door = DoorEnt.create(new Point2D(5000, 0), 'single', 900);
door.rotation = 0;
door.wallThickness = 240;
Engine.addEntities([door]); // 必须先 add 才有 id
door.wallHandle = String(wall.id);
wall.doorWindowHandles = [String(door.id)];
wall.setModified(); // 触发墙体重绘 / 自动开洞
完整两室两厅户型例子:
vjcad/example/plugin/05architecture.js
关联机制(核心)
- 墙体
WallEnt.doorWindowHandles: string[]、门窗wallHandle: string双向引用 WallEnt.buildNestEnts()在绘制时按doorWindowHandles自动开洞- 门窗夹点编辑时被 约束在墙中线
- 墙体移动时
WallService监听EntityModified自动 重投影门窗 位置 - 门窗删除前
WallService监听EntitiesErasing把对应 ID 从doorWindowHandles移除,墙体补洞
国标图层(自动创建)
| 图层 | 颜色 | 用途 |
|---|---|---|
A_AXIS |
1 红 | 轴线 |
A_COLU |
2 黄 | 柱子 |
A_WALL |
7 白 | 墙体 |
A_DOOR / A_WIND |
4 青 | 门 / 窗 |
A_STRS / A_BALC |
3 绿 | 楼梯 / 阳台 |
A_ROOM |
6 品红 | 房间 |
A_DIMS |
7 白 | 标注 |
A_SYMB |
1 红 | 符号 |
3. 三维视图插件(view3d-plugin,最小骨架)
官方插件里最精简的完整插件,源码结构就是上文"标准 Plugin 接口"的最小实现,可以拷贝它的 index.ts 当起点:
manifest必填字段示范(id: 'view3d')onActivate中registerIcon('VIEW3D')→registerCommand('VIEW3D', ..., View3dCommand)→addMenuItem('tool', …)→addRibbonGroup('plugins', …)的顺序onDeactivate只需销毁插件自建的 UI(源码里仅destroyView3dPanel());命令/菜单/Ribbon/on事件等注册项由 PluginManager 调context._cleanup()自动注销,无需手写逆序注销(图标与once监听不在清理范围,侧栏面板仅unload时移除)
参考实现:vjcad/example/plugin/04pluginmanager.js(运行时构造 pluginCode 并 loadFromContent 加载,等价于真实文件)。
4. insert-plugin(图片矢量化)
INSERTIMAGE / INSERTTABLE / EXTRACTTABLE 三个命令都由 insert 插件(manifest.id: 'insert')在 onActivate 里自己注册,核心库没有;插件未加载时执行这些命令无效果。图片矢量化用插件内部的 VectroizeService(WASM)。插件 dist 带 vcad-plugin-insert.css,而 loadByName 不加载 CSS,推荐:
await pm.loadFromUrl('./plugins/vcad-plugin-insert.js', './plugins/vcad-plugin-insert.css');
// 或(只有 JS,样式缺失)
await pm.loadByName('vcad-plugin-insert'); // 包名是 vcad-plugin-insert,构建产物 vcad-plugin-insert.js
API 用法见 insert/vectorize.md。
红旗
- 加载顺序:建筑插件依赖批注?依赖 dim?目前各官方插件相互独立,但自定义插件如果有
dependencies,先 activate 依赖,再 activate 自身 - 建筑插件实体使用
*.create()工厂方法,不要new WallEnt(...):构造函数无参,传进去的起终点/厚度会被忽略,得到默认墙(0,0→1000,0) - 关联门窗时
Engine.addEntities之后才有entity.id,需要在 add 后再设置wallHandle / doorWindowHandles wall.setModified()是触发开洞重绘的开关,新增/解除关联后必须调用- 批注插件的
_ANNOTATION图层由ensureLayer()按需创建(默认可见,颜色 ACI 1);ANNO_HIDE只是把它layerOn=false(若它是当前图层会先切回0)。保存图纸时图层会随文档带过去 vjcad/example/plugin/05architecture.js需要 先构建并复制建筑插件 dist 文件 到 playground 才能跑
参考(官方文档 MCP)
- 文档:
vjcad/doc/plugin/plugin-annotation.md、vjcad/doc/plugin/plugin-architecture.md - 示例:
vjcad/example/plugin/05architecture.js