ObjectARX--自定义圆的实现

转载:ObjectArx 自定义实体_iMatt的博客-CSDN博客_objectarx 自定义实体

 效果如下:

重点:

1.实现三个重载函数

(一)//利用图纸初始化数据成员(反序列化)
 virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
(二)//将当前数据成员写入图纸(序列化)
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;

(三) //更新绘制模型

 virtual Adesk::Boolean      subWorldDraw(AcGiWorldDraw* mode);

2:重点函数讲解

1.subWorldDraw 这个函数主要是用来实时绘制圆函数

2.dwgInFields和dwgOutFields这两个函数主要是为了保存变化的数据,类似数据库,将数据写入数据库和读取数据库获取数据。

3.  subMoveGripPointsAt这个函数是当拖动构件进行操作的时候就会响应这个函数。

总体代码如下:

CCustomColorCircle.h

#pragma once
#include "StdAfx.h"
#include "acadstrc.h"
#include "geassign.h"

class CCustomColorCircle:public AcDbEntity
{
public:
    ACRX_DECLARE_MEMBERS(CCustomColorCircle);
    CCustomColorCircle();
    CCustomColorCircle(AcGePoint3d centerPt, double m_radius);
    ~CCustomColorCircle();
protected:
    //利用图纸初始化数据成员(反序列化)
    virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
    //将当前数据成员写入图纸(序列化)
    virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
    //利用初始化数据成员(反序列化)CAD数据交换的CAD数据文件格式
    virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);
    //将当前数据成员写入(序列化) CAD数据交换的CAD数据文件格式
    virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;
    //更新绘制模型
    virtual Adesk::Boolean      subWorldDraw(AcGiWorldDraw* mode);
    //获得一个实体的范围
    virtual Acad::ErrorStatus   subGetGeomExtents(AcDbExtents& extents) const;
   //选中一下cad提供的实体,将特征点显示出来
    virtual Acad::ErrorStatus   subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const;
    //用户拖拽特征点的时候,实体应该进行变化
    virtual Acad::ErrorStatus   subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset);
public:
    //setColorIndex设置颜色
    virtual Acad::ErrorStatus   setColorIndex(Adesk::UInt16 color, Adesk::Boolean doSubents = true);
private:
    //圆心
    AcGePoint3d m_CenterPoint;
    double m_radius;
};

CCustomColorCircle.cpp

#include "CCustomColorCircle.h"
#include <math.h>
ACRX_DXF_DEFINE_MEMBERS(CCustomColorCircle, AcDbEntity, AcDb::kDHL_CURRENT,
    AcDb::kMReleaseCurrent, 0, CUSTOMCIRCLE, /*MSG0*/"TSZ");
MAKE_ACDBOPENOBJECT_FUNCTION(CCustomColorCircle);

#define VERSION 1

CCustomColorCircle::CCustomColorCircle() :m_CenterPoint(AcGePoint3d(0, 0, 0)), m_radius(50)
{
}

CCustomColorCircle::CCustomColorCircle(AcGePoint3d centerPt, double radius):m_CenterPoint(centerPt), m_radius(radius)
{

}

CCustomColorCircle::~CCustomColorCircle()
{
}

Acad::ErrorStatus CCustomColorCircle::setColorIndex(Adesk::UInt16 color, Adesk::Boolean doSubents)
{
    return AcDbEntity::setColorIndex(color, doSubents);
}

Adesk::Boolean CCustomColorCircle::subWorldDraw(AcGiWorldDraw* mode)
{
    //因为能够通过setColorIndex设置颜色,在这里设置一下
    int colorIndex = this->colorIndex();
    mode->subEntityTraits().setColor(colorIndex);
    //绘制圆
    mode->geometry().circle(m_CenterPoint, m_radius, AcGeVector3d::kZAxis);
    return Adesk::kTrue;
}

Acad::ErrorStatus CCustomColorCircle::subGetGeomExtents(AcDbExtents& extents) const
{
    extents.addPoint(m_CenterPoint + sqrt(2.0) * m_radius * AcGeVector3d(1, 1, 0));
    extents.addPoint(m_CenterPoint - sqrt(2.0) * m_radius * AcGeVector3d(1, 1, 0));
    return Acad::eOk;
}

Acad::ErrorStatus CCustomColorCircle::dwgInFields(AcDbDwgFiler* filer)
{
    assertWriteEnabled();
    if (AcDbEntity::dwgInFields(filer) != Acad::eOk)
    {
        return filer->filerStatus();
    }
    int version;
    filer->readItem(&version);
    filer->readItem(&m_CenterPoint);
    filer->readItem(&m_radius);
    return filer->filerStatus();
}

