admin 发表于 2024-5-2 22:30:35

ObjectArx 选择实体创建块参照

问题:
想要把多个CAD实体整体调整比例,可以用来对齐调整。

思路:
将要调整的多个实体整体做成一个 块参照 ,然后设置块参照的属性即可实现多个实体整体调整。
(这里仅以选择一个实体并添加至新创建的块参照中为例。)

解决:
1、选择实体
AcDbObjectId SelectEnt()
{
        ads采用name ent;
        ads采用point pt;
        AcDbObjectId entId = AcDbObjectId::kNull;
        int ret = RTNORM;
        ret = acedEntSel(采用T("\nSelect Entity: "), ent, pt);
        if (RTNORM != ret)
                return entId;

        acdbGetObjectId(entId, ent);
        return entId;
}

2、获取指定块表,没有则创建

AcDbObjectId GetBlkId(const CString& sBlkName, bool bCreate)
{
        AcDbObjectId idBlk = AcDbObjectId::kNull;

        // 获取指定块表ID 没有则添加
        AcDbBlockTablePointer pTable(acdbCurDwg(), AcDb::kForRead);
        if (pTable.openStatus() != Acad::eOk)
                return idBlk;
       
        if (pTable->has(sBlkName))// 有指定块表直接获取ID
        {
                pTable->getAt(sBlkName, idBlk);
        }
        else if(bCreate)// 没有指定块表 且允许创建 则创建指定块表
        {
                AcDbBlockTableRecord* pRecord = new AcDbBlockTableRecord();
                pRecord->setName(sBlkName);
                if (pTable->add(idBlk, pRecord) == Acad::eOk)
                        pRecord->close();
                else
                        delete pRecord;
        }
        return idBlk;
}



3、将选择实体添加至新创建的块参照中,并设置属性

void testCreateBlock()
{
        // 选择实体创建块参照
        AcDbObjectId entId = SelectEnt();
        if (entId.isNull())
        {
                acutPrintf(采用T("选择实体失败"));
                return;
        }

        //获取指定块表Id
        AcDbObjectId idRec = GetBlkId(采用BLOCK采用Test采用, true);
        if (idRec.isNull())
        {
                acutPrintf(采用T("获取%s块表Id失败"), 采用BLOCK采用Test采用);
                return;
        }

        AcDbEntityPointer pEnt(entId, AcDb::kForRead);
        if (pEnt.openStatus() != Acad::eOk)
        {
                acutPrintf(采用T("打开实体失败"));
                return;
        }

        //打开新的块表记录 添加实体至新块表中
        AcDbBlockTableRecordPointer pBlkNew(idRec, AcDb::kForWrite);
        if (pBlkNew.openStatus() != Acad::eOk)
                return;
        pBlkNew->appendAcDbEntity(pEnt);

        // 打开当前块表
        AcDbBlockTablePointer pBlkTable(acdbCurDwg(), AcDb::kForRead);
        if (pBlkTable.openStatus() != Acad::eOk)
                return;

        AcGePoint3d ptInsert = AcGePoint3d::kOrigin;
        // 创建块参照
        AcDbObjectPointer<AcDbBlockReference> pBlkRef;
        if (pBlkRef.create() != Acad::eOk)
                return;

        pBlkRef->setDatabaseDefaults();
        pBlkRef->setPosition(ptInsert);
        pBlkRef->setBlockTableRecord(idRec);
       
        // 缩放块 两种方法:
        // 1、通过缩放比例缩放
        pBlkRef->setScaleFactors(1);//缩放比例
        // 2、通过缩放矩阵缩放
        AcGeMatrix3d scaleMat;
        scaleMat.setToScaling(3, ptInsert);
        pBlkRef->transformBy(scaleMat);
       
        // 旋转块 两种方法
        // 1、通过旋转角度旋转
        pBlkRef->setRotation(0);//旋转角度
        // 2、通过旋转矩阵旋转
        AcGeMatrix3d rotateMat;
        rotateMat.setToRotation(3.1415926 * 0.5, AcGeVector3d::kZAxis, ptInsert);
        pBlkRef->transformBy(rotateMat);

        // 打开当前空间的块表记录
        AcDbBlockTableRecordPointer pBlkRcd(curDoc()->database()->currentSpaceId(), AcDb::kForWrite);
        if (pBlkRcd.openStatus() != Acad::eOk)
                return;

        // 添加块参照到数据库
        pBlkRcd->appendAcDbEntity(pBlkRef);
       
        return;
}


页: [1]
查看完整版本: ObjectArx 选择实体创建块参照