Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1578)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 2081)
@@ -8,13 +8,13 @@
 using namespace std;
 
-////////////////////////////////////////////////////////////////////////////
-//																																				//
-//											MeshSimplifier class															//
-//																																				//
-////////////////////////////////////////////////////////////////////////////
-
-//---------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////
+//																																			//
+//											MeshSimplifier class														//
+//																																			//
+//////////////////////////////////////////////////////////////////////////
+
+//-------------------------------------------------------------------------
 //	MeshSimplifier constructor.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 MeshSimplifier::MeshSimplifier(	const Mesh	*m,
 																TIPOFUNC		upb)
@@ -33,7 +33,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	MeshSimplifier destroyer.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 MeshSimplifier::~MeshSimplifier()
 {
@@ -42,7 +42,7 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 // Returns the simplified mesh.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 Mesh *	MeshSimplifier::GetMesh()
 {
@@ -50,15 +50,15 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Set submesh leaves
-//---------------------------------------------------------------------------
-void MeshSimplifier::setMeshLeaves(Index index)
+//-------------------------------------------------------------------------
+void MeshSimplifier::setMeshLeaves(Geometry::Index index)
 {
 	indexMeshLeaves	=	index;
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 // Returns the simplification sequence for general meshes.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence()
 {
@@ -66,20 +66,44 @@
 }
 
-//---------------------------------------------------------------------------
-//	Sort mesh bones.
-//---------------------------------------------------------------------------
-void	MeshSimplifier::sortBones()
-{
+//-------------------------------------------------------------------------
+//    Sort mesh bones.
+//-------------------------------------------------------------------------
+void MeshSimplifier::sortBones()
+{
+<<<<<<< .mine
+	VertexBuffer	*simplified_vb;
+	VertexBuffer	*initial_vb;
+=======
 	VertexBuffer					*mesh_vb;
 	VertexBuffer					*copy_vb;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	std::vector<VertexBoneAssignment>	*simplified_bones;
+	std::vector<VertexBoneAssignment>	*initial_bones;
+=======
 	std::vector<VertexBoneAssignment>	*mesh_bones;
 	std::vector<VertexBoneAssignment>	*copy_bones;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	// After simplifying, the object always is shared vertex
+	// so, the bones must be placed in the GeoMesh
+	simplified_bones	=	&mGeoMesh->mBones;
+	simplified_vb			=	mGeoMesh->mVertexBuffer;
+=======
 	// After simplifying, the object always is shared vertex
 	// so, the bones must be placed in the GeoMesh
 	mesh_bones	=	&mGeoMesh->mBones;
 	mesh_vb	=	mGeoMesh->mVertexBuffer;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	// we assume the original mesh is shared vertex
+	// because before the simplification process
+	// the mesh becomes converted to shared vertex
+	// so, the original bones must be searched in the
+	// Mesh, not in every submesh
+=======
 	// we assume the original mesh is shared vertex 
 	// because before the simplification process
@@ -87,10 +111,24 @@
 	// so, the original bones must be searched in the
 	// Mesh, not in every submesh
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	simplified_bones->clear();
+=======
 	mesh_bones->clear();
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	//    Vertex buffers.
+	initial_vb	=	mInitialMesh->mVertexBuffer;
+=======
 	//	Vertex buffers.
 	copy_vb	=	mInitialMesh->mVertexBuffer;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	//    Bones.
+	initial_bones	=	&mInitialMesh->mBones;
+=======
 	//	Bones.
 	copy_bones = &mInitialMesh->mBones;
@@ -100,7 +138,32 @@
 	{
 		VertexBoneAssignment	assign;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+	//  For each bone assignment.
+	for (int b = 0; b < initial_bones->size(); b++)
+	{
+		VertexBoneAssignment    assign;
+=======
 		int n	=	(*copy_bones)[b].vertexIndex;
-
+>>>>>>> .r2080
+
+<<<<<<< .mine
+		int n	=	(*initial_bones)[b].vertexIndex;
+
+		//	For each vertex.
+		for (int i	=	0;	i < simplified_vb->mVertexCount;	i++)
+		{
+			if (simplified_vb->mPosition[i].x == initial_vb->mPosition[n].x &&
+					simplified_vb->mPosition[i].y == initial_vb->mPosition[n].y &&
+					simplified_vb->mPosition[i].z == initial_vb->mPosition[n].z)
+			{
+				assign.vertexIndex	=	i;
+				assign.boneIndex		=	(*initial_bones)[b].boneIndex;
+				assign.weight				=	(*initial_bones)[b].weight;
+
+				simplified_bones->push_back(assign);
+			}
+=======
 		//	Initialize o.
 		
@@ -117,17 +180,19 @@
 				mesh_bones->push_back(assign);
 			}			
-		}
-	}
-}
-
-////////////////////////////////////////////////////////////////////////////
-//																																				//
-//									GeometryBasedSimplifier class													//
-//																																				//
-////////////////////////////////////////////////////////////////////////////
-
-//---------------------------------------------------------------------------
+>>>>>>> .r2080
+		}
+	}
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//																																			//
+//									GeometryBasedSimplifier class												//
+//																																			//
+//////////////////////////////////////////////////////////////////////////
+
+//-------------------------------------------------------------------------
 //	Constructor.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 GeometryBasedSimplifier::GeometryBasedSimplifier(	const Mesh 	*m,
 																									TIPOFUNC		upb)
@@ -136,24 +201,37 @@
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Destroyer.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 GeometryBasedSimplifier::~GeometryBasedSimplifier()
 {
 }
 
-//---------------------------------------------------------------------------
-// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+// Starts the simplification process. Receives as a parameter 
+// the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify
+// method to perform an image based simplification.
+//-------------------------------------------------------------------------
 void GeometryBasedSimplifier::Simplify(Real paramlod)
 {
 	SimplificationMethod *m_qslim	=	new SimplificationMethod(objmesh);
-	
+
 	m_qslim->setMeshLeaves(indexMeshLeaves);
-	
+
 	msimpsequence	=	m_qslim->Decimate(paramlod,0,mUPB);
-	
+
 	mGeoMesh	=	m_qslim->GetMesh();
-	
+
+	//	Debug.
+	cout	<<	"Number of bone assignaments: "
+				<<	mGeoMesh->mBones.size()
+				<<	endl;
+
+	// if the initial mesh had shared vertex,
+	// convert the mesh to shared vertex
+	//Mesh *sharedMesh = mGeoMesh->toSharedVertex();
+	//delete mGeoMesh;
+	//mGeoMesh = sharedMesh;
+
 	// if the initial mesh had shared vertex, 
 	// convert the mesh to shared vertex
@@ -170,12 +248,15 @@
 
 	//	Sort bones.
-	sortBones();
-	
+	//sortBones();
+
 	delete	m_qslim;
 }
 
-//---------------------------------------------------------------------------
-// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+// Starts the simplification process. Receives as a parameter the 
+// number of vertices of the resulting mesh.
+// Implements the Simplifier::Simplify method to 
+// perform an image based simplification.
+//-------------------------------------------------------------------------
 void GeometryBasedSimplifier::Simplify(uint32 numvertices)
 {
@@ -187,4 +268,10 @@
 
 	mGeoMesh	=	m_qslim->GetMesh();
+
+	// if the initial mesh had shared vertex,
+	// convert the mesh to shared vertex
+	//Mesh *sharedMesh = mGeoMesh->toSharedVertex();
+	//delete mGeoMesh;
+	//mGeoMesh = sharedMesh;
 	
 	// if the initial mesh had shared vertex, 
@@ -202,18 +289,18 @@
 
 	//	Sort bones.
-	sortBones();
+	//sortBones();
 	
 	delete m_qslim;
 }
 
-////////////////////////////////////////////////////////////////////////////
-//																																				//
-//								ViewPointDrivenSimplifier class													//
-//																																				//
-////////////////////////////////////////////////////////////////////////////
-
-//---------------------------------------------------------------------------
-/// Class constructor. Will call Simplifier class constructor.
-//---------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////
+//																																			//
+//								ViewPointDrivenSimplifier class												//
+//																																			//
+//////////////////////////////////////////////////////////////////////////
+
+//------------------------------------------------------------------------
+// Class constructor. Will call Simplifier class constructor.
+//------------------------------------------------------------------------
 ViewPointDrivenSimplifier::ViewPointDrivenSimplifier(	const Mesh 	*m,
 																											TIPOFUNC		upb)
@@ -222,14 +309,15 @@
 	//	Set progress update function
 	VMI::mUPB	=	upb;
-	
+
 	VMI::width  = 256;
 	VMI::height = 256;
 
-	VMI::bEnableOffScreen     = GL_TRUE;
-	VMI::bBeQuiet             = GL_FALSE;
-	VMI::bSaveLog             = GL_FALSE;
-	VMI::bLoadCamerasFromFile = GL_FALSE;
-
-	VMI::cameraType = 2;
+	VMI::bEnableOffScreen     		= GL_TRUE;
+	VMI::bBeQuiet             		= GL_FALSE;
+	VMI::bSaveLog             		= GL_FALSE;
+	VMI::bLoadCamerasFromFile 		= GL_FALSE;
+	VMI::bRemoveRedundantVertices = GL_TRUE;
+
+	VMI::cameraType = 3; // 20 viewpoints
 	VMI::radius = 1.3;
 	VMI::fov = 60.0;
@@ -243,17 +331,27 @@
 			VMI::radius);
 