Acad::ErrorStatus CCustomColorCircle::dwgOutFields(AcDbDwgFiler* filer) const
{
    assertReadEnabled();
    if (AcDbEntity::dwgOutFields(filer) != Acad::eOk)
    {
        return filer->filerStatus();
    }
    filer->writeItem(VERSION);
    filer->writeItem(m_CenterPoint);
    filer->writeItem(m_radius);
    return filer->filerStatus();
}

Acad::ErrorStatus CCustomColorCircle::dxfInFields(AcDbDxfFiler* filer)
{
    assertWriteEnabled();
    if (AcDbEntity::dxfInFields(filer) != Acad::eOk ||
        filer->atSubclassData(_T("CCustomColorCircle")))
    {
        return filer->filerStatus();
    }
    //读取版本
    resbuf rb;
    filer->readItem(&rb);
    int iVersion = rb.resval.rint;
    //读取圆心
    filer->readItem(&rb);
    m_CenterPoint = AcGePoint3d(rb.resval.rpoint[0], rb.resval.rpoint[1],
        rb.resval.rpoint[2]);
    return Acad::eOk;
}

Acad::ErrorStatus CCustomColorCircle::dxfOutFields(AcDbDxfFiler* filer) const
{
    assertReadEnabled();
    Acad::ErrorStatus es;
    if ((es = AcDbEntity::dxfOutFields(filer))
        != Acad::eOk)
    {
        return es;
    }
    filer->writeItem(AcDb::kDxfSubclass, _T("CCustomColorCircle"));
    filer->writeInt16(AcDb::kDxfInt16, VERSION);
    filer->writePoint3d(AcDb::kDxfXCoord, m_CenterPoint);
    return filer->filerStatus();
}

Acad::ErrorStatus CCustomColorCircle::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const
{
    /*这里添加三个点 添加三个点的顺序很重要
    向gripPoints中填充点,这些点在实体被选中后,会显示出来
    */
    gripPoints.append(m_CenterPoint);
    gripPoints.append(m_CenterPoint + m_radius * AcGeVector3d::kXAxis);
    gripPoints.append(m_CenterPoint - m_radius * AcGeVector3d::kXAxis);
    return Acad::eOk;
}

Acad::ErrorStatus   CCustomColorCircle::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset)
{
    /*
    indices:用户选择的特征点的索引(和你在subGetGripPoints的填充顺序是一致的,从0开始)
    offset(拖拽产生的向量)
    */
    //在这里我们这其实只是一个圆,所以简单调用矩阵变换函数
    if (indices.length() == 0 || offset.length() == 0)
        return Acad::eOk;
#ifdef _DEBUG
    //输出当前用户拖拽点的索引
    acutPrintf(_T("\n%d"), inDices)
#endif
    int num = indices.length();
    for (int i = 0; i < num; i++)
    {
        int k = indices[i];
        switch (k)
        {
        case 0:
            m_CenterPoint += offset;
            break;
        case 1:
            if (offset.x > 0)
            {
                m_radius += offset.length();
            }
            else
            {
                m_radius -= offset.length();
            }
            break;
        case 2:
            if (offset.x>0)
            {
                m_radius -= offset.length();
            }
            else
            {
                m_radius += offset.length();
            }
            break;
        default:
            break;
        }
    }
    return transformBy(AcGeMatrix3d::translation(offset));//这个函数又会调用subTransformby
}

实现完实体的功能,需要在dll启动的时候加载自定义的实体。

acrxEntryPoint.cpp

	//加载自定义的实体
	CCustomColorCircle::rxInit();
    acrxBuildClassHierarchy();

 最后初始化圆,加入到块表实体中

    //创建一个实体圆
    AcGePoint3d ptCenter(xPt, yPt, zPt);
    //创建圆,点法线,半径
    CCustomColorCircle* pCircle = new CCustomColorCircle(ptCenter, radius);
    // 将实体添加到图形数据库
    NetworkUtils::PostToModelSpace(pCircle);
AcDbObjectId PostToModelSpace(AcDbEntity* pEnt)
    {
        // 获得指向块表的指针
        assert(pEnt);
        AcDbBlockTable* pBlockTable = NULL;
        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);

        // 获得指向特定的块表记录(模型空间)的指针
        AcDbBlockTableRecord* pBlockTableRecord = NULL;
        Acad::ErrorStatus es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
        assert(pBlockTableRecord);
        pBlockTable->close();
        // 将AcDbLine类的对象添加到块表记录中
        AcDbObjectId entId;
        Acad::ErrorStatus esinfo = pBlockTableRecord->appendAcDbEntity(entId, pEnt);

        // 关闭图形数据库的各种对象
        pBlockTableRecord->close();
        pEnt->close();

        return entId;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值