Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 1600)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 2088)
@@ -3,4 +3,6 @@
 #include <iostream>
 #include <fstream>
+#include <gfx/geom/ProxGrid.h>
+#include "quadrics.h"
 
 using namespace std;
@@ -8,15 +10,13 @@
 using	namespace	simplif;
 
-#include <gfx/geom/ProxGrid.h>
-#include "quadrics.h"
-
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Constructor
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 SimplificationMethod::SimplificationMethod(const Mesh *m)
 {
-	objmesh							=	m;
+	mInitialMesh				=	new Mesh();
+	*mInitialMesh				=	*m;
 	mGeoMesh						=	NULL;
-	first_index_submesh	=	new unsigned int[objmesh->mSubMeshCount];
+	first_index_submesh	=	new unsigned int[mInitialMesh->mSubMeshCount];
 	indexMeshLeaves			=	-1;
 
@@ -25,16 +25,18 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Destructor
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 SimplificationMethod::~SimplificationMethod()
 {
-	delete heap;
-	delete [] first_index_submesh;
-}
-
-//---------------------------------------------------------------------------
+	delete	heap;
+	delete	[] first_index_submesh;
+
+	delete	mInitialMesh;
+}
+
+//-------------------------------------------------------------------------
 //	Recalculate the cost of the vertices of an edge
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::compute_pair_info(simplif::pair_info *auxpair)
 {
@@ -48,5 +50,8 @@
 	simplif::real norm	=	v0_info.norm + v1_info.norm;
 
-	auxpair->cost = simplif::quadrix_pair_target(Q, v0, v1, auxpair->candidate);
+	auxpair->cost = simplif::quadrix_pair_target(	Q,
+																								v0,
+																								v1,
+																								auxpair->candidate);
 
 	if ( simplif::will_weight_by_area )
@@ -74,7 +79,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Reasign the new vertex to the adequate face
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 int SimplificationMethod::predict_face(	simplif::Face& F,
 																				simplif::Vertex *v1,
@@ -87,5 +92,5 @@
 	int nmapped = 0;
 
-	if( F.vertex(0) == v1 || F.vertex(0) == v2 )
+	if ( F.vertex(0) == v1 || F.vertex(0) == v2 )
 	{
 		f1 = vnew;  nmapped++;
@@ -96,5 +101,5 @@
 	}
 
-	if( F.vertex(1) == v1 || F.vertex(1) == v2 )
+	if ( F.vertex(1) == v1 || F.vertex(1) == v2 )
 	{
 		f2 = vnew;  nmapped++;
@@ -105,5 +110,5 @@
 	}
 
-	if( F.vertex(2) == v1 || F.vertex(2) == v2 )
+	if ( F.vertex(2) == v1 || F.vertex(2) == v2 )
 	{
 		f3 = vnew;  nmapped++;
@@ -119,9 +124,10 @@
 #define MESH_INVERSION_PENALTY 1e9
 
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M, simplif::Vertex *v1,
-																		 simplif::Vertex *v2,
-																		 simplif::Vec3& vnew)
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M,
+																											simplif::Vertex *v1,
+																		 									simplif::Vertex *v2,
+																		 									simplif::Vec3& vnew)
 {
 	static simplif::face_buffer changed;
@@ -166,7 +172,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Returns true if the givens vertices are a valid pair
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 bool SimplificationMethod::check_for_pair(simplif::Vertex *v0,
 																					simplif::Vertex *v1)
@@ -185,7 +191,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Create a new pair with two given vertices
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 simplif::pair_info *SimplificationMethod::new_pair(	simplif::Vertex *v0,
 																										simplif::Vertex *v1)
@@ -202,7 +208,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Remove a given pair
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::delete_pair(simplif::pair_info *auxpair)
 {
@@ -221,17 +227,20 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Contract a given pair
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::do_contract(	simplif::Model& m,
 																				simplif::pair_info *auxpair)
 {
-	simplif::Vertex *v0					= auxpair->v0;
-	simplif::Vertex *v1					= auxpair->v1;
-	simplif::vert_info& v0_info = vertex_info(v0);
-	simplif::vert_info& v1_info = vertex_info(v1);
-	simplif::Vec3 vnew					= auxpair->candidate;
-
-	int i;
+	simplif::Vertex 		*v0			= auxpair->v0;
+	simplif::Vertex 		*v1			= auxpair->v1;
+	simplif::Vec3 			vnew		= auxpair->candidate;
+	float								x,y,z;
+	simplif::Vertex			*aux_vert;
+
+	_float3_						removed_vert;
+	int									i;
+	vertex_map_str			lb;
+	vertex_map_str			ub;
 	
 	// V0 must be always the alive vertex
@@ -239,24 +248,70 @@
 	if (vnew == (*v0))
 	{
+		//	Coords of the removed vertex.
+		x	=	(*v1)[X];
+		y	=	(*v1)[Y];
+		z	=	(*v1)[Z];
+
+		aux_vert	=	v1;
+	}
+	else
+	{
+		//	Coords of the removed vertex.
+		x	=	(*v0)[X];
+		y	=	(*v0)[Y];
+		z	=	(*v0)[Z];
+
 		//	Simplification step.
-		simplifstep.mV0 = v0->vID;
-		simplifstep.mV1 = v1->vID;
-	}
-	else
-	{
-		//	Simplification step.
-		simplifstep.mV0 = v1->vID;
-		simplifstep.mV1 = v0->vID;
-		v0->vID = v1->vID;
-	}
-
-	// Make v0 be the new vertex
-	v0_info.Q		+= v1_info.Q;
+		aux_vert	=	v0;
+		v0	=	v1;
+		v1	=	aux_vert;
+	}
+
+	simplif::vert_info&	v0_info = vertex_info(v0);
+	simplif::vert_info&	v1_info = vertex_info(v1);
+
+	//	Simplification step.
+	simplifstep.mV0 = v0->vID;
+	simplifstep.mV1 = v1->vID;
+
+	//	Position of the vertex removed.
+	removed_vert	=	_float3_(x,y,z);
+
+	//	If position of the removed vertex is found.
+	if (vertexMultimap.end() != vertexMultimap.find(removed_vert))
+	{
+		lb	=	vertexMultimap.lower_bound(removed_vert);
+		ub	=	vertexMultimap.upper_bound(removed_vert);
+
+		//	For each vertex.
+		while	(lb != ub)
+		{
+			//	If removed vertex is found.
+			if ((*lb).second == aux_vert->vID)
+			{
+				//	Debug.
+				cout	<<	"to remove: "
+							<<	(*lb).second
+							<<	endl;
+
+				//	Delete vertex that disappears.
+				vertexMultimap.erase(lb);
+				
+				//	Break while.
+				lb	=	ub;
+			}
+			else
+			{
+				//	Next iteration.
+				lb++;
+			}
+		}
+	}
+
+	//	Make v0 be the new vertex
+	v0_info.Q			+= v1_info.Q;
 	v0_info.norm	+= v1_info.norm;
 
 	simplif::Vec3 p(vnew);
-/*	simplif::Vec3 v0antes(v0->operator[](simplif::X),
-						  v0->operator[](simplif::Y),
-						  v0->operator[](simplif::Z));*/
 
 	//	Perform the actual contraction.
@@ -265,13 +320,4 @@
 	changed.reset();
 	m.contract(v0, v1, vnew, changed);
-
-	std::cout << "Simp seq: " << simplifstep.mV1 << " --> " << simplifstep.mV0 << std::endl;
-
-/*	simplif::Vec3 vdesp = p - v0antes;
-
-	//	Stores the displacement in the simplification step.
-	simplifstep.x	=	(float)vdesp[X];
-	simplifstep.y = (float)vdesp[Y];
-	simplifstep.z = (float)vdesp[Z];*/
 
 	//	Stores the displacement in the simplification step.
@@ -360,4 +406,5 @@
 	condemned.reset();
 
+	//	Recalculate pairs associated with v1.
 	for (i	=	0;	i < v1_info.pairs.length(); i++)
 	{
@@ -366,5 +413,5 @@
 		simplif::Vertex *u;
 
-		if( p->v0 == v1 )
+		if ( p->v0 == v1 )
 		{
 			u = p->v1;
@@ -372,5 +419,5 @@
 		else
 		{
-			if( p->v1 == v1)
+			if ( p->v1 == v1)
 			{
 				u = p->v0;
@@ -406,6 +453,6 @@
 }
 
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 bool SimplificationMethod::decimate_quadric(simplif::Vertex *v,
 																						simplif::Mat4& Q)
@@ -422,14 +469,16 @@
 }
 
-//---------------------------------------------------------------------------
-//	Extract a pair from the heap, concract it and remove it form the heap
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//	Extract a pair from the heap, concract it and remove it from the heap.
+//-------------------------------------------------------------------------
 void SimplificationMethod::decimate_contract(simplif::Model& m)
 {
 	simplif::heap_node	*top;
 	simplif::pair_info	*pair;
-	simplif::Vertex		*v0;
-	simplif::Vertex		*v1;
-	simplif::Vec3		candidate;
+	simplif::Vertex			*v0;
+	simplif::Vertex			*v1;
+	simplif::Vec3				candidate;
+	_float3_						f0;
+	_float3_						f1;
 
 	for (;;)
@@ -460,8 +509,26 @@
 		}
 
-		if (pair->isValid() && sharededge)
+		//	Coordinates of the pair.
+		f0	=	_float3_((*pair->v0)[X],(*pair->v0)[Y],(*pair->v0)[Z]);
+		f1	=	_float3_((*pair->v1)[X],(*pair->v1)[Y],(*pair->v1)[Z]);
+
+		if (pair->isValid()
+				&&
+				sharededge
+				&&
+				(vertexMultimap.find(f0) != vertexMultimap.end())
+				&&
+				(vertexMultimap.find(f1) != vertexMultimap.end()))
 		{
 			break;
 		}
+
+		//	Debug.
+		cout	<<	"Deleting pair ("
+					<<	pair->v0->vID
+					<<	"--"
+					<<	pair->v1->vID
+					<<	")"
+					<<	endl;
 
 		//	Deletes repetitions of pair in heap.
@@ -470,4 +537,11 @@
 
 	//	Copy pair.
+<<<<<<< .mine
+	v0	=	new Vertex(	(*pair->v0)[X],
+										(*pair->v0)[Y],
+										(*pair->v0)[Z]);
+
+	v0->vID = pair->v0->vID;
+=======
 	v0	=	new Vertex(	pair->v0->operator[](0),
 										pair->v0->operator[](1),
@@ -475,10 +549,11 @@
 	v0->vID = pair->v0->vID;
 	v0->uniqID = pair->v0->uniqID;
+>>>>>>> .r2086
 	
-	v1	=	new Vertex(	pair->v1->operator[](0),
-										pair->v1->operator[](1),
-										pair->v1->operator[](2));
+	v1	=	new Vertex(	(*pair->v1)[X],
+										(*pair->v1)[Y],
+										(*pair->v1)[Z]);
 	v1->vID = pair->v1->vID;
-	v1->uniqID = pair->v1->uniqID;
+	v1->vID = pair->v1->vID;
 
 	candidate	=	pair->candidate;
@@ -488,5 +563,6 @@
 
 	//	Debug.
-	cout	<<	"Contracting..."	<<	endl;
+	cout	<<	"Contracting... "
+				<<	endl;
 
 	//	Contract main pair.
@@ -499,9 +575,6 @@
 	M0.validVertCount--;
 
-	//	Find an edge of the same coordinates and different vertex identifiers.
-	removeTwinEdges(m,v0,v1,candidate);
-
-	//	Move vertex of non twin edges.
-	contractLonelyVertices(m,v0,v1,candidate);
+	//	Find twin vertices to the contracted one and contract them.
+	removeTwinVertices(m,v0,v1,candidate);
 
 	//	Free Memory.
@@ -510,193 +583,170 @@
 }
 
-//---------------------------------------------------------------------------
-//	Contract lonely vertex that has the same coords that the contracted one.
-//---------------------------------------------------------------------------
-void	SimplificationMethod::contractLonelyVertices(	simplif::Model	&m,	simplif::Vertex	*v0,
-																			simplif::Vertex	*v1,
-																			simplif::Vec3	candidate)
-{
-	bool				lonely_vertex_found;
-	simplif::Vertex		*vert;
-	simplif::Vertex		*new_vert;
-	simplif::Vertex		*lonely_vert;
-	simplif::Edge		*edge;
-	simplif::heap_node	*top;
+//-------------------------------------------------------------------------
+//	Find twin vertices to the contracted one and contract them.
+//-------------------------------------------------------------------------
+void SimplificationMethod::removeTwinVertices(simplif::Model	&m,
+																							simplif::Vertex	*v0,
+																							simplif::Vertex	*v1,
+																							simplif::Vec3		candidate)
+{
+	bool								twin_found;
+	simplif::Edge				*edge;
 	simplif::pair_info	*pair;
+	simplif::Vertex			*vert;
+	simplif::Vertex			*lonely_vert;
+	simplif::Vertex			*new_vert;
+	vertex_map_str			lb;
+	vertex_map_str			ub;
+	vertex_map_str			it;
+	_float3_						f0;
+	_float3_						f1;
+	simplif::Edge				*econ;
 	simplif::vert_info	new_vert_info;
 	Geometry::GeoVertex	vertex_added;
-	simplif::Vertex		*take_bone_from_vert;
-
-	//	Gets the vertex that is not the candidate.
-	if ((*v0) == candidate)
-	{
-		vert = v1;
+	simplif::Vertex			*take_bone_from_vert;
+	float								x,y,z;
+
+	if ((*v0) != (*v1))
+	{
+		//	Gets the vertex that is not the candidate.
+		if ((*v1) == candidate)
+		{
+			vert 								= v0;
+			v0									=	v1;
+			v1									=	vert;
+		}
+
 		take_bone_from_vert = v0;
-	}
-	else if ((*v1) == candidate)
-	{
-		vert = v0;
-		take_bone_from_vert = v1;
-	}
-
-	//	For all vertex.
-	for (int	i = 0; i < heap->getSize();	i++)
-	{
-		//	Initialize lonely vertex flag.
-		lonely_vertex_found	=	false;
-
-		//	Gets the current pair.
-		top		=	heap->getElement(i);
-		pair	=	(simplif::pair_info *)top->obj;
-
-		if (pair->v0->isValid() && (*vert) == (*pair->v0))
-		{
-			lonely_vert	=	pair->v0;
-			lonely_vertex_found	=	true;
-		}
-		else if (pair->v1->isValid() && (*vert) == (*pair->v1))
-		{
-			lonely_vert	=	pair->v1;
-			lonely_vertex_found	=	true;
-		}
-
-		//	If a lonely vertex is found. Creates new vertex and contract.
-		if (lonely_vertex_found)
-		{
-			new_vert	=	m.newVertex(candidate[X],candidate[Y],candidate[Z]);	
-			edge		=	m.newEdge(new_vert,lonely_vert);
-
-            // We assume here the there are the same number of vertices and texture coordinates and normals
-
-			// assign a texture coordinate for the vbertex
-			simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->validID());
-			m.in_TexCoord(newtexcoord);
-
-			// assign a normal coordinate for the vbertex
-			simplif::Vec3 newnormal = m.normal(lonely_vert->validID());
-			m.in_Normal(newnormal);
-
-			//	Adds new vertex information to simplification sequence.
-			vertex_added.id			=	new_vert->vID;
-			vertex_added.bonefrom	=	take_bone_from_vert->vID;
-			vertex_added.position	=	Vector3(candidate[X],candidate[Y],candidate[Z]);
-
-			simplif::Vec2 tc = m.texcoord(new_vert->validID());
-			vertex_added.texcoord	=	Vector2(tc[X],tc[Y]);
-
-			simplif::Vec3 vn = m.normal(new_vert->validID());
-			vertex_added.normal		=	Vector3(vn[X],vn[Y],vn[Z]);
-
-			msimpseq->mNewVertices.push_back(vertex_added);
-
-			pair			=	new_pair(new_vert,lonely_vert);
-			pair->candidate	=	candidate;
-
-			pair->notInHeap();
-/*			vinfo(new_vert->validID()).Q		=	vinfo(lonely_vert->validID()).Q;
-			vinfo(new_vert->validID()).norm	=	vinfo(lonely_vert->validID()).norm;*/
-
-			//	Debug.
-			cout	<<	"Contracting new pair..."	<<	endl;
-
-			//	Contract twin pair.
-			do_contract(m, pair);
-			M0.validVertCount--;
-		}
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Find a twin edge of the given one.
-//---------------------------------------------------------------------------
-void SimplificationMethod::removeTwinEdges(	simplif::Model	&m,
-																						simplif::Vertex	*v0,
-																						simplif::Vertex	*v1,
-																						simplif::Vec3		candidate)
-{
-	bool								twin_found;
-	simplif::heap_node	*top;
-	simplif::pair_info	*pair;
-	simplif::Vertex			*aux_vert;
-
-	//	Find a twin edge in heap.
-	for (int	i	=	0;	i < heap->getSize(); i++)
-	{
-		//	Initialize twin flag.
-		twin_found	=	false;
-
-		//	Gets the current pair.
-		top		=	heap->getElement(i);
-		pair	=	(simplif::pair_info *)top->obj;
-
-		if (pair->v0->isValid()==false || pair->v1->isValid()==false)
-			continue; 
-
-		if (v0->operator[](0) == pair->v0->operator[](0)
-				&&
-				v0->operator[](1) == pair->v0->operator[](1)
-				&&
-				v0->operator[](2) == pair->v0->operator[](2))
-		{
-			if (v1->operator[](0) == pair->v1->operator[](0)
-					&&
-					v1->operator[](1) == pair->v1->operator[](1)
-					&&
-					v1->operator[](2) == pair->v1->operator[](2))
+
+		f0	=	_float3_((*v0)[X],(*v0)[Y],(*v0)[Z]);
+		f1	=	_float3_((*v1)[X],(*v1)[Y],(*v1)[Z]);
+
+		while ((it = vertexMultimap.find(f1)) != vertexMultimap.end())
+		{
+			twin_found	=	false;
+
+			lonely_vert	=	m.vertex((*it).second);
+
+			for (int	i	=	0;	i < lonely_vert->edgeUses().length();	i++)
+			{
+				econ	=	lonely_vert->edgeUses()(i);
+
+				if (((*econ->org()) == (*v0))
+						||
+						((*econ->dest()) == (*v0)))
+				{
+					lb	=	vertexMultimap.lower_bound(f0);
+					ub	=	vertexMultimap.upper_bound(f0);
+
+					//	For each vertex.
+					while	(lb != ub)
+					{
+						//	If removed vertex is found.
+						if (((*lb).second == econ->org()->vID)
+								||
+								((*lb).second == econ->dest()->vID))
+						{
+							twin_found	=	true;
+
+							//	Break while.
+							lb	=	ub;
+						}
+						else
+						{
+							//	Next iteration.
+							lb++;
+						}
+					}
+
+					break;
+				}
+			}
+
+			//	If a twin edge has been found.
+			if (twin_found)
 			{
 				//	Debug.
-				cout	<<	"Twin contracted (NO Swap)..."	<<	endl;
-
-				//	Active twin flag.
-				twin_found	= true;
-			}
-		}
-		else
-		{
-			//	If there is a twin edge in reverse order.
-			if (v0->operator[](0) == pair->v1->operator[](0)
-					&&
-					v0->operator[](1) == pair->v1->operator[](1)
-					&&
-					v0->operator[](2) == pair->v1->operator[](2))
-			{
-				if (v1->operator[](0) == pair->v0->operator[](0)
-						&&
-						v1->operator[](1) == pair->v0->operator[](1)
-						&&
-						v1->operator[](2) == pair->v0->operator[](2))
-				{
-					//	Debug.
-					cout	<<	"Twin contracted (Swap)..."	<<	endl;
-
-					//	Swap.
-					aux_vert	=	pair->v0;
-					pair->v0	=	pair->v1;
-					pair->v1	=	aux_vert;
-
-					//	Active twin flag.
-					twin_found	=	true;
-				}
-			}
-		}
-
+				cout	<<	"Twin Contracted..."	<<	endl;
+
+				//	Extract twin edge from heap.
+				pair	=	new_pair(econ->org(),econ->dest());
+
+				//	Copy candidate.
+				pair->candidate	=	candidate;
+
+				pair->notInHeap();
+
+				//	Contract twin pair.
+				do_contract(m, pair);
+				M0.validVertCount--;
+			}
+			else
+			{
+				//	Debug.
+				cout	<<	"Contracting new pair..."	<<	endl;
+
+				new_vert	=	m.newVertex(candidate[X],candidate[Y],candidate[Z]);
+
+				//	Add new vert to multimap.
+				x	=	(*new_vert)[X];
+				y	=	(*new_vert)[Y];
+				z	=	(*new_vert)[Z];
+
+				//	Adds new vertex to multimap.
+				vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
+
+				//	Creates new edge.
+				edge	=	m.newEdge(new_vert,lonely_vert);
+
+				//	We assume here there are the same number of vertices
+				//	and texture coordinates and normals.
+
+				// Assign a texture coordinate for the vertex.
+				simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->vID);
+				m.in_TexCoord(newtexcoord);
+
+				//	Assign a normal coordinate for the vbertex.
+				simplif::Vec3 newnormal = m.normal(lonely_vert->vID);
+				m.in_Normal(newnormal);
+
+				//	Adds new vertex information to simplification sequence.
+				vertex_added.id				=	new_vert->vID;
+
+				vertex_added.bonefrom	=	take_bone_from_vert->vID;
+
+<<<<<<< .mine
+				vertex_added.position	=	Vector3(candidate[X],
+																				candidate[Y],
+																				candidate[Z]);
+=======
 		//	If a twin edge has been found.
 		if (twin_found)
 		{
 			heap->kill(i);
-
-			//	Copy candidate.
-			pair->candidate	=	candidate;
-
-			//	Contract twin pair.
-			do_contract(m, pair);
-			i--;
-			M0.validVertCount--;
-		}
-	}
-}
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
+>>>>>>> .r2086
+
+				simplif::Vec2 tc 			= m.texcoord(new_vert->vID);
+				vertex_added.texcoord	=	Vector2(tc[X],tc[Y]);
+
+				simplif::Vec3 vn 		= m.normal(new_vert->vID);
+				vertex_added.normal	=	Vector3(vn[X],vn[Y],vn[Z]);
+
+				msimpseq->mNewVertices.push_back(vertex_added);
+
+				pair						=	new_pair(new_vert,lonely_vert);
+				pair->candidate	=	candidate;
+				pair->notInHeap();
+
+				//	Contract new pair.
+				do_contract(m, pair);
+				M0.validVertCount--;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
 {
@@ -705,5 +755,5 @@
 	simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
 
-    if( simplif::will_weight_by_area )
+    if ( simplif::will_weight_by_area )
 		{
 			err /= info.norm;
@@ -713,7 +763,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Extract the minimum cost of the the valid nodes (not simplified)
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 simplif::real SimplificationMethod::decimate_min_error()
 {
@@ -744,7 +794,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Returns the maximum error by vertex
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
 {
@@ -760,8 +810,9 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Initializations
-//---------------------------------------------------------------------------
-void SimplificationMethod::decimate_init(simplif::Model& m, simplif::real limit)
+//-------------------------------------------------------------------------
+void SimplificationMethod::decimate_init(	simplif::Model	&m,
+																					simplif::real 	limit)
 {
 	int i,j;
@@ -783,7 +834,4 @@
 		}
 	}
-
-	//	Sets the fill value of the vinfo buffer.
-	//vinfo.setFill(m.vertCount());
 
 	//	For each face, recalculate constraints.
@@ -849,4 +897,5 @@
 			simplif::pair_info *pair = new_pair(m.edge(i)->org(), m.edge(i)->dest());
 			//pointers_to_remove.push_back(pair);
+
 			compute_pair_info(pair);
 			pair_count++;
@@ -901,7 +950,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Initilizations
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::simplifmethod_init(void)
 {
@@ -936,7 +985,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Do the contractions till the required LOD (percentage option)
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
 {
@@ -989,7 +1038,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Do the contractions till the required LOD (number of vertices option)
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
 {
@@ -1051,50 +1100,16 @@
 }
 
-//---------------------------------------------------------------------------
-// Class to create a map without repeated vertices
-//---------------------------------------------------------------------------
-class _float3_
-{
-	public:
-
-		float x,y,z;
-
-		_float3_(float x=0.0f, float y=0.0f, float z=0.0f)
-		{
-			this->x = x; this->y = y; this->z = z;
-		}
-
-		_float3_(const _float3_ &f)
-		{
-			x=f.x; y=f.y; z=f.z;
-		}
-
-		_float3_ & operator=(const _float3_ &f)
-		{
-			x=f.x; y=f.y; z=f.z; return *this;
-		}
-
-		bool operator<(const _float3_ &f) const 
-		{ 
-			if (x<f.x) return true;
-			if (x>f.x) return false;
-			if (y<f.y) return true;
-			if (y>f.y) return false;
-			if (z<f.z) return true;
-			if (z>f.z) return false;
-			return false;
-		}
-};
-
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Generate simplification model.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void	SimplificationMethod::generateSimplifModel(void)
 {
-	int	face_index	=	0;
+	int		face_index	=	0;
+	int		vertID;
+	float	x,y,z;
 
 	//	For each submesh.
 	bool added_vertices = false;
-	for (size_t	i =	0;	i	<	objmesh->mSubMeshCount;	i++)
+	for (size_t	i =	0;	i	<	mInitialMesh->mSubMeshCount;	i++)
 	{
 		//	If is not a tree leaves submesh.
@@ -1103,28 +1118,35 @@
 			//	For all the vertices of each submesh.
 			for (	size_t	j	=	0;
-					j < objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
+					j < mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
 					j++)
 			{
+				x	=	mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
+				y	=	mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
+				z	=	mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
+
 				//	If the vertex is not in vertices_map, then is added.
-				M0.in_Vertex(simplif::Vec3(
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
+				vertID	=	M0.in_Vertex(simplif::Vec3(
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
 
 				M0.in_Normal(simplif::Vec3(
-							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
-							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
-							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
 
 				M0.in_TexCoord(simplif::Vec2(
-							objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
-							objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
+							mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
 
 				added_vertices = true;
-			}
-		}	
-		
+
+				//	Add vertex to multimap.
+				vertexMultimap.insert(vertex_pair(_float3_(x,y,z),vertID));
+			}
+		}
+
 		//	If is shared vertex buffer object.
-		if (objmesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
+		if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
 		{
 			printf("Shared break");
@@ -1134,18 +1156,20 @@
 
 	//	For each submesh.
-	for (size_t	i = 0;	i < objmesh->mSubMeshCount;	i++)
+	for (size_t	i = 0;	i < mInitialMesh->mSubMeshCount;	i++)
 	{
 		if (i != indexMeshLeaves)
 		{
-			for (Index	j	=	0;	j < objmesh->mSubMesh[i].mIndexCount;	j	+=	3)
+			for (	Geometry::Index	j	=	0;
+						j < mInitialMesh->mSubMesh[i].mIndexCount;
+						j	+=	3)
 			{
 				//	+1 is required because the first index in the
 				//	simplification method is 1
 				//	Index of the vertex in vertices_map.
-				Index index0	=		objmesh->mSubMesh[i].mIndex[j];
+				Geometry::Index index0	=		mInitialMesh->mSubMesh[i].mIndex[j];
 				
-				Index index1	=		objmesh->mSubMesh[i].mIndex[j + 1];
+				Geometry::Index index1	=		mInitialMesh->mSubMesh[i].mIndex[j + 1];
 				
-				Index index2	=		objmesh->mSubMesh[i].mIndex[j + 2];
+				Geometry::Index index2	=		mInitialMesh->mSubMesh[i].mIndex[j + 2];
 				
 				//	Create a triangle with its indices in vertices_map.
@@ -1163,14 +1187,33 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	simplifmethod_init is executed to do some initalizations
 //	simplifmethod_run is executed to do the decimation
 //	Then, the simpified model is created and the decimation 
 //	information is returned.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 MeshSimplificationSequence *SimplificationMethod::Decimate(	float lod,
 																														int simpliftype,
 																														TIPOFUNC upb)
 {
+	bool												shared_vertex;
+	unsigned	int								vertex_count;
+	std::map<int,int>::iterator	findit;
+	//	Initialize	vertex count.
+	vertex_count	=	0;
+
+	//	Initialize shared vertex buffer flag.
+	shared_vertex	=	false;
+
+	//	Determines if the mesh have shared vertex buffer.
+	for (int i = 0;	i < mInitialMesh->mSubMeshCount;	i++)
+	{
+		if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
+		{
+			shared_vertex	=	true;
+			break;
+		}
+	}
+
 	simplifmethod_init();
 
@@ -1186,19 +1229,15 @@
 	}
 
-	//	Store unique vertices by submesh (without repetitions).
-	typedef std::map<int,int> MAPAINDIND;
-
-	//	Store all the indices by submesh (with repetitions).
-	typedef std::vector<int> REPINDLIST;
-
 	MAPAINDIND *unique_verts_inds_by_geo =
-														new MAPAINDIND[objmesh->mSubMeshCount];
-
-	REPINDLIST *ver_inds_rep_by_geo	= new REPINDLIST[objmesh->mSubMeshCount];
+		new MAPAINDIND[mInitialMesh->mSubMeshCount];
+
+	MAPAINDIND	shared_vertex_map;
+
+	REPINDLIST *ver_inds_rep_by_geo	= new REPINDLIST[mInitialMesh->mSubMeshCount];
 
 	//	Index counter by submesh.
-	int *inextvert = new int[objmesh->mSubMeshCount];
-
-	for (unsigned int	i = 0;	i < objmesh->mSubMeshCount;	i++)
+	int *inextvert = new int[mInitialMesh->mSubMeshCount];
+
+	for (unsigned int	i = 0;	i < mInitialMesh->mSubMeshCount;	i++)
 	{
 		inextvert[i] = 0;
@@ -1207,4 +1246,6 @@
 	//	Construct the model.
 	std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
+
+	//	For each face.
 	for (int	i = 0;	i < M0.faceCount();	i++)
 	{
@@ -1216,43 +1257,39 @@
 			int igeo = auxface->igeo;
 
-			//	Insert to each submesh its triangles.
-			std::map<int,int>::iterator findit =
-				unique_verts_inds_by_geo[igeo].find(auxface->vertex(0)->validID());
-			
-			if (findit == unique_verts_inds_by_geo[igeo].end())
-			{
-				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(0)->validID()] =
-																														inextvert[igeo];
-				
-				inextvert[igeo]++;
-			}
-
-			findit =
-				unique_verts_inds_by_geo[igeo].find(auxface->vertex(1)->validID());
-			
-			if (findit == unique_verts_inds_by_geo[igeo].end())
-			{
-				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(1)->validID()] =
-																														inextvert[igeo];
-				inextvert[igeo]++;
-			}
-			
-			findit = 
-				unique_verts_inds_by_geo[igeo].find(auxface->vertex(2)->validID());
-			
-			if (findit == unique_verts_inds_by_geo[igeo].end())
-			{
-				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(2)->validID()] = 
-																														inextvert[igeo];
-				inextvert[igeo]++;
-			}
-
-			//	Total number of indices by submesh.
-			ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(0)->validID());
-			ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(1)->validID());
-			ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(2)->validID());
+			//	For each index of the face.
+			for (size_t	j = 0; j < 3; j++)
+			{
+				if (shared_vertex)
+				{
+					//	Insert to each submesh its triangles.
+					findit =	shared_vertex_map.find(auxface->vertex(j)->vID);
+
+					if (findit == shared_vertex_map.end())
+					{
+						//	If it is not added... add and map it.
+						shared_vertex_map[auxface->vertex(j)->vID] =	vertex_count;
+
+						vertex_count++;
+					}
+				}
+				else
+				{
+					//	Insert to each submesh its triangles.
+					findit =	unique_verts_inds_by_geo[igeo].
+						find(auxface->vertex(j)->vID);
+
+					if (findit == unique_verts_inds_by_geo[igeo].end())
+					{
+						//	If it is not added... add and map it.
+						unique_verts_inds_by_geo[igeo][auxface->vertex(j)->vID] =
+							inextvert[igeo];
+
+						inextvert[igeo]++;
+					}
+				}
+
+				//	Total number of indices by submesh.
+				ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(j)->vID);
+			}
 		}
 	}
@@ -1262,40 +1299,279 @@
 	mGeoMesh->mVertexBuffer	=	new	VertexBuffer();
 
-	mGeoMesh->mSubMeshCount = objmesh->mSubMeshCount;
+	mGeoMesh->mSubMeshCount = mInitialMesh->mSubMeshCount;
 
 	//	Memory allocation for the submeshes.
-	mGeoMesh->mSubMesh = new SubMesh[objmesh->mSubMeshCount];
+	mGeoMesh->mSubMesh = new SubMesh[mInitialMesh->mSubMeshCount];
 
 	//	Fill up bounding box settings.
-	mGeoMesh->mMeshBounds.maxX					=	objmesh->mMeshBounds.maxX;
-	mGeoMesh->mMeshBounds.maxY					=	objmesh->mMeshBounds.maxY;
-	mGeoMesh->mMeshBounds.maxZ					=	objmesh->mMeshBounds.maxZ;
-	mGeoMesh->mMeshBounds.minX					=	objmesh->mMeshBounds.minX;
-	mGeoMesh->mMeshBounds.minY					=	objmesh->mMeshBounds.minY;
-	mGeoMesh->mMeshBounds.minZ					=	objmesh->mMeshBounds.minZ;
-	mGeoMesh->mMeshBounds.radius				=	objmesh->mMeshBounds.radius;
-	mGeoMesh->mMeshBounds.scaleFactor		=	objmesh->mMeshBounds.scaleFactor;
+	mGeoMesh->mMeshBounds.maxX					=	mInitialMesh->mMeshBounds.maxX;
+	mGeoMesh->mMeshBounds.maxY					=	mInitialMesh->mMeshBounds.maxY;
+	mGeoMesh->mMeshBounds.maxZ					=	mInitialMesh->mMeshBounds.maxZ;
+	mGeoMesh->mMeshBounds.minX					=	mInitialMesh->mMeshBounds.minX;
+	mGeoMesh->mMeshBounds.minY					=	mInitialMesh->mMeshBounds.minY;
+	mGeoMesh->mMeshBounds.minZ					=	mInitialMesh->mMeshBounds.minZ;
+	mGeoMesh->mMeshBounds.radius				=	mInitialMesh->mMeshBounds.radius;
+	mGeoMesh->mMeshBounds.scaleFactor		=	mInitialMesh->mMeshBounds.scaleFactor;
 
 	//	Copy skeleton name.
-	if (objmesh->hasSkeleton)
+	if (mInitialMesh->hasSkeleton)
 	{
 		mGeoMesh->hasSkeleton	=	true;
 
-		strcpy(mGeoMesh->mSkeletonName,objmesh->mSkeletonName);
-	}
-
-	//	Copy mesh bones.
-	if (!objmesh->mBones.empty())
-	{
-		for (unsigned int j = 0; j < objmesh->mBones.size(); j++)
-		{
-			mGeoMesh->mBones.push_back(objmesh->mBones[j]);
-		}
-	}
-
+		strcpy(mGeoMesh->mSkeletonName,mInitialMesh->mSkeletonName);
+	}
+
+	//	If the mesh has shared vertex.
+	if (shared_vertex)
+	{
+		fillUpSharedVertices(shared_vertex_map,ver_inds_rep_by_geo);
+	}
+	else
+	{
+		fillUpVertices(unique_verts_inds_by_geo,ver_inds_rep_by_geo);
+	}
+
+	//------------------------//
+	//	Bones reassignment.		//
+	//------------------------//
+	VertexBoneAssignment	bone;
+	bool									vertex_found;
+	MAPAINDIND::iterator	it;
+
+	addNewBoneAssignments();
+
+	//	For each bone assignment.
+	for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
+	{
+		bone.vertexIndex	=	mInitialMesh->mBones[i].vertexIndex;
+		bone.boneIndex		=	mInitialMesh->mBones[i].boneIndex;
+		bone.weight				=	mInitialMesh->mBones[i].weight;
+
+		vertex_found	=	false;
+
+		//	If the vertex is found in the simplification model.
+		if ((it = shared_vertex_map.find(bone.vertexIndex))
+				!=
+				shared_vertex_map.end())
+		{
+			bone.vertexIndex	=	(*it).second;
+
+			mGeoMesh->mBones.push_back(bone);
+			vertex_found	=	true;
+		}
+	}
+	//------------------------------------------------------------//
+
+	delete[] unique_verts_inds_by_geo;
+	delete[] ver_inds_rep_by_geo;
+	delete[] inextvert;
+
+	//	Store the simplification steps in MeshSimplificationSequence.
+	int	acum	=	0;
+
+	for (size_t i	=	0; i < mInitialMesh->mSubMeshCount; i++)
+	{
+		if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
+		{
+			first_index_submesh[i]	=	0;
+		}
+		else
+		{
+			first_index_submesh[i]	=	acum;
+		}
+
+		acum	+=	(int)mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
+	}
+
+	vector<int>	v0;
+	vector<int>	v1;
+	vector<int>	submesh0;
+	vector<int>	submesh1;
+
+	return msimpseq;
+}
+
+//-------------------------------------------------------------------------
+//	Add bone assignments for new bones.
+//-------------------------------------------------------------------------
+void	SimplificationMethod::addNewBoneAssignments()
+{
+	size_t	vertex_id;
+	size_t	bones_count;
+	VertexBoneAssignment bone;
+	vector<VertexBoneAssignment>::iterator	it;
+
+	//	Copy new vertices.
+	for (unsigned	int	i	=	0;	i < msimpseq->mNewVertices.size();	i++)
+	{
+		vertex_id	=	msimpseq->mNewVertices[i].id;
+
+		//	Initialize number of bones.
+		bones_count	=	mInitialMesh->mBones.size();
+
+		// check if my twin-vertex-bone has a bone assignment
+		// we check only the GeoMesh bones because the lodstrips
+		// only works for sharedvertex bones.
+		for (int  j = 0; j < bones_count; j++)
+		{
+			it	=	mInitialMesh->mBones.begin() + j;
+
+			if (it->vertexIndex == msimpseq->mNewVertices[i].bonefrom)
+			{
+				bone.vertexIndex	= vertex_id;
+				bone.boneIndex		= it->boneIndex;
+				bone.weight				= it->weight;
+
+				mInitialMesh->mBones.push_back(bone);
+				bones_count++;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+//	Erase submeshes that have not indices.
+//-------------------------------------------------------------------------
+void	SimplificationMethod::eraseVoidSubMeshes(Mesh	*geoMesh)
+{
+	SubMesh	*geosubmesh;
+	size_t	valid_submesh_count;
+	size_t	submesh;
+
+	valid_submesh_count	=	0;
+
+	//	For each submesh.
+	for	(size_t	i	=	0; i < geoMesh->mSubMeshCount;	i++)
+	{
+		//	Debug.
+		cout	<<	"Indices of submesh "
+					<<	i
+					<<	": "
+					<<	geoMesh->mSubMesh[i].mIndexCount
+					<<	endl;
+
+		if ((geoMesh->mSubMesh[i].mIndexCount > 0)
+				||
+				(indexMeshLeaves == i))
+		{
+			valid_submesh_count++;
+		}
+	}
+
+	//	Reassign submesh count.
+	geoMesh->mSubMeshCount	=	valid_submesh_count;
+
+	//	Reserve memory for valid submeshes.
+	geosubmesh	=	new	SubMesh[valid_submesh_count];
+
+	submesh	=	0;
+	
+	//	For each submesh.
+	for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
+	{
+		//	If leaves submesh is found.
+		if (indexMeshLeaves == i)
+		{
+			geosubmesh[i].mStripCount	=	0;
+			geosubmesh[i].mStrip			=	NULL;
+
+			geosubmesh[i].mSharedVertexBuffer	=	false;
+
+			strcpy(	geosubmesh[i].mMaterialName,
+					mInitialMesh->mSubMesh[i].mMaterialName);
+
+			//	Copy submesh bones.
+			if (!mInitialMesh->mSubMesh[i].mBones.empty())
+			{
+				for (	size_t j = 0;
+						j < mInitialMesh->mSubMesh[i].mBones.size();
+						j++)
+				{
+					geosubmesh[i].mBones.push_back(mInitialMesh->
+							mSubMesh[i].mBones[j]);
+				}
+			}
+
+			//	Leaves mesh.
+			geosubmesh[i].mIndexCount	=	
+				mInitialMesh->mSubMesh[i].mIndexCount;
+
+			geosubmesh[i].mIndex	=
+				new Geometry::Index[geosubmesh[i].mIndexCount];
+
+			memcpy(	geosubmesh[i].mIndex,
+					mInitialMesh->mSubMesh[i].mIndex,
+					mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
+
+			//	Copy the leaves submesh vertices.
+			geosubmesh[i].mVertexBuffer	=
+				mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
+
+			//	Next valid submesh.
+			submesh++;
+		}
+		else if (geoMesh->mSubMesh[i].mIndexCount > 0)
+		{
+			geosubmesh[submesh].mSharedVertexBuffer	=
+									geoMesh->mSubMesh[i].mSharedVertexBuffer;
+
+			geosubmesh[submesh].mVertexBuffer	=	geoMesh->mVertexBuffer;
+
+			geosubmesh[submesh].mType				=	geoMesh->mSubMesh[i].mType;
+
+			geosubmesh[submesh].mStripCount	=	geoMesh->mSubMesh[i].mStripCount;
+
+			geosubmesh[submesh].mIndexCount	=	geoMesh->mSubMesh[i].mIndexCount;
+
+			//	Reserve memory for indices.
+			geosubmesh[submesh].mIndex	=
+													new Index[geosubmesh[submesh].mIndexCount];
+
+			//	Copy indices.
+			memcpy(	geosubmesh[submesh].mIndex,
+					geoMesh->mSubMesh[i].mIndex,
+					geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
+
+			//	Reserve memory for array of strips.
+			geosubmesh[submesh].mStrip	=
+				new Index*[geoMesh->mSubMesh[submesh].mStripCount];
+
+			//	Copy strip list of the submesh.
+			for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
+			{
+				geosubmesh[submesh].mStrip[j]	=	geoMesh->mSubMesh[i].mStrip[j];
+			}
+
+			strcpy(	geosubmesh[submesh].mMaterialName,
+					geoMesh->mSubMesh[i].mMaterialName);
+
+			for (size_t	j	=	0;	j < geoMesh->mSubMesh[i].mBones.size();	j++)
+			{
+				geosubmesh[submesh].mBones
+					.push_back(geoMesh->mSubMesh[i].mBones[j]);
+			}
+
+			//	Next valid submesh.
+			submesh++;
+		}
+	}
+
+	//	Delete submeshes.
+	delete	[]geoMesh->mSubMesh;
+
+	geoMesh->mSubMesh	=	geosubmesh;
+}
+
+//-------------------------------------------------------------------------
+//	Fill up vertices.
+//-------------------------------------------------------------------------
+void	SimplificationMethod::fillUpVertices(
+															MAPAINDIND	*unique_verts_inds_by_geo,
+															REPINDLIST	*ver_inds_rep_by_geo)
+{
 	bool copiedShared = false;
 
 	//	For each submesh.
-	for (size_t	i = 0;	i < objmesh->mSubMeshCount;	i++)
+	for (size_t	i = 0;	i < mInitialMesh->mSubMeshCount;	i++)
 	{
 		mGeoMesh->mSubMesh[i].mStripCount	=	0;
@@ -1306,13 +1582,15 @@
 
 		strcpy(	mGeoMesh->mSubMesh[i].mMaterialName,
-				objmesh->mSubMesh[i].mMaterialName);
+				mInitialMesh->mSubMesh[i].mMaterialName);
 
 		//	Copy submesh bones.
-		if (!objmesh->mSubMesh[i].mBones.empty())
-		{
-			for (unsigned int j = 0; j < objmesh->mSubMesh[i].mBones.size(); j++)
-			{
-				mGeoMesh->mSubMesh[i].mBones.push_back(objmesh->
-																				mSubMesh[i].mBones[j]);
+		if (!mInitialMesh->mSubMesh[i].mBones.empty())
+		{
+			for (	unsigned int j = 0;
+						j < mInitialMesh->mSubMesh[i].mBones.size();
+						j++)
+			{
+				mGeoMesh->mSubMesh[i].mBones.push_back(mInitialMesh->
+						mSubMesh[i].mBones[j]);
 			}
 		}
@@ -1322,7 +1600,7 @@
 			//	Indices vectors.
 			mGeoMesh->mSubMesh[i].mIndexCount	=	ver_inds_rep_by_geo[i].size();
-			
-			mGeoMesh->mSubMesh[i].mIndex			=	new Index[mGeoMesh->
-																						mSubMesh[i].mIndexCount];
+
+			mGeoMesh->mSubMesh[i].mIndex			=	new Geometry::Index[mGeoMesh->
+				mSubMesh[i].mIndexCount];
 
 			//	Store the indices.
@@ -1331,7 +1609,5 @@
 				//	Obtain the indices that point at VertexBuffer.
 				mGeoMesh->mSubMesh[i].mIndex[j]	=
-					unique_verts_inds_by_geo[i].
-								operator [](ver_inds_rep_by_geo[i].
-								operator [](j));
+					unique_verts_inds_by_geo[i][ver_inds_rep_by_geo[i][j]];
 			}
 
@@ -1355,20 +1631,20 @@
 
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount	=
-																	unique_verts_inds_by_geo[i].size();
-			
+				unique_verts_inds_by_geo[i].size();
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo	=
-											objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
+				mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
 
 			//	Allocate memory for position, normal and texutre coordinates.
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition	=
-						new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			
+				new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal		=
-						new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			
+				new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords	=
-						new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-
-			for (	MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
+				new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+
+			for (MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
 						mapit != unique_verts_inds_by_geo[i].end();
 						mapit++)
@@ -1381,54 +1657,58 @@
 				//	Construction of the submeshes.
 				Vector3 v3(	(Real)M0.vertex(isrc)->operator [](0),
-										(Real)M0.vertex(isrc)->operator [](1),
-										(Real)M0.vertex(isrc)->operator [](2));
-				
+						(Real)M0.vertex(isrc)->operator [](1),
+						(Real)M0.vertex(isrc)->operator [](2));
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]	=	v3;
 
 				//	Normal coordinates.
 				Vector3 v3n(	(Real)M0.normal(isrc)(0),
-											(Real)M0.normal(isrc)(1),
-											(Real)M0.normal(isrc)(2));
-				
+						(Real)M0.normal(isrc)(1),
+						(Real)M0.normal(isrc)(2));
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]	=	v3n;
 
 				//	Texture coordinates.
 				Vector2 v2(	(Real)M0.texcoord(isrc)(0),
-										(Real)M0.texcoord(isrc)(1));
-				
+						(Real)M0.texcoord(isrc)(1));
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]	=	v2;
 			}
 		}
+		//	Leaves mesh.
 		else
 		{
-			//	Leaves mesh.
-			mGeoMesh->mSubMesh[i].mIndexCount	=	objmesh->mSubMesh[i].mIndexCount;
-			
-			mGeoMesh->mSubMesh[i].mIndex	=		new Index[mGeoMesh->mSubMesh[i].mIndexCount];
+			mGeoMesh->mSubMesh[i].mIndexCount	=	
+														mInitialMesh->mSubMesh[i].mIndexCount;
+
+			mGeoMesh->mSubMesh[i].mIndex	=		
+						new Geometry::Index[mGeoMesh->mSubMesh[i].mIndexCount];
 
 			//	Copy the leaves submesh indexes.
-			for (unsigned int	j	=	0;	j < mGeoMesh->mSubMesh[i].mIndexCount;	j++)
-			{	
-				mGeoMesh->mSubMesh[i].mIndex[j]	=	objmesh->mSubMesh[i].mIndex[j];
+			for (	unsigned int	j	=	0;
+						j < mGeoMesh->mSubMesh[i].mIndexCount;
+						j++)
+			{
+				mGeoMesh->mSubMesh[i].mIndex[j]	=	mInitialMesh->mSubMesh[i].mIndex[j];
 			}
 
 			//	Copy the leaves submesh vertices.
 			mGeoMesh->mSubMesh[i].mVertexBuffer	=	new VertexBuffer();
-			
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount	=
-														objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
-			
+				mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo	=
-														objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
+				mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
 
 			//	Allocate memory for position, normal and texture coordinates.
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition	=
-							new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			
+				new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal	=
-							new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			
+				new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+
 			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords	=
-							new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+				new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
 
 			for (	unsigned int j = 0;
@@ -1438,64 +1718,122 @@
 				//	Position.
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x	=
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
-				
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y	=
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
-				
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z	=
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
 
 				//	Normals.
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x	=
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
-				
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y	=
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
-				
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z	=
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
 
 				//	Textures.
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x	=
-									objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
-				
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
+
 				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y	=
-									objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
-			}
-		}
-	}
-
-	delete[] unique_verts_inds_by_geo;
-	delete[] ver_inds_rep_by_geo;
-	delete[] inextvert;
-
-	//	Store the simplification steps in MeshSimplificationSequence.
-	int	acum	=	0;
-
-	for (size_t i	=	0; i < objmesh->mSubMeshCount; i++)
-	{
-		if (objmesh->mSubMesh[i].mSharedVertexBuffer)
-		{
-			first_index_submesh[i]	=	0;
-		}
-		else
-		{
-			first_index_submesh[i]	=	acum;
-		}
-
-		acum	+=	(int)objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
-	}
-
-	vector<int>	v0;
-	vector<int>	v1;
-	vector<int>	submesh0;
-	vector<int>	submesh1;
-
-	return msimpseq;
-}
-
-//---------------------------------------------------------------------------
+					mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+//	Fill up shared vertices.
+//-------------------------------------------------------------------------
+void	SimplificationMethod::fillUpSharedVertices(
+														MAPAINDIND	&shared_vertex_map,
+														REPINDLIST	*ver_inds_rep_by_geo)
+{
+	mGeoMesh->mVertexBuffer = new VertexBuffer();
+
+	//	For each submesh.
+	for (size_t	i = 0;	i < mInitialMesh->mSubMeshCount;	i++)
+	{
+		mGeoMesh->
+			mSubMesh[i].mSharedVertexBuffer	=	mInitialMesh->
+																					mSubMesh[i].mSharedVertexBuffer;
+
+		//	Reassign submesh vertex buffers.
+		mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
+
+		mGeoMesh->mSubMesh[i].mStripCount	=	0;
+		mGeoMesh->mSubMesh[i].mStrip			=	NULL;
+
+		strcpy(	mGeoMesh->mSubMesh[i].mMaterialName,
+				mInitialMesh->mSubMesh[i].mMaterialName);
+
+		//	Indices vectors.
+		mGeoMesh->mSubMesh[i].mIndexCount	=	ver_inds_rep_by_geo[i].size();
+
+		mGeoMesh->mSubMesh[i].mIndex			=	new Geometry::Index[mGeoMesh->
+																								mSubMesh[i].mIndexCount];
+
+		//	Store the indices.
+		for (unsigned int	j = 0;	j < mGeoMesh->mSubMesh[i].mIndexCount;	j++)
+		{
+			//	Obtain the indices that point at VertexBuffer.
+			mGeoMesh->mSubMesh[i].mIndex[j]	=
+				shared_vertex_map[ver_inds_rep_by_geo[i][j]];
+		}
+	}
+
+	mGeoMesh->mVertexBuffer->mVertexCount	=	shared_vertex_map.size();
+
+	mGeoMesh->mVertexBuffer->mVertexInfo	=	
+															mInitialMesh->mVertexBuffer->mVertexInfo;
+
+	//	Allocate memory for position, normal and texutre coordinates.
+	mGeoMesh->mVertexBuffer->mPosition	=
+		new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
+
+	mGeoMesh->mVertexBuffer->mNormal		=
+		new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
+
+	mGeoMesh->mVertexBuffer->mTexCoords	=
+		new Vector2[mGeoMesh->mVertexBuffer->mVertexCount];
+
+	for (MAPAINDIND::iterator mapit = shared_vertex_map.begin();
+			mapit != shared_vertex_map.end();
+			mapit++)
+	{
+		//	Key and value.
+		int isrc = mapit->first;
+		int idst = mapit->second;
+
+		//	Vertex coordinate.
+		//	Construction of the submeshes.
+		Vector3 v3(	(Real)M0.vertex(isrc)->operator [](0),
+								(Real)M0.vertex(isrc)->operator [](1),
+								(Real)M0.vertex(isrc)->operator [](2));
+
+		mGeoMesh->mVertexBuffer->mPosition[idst]	=	v3;
+
+		//	Normal coordinates.
+		Vector3 v3n((Real)M0.normal(isrc)(0),
+								(Real)M0.normal(isrc)(1),
+								(Real)M0.normal(isrc)(2));
+
+		mGeoMesh->mVertexBuffer->mNormal[idst]	=	v3n;
+
+		//	Texture coordinates.
+		Vector2 v2(	(Real)M0.texcoord(isrc)(0),
+								(Real)M0.texcoord(isrc)(1));
+
+		mGeoMesh->mVertexBuffer->mTexCoords[idst]	=	v2;
+	}
+}
+
+//-------------------------------------------------------------------------
 //	Set submesh leaves.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void SimplificationMethod::setMeshLeaves(int meshLeaves)
 {
@@ -1506,4 +1844,7 @@
 Mesh	*	SimplificationMethod::GetMesh()
 {
+	//	Delete void submeshes.
+	eraseVoidSubMeshes(mGeoMesh);
+
 	return	mGeoMesh;
 }
