ObjectARX2016-2创建直线

众所周知,数据库里面包含各种数据表,而数据表里面又是各种记录,当然还有字段。AUTOCAD里面对于图形的管理也是基于图形数据库的。因此,想要在DWG里面添加一条直线,只需要做三件事:

(1)打开数据表

(2)把直线放进去

(3)关闭数据表

听起来跟把大象关进冰箱里面差不多哈。。。。

图形数据库里面有存放图形的块表,存放图层的表,还有其他的以后会用上的表。因此第一步我们需要打开数据库,打开块表。

acdbHostApplicationServices()->workingDatabase();

这一行代码可以获取到当前图形数据库。刚开始我学习的时候很不理解,为何这个函数的开头是小写,其他的很多都是大写的为啥不一样?为什么不统一起来?然后我鼠标选中

acdbHostApplicationServices 按下F12,VS跳转到了dbapserv.h,定位到了
AcDbHostApplicationServices * acdbHostApplicationServices();

这一行,原来这个acdbHostApplicationServices是 AcDbHostApplicationServices的一个对象,这个对象是在头文件里面声明着的。打开ObjectARX的根目录,找到docs文件夹,打开arxref.chm文件,查找AcDbHostApplicationServices,基于AcRXObject,描述如下:

 

 

 我的英语也不太好,大概就是这个类提供了对于CAD运行时的各种各样的服务。因此在我们调用acdbHostApplicationServices() 的时候,其实就是调用了这个类的构造函数,返回了一个AcDbHostApplicationServices的对象,这个类里面提供了一个workingDatabase()方法,可以返回当前窗口的图形数据库指针。到现在为止我们已经可以得到图形数据库了,即

acdbHostApplicationServices()->workingDatabase();

 

找到了图形数据库之后我们就要打开图形数据库的块表。查找AcDbDatabase,这个类提供了getBlockTable()函数,函数原型:

Acad::ErrorStatus getBlockTable(
    AcDbBlockTable*& pTable, 
    AcDb::OpenMode mode
);

函数返回错误类型,有两个参数,一个是块表指针,另一个是打开模式。头文件里面找到了这个打开模式的定义:

const AcDb::OpenMode kForRead = AcDb::kForRead;
const AcDb::OpenMode kForWrite = AcDb::kForWrite;
const AcDb::OpenMode kForNotify = AcDb::kForNotify;

这个应该很好理解了,读、写、通知。这个通知我也是初学者,也不太清楚,暂且不表。

因此,我们定义一个块表指针,将引用传过去。

//获取块表
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,kForRead);

获取了块表以后,就要添加一条记录,所以我们要先获取记录再添加。AcDbBlockTable块表类提供了getAt()函数,原型如下:

Acad::ErrorStatus getAt(
    const ACHAR* entryName, 
    AcDbBlockTableRecord*& pRec, 
    AcDb::OpenMode openMode, 
    bool openErasedRec = false
) const;

第一个参数暂且用ACDB_MODEL_SPACE,第二个参数是块表记录指针,保存我们打开的块表记录。第三个参数是打开模式,这次要写,使用

kForWrite

第四个暂且用不上,使用默认参数。

//获取块表记录
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,kForWrite);

打开块表记录之后就可以往记录里面追加记录了。

AcDbBlockTableRecord块表记录类提供了appendAcDbEntity()函数,原型如下:

Acad::ErrorStatus appendAcDbEntity(
    AcDbEntity* pEntity
);

因此,我们要创建我们的直线。

AcDbLine(
    const AcGePoint3d& start, 
    const AcGePoint3d& end
);

创建直线需要两个AcGePoint3d类型的点。因此我们定义两个点。注意,在objectarx里面创建的写入到图形数据库的图形一定要在堆区创建,也就是必须使用new创建,不能在栈区创建,这点张帆的书上面没有具体解释为什么,我猜测是arx的机制是函数调用,后续还可能会使用,但是如果arx结束了或者卸载了就会出现问题。

所有new出来的图形数据都必须在不使用的时候close(),但是不能delete

贴一下整个方法的代码,其实代码也就是张帆的书里面的代码:

static void LZGMyGroupMyCommand () {
        // Put your command code here
        AcGePoint3d ptStart(0,0,0);
        AcGePoint3d ptEnd(100,100,0);
        AcDbLine *pLine = new AcDbLine(ptStart,ptEnd);
        //获取块表
        AcDbBlockTable *pBlockTable;
        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,kForRead);
        //获取块表记录
        AcDbBlockTableRecord *pBlockTableRecord;
        pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,kForWrite);
        //将线添加到块表记录中
        AcDbObjectId lineID;
        pBlockTableRecord->appendAcDbEntity(lineID,pLine);
        pBlockTableRecord->close();
        pBlockTable->close();
        pLine->close();
    }

然后将生成的arx文件推拽进cad2016里面,输入

MyCommand

就可以看到原点处出现了一条直线。

总结一下流程:打开图形数据库>打开块表>打开块表记录>块表记录追加图形>关闭所有的图形

其他的所有的内容都是为了实现以上的几个步骤。

 参考文献:张帆  objectarx

posted on 2021-02-05 12:02  路人甲也码  阅读(314)  评论(0编辑  收藏  举报