唯杰地图 logo唯杰地图
VJMAP
EN

插入符号

vjcad/references/insert/symbol-insert.md 6.0 KB134 行
原文

示例:

  • 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 内部依次提示:

  1. 指定插入点
  2. (allowScale 时)输入缩放
  3. (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 — 修改属性后插入(颜色 / 固定缩放)