唯杰地图 logo唯杰地图
VJMAP
EN

mark

vjcad/references/undo/mark.md 5.3 KB143 行
原文

本文回答:撤销标记 = 把"做了一次某种类型的操作"记到栈里。常用方法:added_undoMark / erased_undoMark / modEntity_undoMark / moved_undoMark / rotate_undoMark / scaled_undoMark / mirrored_undoMark / entLayer_undoMark / entColorIndex_undoMark / entLineType_undoMark / entLTScale_undoMark / entTransp_undoMark / clayer_undoMark / layerModified_undoMark / ucs_undoMark / plan_undoMark。Engine.addEntities / eraseEntities 等封装会自动记录,无需手动 mark。

一、最常用:添加 / 删除 / 修改

const u = Engine.undoManager;

// 添加 — 推荐 Engine.addEntities,自动记录
Engine.addEntities(line1);

// 或手动两步
Engine.pcanvas.addEntity(circle1);
u.added_undoMark([circle1]);

// 删除 — 推荐 Engine.eraseEntities,自动记录
Engine.eraseEntities(line1);

// 或手动
Engine.currentDoc.currentSpace.erase([line1]);
u.erased_undoMark([line1]);

// 修改属性前先记
u.modEntity_undoMark(entity);   // 记录修改前状态
entity.color = 1;
entity.setModified();

MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/02mark.js。

二、几何变换

const fromPt = new Point2D(0, 0);
const toPt   = new Point2D(40, 0);

// 移动
for (const e of entities) e.move(fromPt, toPt);
u.moved_undoMark(entities, fromPt, toPt);

// 旋转
const basePt = new Point2D(50, 50);
const ang    = Math.PI / 4;
for (const e of entities) e.rotate(basePt, ang);
u.rotate_undoMark(entities, basePt, ang);

// 缩放
for (const e of entities) e.scale(basePt, 2.0);
u.scaled_undoMark(entities, basePt, 2.0);

// 镜像
const p1 = new Point2D(0, 0), p2 = new Point2D(100, 0);
for (const e of entities) e.mirror(p1, p2);
u.mirrored_undoMark(entities, p1, p2);

MCP 参考:vjcad/doc/undo/undo-redo.md、vjcad/example/undo/02mark.js。

三、属性 / 图层 / 颜色 / 线型

u.entLayer_undoMark(entities);        // 改图层前
u.entColorIndex_undoMark(entities);   // 改颜色前
u.entLineType_undoMark(entities);     // 改线型前
u.entLTScale_undoMark(entities);      // 改线型比例前
u.entTransp_undoMark(entities);       // 改透明度前

// 当前图层切换:Engine.setCurrentLayer 内部已 clayer_undoMark,不要再手动 mark(否则记两次)
Engine.setCurrentLayer('新图层');
// 只有直接赋 Engine.currentDoc.CLAYER 时才需要先手动 u.clayer_undoMark(oldLayer)

// 图层属性修改
u.layerModified_undoMark(layer);
layer.color = 1;

MCP 参考:vjcad/doc/undo/undo-redo.md。

四、UCS / PLAN(视图)

UCS / PLAN 是先改值、再 mark:UcsUndoCommand / PlanViewUndoCommand 构造时就把空间当前值记为 redo 目标,先 mark 会把旧值当成 redo 值(redo 失效)。

// UCS 设置时
const oldOrg = Engine.currentSpace.UCSORG.clone();
const oldAng = Engine.currentSpace.UCSXANG;
Engine.currentSpace.UCSORG  = newOrg;
Engine.currentSpace.UCSXANG = newAng;
u.ucs_undoMark(oldOrg, oldAng);         // 改完再 mark,传旧值

// 平面视图旋转
const oldTwistAngle = Engine.currentSpace.twistAngle;
Engine.currentSpace.twistAngle = newTwistAngle;
u.plan_undoMark(oldTwistAngle);         // 改完再 mark,传旧值

MCP 参考:vjcad/example/view/10ucs.js、11planview.js。

五、撤销标记总表

方法 撤销时行为
added_undoMark(ents) 删除这些实体
erased_undoMark(ents) 恢复这些实体
modEntity_undoMark(ent) 恢复修改前状态
moved_undoMark(ents, from, to) 反向移动
rotate_undoMark(ents, base, angle) 反向旋转
scaled_undoMark(ents, base, scale) 反向缩放(除以 scale)
mirrored_undoMark(ents, p1, p2) 再次镜像(自反)
entLayer_undoMark(ents) 恢复原图层
entColorIndex_undoMark(ents) 恢复原颜色
entLineType_undoMark(ents) 恢复原线型
entLTScale_undoMark(ents) 恢复原比例
entTransp_undoMark(ents) 恢复原透明度
clayer_undoMark(oldLayer) 恢复原当前图层
layerModified_undoMark(layer) 恢复图层属性
ucs_undoMark(oldOrg, oldAng) 恢复 UCS
plan_undoMark(oldTwistAngle) 恢复视图旋转

MCP 参考:vjcad/doc/undo/undo-redo.md。

六、Engine.markModified 封装

Engine.markModified(entity);            // 单个,等价 modEntity_undoMark
entity.color = 1;
entity.setModified();

Engine.markModifiedBatch([e1, e2, e3]); // 批量

MCP 参考:vjcad/doc/undo/undo-redo.md。

反例

  • 修改属性后才 mark:记录的是新值,撤销不了。快照类 mark(modEntity_undoMark、entColorIndex_undoMark 等)必须先 mark,再改;但 ucs_undoMark / plan_undoMark 相反——先改值再 mark(传旧值),见 §四。
  • 用 Engine.addEntities + 手动 added_undoMark:双重记录(addEntities 已自动记录)。撤销按记录条数从块末尾 pop,会多删掉一个原本就存在的实体,重做又会把新实体加两次。
  • 改了 Engine.currentSpace.UCSORG 但不 ucs_undoMark:Ctrl+Z 不会回滚 UCS。

参考(官方文档 MCP)

  • 文档:vjcad/doc/undo/undo-redo.md、vjcad/doc/undo/index.md
  • 示例:vjcad/example/undo/02mark.js