- 积分
- 6498
- 明经币
- 个
- 注册时间
- 2018-1-17
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 MxDraw 于 2024-7-17 19:17 编辑
前言
在DWG数据库中,所有图块都存放在块表McDbBlockTable()中,块表中每一条记录称为图块记录对象McDbBlockTableRecord()。图块记录中存放着所有实体数据,用户可以通过改变图块的属性设置来修改其对应着的实体数据。
块表操作
1. 获取当前控件的数据库块表
我们可以通过调用 mxcad 中的 `MxCpp.getCurrentMxCAD()`得到当前的控件, 然后调用控件实例的getDatabase()方法得到数据库实例McDbDatabase() ,在该数据库实例中调用 getBlockTable()方法我们就能获取到块表 McDbBlockTable() 。
点击[块表 McDbBlockTable()]、[图块记录对象 McDbLinetypeTableRecord()]、[数据库实例 McDbDatabase()]查看详细属性和方法说明,参考代码如下:
- 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梦想画图]
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|