|
[code]重点:
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;
}
原文链接:https://blog.csdn.net/qq_38409301/article/details/125755703[/code] |
|