图层管理 (Layers)
大约 6 分钟
图层管理 (Layers)
图层用于组织和控制实体的显示与编辑。
概述
图层是 CAD 中重要的组织机制,可以:
- 将实体按类别分组
- 控制实体的可见性
- 控制实体的可编辑性(锁定)
- 设置默认颜色、线型等属性
图层属性
| 属性 | 类型 | 说明 |
|---|---|---|
name | string | 图层名称(唯一) |
color | number | 图层颜色(ACI 颜色索引) |
lineType | string | 图层线型 |
lineWeight | number | 图层线宽 |
layerOn | boolean | 图层开关(是否显示) |
isLocked | boolean | 是否锁定 |
isFrozen | boolean | 是否冻结 |
图层状态详解
图层有三种独立的状态控制,它们的效果不同:
| 状态 | 属性 | 可见 | 可选择 | 可编辑 | 参与重生成 |
|---|---|---|---|---|---|
| 正常 | layerOn=true, isFrozen=false, isLocked=false | ✓ | ✓ | ✓ | ✓ |
| 关闭 | layerOn=false | ✗ | ✗ | ✗ | ✓ |
| 冻结 | isFrozen=true | ✗ | ✗ | ✗ | ✗ |
| 锁定 | isLocked=true | ✓ | ✗ | ✗ | ✓ |
状态说明:
- 关闭 (layerOn=false):图层不显示,但实体仍参与重生成计算
- 冻结 (isFrozen=true):图层不显示,实体不参与重生成,性能更好。0 图层和当前图层不能被冻结
- 锁定 (isLocked=true):图层正常显示,但实体不能被选择和编辑,适合作为参考底图
图层操作
获取图层
import { Engine } from 'vjcad';
// 获取所有图层
const layers = Engine.currentDoc.layers;
// 按名称获取图层
const layer = layers.get('墙体');
// 获取当前图层
const currentLayer = Engine.currentDoc.CLAYER;
console.log('当前图层:', currentLayer.name);
// 检查图层是否存在
if (layers.has('门窗')) {
console.log('门窗图层存在');
}创建图层
import { Engine } from 'vjcad';
const doc = Engine.currentDoc;
// 方式一:使用 Engine.createLayer(推荐)
const layer1 = Engine.createLayer("标注层", {
color: 1, // 红色
lineType: "CONTINUOUS",
layerOn: true, // 是否显示
isFrozen: false, // 是否冻结
isLocked: false // 是否锁定
});
// 方式二:使用 doc.layers.addlayer
if (!doc.layers.itemByName("辅助线层")) {
doc.layers.addlayer("辅助线层", true, 3); // 参数:名称, 是否显示, 颜色(绿色)
}
// 创建自动命名的图层
const autoLayer = Engine.createLayer(); // 自动命名为 "图层1", "图层2" 等设置当前图层
import { Engine } from 'vjcad';
// 方式一:使用 Engine 快捷方法
Engine.setCurrentLayer('墙体');
// 方式二:直接设置
Engine.currentDoc.CLAYER = Engine.currentDoc.layers.get('墙体');修改图层属性
import { Engine } from 'vjcad';
const layer = Engine.getLayerByName('墙体');
// 修改颜色
layer.color = 5; // 蓝色
// 修改线型
layer.lineType = 'DASHED';
// 设置可见性(图层开关)
layer.layerOn = false; // 关闭图层
Engine.regen(true); // 需要重新渲染
// 锁定图层
layer.isLocked = true; // 锁定后不能选择和编辑
// 冻结图层
layer.isFrozen = true; // 冻结后不可见且不参与计算
Engine.regen(true); // 需要重新渲染删除图层
import { Engine } from 'vjcad';
// 删除图层(图层上的实体会移到图层 0)
Engine.currentDoc.layers.remove('临时图层');
// 注意:图层 0 不能删除实体与图层
设置实体图层
import { Engine, LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
line.setDefaults();
// 方式一:设置图层 ID
line.layerId = Engine.currentDoc.layers.get('墙体').id;
// 方式二:使用 Engine 方法
Engine.setEntityLayer(line, '墙体');
Engine.addEntities(line);按图层选择实体
import { Engine } from 'vjcad';
// 获取指定图层上的所有实体
const layer = Engine.currentDoc.layers.get('墙体');
const entities = Engine.currentDoc.currentSpace.entities.filter(
ent => ent.layerId === layer.id
);
console.log(`墙体图层有 ${entities.length} 个实体`);ByLayer 颜色
当实体颜色设置为 256(ByLayer)时,使用图层颜色:
import { Engine, LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
line.color = 256; // ByLayer - 使用图层颜色
line.setDefaults();
// 设置图层
Engine.setEntityLayer(line, '墙体');
// 实际显示颜色 = 墙体图层的颜色图层状态控制
图层开关 (layerOn)
控制图层是否显示,关闭的图层实体仍参与重生成计算:
import { Engine } from 'vjcad';
const layer = Engine.getLayerByName('标注');
// 关闭图层
layer.layerOn = false;
Engine.regen(true); // 需要重新渲染
// 打开图层
layer.layerOn = true;
Engine.regen(true);
// 批量控制
function showOnlyLayers(layerNames: string[]) {
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.layerOn = layerNames.includes(layer.name);
});
Engine.regen(true);
}
showOnlyLayers(['墙体', '门窗']); // 只显示墙体和门窗锁定控制 (isLocked)
锁定的图层上的实体可见但不能选择和编辑,适合作为参考底图:
import { Engine } from 'vjcad';
const layer = Engine.getLayerByName('参考');
// 锁定图层
layer.isLocked = true;
// 此时图层上的实体仍然可见,但:
// - 点选、框选、Ctrl+A 全选都无法选中
// - 无法对实体进行任何编辑操作
// 解锁图层
layer.isLocked = false;冻结控制 (isFrozen)
冻结的图层不显示且不参与重生成计算,性能比关闭更好:
import { Engine } from 'vjcad';
const layer = Engine.getLayerByName('施工图');
// 冻结图层
layer.isFrozen = true;
Engine.regen(true); // 需要重新渲染
// 解冻图层
layer.isFrozen = false;
Engine.regen(true);
// 注意:0 图层和当前图层不能被冻结
// 尝试冻结当前图层会被拒绝使用 Layers 快速查询方法
对于大量实体的场景(百万级),使用 Layers 集合的快速查询方法可获得更好的性能:
import { Engine } from 'vjcad';
const layers = Engine.currentDoc.layers;
// 检查图层是否可见(layerOn=true 且 isFrozen=false)
const isVisible = layers.isLayerVisible(layerId);
// 检查图层是否可选择(可见且未锁定)
const isSelectable = layers.isLayerSelectable(layerId);
// 检查图层是否冻结
const isFrozen = layers.isLayerFrozen(layerId);
// 检查图层是否锁定
const isLocked = layers.isLayerLocked(layerId);完整示例
图层管理器
import { Engine } from 'vjcad';
class LayerManager {
// 创建标准图层集
static createStandardLayers() {
const layerDefs = [
{ name: '墙体', color: 1, lineType: 'CONTINUOUS' },
{ name: '门窗', color: 3, lineType: 'CONTINUOUS' },
{ name: '家具', color: 4, lineType: 'CONTINUOUS' },
{ name: '标注', color: 2, lineType: 'CONTINUOUS' },
{ name: '中心线', color: 1, lineType: 'CENTER' },
{ name: '参考底图', color: 8, lineType: 'CONTINUOUS', isLocked: true },
];
for (const def of layerDefs) {
Engine.createLayer(def.name, {
color: def.color,
lineType: def.lineType,
isLocked: def.isLocked || false
});
}
}
// 显示所有图层
static showAll() {
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.layerOn = true;
layer.isFrozen = false;
});
Engine.regen(true);
}
// 关闭其他图层(除当前图层)
static hideOthers() {
const currentLayerName = Engine.getCurrentLayer();
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.layerOn = layer.name === currentLayerName;
});
Engine.regen(true);
}
// 锁定所有图层(除当前图层)
static lockOthers() {
const currentLayerName = Engine.getCurrentLayer();
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.isLocked = layer.name !== currentLayerName;
});
}
// 解锁所有图层
static unlockAll() {
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.isLocked = false;
});
}
// 冻结所有图层(除当前图层和 0 图层)
static freezeOthers() {
const currentLayerName = Engine.getCurrentLayer();
const layers = Engine.getLayers();
layers.forEach(layer => {
// 0 图层和当前图层不能冻结
if (layer.name !== '0' && layer.name !== currentLayerName) {
layer.isFrozen = true;
}
});
Engine.regen(true);
}
// 解冻所有图层
static thawAll() {
const layers = Engine.getLayers();
layers.forEach(layer => {
layer.isFrozen = false;
});
Engine.regen(true);
}
// 获取图层统计
static getStatistics(): Map<string, number> {
const stats = new Map<string, number>();
const entities = Engine.currentSpace.aliveItems;
for (const ent of entities) {
const layer = Engine.currentDoc.layers.itemById(ent.layerId);
const layerName = layer?.name || '未知';
stats.set(layerName, (stats.get(layerName) || 0) + 1);
}
return stats;
}
}
// 使用
LayerManager.createStandardLayers();
Engine.setCurrentLayer('墙体');
// 查看统计
const stats = LayerManager.getStatistics();
for (const [name, count] of stats) {
console.log(`${name}: ${count} 个实体`);
}ACI 颜色索引
常用颜色索引值:
| 索引 | 颜色 |
|---|---|
| 1 | 红色 |
| 2 | 黄色 |
| 3 | 绿色 |
| 4 | 青色 |
| 5 | 蓝色 |
| 6 | 洋红 |
| 7 | 白色/黑色 |
| 8 | 灰色 |
| 256 | ByLayer |
| 0 | ByBlock |
在线示例
以下示例可在 Playground 中运行:
| 示例 | 说明 |
|---|---|
layer/01create.js | 创建图层 |
layer/02switch.js | 切换当前图层 |
layer/03visibility.js | 图层可见性 (layerOn) |
layer/04getlayers.js | 获取图层列表 |
layer/05getentitiesbylayer.js | 按图层获取实体 |
layer/06frozen.js | 冻结图层 (isFrozen) |
layer/07locked.js | 锁定图层 (isLocked) |
layer/08states.js | 图层状态综合对比 |