判斷三維模型是否是閉合的算法

基於多邊形網格的三維模型在我們的工作中是最常見的,這裏,我們只針對被多邊形面片“離散化”的三維模型。

計算機圖形學相關的項目(比如快速成型,逆向工程等等)中,經常的需要判斷三維模型是否閉合,最常規的做法就是對每個n邊形面片進行判斷,如果每個n邊形面片都與其他n個m邊形面片相鄰(m可以等於n,也可以不等於),那麼這個三維模型就是閉合的,這樣做的時間複雜度是:O(n方);對比較複雜的模型,比如:幾萬個甚至更多的n邊形面片,這個複雜度過大了,會影響系統效率。

這裏,提出一個效率比較好的方法,假設三維模型網格的邊數爲:line_count,組成三維模型的w個n邊形面片分別爲:polygon1,polygon2,……polygonw;它們的邊數依次是:n1,n2,……nw,則假如是閉合的三維模型,就滿足:line_count*2=polygon1*n1+polygon2*n2+……+polygonw*nw。否則(line_count*2!=polygon1*n1+polygon2*n2+……+polygonw*nw),就是不閉合的三維模型;使用這個公式,除了line_count,其他變量都爲已知,時間複雜度爲:O(n*logn)。這是因爲:如果三維模型閉合,則每條邊必然是兩個n邊形面片的鄰邊,我們把鄰邊看成是兩條邊,則順利成章的出來了上面的公式。在模型離散化表示中,三角面片是最常見的,下面我們將以三角面片爲例進行闡述,其他的可以類推。

在中國圖像圖形學報上的一篇“三維散亂點集的曲面三角剖分”上有這樣一個公式,也印證了我的想法,看下圖:

 

下面呈上簡單的代碼,代碼中使用了紅黑樹,紅黑樹相關的內容,詳見我的另一篇博文:紅黑樹的代碼實現。這裏代碼略去:

struct Section
{
	Triangle** tri;
	int tri_count;
};

enum SectionType
{
	SECTION_TYPE_CLOSED, SECTION_TYPE_CONNECTED, SECTION_DETACH, SECTION_TYPE_UNDEFINE
};

//獲得三維模型中點的個數
static int get_vertex_count(Triangle ** pTri,int tri_num)
{
	float3* vertex_collection=new float3[tri_num*5];

	int i = 0;

	RB_Tree tree_vertex;

	initial_tree_with_vertex( pTri, tree_vertex, vertex_collection, i );

	for ( int j = 1; j != tri_num; ++j )
	{
		add__tree_with_vertex( pTri, tree_vertex, vertex_collection, i, j );
	}

	delete[] vertex_collection;

	return tree_vertex.size;
}


//獲得三維模型中邊的數量
static int get_line_count( Triangle** pTri,int tri_num)
{
	float3* line_center_collection = new float3[tri_num*5];

	int i = 0;

	RB_Tree tree_line;

	initial_tree_for_judgeTopological( pTri, tree_line, line_center_collection, i );

	for ( int j = 1; j != tri_num; ++j )
	{
		add__tree_for_judgeTopological( pTri, tree_line, line_center_collection, i, j );
	}

	delete[] line_center_collection;

	return tree_line.size;
}


/// <summary>   
///獲得模型的拓撲結構(連通,閉合,分離)
/// </summary>   
/// <param name="sect">三維模型</param>    
/// <returns>模型的拓撲結構(連通,閉合,分離)</returns>  
SectionType get_section_type(Section *sect)
{
	LinkObject object;

	int vertex_count=get_vertex_count(sect->tri,sect->tri_count);

	int line_count=get_line_count(sect->tri,sect->tri_count);

	if(line_count<vertex_count-1)
	{
		return SECTION_DETACH;
	}

	split_STL_model(object,sect->tri,sect->tri_count);

	if(object.m_pEnd!=NULL)
	{
		return SECTION_DETACH;
	}
	else if(line_count * 2 == sect->tri_count * 3 )
	{
		return SECTION_TYPE_CLOSED;
	}
	else if(line_count * 2 > sect->tri_count * 3)
	{
		return SECTION_TYPE_CONNECTED;
	}

	return SECTION_TYPE_UNDEFINE;
}




參考文獻:

1,三維散亂點集的曲面三角剖分 張永春,達飛鵬,宋文忠(東南大學自動化研究所)

 

發佈了31 篇原創文章 · 獲贊 57 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章