插入符号
示例:
vjcad/example/insert/symbol/03insertbasic.js— 基础(指定参数插入)vjcad/example/insert/symbol/04insertinteractive.js— 交互式(getPoint)vjcad/example/insert/symbol/07insertmodify.js— 修改属性后插入(颜色 / 固定缩放)
1. 三种插入路径
| 场景 | API |
|---|---|
| 已知插入点 / 缩放 / 旋转 | mergeSymbolToDocument(symbolDoc, insertPoint, basePoint, scale, rotation, clearSourceInfo) |
| 让用户依次拾取插入点 / 缩放 / 旋转 | insertSymbolInteractive(vcadData, basePoint, options) |
| 修改实体属性后再插入(固定/不固定参数) | parseSymbolVcadData(vcadData) → 改实体 → new SymbolInteractiveInserter(...).execute() |
2. 基础:API 方式插入到固定位置
const localService = getLocalStorageService();
const cats = await localService.getLocalSymbolCategories();
const symbolMeta = (await localService.getLocalSymbolList(cats[0].id))[0];
const detail = await localService.getLocalSymbol(symbolMeta.id);
const symbolDoc = await parseSymbolVcadData(detail.vcadData); // detail = { record, vcadData }
const insertPoint = new Point2D(50, 50);
Engine.startUndoMark('插入符号'); // mergeSymbolToDocument 本身不记 undo
const addedEntities = mergeSymbolToDocument(
symbolDoc,
insertPoint,
symbolMeta.basePoint, // [x, y]
1.5, // 缩放
45, // 旋转角度(度,不是弧度)
false // clearSourceInfo: 是否清空来源图信息
);
if (addedEntities.length) Engine.undoManager.added_undoMark(addedEntities);
Engine.endUndoMark();
Engine.regen();
服务端符号则需要先解压:
const fullSymbol = await Engine.service.getSymbol(metaId);
const vcadData = await decompressSymbolData(fullSymbol.data);
const symbolDoc = await parseSymbolVcadData(vcadData);
mergeSymbolToDocument(symbolDoc, new Point2D(150, 50), fullSymbol.basePoint, 1, 0, false);
完整代码:
vjcad/example/insert/symbol/03insertbasic.js
3. 交互式插入(getPoint 拾取)
class InsertSymbolCommand {
async main() {
// ...拿到 vcadData / basePoint...
const entities = await insertSymbolInteractive(vcadData, basePoint, {
allowScale: true, // 提示输入缩放
allowRotation: true, // 提示输入旋转
clearSourceInfo: false,
});
if (entities) {
message.info("已插入 " + entities.length + " 个实体");
Engine.zoomExtents();
}
}
}
CommandRegistry.regist(new CommandDefinition('MYINSERTSYMBOL', '插入符号', InsertSymbolCommand, new CommandOptions()));
await Engine.editor.executerWithOp('MYINSERTSYMBOL');
insertSymbolInteractive 内部依次提示:
- 指定插入点
- (
allowScale时)输入缩放 - (
allowRotation时)输入旋转角度
完整代码:
vjcad/example/insert/symbol/04insertinteractive.js
4. 修改属性后插入
如果要在插入前批量调整符号实体(例如统一改颜色),用 parseSymbolVcadData 取出 *Model 块,改 items,再用 SymbolInteractiveInserter:
const symbolDoc = await parseSymbolVcadData(vcadData);
const modelBlock = symbolDoc.blocks.itemByName("*Model");
for (const e of modelBlock.items) e.color = 1; // 改成红色
const inserter = new SymbolInteractiveInserter(
symbolDoc,
symbolMeta.basePoint,
/* allowScale */ false,
/* allowRotation */ false,
/* clearSourceInfo */ false,
/* initialScale */ 2,
/* initialRotation */ 30
);
const entities = await inserter.execute();
参数 allowScale=false + initialScale=2 表示 强制 2 倍,用户无法修改。同理 allowRotation=false + initialRotation=30 表示 强制旋转 30°。
完整代码:
vjcad/example/insert/symbol/07insertmodify.js
5. mergeSymbolToDocument 参数
| 位置 | 参数 | 类型 | 说明 |
|---|---|---|---|
| 1 | symbolDoc |
CadDocument |
parseSymbolVcadData 的产物 |
| 2 | insertPoint |
Point2D |
当前文档中的插入点 |
| 3 | basePoint |
[x, y] |
符号的基点(来自 symbolMeta) |
| 4 | scale |
number | 缩放倍数(1 = 原大小) |
| 5 | rotation |
number | 角度(度),0 = 不旋转 |
| 6 | clearSourceInfo |
boolean | 是否清空实体溯源信息(来源 objectId,默认 false) |
返回值:插入后的实体数组(已入当前空间——内部走 Engine.pcanvas.addEntity 逐个克隆插入,不是 Engine.addEntities,因此不记录 undo;内置 SYMBOL 命令是外包 startUndoMark + added_undoMark(entities) + endUndoMark + regen 实现可撤销的)。
变换顺序:对每个克隆实体依次 move(basePoint→原点) → scale(原点, scale) → rotate(原点, rotation弧度) → move(原点→insertPoint)。即"先归基点、再缩放旋转、再落插入点"。例:基点 (10,10) 处圆心 (15,10) r=5 的圆,mergeSymbolToDocument(doc, Point2D(100,100), [10,10], 2, 90) 后落在 (100,110) r=10。
红旗
- 旋转角度全是 度,不是弧度
mergeSymbolToDocument内部已把实体加进当前空间,不要再addEntities一次- 服务端符号必须
decompressSymbolData才能给parseSymbolVcadData parseSymbolVcadData是 async- 插入大量符号(几百个)时:
suspendEvents()/resumeEvents()只静默(默认直接丢弃)事件,不会合并重绘;批量请包在一个 undo 组里(startUndoMark+added_undoMark+endUndoMark),最后Engine.regen()一次
参考(官方文档 MCP)
- 示例:
vjcad/example/insert/symbol/03insertbasic.js— 基础(指定参数插入)vjcad/example/insert/symbol/04insertinteractive.js— 交互式(getPoint)vjcad/example/insert/symbol/07insertmodify.js— 修改属性后插入(颜色 / 固定缩放)