Skip to content
On this page

实体

图纸所有对象都是从类 McDbObject 继承,该类提供得到对象句柄、ID、对象类型信息等函数。图上可见的对象是从类 McDbEntity 继承,该类提供可见实体的通用属性操作,如线型,图层,文字样式,颜色等函数。

点击 数据库对象 McDbObject实体对象 McDbEntity 查看详细属性和方法说明。

实体ID和句柄

ID和句柄都用来标识一个对象,ID是一个64位长整型变量,是一个内存地址,访问速度最快,但它每次打开都不一样,如果需要把一个对象的标识存起来,下次又能找到对象,就需要使用句柄,句柄是一个字符串变量,它保证不管什么时候总是不会变化,句柄在DWG图纸中是唯一存在,ID是内存中唯一存在。

我们可以通过 McDbObject 类中提供的 getHandle() 方法获得对象句柄,通过 getObjectID() 方法获得对象ID。

点击 McDbObject.getHandle()McDbObject.getObjectID() 查看详细属性和方法说明。

ts
// 选择一个目标对象
const getEnt = new MxCADUiPrEntity();
getEnt.setMessage('选择目标对象');
const entVal = await getEnt.go();
if (!entVal.id) return;
// 获取该对象的实体
const ent = entVal.getMcDbEntity();
if(!ent) return;
// 获取对象ID
const entId = ent.getObjectID();
// 获取对象句柄
const sHandle = ent.getHandle();
console.log("对象id", entId);
console.log("对象句柄", sHandle);

实体的类型信息

我们可以通过调用 McDbObject 类中提供的 objectName 属性得到对象的类型名,有了类型名就能判断实体具体是一个什么对象,再调用 dxf0 属性,得到对象的DXF组码的类型名,这个和AutoCAD中的DXF组码是一样,比如直线的类型名为:McDbLine,DXF0组码值: LINE,DXF0组码值可以用来构造集时的类型过滤。

点击 McDbObject.objectNameMcDbObject.dxf0 查看详细属性和方法说明。

ts
// 让用户在图上选择一个对象。
const getEnt = new MxCADUiPrEntity();
getEnt.setMessage('选择目标对象');
const entVal = await getEnt.go();
if (!entVal.id) return;
// 获取对象实体
const ent = entVal.getMcDbEntity();
// 得到Dxf0的值。
const sDxfType = ent?.dxf0;
console.log("Dxf0值", sDxfType)
if (ent?.objectName == "McDbLine"){
    // ent是一个直线
    const line = ent as McDbLine;
    // 得到直线开始点
    const pt1 = line.startPoint;
    // 得到直线结束点
    const pt2 = line.endPoint;
    console.log(pt1, pt2);
}else if(ent?.objectName == "..."){
    // 其他类型
}

可见实体属性

图上可见实体 McDbEntity 的主要属性,有线型,图层,文字样式,颜色,是否可见,显示顺序等。我们可以提取,和修改这些属性。

  1. 设置实体是否可见
ts
// 隐藏实体
ent.visible = false;
  1. 修改对象颜色
ts
// 选择目标对象
let getEntity = new MxCADUiPrEntity();
getEntity.setMessage("选择目标对象");
let id = await getEntity.go();
if (!id.isValid()) return;

let ent = id.getMcDbEntity();
if (!ent) return;
// 修改对象颜色
ent.trueColor = new McCmColor(255, 0, 255);
  1. 修改显示顺序

在用户绘图时,在默认情况下,重叠对象(例如文字、宽多段线和实体填充多边形)通常按其创建次序显示:新创建的对象显示在现有对象前面。本实例演示了如何控制显示顺序,具体实现代码如下:

ts
let ss = new MxCADSelectionSet();
if (!await ss.userSelect("\n选择对象")) return;
//得到当前图上对象的最大,最小显示顺序.
let minmaxOrder = MxCpp.getCurrentDatabase().currentSpace.getMinMaxDrawOrder();
// 把对象放到最上面。
let lOrder = minmaxOrder.maxDrawOrder + 1;
ss.forEach((id) => {
let ent = id.getMcDbEntity();
if (ent) {
    ent.drawOrder = lOrder;
}
})

扩展数据

用户可给图纸上的对象设置扩展数据,这些扩展数据可以是用户实际需求的专业数据,扩展数据支持字符串、double、int等类型。每个扩展数据都一个扩展数据名称,每个名称下也可能有多个扩展数据,一个实体可以有多个扩展数据名称,这些扩展数据在内存中是一个链表 MxCADResbuf 来存放的,每个链结代表一个数据,每个链结中字符串数据长度不超过200(由DWG图纸格式确定)。

点击 链表 MxCADResbuf 查看详细属性和方法说明。

