ObjectARX第一课:创建自定义实体

源地址:https://blog.csdn.net/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;
3 )需要获取当前用户采取什么模式预览:
    virtual AcGiRegenType           regenType() const = 0;
还回值为枚举型

三。实现流程
1)首先创建一个继承自AcDbEntity的自定义实体类,将几个必须由自定义
实体 实现的虚函数声明!
2)绘制你的自定义实体:
[cpp]  view plain  copy
  1. void AcDbMyEntity::MyEntityShell(AcGiWorldDraw *mode, const AcGePoint3d &ptBase, INT32 xLen, INT32 yLen, INT32 zLen)  
  2. {  
  3.     const INT32 POINT_COUNT = 8;  
  4.     AcGePoint3d ptList[POINT_COUNT] = {};  
  5.   
  6.     INT32 index = 0;  
  7.     ptList[index++].set(ptBase[X],          ptBase[Y],          ptBase[Z]);  
  8.     ptList[index++].set(ptBase[X] + xLen,   ptBase[Y],          ptBase[Z]);  
  9.     ptList[index++].set(ptBase[X] + xLen,   ptBase[Y] + yLen,   ptBase[Z]);  
  10.     ptList[index++].set(ptBase[X],          ptBase[Y] + yLen,   ptBase[Z]);  
  11.   
  12.     ptList[index++].set(ptBase[X],          ptBase[Y],          ptBase[Z] + zLen);  
  13.     ptList[index++].set(ptBase[X] + xLen,   ptBase[Y],          ptBase[Z] + zLen);  
  14.     ptList[index++].set(ptBase[X] + xLen,   ptBase[Y] + yLen,   ptBase[Z] + zLen);  
  15.     ptList[index++].set(ptBase[X],          ptBase[Y] + yLen,   ptBase[Z] + zLen);  
  16.   
  17.   
  18.     Adesk::Int32 faceList[] = {4, 0, 1, 2, 3,  
  19.                                 4, 4, 5, 6, 7,  
  20.                                 4, 0, 1, 5, 4,  
  21.                                 4, 1, 2, 6, 5,  
  22.                                 4, 2, 3, 7, 6,  
  23.                                 4, 3, 0, 4, 7,  
  24.                                 };  
  25.   
  26.     INT32 faceLen = sizeof(faceList) / sizeof(faceList[0]);  
  27.   
  28.     AcGiFaceData faceData;  
  29.     INT32 baseColor = 10;  
  30.     INT32 incColor = 30;  
  31.     short colors[] = {(baseColor += incColor),  
  32.                         (baseColor += incColor),  
  33.                         (baseColor += incColor),  
  34.                         (baseColor += incColor),  
  35.                         (baseColor += incColor),  
  36.                         (baseColor += incColor)};  
  37.     faceData.setColors(colors);  
  38.   
  39.     mode->geometry().shell(POINT_COUNT, ptList, faceLen, faceList, NULL, &faceData);  
  40. }  

这里我采用的是shell(),当然mesh()也是可以的,简单说一下这个函数,
如facelist 第一组属性,{4,0,1,2,3,****}
第一个数字4表明此面是由4个点组成,后面0,1,2,3是ptList中点的索引,由
此4点组 成一个面,后面几组数值以此类推!
3)支持二维三维显示:
[cpp]  view plain  copy
  1. Adesk::Boolean AcDbMyEntity::subWorldDraw (AcGiWorldDraw *mode) {  
  2.     assertReadEnabled () ;  
  3.   
  4.     INT32 xBase = m_ptBase[X];  
  5.     INT32 yBase = m_ptBase[Y];  
  6.     INT32 zBase = m_ptBase[Z];  
  7.     INT32 xLen = m_len3D[X];  
  8.     INT32 yLen = m_len3D[Y];  
  9.     INT32 zLen = m_len3D[Z];  
  10.   
  11.     switch (mode->regenType())  
  12.     {  
  13.   
  14.     case kAcGiStandardDisplay:  
  15.         {  
  16.             const INT32 POINT_COUNT = 5;  
  17.             AcGePoint3d ptList[POINT_COUNT] = {};  
  18.               
  19.             INT32 index = 0;  
  20.             ptList[index++].set(xBase,          yBase,          zBase);  
  21.             ptList[index++].set(xBase + xLen,   yBase,          zBase);  
  22.             ptList[index++].set(xBase + xLen,   yBase + yLen,   zBase);  
  23.             ptList[index++].set(xBase,          yBase + yLen,   zBase);  
  24.             ptList[index].set(xBase,            yBase,          zBase);  
  25.   
  26.             mode->geometry().polyline(POINT_COUNT, ptList);  
  27.   
  28.             m_enShowMode = en2D;  
  29.         }  
  30.         break;;  
  31.     case eAcGiRegenTypeInvalid:  
  32.     case kAcGiHideOrShadeCommand:  
  33.     case kAcGiRenderCommand:  
  34.     case kAcGiForExplode:  
  35.     case kAcGiSaveWorldDrawForProxy:  
  36.         {  
  37.             MyEntityShell(mode, m_ptBase, xLen, yLen, zLen);  
  38.         }  
  39.     default:  
  40.         break;;       
  41.     }  
  42.       
  43.     return (AcDbEntity::subWorldDraw (mode)) ;  
  44. }  

四。效果截图:
1)三维实体,每一面都有特定颜色,可以简单的加宽

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

3)编辑二维下的长宽

五。源码地址:
http://download.csdn.net/detail/u012158162/9797021

六。后记
浮名本事身外物,不着方寸也风流---香独秀
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值