+	//	Fill up attributes.
+	fillUpPosNorTC(mInitialMesh);
+
+	VMI::vPositions	=	vPositions;
+	VMI::vNormals		=	vNormals;
+	VMI::vTexCoords	=	vTexCoords;
 
 	mGeoMesh	=	new Mesh();
-	
+
 	*mGeoMesh	=	*m;
-	
+
 	//	Transform NoSV Mesh to a SV Mesh.
-	mGeoMesh	=	mGeoMesh->toSharedVertex();
+	//mGeoMesh	=	mGeoMesh->toSharedVertex();
+	
+	//	Join Vertices.
+	mTexConserver	=	 new	TextureConserver();
+	mTexConserver->JoinVertices(mGeoMesh);
 
 	//	Loads the vmi mesh structure for a geometry mesh given.
 	VMI::mesh = initMeshStructure(mGeoMesh);
-	
+
 	// RGB and Alpha.
-	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); 
+	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
 	glutInitWindowSize(VMI::width, VMI::height);
 	glutInitWindowPosition(100, 100);
@@ -266,46 +364,24 @@
 
 	if (VMI::bLoadCamerasFromFile == GL_FALSE)
-	{
-		switch (VMI::cameraType)
-		{
-			case 0:
-				VMI::cameras = VMI::setCameras(VMI::radius, OCTAHEDRON, &VMI::numCameras);
-				printf("Number of cameras: %d\n", OCTAHEDRON);
-				break;
-			case 1:
-				VMI:: cameras = VMI::setCameras(VMI::radius, ICOSAHEDRON, &VMI::numCameras);
-				printf("Number of cameras: %d\n", ICOSAHEDRON);
-				break;
-			case 2:
-				VMI::cameras = VMI::setCameras(VMI::radius, DODECAHEDRON, &VMI::numCameras);
-				printf("Number of cameras: %d\n", DODECAHEDRON);
-				break;
-			default:
-				break;
-		}
-	}
+		VMI::cameras = VMI::setCameras(VMI::radius, VMI::cameraType, &VMI::numCameras);
 
 	VMI::histogram	=	VMI::initHistogram(	VMI::mesh->currentNumTriangles,
-																				VMI::numCameras);
+			VMI::numCameras);
 
 	VMI::initialIs	=	VMI::initIs(VMI::numCameras);
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 /// Class destructor.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 ViewPointDrivenSimplifier::~ViewPointDrivenSimplifier(void)
 {
 	// Free memory
-	 VMI::freeMemory();
-}
-
-/// Copy constructor
-//ViewPointDrivenSimplifier(const ViewPointDrivenSimplifier&);
-
-/// Assignment operator
-//ViewPointDrivenSimplifier& operator =(const ViewPointDrivenSimplifier&);
-
-/// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify method to perform an image based simplification.
+	VMI::freeMemory();
+}
+
+/// Starts the simplification process. Receives as a parameter the 
+///	LOD factor in a range of [0,1]. Implements the 
+///	Simplifier::Simplify method to perform an image based simplification.
 void ViewPointDrivenSimplifier::Simplify(Real percent)
 {
@@ -321,16 +397,26 @@
 	VMI::display();
 
+	//	Cleans firts simplification.
+	VMI::freeMemory();
+
+	VMI::mesh =	initMeshStructure(mInitialMesh);
+
+	VMI::contractInitialMesh(VMI::mesh);
+
 	//	Load a geometry mesh for vmi mesh.
 	loadMesh();
+	
+	GetMeshSimpSequence();
 
 	//	Sort bones.
-	sortBones();
-	
-	GetMeshSimpSequence();
-}
-
-//---------------------------------------------------------------------------
-/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
-//---------------------------------------------------------------------------
+	bonesReassignament();
+}
+
+//-------------------------------------------------------------------------
+/// Starts the simplification process. Receives as a parameter 
+///	the number of vertices of the resulting mesh.
+/// Implements the Simplifier::Simplify method to perform 
+///	an image based simplification.
+//-------------------------------------------------------------------------
 void ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
 {
@@ -350,100 +436,39 @@
 	VMI::display();
 
+	//	Cleans firts simplification.
+	VMI::freeMemory();
+
+	VMI::mesh =	initMeshStructure(mInitialMesh);
+
+	VMI::contractInitialMesh(VMI::mesh);
+
 	//	Load a geometry mesh for vmi mesh.
 	loadMesh();
+	
+	GetMeshSimpSequence();
 
 	//	Sort bones.
-	sortBones();
-	
-	GetMeshSimpSequence();
-}
-
-// Returns the simplified mesh.
-//Mesh	*	ViewPointDrivenSimplifier::GetMesh()
-//{
-//	return mGeoMesh;
-//}
-
-//---------------------------------------------------------------------------
+	bonesReassignament();
+}
+
+//-------------------------------------------------------------------------
 //	Gets the VMI mesh simplification sequence.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void	ViewPointDrivenSimplifier::GetMeshSimpSequence()
 {
-	unsigned	int j = 0;
+	size_t	j = 0;
 	
 	MeshSimplificationSequence::Step	current_step;
 	
 	msimpsequence	=	new MeshSimplificationSequence();
-	
-	//	For each simplification step.
-	for (unsigned	int i = 0;	i < VMI::mVMISteps.size();	i++)
-	{
-		current_step.mV0	=	VMI::mVMISteps[i].mV0;
-		current_step.mV1	=	VMI::mVMISteps[i].mV1;
-		current_step.mT0	=	VMI::mVMISteps[i].mT0;
-		current_step.mT1	=	VMI::mVMISteps[i].mT1;
-		
-		current_step.x	=	VMI::mVMISteps[i].x;
-		current_step.y	=	VMI::mVMISteps[i].y;
-		current_step.z	=	VMI::mVMISteps[i].z;
-
-		current_step.obligatory	=	VMI::mVMISteps[i].obligatory;
-
-		//	For each face modificated.
-		while (j < VMI::mVMISteps[i].mModfaces.size())
-		{
-			current_step.mModfaces.push_back(VMI::mVMISteps[i].mModfaces[j]);
-			
-			j++;
-		}
-		
-		msimpsequence->mSteps.push_back(current_step);
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Class for join triangle holes.
-//---------------------------------------------------------------------------
-class _coord_
-{
-	public:
-		float x,y,z;
-		inline _coord_(	float x	=	0.0f,
-										float y	=	0.0f,
-										float z	=	0.0f)
-		{ this->x = x; this->y = y; this->z = z; }
-		
-		inline _coord_(const _coord_ &f)
-		{
-			x	=	f.x;
-			y=f.y;
-			z=f.z;
-		}
-		
-		inline _coord_ & operator=(const _coord_ &f)
-		{
-			x	=	f.x;
-			y	=	f.y;
-			z	=	f.z;
-			
-			return *this;
-		}
-		
-		inline bool operator<(const _coord_ &f) const
-		{
-			if (x<f.x-0.0001) return true;
-			if (x>f.x+0.0001) return false;
-			if (y<f.y-0.0001) return true;
-			if (y>f.y+0.0001) return false;
-			if (z<f.z-0.0001) return true;
-			if (z>f.z+0.0001) return false;
-			
-			return	false;
-		}
-};
-
-//---------------------------------------------------------------------------
+
+	//	Copy the mesh simplification sequence.
+	msimpsequence->mSteps				=	VMI::mSequence->mSteps;
+	msimpsequence->mNewVertices	=	VMI::mSequence->mNewVertices;
+}
+
+//-------------------------------------------------------------------------
 //	Initialize the mesh of VMI module.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 VMI::Mesh *	ViewPointDrivenSimplifier::initMeshStructure(Mesh	*geoMesh)
 {
@@ -481,7 +506,9 @@
 	mesh_index_count	=	0;
 	
-	for (unsigned int submesh	=	0; submesh < mGeoMesh->mSubMeshCount; submesh++)
-	{
-		mesh_index_count	+=	int(mGeoMesh->mSubMesh[submesh].mIndexCount);
+	for (	unsigned int submesh	=	0;
+				submesh < geoMesh->mSubMeshCount;
+				submesh++)
+	{
+		mesh_index_count	+=	int(geoMesh->mSubMesh[submesh].mIndexCount);
 	}
 	
@@ -498,31 +525,8 @@
 
 	printf("Adding vertices...");
+
 	//	Fill up vertices.
-	std::map<_coord_, int> uniquevertices;
-	std::map<int, int> newindices;
 	for (i = 0; i < vertex_buffer->mVertexCount; i++)
 	{
- 		_coord_ vertex_aux;
-		vertex_aux.x= vertex_buffer->mPosition[i].x;
-		vertex_aux.y= vertex_buffer->mPosition[i].y;
-		vertex_aux.z= vertex_buffer->mPosition[i].z;
-		//New index
-		if (uniquevertices.find(vertex_aux)==uniquevertices.end())
-		{
-			uniquevertices[vertex_aux]= i;
-			newindices[i]= i;
-
-			VMI::INTVECTOR intvectoraux;
-			intvectoraux.push_back(i);
-			VMI::inversemap[i]= intvectoraux;
-
-		}else//The map of unique vertices already contains this vertex
-		{
-			int newindex= uniquevertices[vertex_aux];
-			newindices[i]= newindex;
-
-			VMI::inversemap[newindex].push_back(i);;
-		}
-
 		// Vertices start at 0.
 		vmi_mesh->vertices[i].x = vertex_buffer->mPosition[i].x;
@@ -532,5 +536,6 @@
 		vmi_mesh->vertices[i].numTriangles = 0;
 		vmi_mesh->vertices[i].triangles = NULL;
-		vmi_mesh->vertices[i].enable = GL_TRUE;
+		vmi_mesh->vertices[i].enable 	= GL_TRUE;
+		vmi_mesh->vertices[i].movable = GL_TRUE;
 	}
 	
@@ -539,4 +544,6 @@
 	vmi_mesh->currentNumVertices = int(vertex_buffer->mVertexCount);
 
+	printf("Vertices: %d\n",vmi_mesh->numVertices);
+
 	//	Fill up triangles.
 	printf("Adding triangles...");
@@ -546,20 +553,22 @@
 	
 	//	For each submesh.
-	for (unsigned int submesh	=	0; submesh	<	mGeoMesh->mSubMeshCount; submesh++)
+	for (	unsigned int submesh	=	0;
+				submesh	<	geoMesh->mSubMeshCount;
+				submesh++)
 	{
 		//	Gets actual submesh.
-		geosubmesh	=	&mGeoMesh->mSubMesh[submesh];
+		geosubmesh	=	&geoMesh->mSubMesh[submesh];
 		
+		//	For each three vertices.
 		for (i = 0; i < (geosubmesh->mIndexCount / 3); i++)
 		{
 			vmi_mesh->triangles[index].id 				= index;
 			vmi_mesh->triangles[index].submesh		= submesh;
-			vmi_mesh->triangles[index].indices[0] = newindices[geosubmesh->mIndex[(3 * i)]];
-			vmi_mesh->triangles[index].indices[1] = newindices[geosubmesh->mIndex[(3 * i) + 1]];
-			vmi_mesh->triangles[index].indices[2] = newindices[geosubmesh->mIndex[(3 * i) + 2]];
+			vmi_mesh->triangles[index].indices[0] = geosubmesh->mIndex[(3 * i)];
+			vmi_mesh->triangles[index].indices[1] = geosubmesh->mIndex[(3 * i) + 1];
+			vmi_mesh->triangles[index].indices[2] = geosubmesh->mIndex[(3 * i) + 2];
 
 			vmi_mesh->triangles[index].area = computeTriangleArea(vmi_mesh->vertices, 
 					&vmi_mesh->triangles[index]);
-			//printf("\n%d a: %f",index , vmi_mesh->triangles[index].area);
 			computeTriangleNormal(vmi_mesh->vertices, &vmi_mesh->triangles[index]);
 
@@ -575,5 +584,8 @@
 				// Reallocate memory for the new adjacent triangle.
 				vmi_mesh->vertices[v1].triangles = (GLuint *)realloc(vmi_mesh->vertices[v1].triangles, (vmi_mesh->vertices[v1].numTriangles + 1) * sizeof(GLuint));
-				VMI::addItem((int *)vmi_mesh->vertices[v1].triangles, (int *)&vmi_mesh->vertices[v1].numTriangles, index);
+
+				VMI::addItem(	(int *)vmi_mesh->vertices[v1].triangles,
+											(int *)&vmi_mesh->vertices[v1].numTriangles,
+											index);
 			}
 
@@ -601,15 +613,9 @@
 	}
 
-	// Init edges
-	for (i=0; i<vmi_mesh->numTriangles * 3; i++)
-	{
-		vmi_mesh->edges[i].triangles    = NULL;
-		vmi_mesh->edges[i].numTriangles = 0;
-	}
-
 	printf("Adding edges...");
 	n = 0;
 
-	for (i=0; i<vmi_mesh->numTriangles; i++)
+	//	For each triangle adds three edges.
+	for (i	=	0; i < vmi_mesh->numTriangles; i++)
 	{
 		t		=	0;
@@ -620,13 +626,17 @@
 		if ((e = findEdge(vmi_mesh->edges, n, v1, v2)) == -1)
 		{
-			vmi_mesh->edges[n].u			=	v1;
-			vmi_mesh->edges[n].v			=	v2;
-			vmi_mesh->edges[n].enable =	GL_TRUE;
+			vmi_mesh->edges[n].u						=	v1;
+			vmi_mesh->edges[n].v						=	v2;
+			vmi_mesh->edges[n].triangles    = NULL;
+			vmi_mesh->edges[n].numTriangles = 0;
+			vmi_mesh->edges[n].enable 			=	GL_TRUE;
 
 			// Reallocate memory for the new adjacent triangle
 			vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge n
-			VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
-			//printf("n:%d i:%d\n", n, i);
+			VMI::addItem(	(int *)vmi_mesh->edges[n].triangles,
+										(int *)&vmi_mesh->edges[n].numTriangles,
+										i);
 
 			// Adding edge n adjacent to triangle i
@@ -638,22 +648,29 @@
 			// Reallocate memory for the new adjacent triangle.
 			vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge e
-			VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
-			//printf("n:%d i:%d\n", e, i);
+			VMI::addItem(	(int *)vmi_mesh->edges[e].triangles,
+										(int *)&vmi_mesh->edges[e].numTriangles,
+										i);
 
 			// Adding edge e adjacent to triangle i
 			VMI::addItem((int *)vmi_mesh->triangles[i].edges, (int *)&t, e);
 		}
+
 		if ((e = findEdge(vmi_mesh->edges, n, v2, v3)) == -1)
 		{
-			vmi_mesh->edges[n].u = v2;
-			vmi_mesh->edges[n].v = v3;
-			vmi_mesh->edges[n].enable = GL_TRUE;
+			vmi_mesh->edges[n].u 						= v2;
+			vmi_mesh->edges[n].v 						= v3;
+			vmi_mesh->edges[n].triangles    = NULL;
+			vmi_mesh->edges[n].numTriangles = 0;
+			vmi_mesh->edges[n].enable 			= GL_TRUE;
 
 			// Reallocate memory for the new adjacent triangle
 			vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge n
 			VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
-			//printf("n:%d i:%d\n", n, i);
+			vmi_mesh->edges[n].triangles    = NULL;
+			vmi_mesh->edges[n].numTriangles = 0;
 
 			// Adding edge n adjacent to triangle i
@@ -665,7 +682,9 @@
 			// Reallocate memory for the new adjacent triangle
 			vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge e
-			VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
-			//printf("n:%d i:%d\n", e, i);
+			VMI::addItem(	(int *)vmi_mesh->edges[e].triangles,
+										(int *)&vmi_mesh->edges[e].numTriangles,
+										i);
 
 			// Adding edge e adjacent to triangle i
@@ -675,13 +694,17 @@
 		if ((e = findEdge(vmi_mesh->edges, n, v3, v1)) == -1)
 		{
-			vmi_mesh->edges[n].u = v3;
-			vmi_mesh->edges[n].v = v1;
-			vmi_mesh->edges[n].enable = GL_TRUE;
-
-			// Reallocate memory for the new adjacent triangle
+			vmi_mesh->edges[n].u 						= v3;
+			vmi_mesh->edges[n].v 						= v1;
+			vmi_mesh->edges[n].triangles    = NULL;
+			vmi_mesh->edges[n].numTriangles = 0;
+			vmi_mesh->edges[n].enable 			= GL_TRUE;
+
+			// Reallocate memory for the new adjacent triangle.
 			vmi_mesh->edges[n].triangles = (GLuint *)realloc(vmi_mesh->edges[n].triangles, (vmi_mesh->edges[n].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge n
-			VMI::addItem((int *)vmi_mesh->edges[n].triangles, (int *)&vmi_mesh->edges[n].numTriangles, i);
-			//printf("n:%d i:%d\n", n, i);
+			VMI::addItem(	(int *)vmi_mesh->edges[n].triangles,
+										(int *)&vmi_mesh->edges[n].numTriangles,
+										i);
 
 			// Adding edge n adjacent to triangle i
@@ -693,7 +716,7 @@
 			// Reallocate memory for the new adjacent triangle
 			vmi_mesh->edges[e].triangles = (GLuint *)realloc(vmi_mesh->edges[e].triangles, (vmi_mesh->edges[e].numTriangles + 1) * sizeof(GLuint));
+
 			// Adding triangle i adjacent to edge e
 			VMI::addItem((int *)vmi_mesh->edges[e].triangles, (int *)&vmi_mesh->edges[e].numTriangles, i);
-			//printf("n:%d i:%d\n", e, i);
 
 			// Adding edge e adjacent to triangle i
@@ -705,10 +728,13 @@
 	vmi_mesh->numEdges = n;
 
+	//	Creates vertex multimap.
+	initVertexMultimap(vmi_mesh,mTexConserver->mVertices);
+
 	return vmi_mesh;
 }
 
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 //	Gets the geometry mesh of a  the vmi mesh given.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void	ViewPointDrivenSimplifier::loadMesh()
 {
@@ -730,5 +756,5 @@
 
 	//	For each submesh.
-	for (unsigned int submesh	=	0; submesh < mGeoMesh->mSubMeshCount; submesh++)
+	for (size_t	submesh	=	0; submesh < mGeoMesh->mSubMeshCount; submesh++)
 	{
 		geosubmesh	=	&mGeoMesh->mSubMesh[submesh];
@@ -740,5 +766,5 @@
 
 		//	For each triangle.
-		for (unsigned int i = 0; i < VMI::mesh->numTriangles; i++)
+		for (size_t	i = 0; i < VMI::mesh->numTriangles; i++)
 		{
 			//	If is enable and of the current submesh.
@@ -754,5 +780,5 @@
 		geosubmesh->mIndexCount	=	num_indices;
 
-		geosubmesh->mIndex	=	new Index[geosubmesh->mIndexCount];
+		geosubmesh->mIndex	=	new Geometry::Index[geosubmesh->mIndexCount];
 
 		//	Initialize number of indices.
@@ -760,5 +786,5 @@
 
 		//	Fill up indices.
-		for (unsigned int i = 0; i < VMI::mesh->numTriangles; i++)
+		for (size_t	i = 0; i < VMI::mesh->numTriangles; i++)
 		{
 			if ((VMI::mesh->triangles[i].enable)
@@ -766,12 +792,17 @@
 					(VMI::mesh->triangles[i].submesh == submesh))
 			{
-				geosubmesh->mIndex[num_indices++]	=	VMI::mesh->triangles[i].indices[0];
-				geosubmesh->mIndex[num_indices++]	=	VMI::mesh->triangles[i].indices[1];
-				geosubmesh->mIndex[num_indices++]	=	VMI::mesh->triangles[i].indices[2];
+				geosubmesh->mIndex[num_indices++]	=
+																	VMI::mesh->triangles[i].indices[0];
+
+				geosubmesh->mIndex[num_indices++]	=
+																	VMI::mesh->triangles[i].indices[1];
+
+				geosubmesh->mIndex[num_indices++]	=
+																	VMI::mesh->triangles[i].indices[2];
 			}
 		}
-
+	
 		//	For each index.
-		for (unsigned int i = 0; i < geosubmesh->mIndexCount; i++)
+		for (size_t	i = 0; i < geosubmesh->mIndexCount; i++)
 		{
 			findVertex(submesh,i);
@@ -784,61 +815,41 @@
 	
 	mGeoMesh->mVertexBuffer	=	mVB;
-
-}
-
-//---------------------------------------------------------------------------
+}
+
+//-------------------------------------------------------------------------
 //	Find vertex in auxiliar vertex buffer.
-//---------------------------------------------------------------------------
+//-------------------------------------------------------------------------
 void	ViewPointDrivenSimplifier::findVertex(size_t	submesh, size_t	elem)
 {
-	bool					found;
-	int						index;
-	unsigned int			i;
-	int						new_elem;
-	VertexBuffer	*vertex_buffer;
+	bool										found;
+	int											index;
+	unsigned int						i;
+	int											new_elem;
+	VertexBuffer						*vertex_buffer;
+	map<int,int>::iterator	it;
 
 	found	=	false;
 
 	//	Shared vertex buffer.
-	vertex_buffer	=	mGeoMesh->mVertexBuffer;
-	
+	vertex_buffer	=	mInitialMesh->mVertexBuffer;
+
 	index	=	mGeoMesh->mSubMesh[submesh].mIndex[elem];
-	
+
 	i	=	0;
-	
-	while (!found && (i < mVB->mVertexCount))
-	{
-		if ((VMI::mesh->vertices[index].x == mVB->mPosition[i].x)
-				&&
-				(VMI::mesh->vertices[index].y == mVB->mPosition[i].y)
-				&&
-				(VMI::mesh->vertices[index].z == mVB->mPosition[i].z))
-		{
-			found	=	true;
-
-			//	Update index.
-			mGeoMesh->mSubMesh[submesh].mIndex[elem]	=	 i;
-		}
-
-		//	Increments index.
-		i++;
-	}
-
-	if (!found)
-	{
+
+	if ((it	=	mIndexMap.find(index)) != mIndexMap.end())
+	{
+		mGeoMesh->mSubMesh[submesh].mIndex[elem]	=	(*it).second;
+	}
+	else
+	{
+		mIndexMap[index]	=	int(mVB->mVertexCount);
+
 		//	Last element.
 		new_elem	=	int(mVB->mVertexCount);
-		
-		//	Add to last.
-		mVB->mPosition[new_elem].x	=	VMI::mesh->vertices[index].x;
-		mVB->mPosition[new_elem].y	=	VMI::mesh->vertices[index].y;
-		mVB->mPosition[new_elem].z	=	VMI::mesh->vertices[index].z;
-
-		mVB->mNormal[new_elem].x	=	vertex_buffer->mNormal[index].x;
-		mVB->mNormal[new_elem].y	=	vertex_buffer->mNormal[index].y;
-		mVB->mNormal[new_elem].z	=	vertex_buffer->mNormal[index].z;
-
-		mVB->mTexCoords[new_elem].x	=	vertex_buffer->mTexCoords[index].x;
-		mVB->mTexCoords[new_elem].y	=	vertex_buffer->mTexCoords[index].y;
+
+		mVB->mPosition[new_elem]	=	VMI::vPositions[index];
+		mVB->mNormal[new_elem]		=	VMI::vNormals[index];
+		mVB->mTexCoords[new_elem]	=	VMI::vTexCoords[index];
 
 		//	Update index.
@@ -850,2 +861,527 @@
 }
 
+//-------------------------------------------------------------------------
+//	Reassigns bones.
+//-------------------------------------------------------------------------
+void ViewPointDrivenSimplifier::bonesReassignament()
+{
+	size_t									vertex_id;
+	size_t									bones_count;
+	bool										vertex_found;
+	map<int,int>::iterator	im;
+	VertexBoneAssignment 		bone;
+
+	vector<VertexBoneAssignment>::iterator	ib;
+
+	//	Copy new vertices.
+	for (unsigned	int	i	=	0;	i < msimpsequence->mNewVertices.size();	i++)
+	{
+		vertex_id	=	msimpsequence->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++)
+		{
+			ib	=	mInitialMesh->mBones.begin() + j;
+
+			if (ib->vertexIndex == msimpsequence->mNewVertices[i].bonefrom)
+			{
+				bone.vertexIndex	= vertex_id;
+				bone.boneIndex		= ib->boneIndex;
+				bone.weight				= ib->weight;
+
+				mInitialMesh->mBones.push_back(bone);
+				bones_count++;
+			}
+		}
+	}
+
+	//	Clears bones.
+	mGeoMesh->mBones.clear();
+
+	//	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 ((im = mIndexMap.find(bone.vertexIndex))
+				!=
+				mIndexMap.end())
+		{
+			bone.vertexIndex	=	(*im).second;
+
+			mGeoMesh->mBones.push_back(bone);
+			vertex_found	=	true;
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+//	Fill up position, normal and texture coordinates.
+//-------------------------------------------------------------------------
+void	ViewPointDrivenSimplifier::fillUpPosNorTC(Mesh	*geoMesh)
+{
+	VertexBuffer	*vertex_buffer;
+	Vector3				v3;
+	Vector2				v2;
+
+	vertex_buffer	=	geoMesh->mVertexBuffer;
+
+	for (size_t	i = 0; i < vertex_buffer->mVertexCount; i++)
+	{
+		v3	=	vertex_buffer->mPosition[i];
+
+		vPositions.push_back(v3);
+
+		v3	=	vertex_buffer->mNormal[i];
+
+		vNormals.push_back(v3);
+
+		v2	=	vertex_buffer->mTexCoords[i];
+
+		vTexCoords.push_back(v2);
+	}
+}
+
+//-------------------------------------------------------------------------
+//	EdgesMultimap class
+//-------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------
+//	Constructor.
+//-------------------------------------------------------------------------
+EdgesMultimap::EdgesMultimap()
+{
+	edges.clear();
+}
+
+//-------------------------------------------------------------------------
+//	Insert and edge.
+//-------------------------------------------------------------------------
+void	EdgesMultimap::insert(int v1,int v2)
+{
+	edges.insert(pair<int,int>(v1,v2));
+	edges.insert(pair<int,int>(v2,v1));
+}
+
+//-------------------------------------------------------------------------
+//	Remove edges with v1 and v2.
+//-------------------------------------------------------------------------
+void	EdgesMultimap::remove(int v1,int v2)
+{
+	multimap<int,int>::iterator	lb;
+	multimap<int,int>::iterator	ub;
+
+	if (edges.find(v1) != edges.end())
+	{
+		lb	=	edges.lower_bound(v1);
+		ub	=	edges.upper_bound(v1);
+
+		while (lb != ub)
+		{
+			if ((*lb).second == v2)
+			{
+				//	Remove edge.
+				edges.erase(lb);
+
+				lb	=	ub;
+			}
+			else
+			{
+				lb++;
+			}
+		}
+	}
+
+	if (edges.find(v2) != edges.end())
+	{
+		lb	=	edges.lower_bound(v2);
+		ub	=	edges.upper_bound(v2);
+
+		while (lb != ub)
+		{
+			if ((*lb).second == v1)
+			{
+				//	Remove edge.
+				edges.erase(lb);
+
+				lb	=	ub;
+			}
+			else
+			{
+				lb++;
+			}
+		}
+	}
+
+}
+
+//-------------------------------------------------------------------------
+//	Checks if the edge (v1,v2) exists.
+//-------------------------------------------------------------------------
+bool	EdgesMultimap::exists(int v1,int v2)
+{
+	bool												found;
+	multimap<int,int>::iterator	lb;
+	multimap<int,int>::iterator	ub;
+
+	found	=	false;
+
+	//	Find range.
+	lb	=	edges.lower_bound(v1);
+	ub	=	edges.upper_bound(v1);
+
+	//	Search for all v1 edges.
+	while (lb != ub)
+	{
+		//	If edge is found.
+		if ((*lb).second = v2)
+		{
+			found	=	true;
+			lb		=	ub;
+		}
+		else
+		{
+			//	Next iteration.
+			lb++;
+		}
+	}
+
+	return	found;
+}
+
+//-------------------------------------------------------------------------
+//	Change vertex v1 to v2 in the map.
+//-------------------------------------------------------------------------
+void	EdgesMultimap::contract(int v1,int v2)
+{
+	multimap<int,int>::iterator	it;
+	int	v_aux;
+
+	//	Remove contracted edge.
+	remove(v1,v2);
+
+	//	Modify all edges where appears v1 to v2.
+	while ((it =	edges.find(v1)) != edges.end())
+	{
+		v_aux	=	(*it).second;
+
+		//	Remove current edge.
+		remove(v1,v_aux);
+
+		//	Modify edge.
+		insert(v2,v_aux);
+	}
+}
+
+//-------------------------------------------------------------------------
+//	TextureConserver class
+//-------------------------------------------------------------------------
+TextureConserver::TextureConserver()
+{
+	mEdges		=	new	EdgesMultimap();
+	mGeoMesh	=	new Mesh();
+}
+
+TextureConserver::~TextureConserver()
+{
+	delete	mGeoMesh;
+}
+
+//-------------------------------------------------------------------------
+//	Join twin vertices into a unique vertex.
+//-------------------------------------------------------------------------
+void	TextureConserver::JoinVertices(Mesh *mesh)
+{
+	map<_coord_, int>							uniquevertices;
+	map<int, int>									newindices;
+	multimap<int, int>::iterator	it;
+	map<int, int>::iterator				it_map;
+	VertexBuffer									*vertex_buffer;
+	VertexBuffer									*mGMVB;
+	unsigned	int									vertex_count;
+	unsigned	int									i;
+	unsigned	int									aux_i;
+	unsigned	int									submesh;
+	SubMesh												*geosubmesh;
+ 	_coord_ 											vertex_aux;
+
+	//	Copy actual mesh.
+	*mGeoMesh		=	*mesh;
+
+	//	Gets the shared vertex buffer.
+	vertex_buffer	=	mGeoMesh->mVertexBuffer;
+
+	//	Initialize unique vertices count.
+	vertex_count	=	0;
+
+	//	Fill up vertices.
+	for (i	=	0; i < vertex_buffer->mVertexCount; i++)
+	{
+		vertex_aux.x	= vertex_buffer->mPosition[i].x;
+		vertex_aux.y	= vertex_buffer->mPosition[i].y;
+		vertex_aux.z	= vertex_buffer->mPosition[i].z;
+
+		//	New index.
+		if (uniquevertices.find(vertex_aux) == uniquevertices.end())
+		{
+			uniquevertices[vertex_aux]	= vertex_count;
+			newindices[i]								= vertex_count;
+
+			mVertices.insert(pair<int,int>(vertex_count,i));
+			
+			//	Increments unique vertices count.
+			vertex_count++;
+		}
+		//	The map of unique vertices already contains this vertex.
+		else
+		{
+			int newindex	=	uniquevertices[vertex_aux];
+			newindices[i]	=	newindex;
+
+			mVertices.insert(pair<int,int>(newindex,i));
+		}
+	}
+
+	//	Delete vertices.
+	delete	mesh->mVertexBuffer;
+
+	mesh->mVertexBuffer	=	new VertexBuffer();
+
+	mesh->mVertexBuffer->mPosition		= new Vector3[vertex_count];
+	mesh->mVertexBuffer->mNormal			= new Vector3[vertex_count];
+	mesh->mVertexBuffer->mTexCoords		= new Vector2[vertex_count];
+
+	mesh->mVertexBuffer->mVertexInfo	= vertex_buffer->mVertexInfo;
+	mesh->mVertexBuffer->mVertexCount	= vertex_count;
+
+	mGMVB	=	mesh->mVertexBuffer;
+
+	//	Fill up unique vertices.
+	for (i	=	 0; i < vertex_count; i++)
+	{
+		//	Find first ocurrence of unique vertex.
+		it	=	mVertices.find(i);
+
+		aux_i	=	(*it).second;
+
+		mGMVB->mPosition[i].x	=	vertex_buffer->mPosition[aux_i].x;
+		mGMVB->mPosition[i].y	=	vertex_buffer->mPosition[aux_i].y;
+		mGMVB->mPosition[i].z	=	vertex_buffer->mPosition[aux_i].z;
+
+		mGMVB->mNormal[i].x	=	vertex_buffer->mNormal[aux_i].x;
+		mGMVB->mNormal[i].y	=	vertex_buffer->mNormal[aux_i].y;
+		mGMVB->mNormal[i].z	=	vertex_buffer->mNormal[aux_i].z;
+
+		mGMVB->mTexCoords[i].x	=	vertex_buffer->mTexCoords[aux_i].x;
+		mGMVB->mTexCoords[i].y	=	vertex_buffer->mTexCoords[aux_i].y;
+	}
+
+	//	Fill up indices to unique vertices.
+	//	For each submesh.
+	for (submesh	=	0; submesh < mesh->mSubMeshCount; submesh++)
+	{
+		geosubmesh	=	&mesh->mSubMesh[submesh];
+
+		//	Change indices.
+		for (i	=	0; i < geosubmesh->mIndexCount; i++)
+		{
+			//	Unique index asociated to the given one.
+			it_map	=	newindices.find(geosubmesh->mIndex[i]);
+
+			geosubmesh->mIndex[i]	=	(*it_map).second;
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+//	Modify the joined vertices sequento to an split.
+//-------------------------------------------------------------------------
+MeshSimplificationSequence *
+TextureConserver::WriteRealSimpSeq(MeshSimplificationSequence *simpseq)
+{
+	bool	edge_found;
+
+	size_t	v0;
+	size_t	v1;
+	size_t	vertex_count;
+	size_t	i,j;
+
+	VertexBuffer	*mVB;
+	GeoVertex			new_vertex;
+
+	multimap<int, int>::iterator	lb0;
+	multimap<int, int>::iterator	ub0;
+	multimap<int, int>::iterator	lb1;
+	multimap<int, int>::iterator	ub1;
+	multimap<int, int>::iterator	it0;
+
+	MeshSimplificationSequence				*real_seq;
+	MeshSimplificationSequence::Step	current_step;
+
+	//	Initialize vertex count.
+	vertex_count	=	mGeoMesh->mVertexBuffer->mVertexCount;
+
+	//	Creates new simplification sequence.
+	real_seq	=	new	MeshSimplificationSequence();
+
+	//	For each simplification step.
+	for (i = 0; i < simpseq->mSteps.size();	i++)
+	{
+		lb0	=	mVertices.lower_bound(simpseq->mSteps[i].mV0);
+		ub0	=	mVertices.upper_bound(simpseq->mSteps[i].mV0);
+		lb1	=	mVertices.lower_bound(simpseq->mSteps[i].mV1);
+		ub1	=	mVertices.upper_bound(simpseq->mSteps[i].mV1);
+
+		//	Removed vertex.
+		while (lb1 != ub1)
+		{
+			//	Real index.
+			v1	=	(*lb1).second;
+
+			//	Begin of iteration v0.
+			it0	=	lb0;
+
+			edge_found	=	false;
+
+			//	Remaining vertex.
+			while (it0 != ub0)
+			{
+				//	Real index.
+				v0	=	(*it0).second;
+
+				//	If edge exists.
+				if (mEdges->exists(v0,v1))
+				{
+					mEdges->contract(v1,v0);
+
+					//	Simplification sequence.
+					current_step.mV0	=	v0;
+					current_step.mV1	=	v1;
+
+					real_seq->mSteps.push_back(current_step);
+
+					edge_found	=	true;
+				}
+
+				it0++;
+			}
+
+			//	If not found a valid edge.
+			if (!edge_found)
+			{
+				//	Id new vertex.
+				new_vertex.id					=	vertex_count;
+				new_vertex.bonefrom		=	v0;
+
+				//	Simplification sequence.
+				current_step.mV0	=	new_vertex.id;
+				current_step.mV1	=	v1;
+
+				real_seq->mSteps.push_back(current_step);
+
+				//	Contracts lonely vertex.
+				mEdges->contract(v1,new_vertex.id);
+
+				//	New vertex adquires position of v0.
+				new_vertex.position.x	=	mGeoMesh->mVertexBuffer->mPosition[v0].x;
+				new_vertex.position.y	=	mGeoMesh->mVertexBuffer->mPosition[v0].y;
+				new_vertex.position.z	=	mGeoMesh->mVertexBuffer->mPosition[v0].z;
+
+				//	New vertex adquires normal of lonely one.
+				new_vertex.normal.x	=	mGeoMesh->mVertexBuffer->mNormal[v1].x;
+				new_vertex.normal.y	=	mGeoMesh->mVertexBuffer->mNormal[v1].y;
+				new_vertex.normal.z	=	mGeoMesh->mVertexBuffer->mNormal[v1].z;
+
+				//	New vertex adquires the texture cood of the lonely one.
+				new_vertex.texcoord.x	=	mGeoMesh->mVertexBuffer->mTexCoords[v1].x;
+				new_vertex.texcoord.y	=	mGeoMesh->mVertexBuffer->mTexCoords[v1].y;
+
+				//	New vertex stored.
+				real_seq->mNewVertices.push_back(new_vertex);
+
+				//	New vertex added.
+				vertex_count++;
+			}
+
+			lb1++;
+		}
+	}
+
+	//	Assigns new simplification sequence.
+	delete	simpseq;
+
+	return	real_seq;
+	/*
+	//	New vertex buffer to add new vertices.
+	mVB	=	new VertexBuffer();
+
+	mVB->mPosition	=	new Vector3[vertex_count];
+	mVB->mNormal		=	new Vector3[vertex_count];
+	mVB->mTexCoords	=	new Vector2[vertex_count];
+
+	mVB->mVertexInfo	=	mGeoMesh->mVertexBuffer->mVertexInfo;
+
+	//	Copy original vertices.
+	for (i = 0; i < mGeoMesh->mVertexBuffer->mVertexCount; i++)
+	{
+		mVB->mPosition[i].x	=	mGeoMesh->mVertexBuffer->mPosition[i].x;
+		mVB->mPosition[i].y	=	mGeoMesh->mVertexBuffer->mPosition[i].y;
+		mVB->mPosition[i].z	=	mGeoMesh->mVertexBuffer->mPosition[i].z;
+
+		mVB->mNormal[i].x	=	mGeoMesh->mVertexBuffer->mNormal[i].x;
+		mVB->mNormal[i].y	=	mGeoMesh->mVertexBuffer->mNormal[i].y;
+		mVB->mNormal[i].z	=	mGeoMesh->mVertexBuffer->mNormal[i].z;
+
+		mVB->mTexCoords[i].x	=	mGeoMesh->mVertexBuffer->mTexCoords[i].x;
+		mVB->mTexCoords[i].y	=	mGeoMesh->mVertexBuffer->mTexCoords[i].y;
+	}
+
+	//	Add new vertices.
+	j	=	mGeoMesh->mVertexBuffer->mVertexCount;
+
+	for (i = 0; i < new_vertices.size(); i++)
+	{
+		mVB->mPosition[j].x	=	new_vertices[i].position.x;
+		mVB->mPosition[j].y	=	new_vertices[i].position.y;
+		mVB->mPosition[j].z	=	new_vertices[i].position.z;
+
+		mVB->mNormal[j].x	=	new_vertices[i].normal.x;
+		mVB->mNormal[j].y	=	new_vertices[i].normal.y;
+		mVB->mNormal[j].z	=	new_vertices[i].normal.z;
+
+		mVB->mTexCoords[j].x	=	new_vertices[i].texcoord.x;
+		mVB->mTexCoords[j].y	=	new_vertices[i].texcoord.y;
+	}
+
+	//	Free memory.
+	delete	[]mGeoMesh->mVertexBuffer;
+
+	//	Reassigns main vertex buffer with new vertices.
+	mGeoMesh->mVertexBuffer	= mVB;
+
+	//	Reassign submesh vertex buffers.
+	for (i = 0; i < mGeoMesh->mSubMeshCount; i++)
+	{
+		mGeoMesh->mSubMesh[i].mVertexBuffer	=	mVB;
+	}
+	*/
+}
+
+//-------------------------------------------------------------------------
+//	Return	mesh that may have repeated vertices for texture aparence.
+//-------------------------------------------------------------------------
+Mesh	*TextureConserver::GetMesh()
+{
+	return	mGeoMesh;
+}
+
