源地址:https://blog.youkuaiyun.com/u012158162/article/details/67644392
一。目的
在ObjectArx中已经有了许多实体,如AcDbLine,AcDbCircle,AcDbArc等,
但在用户使用Cad时,会有一些对他们来讲常用的“实体“,如一扇门,如
果我们能提供一个“门实体“,让用户能向添加直线一样方便,相信用户是
很乐意接受由此功能的软件!这是,我们为这个“门“就相当于一个自定
义实体”!(PS:希望没理解错)!
本文将介绍创建一个长方体的自定义实体,支持简单的编辑以及二维,三维
显示!
二。相关知识储备
1)既然是自定义实体,那你就必须将其显示出来,来告诉用户你的
自定义实体“长”什么样子,如下函数:(与MFC中的OnPaint()有点相似)
virtual Adesk::Boolean subWorldDraw (AcGiWorldDraw *mode) ;扩
可以看出这是一个虚函数,由父类AcDbEntity继承而来,并且绝对需要你
重写的函数,与之类似的还有其他几个从父类继承而来的虚函数,理论上都
需要重写!
2)由于这里需要绘制长方体,就涉及到面的绘制,可以用到以下二个函数
(二者择其一即可完成面的绘制)
virtual Adesk::Boolean mesh(const Adesk::UInt32 rows,
const Adesk::UInt32 columns,
const AcGePoint3d* pVertexList,
const AcGiEdgeData* pEdgeData = NULL,
const AcGiFaceData* pFaceData = NULL,
const AcGiVertexData* pVertexData = NULL,
const bool bAutoGenerateNormals = true
) const = 0;
virtual Adesk::Boolean shell(const Adesk::UInt32 nbVertex,
const AcGePoint3d* pVertexList,
const Adesk::UInt32 faceListSize,
const Adesk::Int32* pFaceList,
const AcGiEdgeData* pEdgeData = NULL,
const AcGiFaceData* pFaceData = NULL,
const AcGiVertexData* pVertexData = NULL,
const struct resbuf* pResBuf = NULL,
const bool bAutoGenerateNormals = true
) const = 0;
const Adesk::UInt32 columns,
const AcGePoint3d* pVertexList,
const AcGiEdgeData* pEdgeData = NULL,
const AcGiFaceData* pFaceData = NULL,
const AcGiVertexData* pVertexData = NULL,
const bool bAutoGenerateNormals = true
) const = 0;
virtual Adesk::Boolean shell(const Adesk::UInt32 nbVertex,
const AcGePoint3d* pVertexList,
const Adesk::UInt32 faceListSize,
const Adesk::Int32* pFaceList,
const AcGiEdgeData* pEdgeData = NULL,
const AcGiFaceData* pFaceData = NULL,
const AcGiVertexData* pVertexData = NULL,
const struct resbuf* pResBuf = NULL,
const bool bAutoGenerateNormals = true
) const = 0;
3
)需要获取当前用户采取什么模式预览:
virtual AcGiRegenType regenType() const = 0;
还回值为枚举型
三。实现流程
1)首先创建一个继承自AcDbEntity的自定义实体类,将几个必须由自定义
实体
类
实现的虚函数声明!
2)绘制你的自定义实体:
- void AcDbMyEntity::MyEntityShell(AcGiWorldDraw *mode, const AcGePoint3d &ptBase, INT32 xLen, INT32 yLen, INT32 zLen)
- {
- const INT32 POINT_COUNT = 8;
- AcGePoint3d ptList[POINT_COUNT] = {};
- INT32 index = 0;
- ptList[index++].set(ptBase[X], ptBase[Y], ptBase[Z]);
- ptList[index++].set(ptBase[X] + xLen, ptBase[Y], ptBase[Z]);
- ptList[index++].set(ptBase[X] + xLen, ptBase[Y] + yLen, ptBase[Z]);
- ptList[index++].set(ptBase[X], ptBase[Y] + yLen, ptBase[Z]);
- ptList[index++].set(ptBase[X], ptBase[Y], ptBase[Z] + zLen);
- ptList[index++].set(ptBase[X] + xLen, ptBase[Y], ptBase[Z] + zLen);
- ptList[index++].set(ptBase[X] + xLen, ptBase[Y] + yLen, ptBase[Z] + zLen);
- ptList[index++].set(ptBase[X], ptBase[Y] + yLen, ptBase[Z] + zLen);
- Adesk::Int32 faceList[] = {4, 0, 1, 2, 3,
- 4, 4, 5, 6, 7,
- 4, 0, 1, 5, 4,
- 4, 1, 2, 6, 5,
- 4, 2, 3, 7, 6,
- 4, 3, 0, 4, 7,
- };
- INT32 faceLen = sizeof(faceList) / sizeof(faceList[0]);
- AcGiFaceData faceData;
- INT32 baseColor = 10;
- INT32 incColor = 30;
- short colors[] = {(baseColor += incColor),
- (baseColor += incColor),
- (baseColor += incColor),
- (baseColor += incColor),
- (baseColor += incColor),
- (baseColor += incColor)};
- faceData.setColors(colors);
- mode->geometry().shell(POINT_COUNT, ptList, faceLen, faceList, NULL, &faceData);
- }
这里我采用的是shell(),当然mesh()也是可以的,简单说一下这个函数,
如facelist
第一组属性,{4,0,1,2,3,****}
第一个数字4表明此面是由4个点组成,后面0,1,2,3是ptList中点的索引,由
此4点组
成一个面,后面几组数值以此类推!
3)支持二维三维显示:
- Adesk::Boolean AcDbMyEntity::subWorldDraw (AcGiWorldDraw *mode) {
- assertReadEnabled () ;
- INT32 xBase = m_ptBase[X];
- INT32 yBase = m_ptBase[Y];
- INT32 zBase = m_ptBase[Z];
- INT32 xLen = m_len3D[X];
- INT32 yLen = m_len3D[Y];
- INT32 zLen = m_len3D[Z];
- switch (mode->regenType())
- {
- case kAcGiStandardDisplay:
- {
- const INT32 POINT_COUNT = 5;
- AcGePoint3d ptList[POINT_COUNT] = {};
- INT32 index = 0;
- ptList[index++].set(xBase, yBase, zBase);
- ptList[index++].set(xBase + xLen, yBase, zBase);
- ptList[index++].set(xBase + xLen, yBase + yLen, zBase);
- ptList[index++].set(xBase, yBase + yLen, zBase);
- ptList[index].set(xBase, yBase, zBase);
- mode->geometry().polyline(POINT_COUNT, ptList);
- m_enShowMode = en2D;
- }
- break;;
- case eAcGiRegenTypeInvalid:
- case kAcGiHideOrShadeCommand:
- case kAcGiRenderCommand:
- case kAcGiForExplode:
- case kAcGiSaveWorldDrawForProxy:
- {
- MyEntityShell(mode, m_ptBase, xLen, yLen, zLen);
- }
- default:
- break;;
- }
- return (AcDbEntity::subWorldDraw (mode)) ;
- }
四。效果截图:
1)三维实体,每一面都有特定颜色,可以简单的加宽

2)二维显示,只显示底面

3)编辑二维下的长宽

五。源码地址:
http://download.youkuaiyun.com/detail/u012158162/9797021
六。后记
浮名本事身外物,不着方寸也风流---香独秀