Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 1007)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 1024)
@@ -22,5 +22,4 @@
 	-# The simplified mesh, contained in a Geometry::Mesh object.
 	-# Simplification sequence, represented by a Geometry::MeshSimplificationSequence object.
-	
 	*/
 
@@ -67,4 +66,7 @@
 			//	Progress bar function.
 			Geometry::TIPOFUNC	mUPB;
+
+			//	Sort mesh bones.
+			void	sortBones();
 	};
 
@@ -113,8 +115,5 @@
 		// Returns the simplified mesh.
 		//Mesh *GetMesh();
-
-
 	};
-
 
 	/// Implementation of a simplification algorithm based on geometry information.
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h	(revision 1009)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h	(revision 1024)
@@ -4,7 +4,10 @@
 #include	"mesh.h"
 #include	<vector>
+#include	<map>
 
 namespace	VMI
 {
+	typedef std::vector<int> INTVECTOR;
+
 	typedef struct change
 	{
@@ -63,4 +66,6 @@
 	//	Save simplification sequence in Geometry Game Tools format.
 	extern void	saveSimplificationSequence(Change	*c);
+
+	extern std::map<int, INTVECTOR> inversemap;
 }
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp	(revision 1009)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp	(revision 1024)
@@ -332,40 +332,52 @@
 }
 
+namespace VMI{
+std::map<int, INTVECTOR> inversemap;
+}
+
 //	Save simplification sequence in Geometry Game Tools format.
 extern void	VMI::saveSimplificationSequence(Change	*c)
 {
-	vmiStep	step;
-	step.mV0	=	c->u;
-	step.mV1	=	c->v;
-
-	//	If only one triangle has been deleted.
-	if (c->numDel == 1)
-	{
-		step.mT0	=	c->deleted[0].id;
-		step.mT1	=	c->deleted[0].id;
-	}
-	//	If two triangles have been deleted.
-	else
-	{
-		step.mT0	=	c->deleted[0].id;
-		step.mT1	=	c->deleted[1].id;
-	}
-
-	step.x	=	0.0;
-	step.y	=	0.0;
-	step.z	=	0.0;
-
-	//	Write obligatory field.
-	step.obligatory	=	0;
-
-	//	List of new triangles.
-	//	For each modified triangle.
-	for (int	i = 0;	i < c->numMod;	i++)
-	{
-		step.mModfaces.push_back(c->modified[i].id);
-	}
-
-	//	Add step to list of changes.
-	mVMISteps.push_back(step);
-}
-
+
+	int stepnum= 1;
+	for(INTVECTOR::iterator it= inversemap[c->u].begin(); it!=inversemap[c->u].end(); it++)
+	{
+		vmiStep	step;
+		step.mV0	=	*it;
+		step.mV1	=	c->v;
+
+		//	If only one triangle has been deleted.
+		if (c->numDel == 1)
+		{
+			step.mT0	=	c->deleted[0].id;
+			step.mT1	=	c->deleted[0].id;
+		}
+		//	If two triangles have been deleted.
+		else
+		{
+			step.mT0	=	c->deleted[0].id;
+			step.mT1	=	c->deleted[1].id;
+		}
+
+		step.x	=	0.0;
+		step.y	=	0.0;
+		step.z	=	0.0;
+
+		//	Write obligatory field.
+		if (stepnum==inversemap[c->u].size())
+			step.obligatory	=	0;
+		else
+			step.obligatory	=	1;
+		stepnum++;
+
+		//	List of new triangles.
+		//	For each modified triangle.
+		for (int	i = 0;	i < c->numMod;	i++)
+		{
+			step.mModfaces.push_back(c->modified[i].id);
+		}
+
+		//	Add step to list of changes.
+		mVMISteps.push_back(step);
+	}
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1014)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1024)
@@ -59,4 +59,84 @@
 {
 	return msimpsequence;
+}
+
+//---------------------------------------------------------------------------
+//	Sort mesh bones.
+//---------------------------------------------------------------------------
+void	MeshSimplifier::sortBones()
+{
+	Mesh									*mesh_copy;
+	int										n;
+	int 									o;
+	int										p;
+	VertexBoneAssignment	assign;
+	VertexBuffer					*mesh_vb;
+	VertexBuffer					*undo_vb;
+	SubMesh								*geosubmesh;
+	SubMesh								*undosubmesh;
+	
+	//	Gets a copy of the mesh.
+	mesh_copy		=	new Mesh();
+	*mesh_copy	=	*mGeoMesh;
+	
+	//	For each submesh.
+	for (size_t	i	=	0; i < mGeoMesh->mSubMeshCount; i++)
+	{
+		geosubmesh	=	&mGeoMesh->mSubMesh[i];
+		undosubmesh	=	&mesh_copy->mSubMesh[i];
+		
+		//	If there is submesh bones.
+		if (!geosubmesh->mBones.empty())
+		{
+			assign.boneIndex	=	0;
+			assign.weight			=	1;
+
+			geosubmesh->mBones.clear();
+
+			for (int	m	=	0;	m < geosubmesh->mVertexBuffer->mVertexCount;	m++)
+			{
+				assign.vertexIndex	=	m;
+				
+				geosubmesh->mBones.push_back(assign);
+			}
+
+			//	Change bones.
+			for (int	m = 0;	m < geosubmesh->mBones.size();	m++)
+			{
+				n	=	geosubmesh->mBones[m].vertexIndex;
+
+				//	Initialize o.
+				o	=	0;
+
+				mesh_vb	=	geosubmesh->mVertexBuffer;
+				undo_vb	=	undosubmesh->mVertexBuffer;
+
+				while (!(
+							(mesh_vb->mPosition[n].x == undo_vb->mPosition[o].x)
+							&&
+							(mesh_vb->mPosition[n].y == undo_vb->mPosition[o].y)
+							&&
+							(mesh_vb->mPosition[n].z == undo_vb->mPosition[o].z)
+							))
+				{
+					o++;
+				}
+
+				//	Initialize p.
+				p	=	0;
+
+				while (undosubmesh->mBones[p].vertexIndex != o)
+				{
+					p++;
+				}
+
+				//	Same bone for 'm' and 'p'.
+				geosubmesh->mBones[m].boneIndex	=	undosubmesh->mBones[p].boneIndex;
+			}
+		}
+	}
+
+	//	Delete copy of the mesh.
+	delete	mesh_copy;
 }
 
@@ -306,5 +386,46 @@
 
 //---------------------------------------------------------------------------
-//	Init vmi mesh structure for a geometry mesh given.
+//	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;
+		}
+};
+
+//---------------------------------------------------------------------------
+//	Initialize the mesh of VMI module.
 //---------------------------------------------------------------------------
 VMI::Mesh *	ViewPointDrivenSimplifier::initMeshStructure(Mesh	*geoMesh)
@@ -360,8 +481,31 @@
 
 	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;
@@ -394,7 +538,7 @@
 			vmi_mesh->triangles[index].id 				= index;
 			vmi_mesh->triangles[index].submesh		= submesh;
-			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].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].area = computeTriangleArea(vmi_mesh->vertices, 
