> **本文回答**：`Engine.pcanvas` 是画布控制器，用来直接添加实体、刷新（`regen / redraw / render`）、高亮、缩放、绘制预览图；区别是：`render()` 仅 GPU 渲染当前帧、`redraw()` 视图变换后渲染、`regen()` 局部更新已 setModified 的实体、`regen(true)` 完全重绘所有图形。

## 一、添加实体（不推荐 vs 推荐）

```js
// 不推荐：pcanvas.addEntity 不自动记录撤销，需要自己 added_undoMark
Engine.pcanvas.addEntity(ent);
Engine.undoManager.added_undoMark([ent]);

// 推荐
Engine.addEntities(ent);   // 自动 undo + 自动 regen
```

MCP 参考：`vjcad/doc/command/api-reference.md`。

## 二、`regen / redraw / render` 区别

> 引自 `vjcad/doc/command/api-reference.md`：

| 方法 | 含义 |
|---|---|
| `Engine.pcanvas.render()` | 最底层，只调用 GPU 渲染当前帧 |
| `Engine.pcanvas.redraw()` | 更新视图变换（位置 / 缩放 / 旋转）后渲染 |
| `Engine.pcanvas.regen()` | 局部更新：只重新渲染已 `setModified` 标记的实体 |
| `Engine.pcanvas.regen(true)` | 完全重绘：清除并重新绘制所有图形 |

```js
Engine.regen();                // 先 reactorManager.updateDirtyReactors()（关联标注等）再 pcanvas.regen()
Engine.pcanvas.regen();        // 只重绘，不刷新脏反应器——关联标注不会跟随几何更新
Engine.pcanvas.regen(true);    // 完全重绘（同样不刷反应器）；业务代码优先用 Engine.regen(true)
```

## 三、高亮 / 夹点 / 选择

```js
Engine.pcanvas.highLightEntities([ent1, ent2]);
Engine.pcanvas.clearHighLight();
Engine.pcanvas.clearGrip();
```

MCP 参考：`vjcad/doc/command/api-reference.md`。

## 四、缩放

```js
Engine.pcanvas.zoomExtents();          // 缩放到全图
Engine.zoomExtents();                  // 等价快捷
Engine.zoomToEntities([ent1, ent2]);   // 缩放到指定实体
```

更多视图操作见 [view/zoom](../view/zoom.md)、[view/pan-redraw](../view/pan-redraw.md)。

## 五、绘制预览图（拖动绘制 / 命令预览）

```js
const dc = Engine.pcanvas.drawControl;

dc.drawPreviewEntity(ent);              // 单实体预览
dc.drawPreviewEntities([e1, e2]);       // 多实体预览
dc.drawHighLightEntity(ent);            // 高亮预览
Engine.clearPreview();                  // 清空预览（= dc.clearPreview()，会移除 MText 等子容器；previewGraphics.clear() 清不掉这些）

dc.setPreviewPosition(point);           // 移动预览到目标点
dc.setPreviewRotation(angle);           // 旋转预览
dc.setPreviewScale(sx, sy);             // 缩放预览
dc.resetPreview();                      // 重置预览
```

MCP 参考：`vjcad/doc/command/api-reference.md`。

在自定义命令里使用预览图见 [command/preview](../command/preview.md)。

## 六、坐标转换

`Engine.pcanvas.trans` 提供 `CanvasToWcs / WcsToCanvas` 等转换，详见 [coordinate](coordinate.md)。

## 反例

- 用 `pcanvas.addEntity(ent)` 后忘记 `added_undoMark`：撤销不到这步操作。
- 在循环里频繁 `regen()`：每帧都重绘很卡；应该改完一批再调一次 `regen()`。
- 用 `previewGraphics.clear()` 清预览：只清图形指令，MText 等子容器残留；用 `Engine.clearPreview()`。注册命令结束后框架会自动 `resetPreview()`，脚本里直接调 `getPoint` 画预览时才必须自己清。

## 参考（官方文档 MCP）

- 文档：`vjcad/doc/command/api-reference.md`、`vjcad/doc/guide/architecture.md`
- 示例：`vjcad/example/command/03withpreview.js`（预览图用法）
