HarmonyOS鸿蒙Next在线CAD(html预览cad插件)二次开发块表

HarmonyOS鸿蒙Next在线CAD(html预览cad插件)二次开发块表

前言

在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);
}

示例效果如下图:

cke_130.png

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_ModifyBlockRecordEntity(blkRec)
}
function Mx_ModifyBlockRecordEntity(blkRec: McDbBlockTableRecord) {
    // 获取图块中所有实体Id
    blkRec.getAllEntityId().forEach(id => {
        let ent = id.getMcDbEntity();
        // 若实体为图块,则递归遍历
        if (ent instanceof McDbBlockReference) {
            let blkref = ent as McDbBlockReference; 
            Mx_ModifyBlockRecordEntity(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();
    });
}

示例效果如下:

cke_131.png cke_132.png

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);
}

示例效果如下:

cke_133.png

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;
})

示例效果如下:

cke_134.png

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梦想画图


更多关于HarmonyOS鸿蒙Next在线CAD(html预览cad插件)二次开发块表的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

HarmonyOS鸿蒙Next在线CAD(HTML预览CAD插件)二次开发块表涉及的技术主要包括鸿蒙系统的分布式能力和Web组件的集成。鸿蒙系统支持分布式任务调度、分布式数据管理和分布式硬件能力,这些特性可以用于实现跨设备的CAD预览和编辑功能。通过鸿蒙的Web组件,可以在应用中嵌入HTML页面,进而集成在线CAD插件。二次开发块表的实现通常依赖于鸿蒙的JS API和Native API,开发者可以通过这些API与CAD插件进行交互,实现数据传递、状态管理和用户操作响应。鸿蒙系统的ArkUI框架也支持声明式UI开发,可以用于构建块表的用户界面。

更多关于HarmonyOS鸿蒙Next在线CAD(html预览cad插件)二次开发块表的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,进行在线CAD(HTML预览CAD插件)的二次开发,特别是块表(Block Table)的处理,可以按照以下步骤进行:

  1. 环境搭建:确保开发环境已安装HarmonyOS SDK,并配置好相关开发工具。

  2. 插件集成:将HTML预览CAD插件集成到HarmonyOS应用中,确保插件能够正常加载和显示CAD文件。

  3. 块表处理:通过插件的API或SDK,访问和操作CAD文件中的块表。块表通常包含块定义和块引用,可以通过API获取块表信息,进行增删改查等操作。

  4. 数据交互:实现HarmonyOS应用与CAD插件之间的数据交互,确保块表数据能够实时更新和同步。

  5. 测试与优化:进行功能测试,确保块表操作的正确性和性能优化。

通过这些步骤,可以在HarmonyOS鸿蒙Next中实现高效的在线CAD块表二次开发。

回到顶部