# VjCAD SDK 快速参考

## 1. 创建实体

### 常用实体速查表

| 实体 | 创建方式 | 关键属性 |
|------|----------|----------|
| `LineEnt` | `new LineEnt([x1,y1], [x2,y2])` | `startPoint`, `endPoint` |
| `CircleEnt` | `new CircleEnt([cx,cy], radius)` | `center`, `radius` |
| `ArcEnt` | `new ArcEnt([cx,cy], r, startAng, endAng)` | `center`, `radius`, `startAngle`, `endAngle` |
| `PolylineEnt` | `new PolylineEnt()` + `setPoints(pts)` | `isClosed`, `bulgePoints` |
| `TextEnt` | `new TextEnt()` | `insertionPoint`, `text`, `height`, `textAlignment` |
| `MTextEnt` | `new MTextEnt()` | `insertionPoint`, `text`, `height`, `maxWidth` |
| `SplineEnt` | `new SplineEnt()` + `setFitPoints(pts)` 或 `setControlPoints(pts)` | `fitPoints`, `controlPoints`, `isClosed` |

**重要**：创建实体后必须先调用 `setDefaults()`，再设置 `color` 等属性。

### 完整示例

```javascript
// === 直线 ===
const line = new LineEnt([0, 0], [100, 100]);
line.setDefaults();
line.color = 1;  // 红色
Engine.addEntities(line);

// === 圆 ===
const circle = new CircleEnt([50, 50], 30);
circle.setDefaults();
Engine.addEntities(circle);

// === 圆弧（角度单位：弧度）===
// 方向规则：逆时针为正方向，从 startAngle 到 endAngle 逆时针绘制
// 角度基准：0 = 正右方(3点钟)，逆时针增加：π/2 = 正上方，π = 正左方
const arc = new ArcEnt([50, 50], 30, 0, Math.PI / 2);  // 从 0° 到 90°，逆时针画 1/4 圆
arc.setDefaults();
Engine.addEntities(arc);

// === 多段线（矩形）===
const rect = new PolylineEnt();
rect.setPoints([[0, 0], [100, 0], [100, 60], [0, 60]]);
rect.isClosed = true;
rect.setDefaults();
Engine.addEntities(rect);

// === 带圆弧的多段线 ===
const pline = new PolylineEnt();
pline.setPoints([
    [0, 0],           // 直线段
    [[50, 0], 0.5],   // 弧段（凸度0.5，逆时针）
    [100, 0]
]);
pline.setDefaults();
Engine.addEntities(pline);

// 凸度: bulge = tan(圆心角/4)，90°圆角用 Math.tan(Math.PI/8) ≈ 0.4142，半圆=1.0
// 圆角矩形: 直线段+圆角交替，每个圆角点用 [[x,y], bulge] 格式

// === 单行文字 ===
const text = new TextEnt();
text.insertionPoint = [0, 100];
text.text = "Hello VjCAD";
text.height = 10;
text.textAlignment = 5;  // 中心对齐
text.setDefaults();
Engine.addEntities(text);

// === 多行文字 ===
const mtext = new MTextEnt();
mtext.insertionPoint = [0, 200];
mtext.text = "第一行\n第二行";
mtext.height = 8;
mtext.maxWidth = 80;  // 超出自动换行
mtext.setDefaults();
Engine.addEntities(mtext);

// === 样条曲线（Spline）===
const spline = new SplineEnt();
// 方式1: 拟合点 — 曲线精确经过所有点
spline.setFitPoints([[0, 0], [30, 50], [60, 20], [100, 40]]);
// 方式2: 控制点 — 控制点"拉动"曲线但不经过
// spline.setControlPoints([[0, 0], [30, 50], [60, 20], [100, 40]]);
// 闭合样条：把首点再追加到末尾，如 setFitPoints([...pts, pts[0]])（SPLINE 命令的 C 选项同理）
// isClosed 是只读 getter（首末点重合即 true）；isPeriodic 只是存档标志，绘制时不读，设了也不会闭合
spline.setDefaults();
Engine.addEntities(spline);

Engine.zoomExtents();  // 缩放到全图
```

### 文本对齐方式（textAlignment）

```
7=左上     8=中上     9=右上
4=左中     5=中心     6=右中
1=左下     2=中下     3=右下
```

