ObjectArx創建自定義實體

ObjectArx創建自定義實體


一。目的
在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)繪製你的自定義實體:
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.csdn.net/detail/u012158162/9797021

六。後記
浮名本事身外物,不着方寸也風流 ---香獨秀
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章