Exemple #1
0
bool Mesh::SaveToObj( const char* fn )
{
	CSimpleObject *object = new CSimpleObject;
	//Init vertex
	map<int, int> vMap;
	for ( int i=0; i<v.size(); ++i )
		if (vExist[i])
			vMap[i] = vMap.size();

	object->m_nVertices = vMap.size();
	object->m_pVertexList = new Vec3f[vMap.size()];
	for ( int i=0; i<v.size(); ++i )
		if (vExist[i])
			object->m_pVertexList[vMap[i]] = Vec3f(v[i].x, v[i].y, v[i].z);

	//Init Faces
	object->m_nTriangles = totFaces;
	object->m_pTriangleList = new Array<int,3>[totFaces];
	int fCnt = 0;
	for (int i=0; i<f.size(); ++i)
		if (f[i].alive)
		{
			for (int p=0; p<3; ++p)
				object->m_pTriangleList[fCnt][p] = vMap[f[i].p[p]];
			++fCnt;
		}
	//Save
	bool success = object->SaveToObj(fn);
	delete object;
	return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
	CSimpleObject obj;

	while(true)
	{
		char filenames[50];
	cout<<"name?"<<endl;
	cin >> filenames;
	obj.LoadFromObj(filenames);
	float bilv;
	cout <<"t?"<<endl;
	cin >> bilv;

	int mode;
	cout <<"mode?"<<endl;
	cin >>mode;

	int v_nums = obj.m_nVertices; 
	int* heap = new int[v_nums];
	int p_nums = obj.m_nTriangles;
	Vec3f* v_array = new Vec3f[v_nums]; 
	Array<int,3>* fs = new Array<int,3>[p_nums]; 

	node* v_graph = new node[v_nums];

	float* v_power = new float[v_nums];
	for(int i=0; i<v_nums; i++) heap[i]=100000;

	for (int i=0; i<v_nums; i++)
	{
		v_array[i].x = obj.m_pVertexList[i].x;
		v_array[i].y = obj.m_pVertexList[i].y;
		v_array[i].z = obj.m_pVertexList[i].z;
	}
	
	for (int i=0; i<p_nums; i++)
	{
		fs[i][0] = obj.m_pTriangleList[i][0];
		fs[i][1] = obj.m_pTriangleList[i][1];
		fs[i][2] = obj.m_pTriangleList[i][2];
	}

	for(int i=0; i<p_nums; i++)
	{
		setup_node(v_graph,fs[i][0],fs[i][1],fs[i][2]);
		setup_node(v_graph,fs[i][1],fs[i][0],fs[i][2]);
		setup_node(v_graph,fs[i][2],fs[i][0],fs[i][1]);
	}



	for(int i=0; i<v_nums; i++)
	{
		node *t = v_graph[i].next;
		float sum = 0; 
		int count = 0;
		while(t != NULL) 
		{

			count += 2;
			sum += dist(v_array[i].x, v_array[i].y, v_array[i].z, v_array[t->x].x, v_array[t->x].y, v_array[t->x].z);
			sum += dist(v_array[i].x, v_array[i].y, v_array[i].z, v_array[t->y].x, v_array[t->y].y, v_array[t->y].z);
			t = t->next;
		}
		v_power[i] = sum/count;

	}

	for(int j=0; j<v_nums; j++)
	{
		heap[j] = j;
		int i=j;
		if(i != 0) //上滤
		{
			while(i > 0)
			{
				if(v_power[heap[(i-1)/2]] > v_power[heap[i]])
				{
					int tt = heap[i];
					heap[i] = heap[(i-1)/2];
					heap[(i-1)/2] = tt;
					i = (i-1)/2;
				}
				else
					break;
			}
		}
	}
	int num = v_nums-1; 
for(int pp=0; pp<v_nums*(1-bilv);pp++)
{	
	int cur_nod = heap[0];
	heap[0] = heap[num];
	num--;  
	int spe_ptr = v_graph[cur_nod].next->x;

	float mindis = dist(v_array[cur_nod].x, v_array[cur_nod].y, v_array[cur_nod].z, 
		v_array[v_graph[cur_nod].next->x].x, v_array[v_graph[cur_nod].next->x].y, v_array[v_graph[cur_nod].next->x].z);
	node* smin = v_graph[cur_nod].next;
	while(smin != NULL)
	{
		if (mindis > dist(v_array[cur_nod].x, v_array[cur_nod].y, v_array[cur_nod].z, 
			v_array[smin->x].x, v_array[smin->x].y, v_array[smin->x].z))
		{
			spe_ptr = smin->x;
			mindis = dist(v_array[cur_nod].x, v_array[cur_nod].y, v_array[cur_nod].z, 
				v_array[smin->x].x, v_array[smin->x].y, v_array[smin->x].z);
		}
		if (mindis > dist(v_array[cur_nod].x, v_array[cur_nod].y, v_array[cur_nod].z, 
			v_array[smin->y].x, v_array[smin->y].y, v_array[smin->y].z))
		{
			spe_ptr = smin->y;
			mindis = dist(v_array[cur_nod].x, v_array[cur_nod].y, v_array[cur_nod].z, 
				v_array[smin->y].x, v_array[smin->y].y, v_array[smin->y].z);
		}
		smin = smin->next;
	}
	
	
	node* de = v_graph[spe_ptr].next;
	while(de->next != NULL)
	{

		if(de->next->x == cur_nod || de->next->y == cur_nod)
		{
			de->next = de->next->next;
		}
		else
			de = de->next;
	}

	if(v_graph[spe_ptr].next->x == cur_nod || v_graph[spe_ptr].next->y == cur_nod)
		v_graph[spe_ptr].next = v_graph[spe_ptr].next->next;

	node* temp_ptr1 = v_graph[cur_nod].next;
	while(temp_ptr1 != NULL)
	{
		if(temp_ptr1->x != spe_ptr && temp_ptr1->y != spe_ptr)
		{			
			setup_node(v_graph,spe_ptr,temp_ptr1->x,temp_ptr1->y);
		}
		temp_ptr1 = temp_ptr1->next;
	}

	node* temp_ptr2 = v_graph[cur_nod].next;
	while (temp_ptr2 != NULL)
	{

		node* ptr_1 = v_graph[temp_ptr2->x].next;
		while (ptr_1 != NULL)
		{
			if(ptr_1->x == cur_nod) ptr_1->x = spe_ptr;
			if(ptr_1->y == cur_nod) ptr_1->y = spe_ptr;
			ptr_1 = ptr_1->next;
		}
		node* ptr_2 = v_graph[temp_ptr2->y].next;
		while (ptr_2 != NULL)
		{
			if(ptr_2->x == cur_nod) ptr_2->x = spe_ptr;
			if(ptr_2->y == cur_nod) ptr_2->y = spe_ptr;
			ptr_2 = ptr_2->next;
		}		
		temp_ptr2 = temp_ptr2->next;
	}
	if (mode==1)
	{
		v_array[spe_ptr].x = (v_array[spe_ptr].x + v_array[cur_nod].x)/2;
		v_array[spe_ptr].y = (v_array[spe_ptr].y + v_array[cur_nod].y)/2;
		v_array[spe_ptr].z = (v_array[spe_ptr].z + v_array[cur_nod].z)/2;
	}

	node* local_ptr = v_graph[cur_nod].next;

//	rearrage(local_ptr,v_graph,v_array,v_power,num);



	while (local_ptr != NULL) //local_ptr.m, local_ptr.n是需要遍历修改的点;
	{
		
		node* tt = v_graph[local_ptr->x].next;
		float sum = 0; //为节点i对应的值;
		int count = 0;
		while(tt != NULL) 
		{
			count += 2;
			sum += dist(v_array[local_ptr->x].x, v_array[local_ptr->x].y, v_array[local_ptr->x].z, v_array[tt->x].x, v_array[tt->x].y, v_array[tt->x].z);
			sum += dist(v_array[local_ptr->x].x, v_array[local_ptr->x].y, v_array[local_ptr->x].z, v_array[tt->y].x, v_array[tt->y].y, v_array[tt->y].z);
			tt = tt->next;
		}
		v_power[local_ptr->x] = sum/count;
		int k;
		for (k=0; k<num; k++)
		{
			if(heap[k] == local_ptr->x)
				break;
		}
		while( k>0) //上滤;
		{
			if (v_power[heap[k]] < v_power[heap[(k-1)/2]])
			{
				int ttt = heap[k];
				heap[k] = heap[(k-1)/2];
				heap[(k-1)/2] = ttt;
			}
			k = (k-1)/2;
		}
		while( k < num) //下滤;
		{
			int minnum=0;
			if (2*k+1 <= num)
			{
				if(v_power[heap[2*k+1]] < v_power[heap[k]])
				{
					minnum = 1;
				}
			}
			if (2*k+2 <= num)
			{
				if (minnum == 1)
				{
					if (v_power[heap[2*k+1]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
				else
				{
					if (v_power[heap[k]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
			}
			if (minnum == 1)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+1];
				heap[2*k+1] = ttt;
				k = 2*k+1;
			}
			else if (minnum == 2)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+2];
				heap[2*k+2] = ttt;
				k = 2*k+2;
			}
			else break;
			
		}


		node* ttt = v_graph[local_ptr->y].next;
		sum = 0; //为节点i对应的值;
		count = 0;
		while(ttt != NULL) //计算每个节点的值,并存到最小堆中去;
		{
			count += 2;
			sum += dist(v_array[local_ptr->y].x, v_array[local_ptr->y].y, v_array[local_ptr->y].z, v_array[ttt->x].x, v_array[ttt->x].y, v_array[ttt->x].z);
			sum += dist(v_array[local_ptr->y].x, v_array[local_ptr->y].y, v_array[local_ptr->y].z, v_array[ttt->y].x, v_array[ttt->y].y, v_array[ttt->y].z);
			ttt = ttt->next;
		}
		v_power[local_ptr->y] = sum/count;
		for (k=0; k<num; k++)
		{
			if(heap[k] == local_ptr->y)
				break;
		}
		while( k>0) //上滤;
		{
			if (v_power[heap[k]] < v_power[heap[(k-1)/2]])
			{
				int ttemp_ptr2 = heap[k];
				heap[k] = heap[(k-1)/2];
				heap[(k-1)/2] = ttemp_ptr2;
			}
			k = (k-1)/2;
		}
		while( k < num) //下虑;
		{
			int minnum=0;
			if (2*k+1 <= num)
			{
				if(v_power[heap[2*k+1]] < v_power[heap[k]])
				{
					minnum = 1;
				}
			}
			if (2*k+2 <= num)
			{
				if (minnum == 1)
				{
					if (v_power[heap[2*k+1]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
				else
				{
					if (v_power[heap[k]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
			}
			if (minnum == 1)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+1];
				heap[2*k+1] = ttt;
				k = 2*k+1;
			}
			else if (minnum == 2)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+2];
				heap[2*k+2] = ttt;
				k = 2*k+2;
			}
			else break;

		}

		local_ptr = local_ptr->next;
	}

	if (mode == 1)
	{
	local_ptr = v_graph[spe_ptr].next;

//	rearrage(local_ptr,v_graph,v_array,v_power,num);



	while (local_ptr != NULL) //local_ptr.m, local_ptr.n是需要遍历修改的点;
	{
		
		node* tt = v_graph[local_ptr->x].next;
		float sum = 0; //为节点i对应的值;
		int count = 0;
		while(tt != NULL) 
		{
			count += 2;
			sum += dist(v_array[local_ptr->x].x, v_array[local_ptr->x].y, v_array[local_ptr->x].z, v_array[tt->x].x, v_array[tt->x].y, v_array[tt->x].z);
			sum += dist(v_array[local_ptr->x].x, v_array[local_ptr->x].y, v_array[local_ptr->x].z, v_array[tt->y].x, v_array[tt->y].y, v_array[tt->y].z);
			tt = tt->next;
		}
		v_power[local_ptr->x] = sum/count;
		int k;
		for (k=0; k<num; k++)
		{
			if(heap[k] == local_ptr->x)
				break;
		}
		while( k>0) //上滤;
		{
			if (v_power[heap[k]] < v_power[heap[(k-1)/2]])
			{
				int ttt = heap[k];
				heap[k] = heap[(k-1)/2];
				heap[(k-1)/2] = ttt;
			}
			k = (k-1)/2;
		}
		while( k < num) //下滤;
		{
			int minnum=0;
			if (2*k+1 <= num)
			{
				if(v_power[heap[2*k+1]] < v_power[heap[k]])
				{
					minnum = 1;
				}
			}
			if (2*k+2 <= num)
			{
				if (minnum == 1)
				{
					if (v_power[heap[2*k+1]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
				else
				{
					if (v_power[heap[k]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
			}
			if (minnum == 1)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+1];
				heap[2*k+1] = ttt;
				k = 2*k+1;
			}
			else if (minnum == 2)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+2];
				heap[2*k+2] = ttt;
				k = 2*k+2;
			}
			else break;
			
		}


		node* ttt = v_graph[local_ptr->y].next;
		sum = 0; 
		count = 0;
		while(ttt != NULL) 
		{
			count += 2;
			sum += dist(v_array[local_ptr->y].x, v_array[local_ptr->y].y, v_array[local_ptr->y].z, v_array[ttt->x].x, v_array[ttt->x].y, v_array[ttt->x].z);
			sum += dist(v_array[local_ptr->y].x, v_array[local_ptr->y].y, v_array[local_ptr->y].z, v_array[ttt->y].x, v_array[ttt->y].y, v_array[ttt->y].z);
			ttt = ttt->next;
		}
		v_power[local_ptr->y] = sum/count;
		for (k=0; k<num; k++)
		{
			if(heap[k] == local_ptr->y)
				break;
		}
		while( k>0) //上滤;
		{
			if (v_power[heap[k]] < v_power[heap[(k-1)/2]])
			{
				int ttemp_ptr2 = heap[k];
				heap[k] = heap[(k-1)/2];
				heap[(k-1)/2] = ttemp_ptr2;
			}
			k = (k-1)/2;
		}
		while( k < num) //下虑;
		{
			int minnum=0;
			if (2*k+1 <= num)
			{
				if(v_power[heap[2*k+1]] < v_power[heap[k]])
				{
					minnum = 1;
				}
			}
			if (2*k+2 <= num)
			{
				if (minnum == 1)
				{
					if (v_power[heap[2*k+1]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
				else
				{
					if (v_power[heap[k]] > v_power[heap[2*k+2]])
					{
						minnum = 2;
					}
				}
			}
			if (minnum == 1)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+1];
				heap[2*k+1] = ttt;
				k = 2*k+1;
			}
			else if (minnum == 2)
			{
				int ttt = heap[k];
				heap[k] = heap[2*k+2];
				heap[2*k+2] = ttt;
				k = 2*k+2;
			}
			else break;

		}

		local_ptr = local_ptr->next;
	}
	}

	} 

	save_obj("out.obj",v_nums, num, heap, v_array, v_graph); //num]
	obj.Destroy();
	cout<<endl<<endl;
	}
	return 0;
}
Exemple #3
0
bool Mesh::LoadFromObj( const char* fn )
{
	//Clear data structure
	v.clear();
	f.clear();
	adj.clear();
	f.clear();
	relTri.clear();
	eLastUpdate.clear();
	while (!nextEdgeCollapse.empty()) nextEdgeCollapse.pop();

	//Create a new CSimpleObject
	CSimpleObject *simpleObject = new CSimpleObject();
	bool success = simpleObject->LoadFromObj(fn);
	//Copy the Information from CSimpleObject		
	for ( int i=0; i<simpleObject->m_nVertices; ++i )
	{
		v.push_back(simpleObject->m_pVertexList[i]);									//Copy vertexes
	}
	adj.resize(v.size());	
	relTri.resize(v.size());
	vExist = vector<bool>(v.size(), true);
	totFaces = simpleObject->m_nTriangles;
	for ( int i=0; i<simpleObject->m_nTriangles; ++i )
	{					
		Triangle t = Triangle(simpleObject->m_pTriangleList[i]);
		f.push_back(t);																					//Copy faces
		for ( int p1=0; p1<3; ++p1 )																//Construct adjacent list
			for ( int p2=0; p2<3; ++p2 )
				if ( p1!=p2 )
					adj[t.p[p1]].push_back(t.p[p2]);

		for (int p1=0; p1<3; ++p1)																//Construct triangle relevant list
			relTri[t.p[p1]].push_back(i);

		for (int p1=0; p1<3; ++p1)																//Initial edge last update list
			for (int p2=0; p2<3; ++p2)
				if (p1!=p2)
					eLastUpdate[std::make_pair(t.p[p1], t.p[p2])] = iterTimes;
	}
	for (unsigned int i=0; i<v.size(); ++i)													//Sort the lists
	{
		sort(adj[i].begin(), adj[i].end());
		sort(relTri[i].begin(), relTri[i].end());
	}
	vQ.resize(v.size());
	for (unsigned int i=0; i<v.size(); ++i)													//Init Vertex Q
		vQ[i] = Q(i);
	for ( int i=0; i<simpleObject->m_nTriangles; ++i )
	{					
		Triangle t = Triangle(simpleObject->m_pTriangleList[i]);
		for (int p1=0; p1<3; ++p1)																//Push edge collapses into the queue
			for (int p2=p1+1; p2<3; ++p2)
				addEdgeCollapse(t.p[p1], t.p[p2]);
	}
	
	//Release simpleObject
	delete simpleObject;
	//Return the result
	return success;
}