---

## 2. 修改实体

### 变换操作

```javascript
const { Point2D, Engine } = vjcad;

// === 移动 ===
entity.move([0, 0], [50, 30]);  // 从 from 移动到 to
Engine.regen();

// === 复制 ===
const copy = entity.clone();
copy.move([0, 0], [100, 0]);
Engine.addEntities(copy);

// === 旋转（绕点旋转，角度为弧度）===
entity.rotate(new Point2D(0, 0), Math.PI / 4);  // 旋转 45°
Engine.regen();

// === 缩放 ===
entity.scale(new Point2D(0, 0), 2.0);  // 放大 2 倍
Engine.regen();

// === 镜像（沿 p1-p2 直线镜像）===
entity.mirror(new Point2D(100, 0), new Point2D(100, 100));
Engine.regen();
```

**注意**：`move/rotate/scale/mirror` 的点参数类型都是 `PointInput`（`Point2D` 或 `[x,y]` 数组均可）。

### 删除实体

```javascript
Engine.eraseEntities(entity);           // 删除单个
Engine.eraseEntities([ent1, ent2]);     // 删除多个
```

---

## 3. 查询实体

```javascript
// ⚠️ getEntities / getEntitiesByType 返回 currentSpace.items 原样——含已删除实体（isAlive=false）
// 获取所有存活实体
const all = Engine.getEntities(ent => ent.isAlive);   // 或 Engine.currentSpace.aliveItems

// 按类型获取（同样含已删除实体，需再过滤）
const lines = Engine.getEntitiesByType('LINE').filter(ent => ent.isAlive);
const circles = Engine.getEntitiesByType('CIRCLE').filter(ent => ent.isAlive);
const plines = Engine.getEntitiesByType('PLINE').filter(ent => ent.isAlive);
const texts = Engine.getEntitiesByType('TEXT').filter(ent => ent.isAlive);

// 按条件过滤（条件里带上 isAlive）
const redEnts = Engine.getEntities(ent => ent.isAlive && ent.color === 1);
const layerA = Engine.getEntities(ent => ent.isAlive && ent.layer === "图层A");
```

### 选择集操作

```javascript
// 设置选择集
Engine.ssSetFirst([entity1, entity2]);

// 获取选择集
const { ssGetFirst } = vjcad;
const selected = ssGetFirst();
```

### 获取实体范围

```javascript
// 单个实体：返回 BoundingBox（pt1/pt2/width/height/center/minPoint/maxPoint/minX..maxY）
const bbox = entity.boundingBox();
// 多个实体的组合范围（保证返回 BoundingBox 实例）
const combinedBbox = Engine.getBoundsByEntities([ent1, ent2], "WCS");
```

---

## 4. 颜色与属性

### 颜色代码表

| 代码 | 颜色 | 代码 | 颜色 |
|------|------|------|------|
| 1 | 红色 | 5 | 蓝色 |
| 2 | 黄色 | 6 | 洋红 |
| 3 | 绿色 | 7 | 白色 |
| 4 | 青色 | 8 | 灰色 |

### RGB 真彩色

RGB 颜色使用 `ColorConverter` 工具类：

```javascript
const { ColorConverter } = vjcad;
entity.color = ColorConverter.createRgbColorIndexFromHexStr("#FFD700");  // 金色
```

### 通用属性

```javascript
entity.color = 1;              // ACI 颜色（1-255），256=随层，0=随块
entity.layer = "图层名";        // 图层
entity.lineType = "HIDDEN";    // 线型：CONTINUOUS, HIDDEN, CENTER
entity.lineTypeScale = 1.0;    // 线型比例
```

直接赋属性**不记录撤销**。需要可撤销时改用 Engine 批量方法（自动记录撤销）：`Engine.setEntityColor(ents, 1)` / `Engine.setEntityLayer(ents, "图层名")` 可传单个实体或数组；`Engine.setEntityLineType` / `setEntityLineTypeScale` / `setEntityTransparency` **只收数组**（传单个实体会在撤销记录里 `t.map` 抛 TypeError）。

---

## 5. Engine 核心方法