ts
// 让用户在图上选择一个对象。
const getEnt = new MxCADUiPrEntity();
getEnt.setMessage('选择目标对象');
const entVal = await getEnt.go();
if (!entVal.id) return;
// 获取对象实体
const ent = entVal.getMcDbEntity();
if(!ent) return;
const xData = new MxCADResbuf();
// 设置扩展数据名称 TestApp
xData.AddString("TestApp",1001);
// 设置字符串数据,DXF组码是1000;
xData.AddString("string data", 1000);
// 设置一个 Long数据,DXF组码是1071
xData.AddLong(77677, 1071);
// 把准备好的数据,写到实体上。
ent.setxData(xData);

编辑实体

我们提供了复制、平移、缩放、变换、镜向、旋转等编辑实体的函数。下面以对实体进行复制平移为例,更多的编辑函数请参考 McDbEntity

  1. 复制平移
ts
import { MxCpp, MxCADUiPrEntity, MxCADUiPrPoint, McGeMatrix3d} from "mxcad";
// 复制平移 
export async function test_copyMove() {
    // 获取画布实例
    const mxcad = MxCpp.App.getCurrentMxCAD();
    let copyObj = new MxCADUiPrEntity();//选择复制对象
    copyObj.setMessage('请选择需要复制的对象')
    let copyObj_id = await copyObj.go();
    if (copyObj_id === null) return;
    let copyEvent: any = await copyObj_id.getMcDbEntity()//复制的实例对象
    if (!copyEvent) return;
    let getFristPoint = new MxCADUiPrPoint();
    getFristPoint.setMessage('请设定复制基点')
    let fristPoint: any = await getFristPoint.go();//基点
    if (!fristPoint) return;
    let getNextPoint = new MxCADUiPrPoint();
    getNextPoint.setMessage('请设置移动长度和方向');
    // 动态绘制
    getNextPoint.setUserDraw((pt, pw) => {
        let evrnt_clone = copyEvent.clone();// 复制实体
        let matrix = new McGeMatrix3d();// 创建一个矩阵
        matrix.setToTranslation(pt.sub(fristPoint));//设置移动矩阵
        evrnt_clone.transformBy(matrix);// 变换实体
        pw.drawMcDbEntity(evrnt_clone);// 动态绘制平移后的实体
        let pl = new McDbPolyline();// 创建多段线对象
        pl.addVertexAt(fristPoint);
        pl.addVertexAt(pt);
        pw.drawMcDbEntity(pl);// 绘制平移路径
    });
    let nextPoint = await getNextPoint.go();
    if (!nextPoint) return;
    // 平移变换
    let matrix = new McGeMatrix3d();// 创建一个矩阵
    let evrnt_clone = copyEvent.clone();
    matrix.clone();
    matrix.setToTranslation(nextPoint.sub(fristPoint));//设置移动矩阵
    evrnt_clone.transformBy(matrix);// 变换实体
    mxcad.drawEntity(evrnt_clone);// 绘制平移后的实体
}

删除实体

我们可以直接通过实体对象或实体对象id调用 McDbEntity 类中的erase() 方法删除实体。

点击McDbEntity.erase() 查看详细属性和方法说明。

ts
// 选择目标对象
let getEntity = new MxCADUiPrEntity();
getEntity.setMessage("选择目标对象");
let id = await getEntity.go();
if (!id.isValid()) return;
id.erase();
ts
// 选择目标对象
let getEntity = new MxCADUiPrEntity();
getEntity.setMessage("选择目标对象");
let id = await getEntity.go();
if (!id.isValid()) return;
// 获取对象实体
const ent = id.getMcDbEntity();
ent.erase();

得到实体坐标

不同的实体它的坐标属性不一样,比如直线就是开始点,和结束点属性,圆的就是中心点坐标和半径属性。所以要得实体的坐标,需要判断对象类型,然后再转换成具体的对象,再读取它的坐标。我们可以通过调用 McDbEntity 类中的 getBoundingBox() 方法得到对象最小外包矩形框坐标。

点击 McDbEntity.getBoundingBox() 查看详细属性和方法说明。

ts
// 让用户在图上选择一个对象。
const getEnt = new MxCADUiPrEntity();
getEnt.setMessage('选择目标对象');
const entVal = await getEnt.go();
if (!entVal.id) return;
// 获取对象实体
const ent = entVal.getMcDbEntity();
if(!ent) return;
// 得到实体的包围盒
const {ret, minPt, maxPt} = ent.getBoundingBox();
if(ret){
    // 将显示范围设置为该包围盒的大小
    MxCpp.getCurrentMxCAD().zoomW(minPt, maxPt);
}