前言
在DWG数据库中,所有图块都存放在块表McDbBlockTable()中,块表中每一条记录称为图块记录对象McDbBlockTableRecord(),图块记录中存放着所有实体数据,用户可以通过改变图块的属性设置来修改其对应着的实体数据。
块表操作
1. 获取当前控件的数据库块表
我们可以通过调用 mxcad 中的MxCpp.getCurrentMxCAD()得到当前的控件, 然后调用控件实例的getDatabase()方法得到数据库实例McDbDatabase() ,在该数据库实例中调用getBlockTable()方法我们就能获取到块表McDbBlockTable()。
查看详细属性和方法说明,参考代码如下:
import { MxCpp} from "mxcad" // 得到当前控件 let mxcad = MxCpp.App.getCurrentMxCAD(); // 获取块表 let blockTable = mxcad.getDatabase().getBlockTable();
2. 插入图块
我们可以调用 mxcad 的实例对象中的insertBlock()方法引入插件图块文件得到引用的图块 ID ,最后通过McDbBlockReference()实例化一个 CAD 图块引用实体,设置该实体的blockTableRecordId属性值为引用的图块 ID ,就能实现在图纸中插入目标块。
点击 [McObject.insertBlock()]、[McDbBlockReference()]查看详细属性和方法说明,参考代码如下:
import { MxCpp, McDbBlockReference, MxCADUiPrPoint } from "mxcad" async function MxTest\_InsertBlock(){ // 目标块文件网络文件路径 且该文件为mxweb格式 let blkFilePath = new URL("../src/assets/tree.mxweb", import.meta.url).href let mxcad = MxCpp.getCurrentMxCAD() let blkrecId = await mxcad.insertBlock(blkFilePath, "tree") if (!blkrecId.isValid()) return; let blkRef = new McDbBlockReference(); blkRef.blockTableRecordId = blkrecId; // 设置块大小 let box = blkRef.getBoundingBox(); if (box.ret) { let dLen = box.maxPt.distanceTo(box.minPt); if (dLen > 0.00001) { blkRef.setScale(mxcad.getMxDrawObject().screenCoordLong2Doc(100) / dLen); } } // 设置块基点 let getPoint = new MxCADUiPrPoint(); getPoint.setMessage("\指定插入基点"); getPoint.setUserDraw((v, worldDraw) => { blkRef.position = v; worldDraw\.drawMcDbEntity(blkRef); }); let pt = await getPoint.go(); if (!pt) return; blkRef.position = pt; mxcad.drawEntity(blkRef); }
示例效果如下图:
3. 遍历所有图块
我们可以通过调用块表McDbBlockTable()中的 getAllRecordId()方法获取所有图块的id,再调用getMcDbBlockTableRecord()方法返回图块记录对象McDbBlockTableRecord() ,得到所有图块记录对象数据,参考代码如下:
import { MxCpp } from "mxcad" let mxcad = MxCpp.App.getCurrentMxCAD(); let blockTable = mxcad.getDatabase().getBlockTable(); let aryId = blockTable.getAllRecordId(); aryId.forEach((id) => { let blkRec = id.getMcDbBlockTableRecord(); if (blkRec === null) return; console.log(blkRec); console.log("blkRec.name:" + blkRec.name); console.log("blkRec.origin:" + blkRec.origin); });
4. 删除图块
我们得到图块记录对象McDbBlockTableRecord()后可调用该对象实例的erase()方法删除对象,参考代码如下:
import { MxCpp } from "mxcad" let blockTable = MxCpp.getCurrentMxCAD().getDatabase().getBlockTable() let blockId = blockTable.get("目标图块名") blockId.erase() // 更新显示 mxcad.updateDisplay()
5. 查找图块
我们可以调用McDbBlockTable块表中的has()方法判断当前数据库中,是否存在指定的块名,参考代码如下:
import { MxCpp } from "mxcad"; const mxcad = MxCpp.getCurrentMxCAD(); const dataBase = mxcad.getDatabase(); const blkTable = dataBase.getBlockTable(); const res = blkTable.has("目标块名"); if(res){ console.log("存在目标块") }
6. 遍历图块下的所有实体
由于图块中的实体可能是另外的一个图块,因此,在遍历图块下所有实体时我们还需要遍历图块中的图块。下面以选择目标图块输出图块中所有实体的id和对象类型为例,参考代码如下:
import { MxCADResbuf, MxCADUiPrEntity , McDbBlockReference, McDbBlockTableRecord} from "mxcad"; // 遍历图块下所有实体 async function Mx\_ForEachBlkEntity(){ // 选择目标块 let filter = new MxCADResbuf(); filter.AddMcDbEntityTypes("INSERT"); const getBlockEvent = new MxCADUiPrEntity() getBlockEvent.setMessage('选择目标块'); getBlockEvent.setFilter(filter); const block\_id = await getBlockEvent.go(); if (!block\_id.id) return; // 获取块实体 const blkRef = block\_id.getMcDbEntity() as McDbBlockReference; // 获取块表记录对象 let blkRec = blkRef.blockTableRecordId.getMcDbBlockTableRecord(); // 遍历图块实体 Mx\_ModyfBlockRecordEntity(blkRec) } function Mx\_ModyfBlockRecordEntity(blkRec: McDbBlockTableRecord) { // 获取图块中所有实体Id blkRec.getAllEntityId().forEach(id => { let ent = id.getMcDbEntity(); // 若实体为图块,则递归遍历 if (ent instanceof McDbBlockReference) { let blkref = ent as McDbBlockReference; Mx\_ModyfBlockRecordEntity(blkref.blockTableRecordId.getMcDbBlockTableRecord()); }else{ // 输出实体id、实体类名 console.log(id.id,ent.objectName); } }) }
7. 选择实体做成块
我们可以通过MxCADSelectionSet选择集获取目标实体,再新建McDbBlockTableRecord块表记录对象,将选择的实体对象通过appendAcDbEntity()方法写入记录对象中,最后设置图块的基点、位置等,参考代码如下:
import { MxCADSelectionSet, MxCpp, McDbBlockTableRecord, McGePoint3d } from "mxcad"; // 选择实体做成块 async function MxTest\_SelectEntitysToBlock() { // 选择要做成块的对象 let ss = new MxCADSelectionSet(); if(!await ss.userSelect("选择要做成块的对象:") ) return; if(ss.count() == 0) return; let mxcad = MxCpp.getCurrentMxCAD(); // 获取数据库块表 let blkTable = mxcad.getDatabase().getBlockTable(); // 创建新的块表记录对象 let blkRecId = blkTable.add(new McDbBlockTableRecord()); let blkTableRecord:McDbBlockTableRecord = blkRecId.getMcDbBlockTableRecord() as any; if(blkTableRecord == null) return; // 定义新建图块的包围盒最大点和最小点 let pt1x:any,pt1y:any,pt2x:any,pt2y:any; // 遍历选择的实体获取新建图块的包围盒最大点和最小点 ss.forEach((id)=>{ let ent = id.getMcDbEntity(); if(!ent) return; let cent = ent.clone() as McDbEntity; blkTableRecord.appendAcDbEntity(cent); let entBox = ent.getBoundingBox(); if(entBox.ret){ if(!pt1x){ pt1x = entBox.minPt.x; pt1y = entBox.minPt.y; pt2x = entBox.maxPt.x; pt2y = entBox.maxPt.y; } else { if(pt1x > entBox.minPt.x) pt1x= entBox.minPt.x; if(pt1y > entBox.minPt.y) pt1y= entBox.minPt.y; if(pt2x < entBox.maxPt.x) pt2x= entBox.maxPt.x; if(pt2y < entBox.maxPt.y) pt2y= entBox.maxPt.y; } } }) if(pt1x === undefined){ return; } let insertPtx = pt1x + (pt2x - pt1x) \* 0.5; let insertPty = pt1y + (pt2y - pt1y) \* 0.5; // 设置图块的插入基点,在图形对象的中心位置。 blkTableRecord.origin = new McGePoint3d(insertPtx,insertPty,0); // 设置图块位置 let blkRef = new McDbBlockReference(); blkRef.blockTableRecordId = blkRecId; blkRef.position = new McGePoint3d(insertPtx,insertPty,0); // 绘制图块 mxcad.drawEntity(blkRef); // 删除原实体 ss.forEach((id)=>{ let ent = id.getMcDbEntity(); if(!ent) return; ent.erase(); }); }
示例效果如下:
8. 把一个DWG文件插入到当前文件
我们可以调用 mxcad 对象的insertBlock()方法把一个DWG文件,插入到图上,指定一个块名,放在块表记录中,下面以在文件中插入一个图章为例,点击[McObject.insertBlock()]查看详细属性和方法说明,参考代码如下:
import { MxCpp, McDbBlockReference, MxCADUiPrPoint } from "mxcad"; // 插入图章 async function MxTest\_InsertStamp() { // 设置块文件地址 let baseUrl = "<http://localhost:3000/mxcad/>" if (baseUrl.substring(0, 16) == "<http://localhost>") { baseUrl = getHostUrl() + baseUrl.substring(16); } let blkFilePath = baseUrl + "stamp.mxweb"; let mxcad = MxCpp.App.getCurrentMxCAD(); // 插件图块文件 let blkrecId = await mxcad.insertBlock(blkFilePath, "stamp"); if (!blkrecId.isValid()) { // 未插入图块 return; } // 创建一个新的图块引用实体 let blkRef = new McDbBlockReference(); // 设置图块引用实体的图块记录id为blkrecId blkRef.blockTableRecordId = blkrecId; // 适应图块大小 let box = blkRef.getBoundingBox(); if (box.ret) { let dLen = box.maxPt.distanceTo(box.minPt); if (dLen > 0.00001) { blkRef.setScale(mxcad.getMxDrawObject().screenCoordLong2Doc(100) / dLen); } } // 设置图块基点 let getPoint = new MxCADUiPrPoint(); getPoint.setMessage("\指定插入基点"); // 动态绘制图块 getPoint.setUserDraw((v, worldDraw) => { blkRef.position = v; worldDraw\.drawMcDbEntity(blkRef); }); // 设置图块位置 let pt = await getPoint.go(); if (!pt) return; blkRef.position = pt; // 绘制图块实体 mxcad.drawEntity(blkRef); }
示例效果如下:
9. 块属性
在AutoCAD中,块属性是将数据附着到块上的标签或标记。我们可以通过新创建一个块引用中的属性定义文字类McDbAttribute来为目标图块添加属性文字。下面以插入一个带有属性文字的图块为例,点击[McDbAttribute]查看详细属性和方法说明,参考代码如下:
// 在块中插入属性文字 ent:块实体 let blkRef: McDbBlockReference = ent; const blkrecId = blkRef.blockTableRecordId // 获取图块记录对象 let blkRecord: any = blkrecId.getMcDbBlockTableRecord(); // 获取图块记录中的所有实体对象ID let ids = blkRecord.getAllEntityId(); // 遍历实体类型,添加属性文字 ids.forEach((id: any, index: any) => { if (!id.isKindOf("McDbAttributeDefinition")) return; let attribDef = id.getMcDbEntity() as McDbAttributeDefinition; let tag = attribDef.tag; // 设置属性详情 let attrib = new McDbAttribute(); attrib.position = attribDef.position; attrib.alignmentPoint = attribDef.alignmentPoint; attrib.height = attribDef.height; attrib.trueColor = attribDef.trueColor; attrib.widthFactor = attribDef.widthFactor; attrib.textString = "test" + index; attrib.tag = tag; attrib.isInvisible = attribDef.isInvisible; attrib.transformBy(blkRef.blockTransform); attrib = blkRef.appendAttribute(attrib).getMcDbEntity() as McDbAttribute; attrib.textStyle = attribDef.textStyle; attrib.layer = attribDef.layer; })
示例效果如下:
10. 遍历块中的属性文字
我们可以调用图块引用实体McDbBlockReference对象中的getAllAttribute()方法获取图块中的所有属性文字,点击[getAllAttribute()]查看详细属性和方法说明,参考代码如下:
import { McDbBlockReference, McDbAttribute } from "mxcad" // 遍历块中的属性文字 ent:块实体 let blkRef: McDbBlockReference = ent; let aryId = blkRef.getAllAttribute(); aryId.forEach((id) => { let attribt: McDbAttribute = id.getMcDbEntity() as any; console.log(attribt.textString); console.log(attribt.tag); })
在线示例
示例项目地址: [在线CAD梦想画图]
标签:插件,blkRef,实体,图块,mxcad,let,二次开发,id,CAD From: https://www.cnblogs.com/yzy0224/p/18245274