```javascript
// 实体操作
Engine.addEntities(entity);           // 添加
Engine.addEntities([ent1, ent2]);     // 批量添加
Engine.eraseEntities(entity);         // 删除

// 视图操作
Engine.zoomExtents();                 // 缩放到全图
Engine.zoomToEntities(entities);      // 缩放到指定实体
Engine.regen();                       // 刷新显示
Engine.regen(true);                   // 完全重绘
```

---

## 6. 撤销/重做

**关键规则**：能否撤销取决于是否记录了撤销标记——`Engine.addEntities` / `eraseEntities` / `setEntityColor` / `setEntityLayer` 等已自动记录；直接改属性或 `entity.move/rotate/scale/mirror` 不记录，需先 `Engine.markModified(ent)`（或事后补 `moved_undoMark` 等）。`start_undoMark` / `end_undoMark` 只负责把多条标记合并成一步撤销（单条标记本身就是一步）。

### 基本用法

```javascript
const undoMgr = Engine.undoManager;

// 字符串简写（最常用，默认 category: 'edit'）
undoMgr.start_undoMark('绘制图形');
try {
    // ... 创建/修改/删除实体 ...
    Engine.addEntities(entity);   // 已自动 added_undoMark，切勿再手动记一次（重复记录会在撤销时多删一个无关实体）
} finally {
    undoMgr.end_undoMark();
}

```

仅在改用底层 `Engine.pcanvas.addEntity` / `Engine.currentSpace.erase` 时才手动补 `added_undoMark` / `erased_undoMark`。

### 支持嵌套的包装（推荐在命令中使用）

```javascript
Engine.startUndoRecord('我的操作');  // 支持嵌套，只有最外层生效
// ... 操作 ...
Engine.endUndoRecord();
```

### 撤销/重做

```javascript
undoMgr.undo();                           // 撤销一步
undoMgr.redo();                           // 重做一步
undoMgr.undoSteps(3);                     // 撤销3步
undoMgr.undoSteps('绘制图形');             // 按名称撤销到最近匹配项（含），无匹配不执行
undoMgr.redoSteps('绘制图形');             // 按名称重做
undoMgr.undoSteps(3, { silent: true });   // 静默撤销（不触发命令行消息）
```

### 修改已有实体的撤销模式

```javascript
undoMgr.start_undoMark('修改颜色');
try {
    Engine.markModified(entity);   // 先标记（记录修改前状态）
    entity.color = 1;              // 再修改属性
    entity.setModified();          // 通知修改完成
} finally {
    undoMgr.end_undoMark();
}
```

### 删除实体的撤销

```javascript
undoMgr.start_undoMark('删除实体');
try {
    Engine.eraseEntities(entities);     // 已自动 erased_undoMark，勿再手动记录（组外重复记录会多出一个空撤销步）
} finally {
    undoMgr.end_undoMark();
}
```

---

## 7. 进阶功能

需要更多功能时，请查阅以下文档：

- [常用实体详解](entities-basic.md) - Line, Circle, Arc, Polyline, Text 完整属性
- [进阶实体](entities-advanced.md) - Hatch 填充, Dimension 标注, Insert 块
- [填充图案](hatch-pattern.md) - 80+ 内置图案、自定义图案
- [编辑与选择](edit-selection.md) - 移动、复制、旋转、选择集、撤销
- [命令系统](commands.md) - 自定义交互命令
- [输入与事件](input-events.md) - getPoint、getSelections、事件监听
- [图层与属性](layer-property.md) - 图层管理、XData
- [几何计算](geometry.md) - 距离、交点、面积
- [文件操作](file-operations.md) - 打开、保存 DWG
- [UI 用户界面](ui-plugin.md) - 界面插件、面板、对话框、工具栏、浮动工具栏
- [自定义对话框](custom-dialog.md) - 对话框结构与回调
- [插件开发](plugin-development.md) - Plugin 生命周期、PluginContext
- [反应器](reactor.md) - IEntityReactor、实体联动
- [线型进阶](linetype-advanced.md) - 线型文件、线型管理
- [SVG 导入](svg-import.md) - SVG 转实体
- [符号系统](symbol-system.md) - 符号库创建与插入
- [地图叠加](map-overlay.md) - CAD 叠互联网底图
- [瓦片模式](tile-mode.md) - 大图分块编辑
- [表格提取](table-extraction.md) - 图纸表格识别
- [版本控制](version-control.md) - 分支、补丁、合并
