Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 980)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 1007)
@@ -78,4 +78,5 @@
 			SmallInt	mTotalStrips;		///Total strips of the multiresolution object.
 			SmallInt	mTotalVertices;	///Total vertices of the multiresolution object.
+			SmallInt	mMaxVerticesLOD;///Number of vertices of the max LOD.
 			SmallInt	mTotalChanges;	///Total changes of the multiresolution object.
 			SmallInt	mLods;					///Available Lods.
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 986)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 1007)
@@ -48,8 +48,13 @@
 			struct Step
 			{
-				Index mV0, mV1;
-				Index mT0, mT1;
-				float x,y,z;
-				std::vector<Index> mModfaces;
+				Index mV0;
+				Index	mV1;
+				Index mT0;
+				Index	mT1;
+				float x;
+				float	y;
+				float	z;
+				
+				std::vector<Index>	mModfaces;
 
 				//	Indicates the the step is obligatory to execute
@@ -78,2 +83,3 @@
 
 #endif
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 980)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 1007)
@@ -6,4 +6,5 @@
 #include	"GeoMeshSimpSequence.h"
 #include	"vmi_simplifier.h"
+#include	"change.h"
 
 //#include "SimplificationMethod.h"
@@ -86,4 +87,7 @@
 		void	findVertex(size_t	submesh, size_t	index);
 		
+		//	Gets the VMI mesh simplification sequence.
+		void	GetMeshSimpSequence();
+
 	public:
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoTreeSimplifier.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoTreeSimplifier.h	(revision 774)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoTreeSimplifier.h	(revision 1007)
@@ -6,6 +6,8 @@
 #include "Hoja.h"
 
-#define K1		0.8f //distancia
-#define K2		0.2f // coplanar
+#define K1		0.8f //distance factor
+#define K2		0.2f //coplanar factor
+
+class LeafOctree;
 
 namespace Geometry
@@ -34,15 +36,8 @@
 	public:
 		/// Class constructor. Retrieves a pointer to a valid Mesh object to simplify
-		TreeSimplifier(	const Geometry::Mesh 	*,
-										Geometry::TIPOFUNC		upb=0);
+		TreeSimplifier(const Geometry::Mesh *, Geometry::TIPOFUNC upb=0);
 
 		/// Class destructor.
 		~TreeSimplifier(void);
-
-		/// Copy constructor
-		//TreeSimplifier(const TreeSimplifier&);
-
-		/// Assignment operator
-		//TreeSimplifier& operator =(const TreeSimplifier&);
 
 		/// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1].
@@ -55,41 +50,52 @@
 		TreeSimplificationSequence *GetSimplificationSequence();
 
-	//private:
-		void Centroh(Hoja	&);
-		void GetNormal(Hoja	&);
-		void DistanciaEntreHojas(void);
-		void CoplanarEntreHojas(FILE*);
-		float DiametroEsferaEnvolvente();
-		void EstableceCriterio(float);
+	private:
+		void CalculateLeafCenter(Hoja &);
+		void CalculateLeafNormal(Hoja &);
+		float CalculateLeafArea(Hoja &) const;
+		void CoplanarBetweenLeaves(void);
+		float BoundingSphereDiameter() const;
+//		void SetCriteria(float);  // to be erased: obsolete!
+		void SetCriteriaOptimized(float);
 
-		float max(float, float);
-		float min(float, float);
+		float max(float, float) const;
+		float min(float, float) const;
 
-		//long int Colapsa (TreeSimplificationSequence *, float);
-		long int Colapsa(float);
-		void DosMayores(float*, int* );
-		void ElijeVertices(Hoja& , Hoja& , long int);
-		float Hausdorff(Hoja &, Hoja&);
-		float distan(float, float, float, float, float, float);
-		long int MinimaDistancia(void);
-		void NormalizaDistancia(float diametro);
-		void EstableceCriterio2(float, long int);
-		long int MinimoCriterio(void);
+		long int Collapse(float);
+		void TwoGreater(float*, int* );
+		void ChooseVertices(Hoja& , Hoja& , long int);
+		float HausdorffOptimized(const Hoja &, const Hoja&) const;
+		float DistanceFromCenters(const Hoja &, const Hoja &) const;
+		float distan(float, float, float, float, float, float) const;
+		long int MinDistance(void);
+		void NormalizeDistance(float diametro);
+//		void SetCriteria2(float, long int); obsolete!
+		void SetCriteria2Optimized(float, long int);
+		long int MinCriteria(void);
 
-		void Mesh2Estructura(	const Geometry::Mesh *,
-													Index);
-		
-		void EscribeMesh(int);
+		void Mesh2Structure(const Geometry::Mesh *,Index);
+		void BuildOutputMesh(int);
+		void CrossProduct(const float *v1, const float *v2, float *res) const;
+		float SquaredModule(const float *v) const;
 
-		Mesh			*mesh; // objeto mesh simplificado (para la salida)
+		Mesh			*mesh; // simplified mesh object (for output)
 		const			Mesh *objmesh;
 		float			(*Vertex)[3];
-		Hoja			*Hojasa;  // las activas
-		long int	activas, counth;
+		Hoja			*Leaves;
+		long int	activeLeaves, countLeaves;
 		TreeSimplificationSequence	*mtreesimpsequence;
 		
-	private:
 		//	Update progress bar.
 		Geometry::TIPOFUNC	mUPB;
+
+		// the octree used to speed up the simplification process
+		LeafOctree *octree;
+		void RecursiveCreateLeafOctree(LeafOctree*, int deep); // this is called from CreateLeafNode
+		void RecursiveFillOctreeWithLeaves(LeafOctree*);
+		LeafOctree* CreateLeafOctree(int deep); // generates a new leaf octree and returns its root node
+		int vertex_count;
+		LeafOctree ** octree_owning_leaf;
+		LeafOctree *GetMinOctreeNodeForLeaf(LeafOctree *start, const Hoja &leaf);
+		bool PruneOctree(LeafOctree *); // erases one octree level and translates its leaves to the parent. Returns true if the node itself was pruned
 	};
 }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 985)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 1007)
@@ -327,9 +327,5 @@
 uint32	LodStripsLibrary::MaxVertices()
 {
-	uint32	number_of_vertices;
-
-	number_of_vertices	=	mTotalVertices;
-
-	return	number_of_vertices;
+	return	mMaxVerticesLOD;
 }
 
@@ -340,5 +336,5 @@
 
 	//	Total vertices less total lod.
-	number_of_vertices	=	mTotalVertices - (mMaxLod + 1);
+	number_of_vertices	=	mMaxVerticesLOD - (mMinLod + 1);
 
 	return	number_of_vertices;
@@ -394,4 +390,7 @@
 void		LodStripsLibrary::TrimByLod(uint32 minLod, uint32 maxLod)
 {
+	//	Refresh number of vercies of the max lod.
+	mMaxVerticesLOD	+=	mMaxLod - maxLod;
+	
 	mMinLod	=	minLod;
 	mMaxLod	=	maxLod;
@@ -621,6 +620,6 @@
 		//	Max / Min values for LOD.
 		mLods											=	int(p_changes.size());
-		mMinLod										=	0;
-		mMaxLod										=	mLods;
+		mMaxLod										=	0;
+		mMinLod										=	mLods;
 
 		//// CHAPUZA PROVISIONAL: EL ULTIMO ELEMENTO SE REPITE 2 VECES V.v
@@ -632,7 +631,8 @@
 		}
 
-		mTotalVertices			=	int(mFileVertices.size());
-		mTotalStrips				=	int(mFileStrips.size());
-		mTotalChanges				=	int(mFileChangesLOD.size());
+		mTotalVertices		=	int(mFileVertices.size());
+		mMaxVerticesLOD		=	mTotalVertices;
+		mTotalStrips			=	int(mFileStrips.size());
+		mTotalChanges			=	int(mFileChangesLOD.size());
 
 		//Copy the data to the structure we will use
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/simplify.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/simplify.h	(revision 983)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/simplify.h	(revision 1007)
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 983)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h	(revision 1007)
@@ -2,40 +2,65 @@
 #define __change_h_
 
-#include "mesh.h"
+#include	"mesh.h"
+#include	<vector>
 
 namespace	VMI
 {
-typedef struct change {
-  int e;
-  int u, v;           // Edge
-  int numDel;         // Number of deleted triangles
-  Triangle *deleted;  // List of deleted triangles 
-  int numMod;         // Number of modified triangles 
-  Triangle *modified; // List of triangles deleted  
-} Change;
+	typedef struct change
+	{
+		int e;
+		int u, v;           // Edge
+		int numDel;         // Number of deleted triangles
+		Triangle *deleted;  // List of deleted triangles 
+		int numMod;         // Number of modified triangles 
+		Triangle *modified; // List of triangles deleted  
+	} Change;
 
-extern Change *createChange (Mesh *mesh, int e);
-extern void writeChange(FILE* file, Change *c);
-extern void deleteChange(Change *c);
-extern void printChange(Change *c);
+	// Represents a simplification step in the sequence.
+	struct vmiStep
+	{
+		unsigned int	mV0;
+		unsigned int	mV1;
+		unsigned int	mT0;
+		unsigned int	mT1;
+		float x;
+		float	y;
+		float	z;
+		
+		std::vector<unsigned int>	mModfaces;
 
-extern void modifyTriangle(Triangle *t, int c, int p);
-extern int isATriangleToModify(Triangle *t, int c, int p);
-extern int getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified);
-extern int isATriangleToDelete(Triangle *t, int c, int p);
-extern int getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p);
+		//	Indicates the the step is obligatory to execute
+		//	joined width the following step.
+		unsigned int obligatory;
+	};
 
-extern void modifyTriangles(Mesh *mesh, Change *c);
-extern void unmodifyTriangles(Mesh *mesh, Change *c);
-extern void deleteTriangles(Mesh *mesh, Change *c);
-extern void undeleteTriangles(Mesh *mesh, Change *c);
+	// Stores all the simplification steps.
+	extern	std::vector<vmiStep> mVMISteps;
 
-extern void printList(Triangle *list, int n);
-extern void deleteItem(Triangle *list, int *n, int item);
+	extern Change *createChange (Mesh *mesh, int e);
+	extern void writeChange(FILE* file, Change *c);
+	extern void deleteChange(Change *c);
+	extern void printChange(Change *c);
 
-extern void doChange(Mesh *mesh, Change *c);
-extern void undoChange(Mesh *mesh, Change *c);
-extern void computeChanges(Mesh *mesh, Change *c);
+	extern void modifyTriangle(Triangle *t, int c, int p);
+	extern int isATriangleToModify(Triangle *t, int c, int p);
+	extern int getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified);
+	extern int isATriangleToDelete(Triangle *t, int c, int p);
+	extern int getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p);
 
+	extern void modifyTriangles(Mesh *mesh, Change *c);
+	extern void unmodifyTriangles(Mesh *mesh, Change *c);
+	extern void deleteTriangles(Mesh *mesh, Change *c);
+	extern void undeleteTriangles(Mesh *mesh, Change *c);
+
+	extern void printList(Triangle *list, int n);
+	extern void deleteItem(Triangle *list, int *n, int item);
+
+	extern void doChange(Mesh *mesh, Change *c);
+	extern void undoChange(Mesh *mesh, Change *c);
+	extern void computeChanges(Mesh *mesh, Change *c);
+
+	//	Save simplification sequence in Geometry Game Tools format.
+	extern void	saveSimplificationSequence(Change	*c);
 }
 
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 983)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp	(revision 1007)
@@ -9,4 +9,6 @@
 
 using namespace VMI;
+
+std::vector<VMI::vmiStep> VMI::mVMISteps;
 
 Change *VMI::createChange (Mesh *mesh, int e) {
@@ -29,205 +31,228 @@
 }
 
-void VMI::deleteChange(Change *c) {
-    
-    if (NULL != c) {
-        if (c->deleted != NULL)   free(c->deleted);
-        if (c->modified != NULL)  free(c->modified);
-        c->modified = NULL;
-        c->deleted = NULL;
-        c->numDel = 0;
-        c->numMod = 0;
-        
-        free(c);
-        c = NULL;
-    }
-}
-
-void VMI::writeChange(FILE* file, Change *c) {
-    int i;
-
-    fputc('v',file);
-    fputc('%',file);
-    fprintf(file, " %d %d 0 0 0 ", c->v, c->u);
-
-    for (i=0; i<c->numDel; i++) {
-        fprintf(file, "%d ", c->deleted[i].id);
-    }
-
-    fputc('&',file);
-    for (i=0; i<c->numMod; i++) {
-        fprintf(file, " %d", c->modified[i].id);
-    }
-
-    fputc('\n',file);
-}
-
-void VMI::printChange(Change *c) {
-    int i;
-    
-    if (NULL != c) {
-        
-        printf("e%d(%d,%d)\n",c->e,c->u,c->v);
-        
-        printf("d %d\n", c->numDel);
-        for (i=0;i<c->numDel;i++) {
-            printf(" %d", c->deleted[i].id);
-        }
-        printf("\n");
-        printf("m %d\n", c->numMod);
-        for (i=0;i<c->numMod;i++) {
-            printf(" %d", c->modified[i].id);
-        }
-        printf("\n");
-    }
-}
-
-void VMI::modifyTriangle(Triangle *t, int c, int p) {
-    
-    if ((int)t->indices[0] == c)
-        t->indices[0]= p;
-    if ((int)t->indices[1] == c)
-        t->indices[1]= p;
-    if ((int)t->indices[2] == c)
-        t->indices[2]= p;
-}
-
-int VMI::isATriangleToModify(Triangle *t, int c, int p) {
-    int u = t->indices[0],
-        v = t->indices[1],
-        w = t->indices[2];
-    
-    if ((u == c) || (v == c) || (w == c)) return TRUE;
-
-    return FALSE;
-}
-
-void VMI::modifyTriangles(Mesh *mesh, Change *c) {
-    int i, t;
-    
-    for (i=0; i<c->numMod; i++) {
-        t = c->modified[i].id;
-        modifyTriangle(&mesh->triangles[t], c->u, c->v);
-
-        //printf("New area of triangle %d:\n", t);
-        mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]);
-
-        computeTriangleNormal(mesh->vertices, &mesh->triangles[t]);
-    }
-}
-
-void VMI::unmodifyTriangles(Mesh *mesh, Change *c) {
-    int i, t;
-    
-    for (i=0; i<c->numMod; i++) {
-        t = c->modified[i].id;
-
-        memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle));
-        /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], 
-                                  mesh->triangles[t].indices[1],
-                                  mesh->triangles[t].indices[2]);*/
-    }
-}
-
-void VMI::deleteTriangles(Mesh *mesh, Change *c) {
-    int i, t;
-    
-    for (i=0; i<c->numDel; i++) {
-        t = c->deleted[i].id;
-
-        //printf("Deleting triangle %d\n",t);
-        mesh->triangles[t].enable = FALSE;
-        mesh->currentNumTriangles--;
-    }
-}
-
-void VMI::undeleteTriangles(Mesh *mesh, Change *c) {
-    int i, t;
-    
-    for (i=0; i<c->numDel; i++) {
-        t = c->deleted[i].id;
-        
-        memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle));
-        /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], 
-                                  mesh->triangles[t].indices[1], 
-                                  mesh->triangles[t].indices[2]);*/
-
-        mesh->triangles[t].enable = TRUE;
-        mesh->currentNumTriangles++;
-    }
-}
-
-int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified) {
-    GLuint i, num = 0;
-    
-    for (i=0; i<mesh->numTriangles; i++) {
-        if ((mesh->triangles[i].enable == TRUE) && 
-            isATriangleToModify(&mesh->triangles[i], c, p)) {
-                                                     
-                //printf("Triangle to modify %d\n", i);
-                // Save the original values of the triangle
-                memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle));
-                num++;
-        }
-    }
-    
-    return num;
-}
-
-int VMI::isATriangleToDelete(Triangle *t, int c, int p) {
-    int u = t->indices[0],
-        v = t->indices[1],
-        w = t->indices[2];
-    
-    if (((u == c) && ( v == p)) ||
-        ((u == c) && ( w == p)) || 
-        ((v == c) && ( w == p)))
-        return TRUE;
-    if (((u == p) && ( v == c)) ||
-        ((u == p) && ( w == c)) || 
-        ((v == p) && ( w == c)))
-        return TRUE;
-
-    return FALSE;
-}
-
-int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p) {
-    int i, num = 0;
-    GLuint t;
-    
-    for (i=0; i<numMod; i++) {
-        t = modified[i].id;
-        
-        if (isATriangleToDelete(&mesh->triangles[t], c, p)) {
-                                                     
-            //printf("Triangle to delete %d\n",t);                    
-            memcpy(&deleted[num], &modified[i], sizeof(Triangle));
-            num++;
-        }
-    }
-    return num;
-}
-
-void VMI::printList(Triangle *list, int n) {
-    int i;
-    
-    for (i=0; i<n; i++)
-        printf("%d ",list[i].id);
-
-    printf("\n");
-}
-
-void VMI::deleteItem(Triangle *list, int *n, int item) {
-    int i, j;
-    
-    for (i=0; i<*n; i++) {
-        if (list[i].id == (GLuint)item) {
-            // delete it
-            for (j =i + 1 ; j<*n; j++)
-                list[j - 1] = list[j];
-            (*n)--;
-            i--; // Delete all ocurrencies of an item
-        }
-    }
+void VMI::deleteChange(Change *c)
+{
+
+	if (NULL != c)
+	{
+		if (c->deleted != NULL)   free(c->deleted);
+		if (c->modified != NULL)  free(c->modified);
+		c->modified = NULL;
+		c->deleted = NULL;
+		c->numDel = 0;
+		c->numMod = 0;
+
+		free(c);
+		c = NULL;
+	}
+}
+
+void VMI::writeChange(FILE* file, Change *c)
+{
+	int i;
+
+	fputc('v',file);
+	fputc('%',file);
+	fprintf(file, " %d %d 0 0 0 ", c->v, c->u);
+
+	for (i=0; i<c->numDel; i++) {
+		fprintf(file, "%d ", c->deleted[i].id);
+	}
+
+	fputc('&',file);
+	for (i=0; i<c->numMod; i++) {
+		fprintf(file, " %d", c->modified[i].id);
+	}
+
+	fputc('\n',file);
+}
+
+void VMI::printChange(Change *c)
+{
+	int i;
+
+	if (NULL != c) {
+
+		printf("e%d(%d,%d)\n",c->e,c->u,c->v);
+
+		printf("d %d\n", c->numDel);
+		for (i=0;i<c->numDel;i++) {
+			printf(" %d", c->deleted[i].id);
+		}
+		printf("\n");
+		printf("m %d\n", c->numMod);
+		for (i=0;i<c->numMod;i++) {
+			printf(" %d", c->modified[i].id);
+		}
+		printf("\n");
+	}
+}
+
+void VMI::modifyTriangle(Triangle *t, int c, int p)
+{
+
+	if ((int)t->indices[0] == c)
+		t->indices[0]= p;
+	if ((int)t->indices[1] == c)
+		t->indices[1]= p;
+	if ((int)t->indices[2] == c)
+		t->indices[2]= p;
+}
+
+int VMI::isATriangleToModify(Triangle *t, int c, int p)
+{
+	int u = t->indices[0],
+			v = t->indices[1],
+			w = t->indices[2];
+
+	if ((u == c) || (v == c) || (w == c)) return TRUE;
+
+	return FALSE;
+}
+
+void VMI::modifyTriangles(Mesh *mesh, Change *c)
+{
+	int i, t;
+
+	for (i=0; i<c->numMod; i++)
+	{
+		t = c->modified[i].id;
+		modifyTriangle(&mesh->triangles[t], c->u, c->v);
+
+		//printf("New area of triangle %d:\n", t);
+		mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]);
+
+		computeTriangleNormal(mesh->vertices, &mesh->triangles[t]);
+	}
+}
+
+void VMI::unmodifyTriangles(Mesh *mesh, Change *c)
+{
+	int i, t;
+
+	for (i=0; i<c->numMod; i++) {
+		t = c->modified[i].id;
+
+		memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle));
+		/*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], 
+			mesh->triangles[t].indices[1],
+			mesh->triangles[t].indices[2]);*/
+	}
+}
+
+void VMI::deleteTriangles(Mesh *mesh, Change *c)
+{
+	int i, t;
+
+	for (i=0; i<c->numDel; i++)
+	{
+		t = c->deleted[i].id;
+
+		//printf("Deleting triangle %d\n",t);
+		mesh->triangles[t].enable = FALSE;
+		mesh->currentNumTriangles--;
+	}
+}
+
+void VMI::undeleteTriangles(Mesh *mesh, Change *c)
+{
+	int i, t;
+
+	for (i=0; i<c->numDel; i++)
+	{
+		t = c->deleted[i].id;
+
+		memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle));
+		/*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], 
+			mesh->triangles[t].indices[1], 
+			mesh->triangles[t].indices[2]);*/
+
+		mesh->triangles[t].enable = TRUE;
+		mesh->currentNumTriangles++;
+	}
+}
+
+int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified)
+{
+	GLuint i, num = 0;
+
+	for (i=0; i<mesh->numTriangles; i++)
+	{
+		if ((mesh->triangles[i].enable == TRUE) && 
+				isATriangleToModify(&mesh->triangles[i], c, p))
+		{
+
+			//printf("Triangle to modify %d\n", i);
+			// Save the original values of the triangle
+			memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle));
+			num++;
+		}
+	}
+
+	return num;
+}
+
+int VMI::isATriangleToDelete(Triangle *t, int c, int p)
+{
+	int u = t->indices[0],
+			v = t->indices[1],
+			w = t->indices[2];
+
+	if (((u == c) && ( v == p)) ||
+			((u == c) && ( w == p)) || 
+			((v == c) && ( w == p)))
+		return TRUE;
+	if (((u == p) && ( v == c)) ||
+			((u == p) && ( w == c)) || 
+			((v == p) && ( w == c)))
+		return TRUE;
+
+	return FALSE;
+}
+
+int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p)
+{
+	int i, num = 0;
+	GLuint t;
+
+	for (i=0; i<numMod; i++)
+	{
+		t = modified[i].id;
+
+		if (isATriangleToDelete(&mesh->triangles[t], c, p))
+		{                                             
+			//printf("Triangle to delete %d\n",t);                    
+			memcpy(&deleted[num], &modified[i], sizeof(Triangle));
+			num++;
+		}
+	}
+	return num;
+}
+
+void VMI::printList(Triangle *list, int n)
+{
+	int i;
+
+	for (i=0; i<n; i++)
+		printf("%d ",list[i].id);
+
+	printf("\n");
+}
+
+void VMI::deleteItem(Triangle *list, int *n, int item)
+{
+	int i, j;
+
+	for (i=0; i<*n; i++)
+	{
+		if (list[i].id == (GLuint)item)
+		{
+			// delete it
+			for (j =i + 1 ; j<*n; j++)
+				list[j - 1] = list[j];
+			(*n)--;
+			i--; // Delete all ocurrencies of an item
+		}
+	}
 }
 
@@ -235,64 +260,111 @@
 
 // Compute the triangle mesh changes due to a heap node simplification
-void VMI::computeChanges(Mesh *mesh, Change *c) {
-    Triangle m[MAX_NUM_TRI], d[MAX_NUM_TRI/2];
-    int numMod = getTrianglesToModify(mesh, c->u, c->v, m);
-    int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v);
-    int i;
-    
-    //printf("d %d\n",numDel);
-    //printList(d, numDel);
-
-    for (i=0; i<numDel; i++)
-        deleteItem(m, &numMod, d[i].id);
-
-    //printf("m %d\n",numMod);
-    //printList(m, numMod);
-    //getchar();
-    
-    c->numDel = numDel;
-    // Free memory
-    if (c->deleted != NULL) free(c->deleted);
-    // Allocate memory
-    c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel);
-    if (c->deleted == NULL) {
-        fprintf(stderr, "Error allocating memory\n");
-        exit(1);
-    }
-    memcpy(c->deleted, d, sizeof(Triangle) * numDel);
-    
-    c->numMod = numMod;
-    // Free memory
-    if (c->modified != NULL) free(c->modified);
-    // Allocate memory
-    c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod);
-    if (c->modified == NULL) {
-        fprintf(stderr, "Error allocating memory\n");
-        exit(1);
-    }
-    memcpy(c->modified, m, sizeof(Triangle) * numMod);
-
-    //printChange(c);
-    //getchar();
+void VMI::computeChanges(Mesh *mesh, Change *c)
+{
+	Triangle m[MAX_NUM_TRI], d[MAX_NUM_TRI/2];
+	int numMod = getTrianglesToModify(mesh, c->u, c->v, m);
+	int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v);
+	int i;
+
+	//printf("d %d\n",numDel);
+	//printList(d, numDel);
+
+	for (i=0; i<numDel; i++)
+		deleteItem(m, &numMod, d[i].id);
+
+	//printf("m %d\n",numMod);
+	//printList(m, numMod);
+	//getchar();
+
+	c->numDel = numDel;
+	// Free memory
+	if (c->deleted != NULL) free(c->deleted);
+	// Allocate memory
+	c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel);
+	
+	if (c->deleted == NULL)
+	{
+		fprintf(stderr, "Error allocating memory\n");
+		exit(1);
+	}
+	
+	memcpy(c->deleted, d, sizeof(Triangle) * numDel);
+
+	c->numMod = numMod;
+	
+	// Free memory
+	if (c->modified != NULL) free(c->modified);
+	
+	// Allocate memory
+	c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod);
+	
+	if (c->modified == NULL)
+	{
+		fprintf(stderr, "Error allocating memory\n");
+		exit(1);
+	}
+	
+	memcpy(c->modified, m, sizeof(Triangle) * numMod);
+
+	//printChange(c);
+	//getchar();
 }
 
 // Update the triangle mesh due to a heap node simplification
-void VMI::doChange(Mesh *mesh, Change *c) {
-    
-    modifyTriangles(mesh, c);
-    
-    deleteTriangles(mesh, c);
-
-    mesh->vertices[c->u].enable = FALSE;
-    mesh->currentNumVertices--;
-}
-
-void VMI::undoChange(Mesh *mesh, Change *c) {
-    
-    unmodifyTriangles(mesh, c);
-    
-    undeleteTriangles(mesh, c);
-
-    mesh->vertices[c->u].enable = TRUE;
-    mesh->currentNumVertices++;
-}
+void VMI::doChange(Mesh *mesh, Change *c)
+{
+	modifyTriangles(mesh, c);
+
+	deleteTriangles(mesh, c);
+
+	mesh->vertices[c->u].enable = FALSE;
+	mesh->currentNumVertices--;
+}
+
+void VMI::undoChange(Mesh *mesh, Change *c)
+{    
+	unmodifyTriangles(mesh, c);
+
+	undeleteTriangles(mesh, c);
+
+	mesh->vertices[c->u].enable = TRUE;
+	mesh->currentNumVertices++;
+}
+
+//	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);
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/simplify.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/simplify.cpp	(revision 983)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/simplify.cpp	(revision 1007)
@@ -424,97 +424,132 @@
 ///////////////////////////////////////////////////////////////////////////////
 
-void VMI::simplifyModel(Mesh *mesh, GLuint numDemandedTri) {
-    int e;
-    Change *c;
-    FILE* file = NULL;
-    char s[MAX_CHAR];
-    double cost = 0.0;
-    bheap_t *h = NULL;
-    float	percent	=	(40.0) / (float)(mesh->numTriangles - numDemandedTri);
-
-    if (numDemandedTri > mesh->currentNumTriangles) return;
-
-    if (bSaveLog == TRUE) { // Save changes into a file
+void VMI::simplifyModel(Mesh *mesh, GLuint numDemandedTri)
+{
+	int			e;
+	Change	*c;
+	FILE		*file 					= NULL;
+	FILE		*file_simp_seq	=	NULL;
+	char		s[MAX_CHAR];
+	double	cost 						= 0.0;
+	bheap_t	*h 							= NULL;
+	float		percent	=	(40.0) / (float)(mesh->numTriangles - numDemandedTri);
+
+	if (numDemandedTri > mesh->currentNumTriangles)
+	{
+		return;
+	}
+
+	// Save changes into a file
+	if (bSaveLog == TRUE)
+	{
 #ifdef SALIENCY       
 #ifdef KL // Kullback-Leibler
-        sprintf(s,"%s_VKL_S.log", filename);
+		sprintf(s,"%s_VKL_S.log", filename);
 #endif
 #ifdef MI // Mutual Information
-        sprintf(s,"%s_VMI_S.log", filename);
+		sprintf(s,"%s_VMI_S.log", filename);
 #endif
 #ifdef HE // Hellinger
-        sprintf(s,"%s_VHE_S.log", filename);
+		sprintf(s,"%s_VHE_S.log", filename);
 #endif
 #ifdef CS // Chi-Square
-        sprintf(s,"%s_VCS_S.log", filename);
+		sprintf(s,"%s_VCS_S.log", filename);
 #endif
 #else
 #ifdef KL // Kullback-Leibler
-        sprintf(s,"%s_VKL.log", filename);
+		sprintf(s,"%s_VKL.log", filename);
 #endif
 #ifdef MI // Mutual Information
-        sprintf(s,"%s_VMI.log", filename);
+		sprintf(s,"%s_VMI.log", filename);
 #endif
 #ifdef HE // Hellinger
-        sprintf(s,"%s_VHE.log", filename);
+		sprintf(s,"%s_VHE.log", filename);
 #endif
 #ifdef CS // Chi-Square
-        sprintf(s,"%s_VCS.log", filename);
-#endif
-#endif
-        
-        glmWriteOBJ(pmodel, s, GLM_NONE);
-        
-        /* open the file */
-        file = fopen(s, "a+");
-        if (!file) {
-            fprintf(stderr, "simplifyModel() failed: can't open file \"%s\" to write.\n", s);
-            exit(1);
-        }
-    }
-
-    h = initHeap(mesh);
-
-    printf("Starting simplification...\n");
-
-    while (mesh->currentNumTriangles > numDemandedTri /*&& cost == 0.0*/) {
-        
-        // Get the edge that has the minimum cost
-        e = bh_min(h);
-
-        c = createChange(mesh, e);
-
-        // Apply the edge collapse
-        computeChanges(mesh, c);
-        doChange(mesh, c);
-
-        if (bSaveLog == TRUE) writeChange(file, c);
-
-        cost = h->a[h->p[e]].key;
-        printf("Edge collapse e%d(%d,%d) %f MIN d %d m %d\n",c->e, c->u, c->v, cost, c->numDel, c->numMod);
-
-        mesh->edges[e].enable = FALSE;
-        bh_delete(h, e);
-        
-        // Get projected areas after the edge collapse
-        getProjectedAreas(histogram, numCameras);
-
-        computeCameraIs(histogram, numCameras, initialIs);
-
-        // Update the heap according to the edge collapse
-        h = updateHeap(h, mesh, c);
-
-				mUPB((float)c->numDel * percent);
-
-        deleteChange(c);
-
-        printf("t %d\n", mesh->currentNumTriangles);
-    }
-
-    if (bSaveLog == TRUE) {
-        fclose(file);
-        printf("Log file written...Ok\n");
-    }
-
-    bh_free(h);
-}
+		sprintf(s,"%s_VCS.log", filename);
+#endif
+#endif
+
+		glmWriteOBJ(pmodel, s, GLM_NONE);
+
+		/* open the file */
+		file = fopen(s, "a+");
+		
+		if (!file)
+		{
+			fprintf(stderr, "simplifyModel() failed: can't open file \"%s\" to write.\n", s);
+			exit(1);
+		}
+	}
+
+	//	Open file of simplification sequence.
+	file_simp_seq	=	fopen("SimplifSequence.txt", "w");
+	
+	if (!file_simp_seq)
+	{
+		fprintf(stderr,
+						"simplifyModel() failed: ",
+						"can't open file \"SimplifSequence\" to write.\n");
+	}
+	
+	h = initHeap(mesh);
+
+	printf("Starting simplification...\n");
+
+	while (mesh->currentNumTriangles > numDemandedTri /*&& cost == 0.0*/)
+	{
+		// Get the edge that has the minimum cost
+		e = bh_min(h);
+
+		c = createChange(mesh, e);
+
+		// Apply the edge collapse
+		computeChanges(mesh, c);
+		doChange(mesh, c);
+
+		if (bSaveLog == TRUE) writeChange(file, c);
+
+		//	Write Simplification sequence.
+		saveSimplificationSequence(c);
+		
+		cost = h->a[h->p[e]].key;
+		
+		printf(	"Edge collapse e%d(%d,%d) %f MIN d %d m %d\n",
+						c->e,
+						c->u,
+						c->v,
+						cost,
+						c->numDel,
+						c->numMod);
+
+		mesh->edges[e].enable = FALSE;
+		
+		bh_delete(h, e);
+
+		// Get projected areas after the edge collapse
+		getProjectedAreas(histogram, numCameras);
+
+		computeCameraIs(histogram, numCameras, initialIs);
+
+		// Update the heap according to the edge collapse
+		h = updateHeap(h, mesh, c);
+
+		mUPB((float)c->numDel * percent);
+
+		deleteChange(c);
+
+		printf("t %d\n", mesh->currentNumTriangles);
+	}
+
+	if (bSaveLog == TRUE)
+	{
+		fclose(file);
+		printf("Log file written...Ok\n");
+	}
+
+	//	Close simplification sequence file.
+	fclose(file_simp_seq);
+
+	bh_free(h);
+}
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 986)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 1007)
@@ -222,16 +222,23 @@
 	simplifstep.y = (float)vdesp[qslim::Y];
 	simplifstep.z = (float)vdesp[qslim::Z];
-	simplifstep.mV1 = v0->validID(); // the simplification method returns as v0 the alive vertex
-	simplifstep.mV0 = v1->validID(); // the simplification method returns as v1 the dead vertex
-
-	// Number of triangles that are removed in this simplification step
-	int _numDelTris = 0; // 1 or 2 triangles can be removed
-
-	for (i=0; i<changed.length(); i++)
-	{
-		if (! changed(i)->isValid())
+	
+	//	Submeshes which pertains each vertex
+	simplifstep.mV1 = v0->validID(); 
+
+	//	The simplification method returns as v1 the dead vertex.
+	simplifstep.mV0 = v1->validID();
+
+	//	Number of triangles that are removed in this simplification step.
+	int _numDelTris = 0; // 1 or 2 triangles can be removed.
+
+	for (i = 0;	i < changed.length();	i++)
+	{
+		if (!changed(i)->isValid())
+		{
 			_numDelTris++;
-	}
-	int del_index=0;
+		}
+	}
+
+	int del_index	=	0;
 
 	// mModfaces y mT0, mT1 of simplifstep stores the triangles id's -> geomesh has not triangles id's
@@ -239,10 +246,11 @@
 	{
 		qslim::Face *auxface = changed(i);
-		if (auxface->isValid()) 
+
+		if (auxface->isValid())
 		{
 			// Modified triangles
 			simplifstep.mModfaces.push_back(auxface->validID());
 		}
-		else 
+		else
 		{
 			// Removed triangles
@@ -252,12 +260,12 @@
 				simplifstep.mT1=auxface->validID();
 			}
-			else 
-			{
-				if(del_index==0) 
+			else
+			{
+				if(del_index==0)
 				{
 					simplifstep.mT0=auxface->validID();
 					del_index++;
 				}
-				else 
+				else
 				{
 					simplifstep.mT1=auxface->validID();
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 981)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 1007)
@@ -22,43 +22,89 @@
 	int initialFaceCount;
 
-	inline qslim::vert_info& vertex_info(qslim::Vertex *v){	return vinfo(v->validID()); }
-	qslim::real pair_mesh_penalty(qslim::Model& M, qslim::Vertex *v1, qslim::Vertex *v2, qslim::Vec3& vnew);
-	int predict_face(qslim::Face& F, qslim::Vertex *v1, qslim::Vertex *v2, qslim::Vec3& vnew, qslim::Vec3& f1, qslim::Vec3& f2, qslim::Vec3& f3);
+	inline qslim::vert_info& vertex_info(qslim::Vertex *v)
+	{
+		return vinfo(v->validID());
+	}
+	
+	qslim::real pair_mesh_penalty(qslim::Model& M,
+																qslim::Vertex *v1,
+																qslim::Vertex *v2,
+																qslim::Vec3& vnew);
+	
+	int predict_face(qslim::Face& F,
+									qslim::Vertex *v1,
+									qslim::Vertex *v2,
+									qslim::Vec3& vnew,
+									qslim::Vec3& f1,
+									qslim::Vec3& f2,
+									qslim::Vec3& f3);
+	
 	bool check_for_pair(qslim::Vertex *v0, qslim::Vertex *v1);
+	
 	qslim::pair_info *new_pair(qslim::Vertex *v0, qslim::Vertex *v1);
+	
 	void delete_pair(qslim::pair_info *pair);
+	
 	void do_contract(qslim::Model& m, qslim::pair_info *pair);
+	
 	bool decimate_quadric(qslim::Vertex *v, qslim::Mat4& Q);
+	
 	void decimate_contract(qslim::Model& m);
+	
 	qslim::real decimate_error(qslim::Vertex *v);
+	
 	qslim::real decimate_min_error();
+	
 	qslim::real decimate_max_error(qslim::Model& m);
+	
 	void decimate_init(qslim::Model& m, qslim::real limit);
+	
 	bool pair_is_valid(qslim::Vertex *u, qslim::Vertex *v);
+	
 	void simplifmethod_run(int,	Geometry::TIPOFUNC	upb=0);
+	
 	void simplifmethod_runv(int,	Geometry::TIPOFUNC	upb=0);
+	
 	void simplifmethod_init(void);
 
-	//To map the mesh with de simplification method structure
-	std::map<int,std::vector<int> > submeshmap; //submeshes which pertains each vertex
-	std::map<int,std::vector<int> > vertexbuffermap; //vertices of the VertexBuffer that point at this vertex of the simplification method
+	//	To map the mesh with de simplification method structure.
+	//	Submeshes which pertains each vertex.
+	std::map<int,std::vector<int> > submeshmap;
+	
+	//	Vertices of the VertexBuffer that point 
+	//	at this vertex of the simplification method.
+	std::map<int,std::vector<int> > vertexbuffermap; 
 
-	//simplification sequence of the simplification method
+	//	Simplification sequence of the simplification method.
 	std::vector<Geometry::MeshSimplificationSequence::Step> decim_data;
+	
 	std::string meshName;
+	
 	void WriteOBJ(void);
+	
 	unsigned int *first_index_submesh;
+	
 	//std::vector<qslim::pair_info *> pointers_to_remove;
 
 	int indexMeshLeaves;
+	
 public:
+	
 	const Geometry::Mesh *objmesh;
-	int number_of_triangles; //total number of triangles of all the submeshes
+	
+	//	Total number of triangles of all the submeshes.
+	int number_of_triangles;
+	
 	SimplificationMethod(const Geometry::Mesh *m);
+	
 	void geomesh2simplifModel(void);
-	Geometry::MeshSimplificationSequence *Decimate(float lod, int simpliftype,Geometry::TIPOFUNC	upb=0);
+	
+	Geometry::MeshSimplificationSequence *Decimate(	float lod,
+																									int simpliftype,
+																									Geometry::TIPOFUNC	upb=0);
+	
 	void setMeshLeaves(int meshLeaves);
 
-	//	Gets mesh simplified.
+	///	Gets mesh simplified.
 	Geometry::Mesh	*	GetMesh();
 	
@@ -66,2 +112,3 @@
 	~SimplificationMethod();
 };
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp	(revision 774)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp	(revision 1007)
@@ -63,5 +63,5 @@
 }
 
-void MeshSimplificationSequence::Save(Serializer &s) 
+void MeshSimplificationSequence::Save(Serializer &s)
 {
 	//Stores the simplification sequence in a file
@@ -78,5 +78,5 @@
 		sprintf(simp,"%u %u %u %u %u %f &", paso.mV0, paso.mV1, paso.mT0, paso.mT1,paso.obligatorio,paso.x);
 		s.WriteData(simp,sizeof(char),strlen(simp));
-		for (unsigned int j=0; j<paso.mModfaces.size(); j++) 
+		for (unsigned int j=0; j<paso.mModfaces.size(); j++)
 		{
 			sprintf(simp," %u",paso.mModfaces.operator [](j));
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 985)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1007)
@@ -139,5 +139,5 @@
 	VMI::bLoadCamerasFromFile = GL_FALSE;
 
-	VMI::cameraType = 1;
+	VMI::cameraType = 2;
 	VMI::radius = 1.3;
 	VMI::fov = 60.0;
@@ -169,5 +169,6 @@
 
 	//glutInit(&argc, argv);
-	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); /* RGB and Alpha */
+	// RGB and Alpha.
+	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); 
 	glutInitWindowSize(VMI::width, VMI::height);
 	glutInitWindowPosition(100, 100);
@@ -262,4 +263,6 @@
 	//	Load a geometry mesh for vmi mesh.
 	loadMesh();
+
+	GetMeshSimpSequence();
 }
 
@@ -287,4 +290,5 @@
 	loadMesh();
 
+	GetMeshSimpSequence();
 }
 
@@ -294,4 +298,51 @@
 //	return mGeoMesh;
 //}
+
+//---------------------------------------------------------------------------
+//	Gets the VMI mesh simplification sequence.
+//---------------------------------------------------------------------------
+void	ViewPointDrivenSimplifier::GetMeshSimpSequence()
+{
+	unsigned	int j = 0;
+	
+	MeshSimplificationSequence::Step	current_step;
+	
+	msimpsequence	=	new MeshSimplificationSequence();
+	
+	//	Debug.
+	cout	<<	"GetMeshsimpSequence VMI"
+				<<	endl;
+
+	//	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.obligatorio	=	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++;
+		}
+		
+		//	Debug.
+		cout	<<	"Step "
+					<<	i
+					<<	" added."
+					<<	endl;
+		
+		msimpsequence->mSteps.push_back(current_step);
+	}
+}
 
 //---------------------------------------------------------------------------
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoTreeSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoTreeSimplifier.cpp	(revision 998)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoTreeSimplifier.cpp	(revision 1007)
@@ -4,19 +4,31 @@
 #include <iostream>
 #include <fstream>
-#include <ctime>
 
 using namespace Geometry;
 using namespace std;
 
-TreeSimplifier::TreeSimplifier(	const	Mesh	*m,
-																TIPOFUNC		upb)
-{
-	objmesh						=	m;
-	mtreesimpsequence	=	new Geometry::TreeSimplificationSequence();
-	//mtreesimpsequence=NULL;
-	activas	=	0;
-	counth	=	0;
-
-	// Mesh de salida
+const int VISIT_PARENTS_DEEP=1;
+
+class LeafOctree
+{
+public:
+	float left, right, bottom, top, front, back;
+	std::vector<int> leaves; ///< leaves that are too much big to fit in any of the child leaves of this octree leaf
+	LeafOctree* parent;
+	LeafOctree* children[8];
+	bool PointInsideOctree(float x, float y, float z) const {
+		return (x>=left && x<=right && y>=bottom && y<=top && z>=front && z<=back);
+	}
+	bool HasChildren(void) const { return (children[0] && children[1] && children[2] && children[3] && children[4] && children[5] && children[6] && children[7]); }
+};
+
+TreeSimplifier::TreeSimplifier(const Mesh *m, TIPOFUNC upb)
+{
+	objmesh	= m;
+	mtreesimpsequence = new Geometry::TreeSimplificationSequence();
+	activeLeaves =	0;
+	countLeaves	 =	0;
+
+	// Output mesh
 	mesh	=	new Geometry::Mesh();
 	*mesh	=	*m;
@@ -41,103 +53,106 @@
 	return	mtreesimpsequence;
 }
-
+/*#include <time.h> // necesario para gettickcount
+#include <map>*/
 void TreeSimplifier::Simplify(Real lodfactor,	Index meshLeaves)
 {
-	// paramlod indica el número de vértices
 	long	int	totalv;
-	long	int	hnueva;
-	float			diam;
-
-	//	2006-02-22
-	float			percent;
-	long	int	update;
-	
+	long	int	newleaf;
+	float	diam;
+
 	totalv	=	0;
-	
-	Mesh2Estructura(objmesh, meshLeaves);
-	
-	diam = DiametroEsferaEnvolvente();
-
-	EstableceCriterio(diam);
-
-	float paramlod = lodfactor * activas * 0.01f;
-
-	// El paramlod lo uso como condición de parada de la simplificación
-	if (paramlod >= 6)
-	{
-		//	2006-02-22
-		update	=	long((activas - (6 * paramlod)) / 80);
-		percent	=	0.5;
-		
-		while ( activas > (6*paramlod))
-		{
-			//	2006-02-22
-			if (mUPB	&&	(((long int)(activas - (6 * paramlod)) % update) == 0))
-			{
-				mUPB(percent);
-			}
-			
-			hnueva	=	Colapsa(diam);
-			
-			EstableceCriterio2(diam, hnueva);
-		}
-	}
-	else
-	{
-		//	2006-02-22
-		update	=	(activas - 6) / 80;
-		percent	=	0.5;
-		
-		while ( activas > 6) 
-		{
-			//	2006-02-22
-			if (mUPB	&&	(((activas - 6) % update) == 0))
-			{
-				mUPB(percent);
-			}
-			
-			hnueva	=	Colapsa(diam);
-			
-			EstableceCriterio2(diam, hnueva);
-		}
-	}
-
-	EscribeMesh(meshLeaves);
-	
-	//	2006-02-22
-	//	Fit progress bar to 100%.
-	if (mUPB)
-	{
-		mUPB(40);
-	}
-}
-
-void TreeSimplifier::Mesh2Estructura(	const Mesh	*mesh,
-																			Index				meshLeaves)
-{
-	// Calcular el número de vértices
+
+/*	// DEBUG
+	FILE *f = fopen("timelog.txt","wt");
+	int initime = time(0);
+	fprintf(f,"initime: %d", initime); fflush(f);
+	// DEBUG*/
+	
+	Mesh2Structure(objmesh, meshLeaves);
+	
+	diam = BoundingSphereDiameter();
+
+	// precalculate the octree to speed up the simplification process
+	const int octree_deep = 2;
+	octree=CreateLeafOctree(octree_deep);
+
+	SetCriteriaOptimized(diam);
+
+	int target_face_count = (int)((lodfactor*0.01f) * activeLeaves);
+	int update_each = (activeLeaves - target_face_count)/68;
+//	int prune_each = octree_deep?(activeLeaves - target_face_count)/octree_deep:0;
+	
+//	FILE *fp = fopen("pruning.txt","wt"); // DEBUG
+
+/*	std::map<float,int> hojas_x_crit;
+	for (int i=0; i<countLeaves; i++)
+		hojas_x_crit[Leaves[i].criterio] = i;
+
+	int *leaf_order = new int[countLeaves];
+	std::map<float,int>::iterator kkit = hojas_x_crit.begin();
+	for (int i=0; i<countLeaves; i++, kkit++)
+		leaf_order[i] = kkit->second;*/
+
+//	int erased_leaves = 0;
+	while (activeLeaves > target_face_count)
+	{
+		static int erased_faces_since_last_update = 0;
+		if (mUPB && erased_faces_since_last_update >= update_each)
+		{
+			erased_faces_since_last_update=0;
+			mUPB(1);
+		}
+
+/*		static int erased_faces_since_last_prune = 0;
+		if (octree_deep && erased_faces_since_last_prune >= prune_each)
+		{
+			erased_faces_since_last_prune=0;
+			int pruneinitime = time(0);
+			PruneOctree(octree);
+			int prunefintime = time(0);
+			// DEBUG			
+			fprintf(fp,"pruning at %d activeLeaves [%d (s)]\n", activeLeaves, prunefintime-pruneinitime); fflush(f);
+			// DEBUG
+		}*/
+
+		erased_faces_since_last_update++;				
+//		erased_faces_since_last_prune++;
+
+		newleaf	= Collapse(diam);
+		SetCriteria2Optimized(diam, newleaf);
+//		erased_leaves++;
+	}
+
+//	fclose(fp);
+
+/*	int fintime = time(0);
+	fprintf(f,"fintime: %d",fintime); fflush(f);
+	fprintf(f,"total: %d (s)",fintime-initime); fflush(f);
+	fclose(f);*/
+
+	BuildOutputMesh(meshLeaves);	
+}
+
+void TreeSimplifier::Mesh2Structure(const Mesh *mesh, Index meshLeaves)
+{
 	long int countv=0;
 	long int pos=0;
 	long int v1, v2, v3;
-	long int num_triangulo=0; // Identifica los triángulos en las hojas
-
-	//	2006-02-21.
-	float			percent;
-	long	int	update;
-	
-	countv+=(long int)mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount;
+	long int triangleID=0;
+
+	countv += vertex_count = (int)mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount;	
 	Vertex  = new float[2*countv][3];
-	
-	//	2006-02-21.
-	update	=	long(mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount / 20);
-	percent	=	0.5;
+		
+	int update_each = (int)(mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount / 5);
 	
 	for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mVertexBuffer->mVertexCount; j++)
 	{
-		//	2006-02-21.
-		if (mUPB	&&	((j % update) == 0))
-		{
-			mUPB(percent);
-		}
+		static int ticks_since_last_update = 0;
+		if (mUPB && ticks_since_last_update>=update_each)
+		{
+			ticks_since_last_update=0;
+			mUPB(1);
+		}
+		ticks_since_last_update++;
 		
 		Vertex[pos][0] = mesh->mSubMesh[meshLeaves].mVertexBuffer->mPosition[j].x; 
@@ -147,54 +162,53 @@
 	}
 
-	// Calcular el número de hojas
-	counth+=(long)mesh->mSubMesh[meshLeaves].mIndexCount;
-	counth=counth/6; // Se supone que cada 6 índices forman una hoja.
-
-	if ( counth > 0)
-	{
-		Hojasa  = new Hoja[2*counth];
-	}
-
-	activas = counth;
-
-	// Insertar las hojas en la estructura
+	// Calculate the number of leaves
+	countLeaves += (long)mesh->mSubMesh[meshLeaves].mIndexCount;
+	countLeaves=countLeaves/6; // Each leaf is composed of 6 indices
+
+	if (countLeaves > 0)
+		Leaves = new Hoja[2*countLeaves];
+
+	activeLeaves = countLeaves;
+
+	// Insert leaves into the structure
 	pos=0;
 
-	update	=	long(mesh->mSubMesh[meshLeaves].mIndexCount	/ 20);
-	percent	=	0.5;
-	
-	// Cada hoja son 6 vértices
+	update_each = (int)(mesh->mSubMesh[meshLeaves].mIndexCount / 5);
+	
+	// Each leaf is composed of 6 vertices
 	for (unsigned int j=0; j<mesh->mSubMesh[meshLeaves].mIndexCount; j=j+6) 
 	{
-		//	2006-02-21.
-		if (mUPB	&&	((j % update) == 0))
-		{
-			mUPB(percent);
-		}
+		static int ticks_since_last_update = 0;
+		if (mUPB && ticks_since_last_update>=update_each)
+		{
+			ticks_since_last_update=0;
+			mUPB(1);
+		}
+		ticks_since_last_update+=6;
 		
-		// Primer triángulo
+		// first triangle
 		v1=mesh->mSubMesh[meshLeaves].mIndex[j];
 		v2=mesh->mSubMesh[meshLeaves].mIndex[j+1];
 		v3=mesh->mSubMesh[meshLeaves].mIndex[j+2];
-		Hojasa[pos].Vert_Hoja[0]=v1;
-		Hojasa[pos].Vert_Hoja[1]=v2;
-		Hojasa[pos].Vert_Hoja[2]=v3;
-		Hojasa[pos].id_triangulo[0]=num_triangulo;
-		Hojasa[pos].existe=true;
-		num_triangulo++;
-
-		// Segundo triángulo
+		Leaves[pos].Vert_Hoja[0]=v1;
+		Leaves[pos].Vert_Hoja[1]=v2;
+		Leaves[pos].Vert_Hoja[2]=v3;
+		Leaves[pos].id_triangulo[0]=triangleID;
+		Leaves[pos].existe=true;
+		triangleID++;
+
+		// second triangle
 		v3=mesh->mSubMesh[meshLeaves].mIndex[j+5];
-		Hojasa[pos].Vert_Hoja[3]=v3;
-		Hojasa[pos].id_triangulo[1]=num_triangulo;
-		num_triangulo++;
-
-		Centroh(Hojasa[pos]);
-		GetNormal(Hojasa[pos]);
+		Leaves[pos].Vert_Hoja[3]=v3;
+		Leaves[pos].id_triangulo[1]=triangleID;
+		triangleID++;
+
+		CalculateLeafCenter(Leaves[pos]);
+		CalculateLeafNormal(Leaves[pos]);
 		pos++;
 	}
 }
 
-float TreeSimplifier::max(float a,	float b)
+float TreeSimplifier::max(float a,	float b) const
 {
 	if (a>b) return (a);
@@ -202,5 +216,5 @@
 }
 
-float TreeSimplifier::min(float a,	float b)
+float TreeSimplifier::min(float a,	float b) const
 {
 	if (a>b) return (b);
@@ -208,20 +222,11 @@
 }
 
-float TreeSimplifier::distan(	float	x1,	float	y1,	float	z1,
-															float x2,	float y2,	float z2)
-{
-	float dist = 0;
-
-	dist = ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)) + ((z2-z1)*(z2-z1));
-
-	return ( dist);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-//  CALCULA EL CENTRO DE UNA HOJA
-//--------------------------------------------------------------------------------------------------------------------------------
-
-
-void TreeSimplifier::Centroh(Hoja	&Hoja1)
+float TreeSimplifier::distan(float x1, float y1, float z1, float x2, float y2, float z2) const
+{
+	return ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)) + ((z2-z1)*(z2-z1));
+}
+
+// Calculates the center of a leaf
+void TreeSimplifier::CalculateLeafCenter(Hoja &auxleaf)
 {
 	float	max_x;
@@ -233,47 +238,34 @@
 	
 	//x1
-	max_x	=	max(max(Vertex[Hoja1.Vert_Hoja[0]][0],
-									Vertex[Hoja1.Vert_Hoja[1]][0]),
-				  		max(Vertex[Hoja1.Vert_Hoja[2]][0],
-									Vertex[Hoja1.Vert_Hoja[3]][0]));
-	
-	min_x	=	min(min(Vertex[Hoja1.Vert_Hoja[0]][0],
-									Vertex[Hoja1.Vert_Hoja[1]][0]),
-				  		min(Vertex[Hoja1.Vert_Hoja[2]][0],
-									Vertex[Hoja1.Vert_Hoja[3]][0]));
-
-	Hoja1.Centro[0] = (max_x + min_x)/2;
+	max_x	=	max(max(Vertex[auxleaf.Vert_Hoja[0]][0],Vertex[auxleaf.Vert_Hoja[1]][0]),
+				    max(Vertex[auxleaf.Vert_Hoja[2]][0],Vertex[auxleaf.Vert_Hoja[3]][0]));
+	
+	min_x	=	min(min(Vertex[auxleaf.Vert_Hoja[0]][0],Vertex[auxleaf.Vert_Hoja[1]][0]),
+				  	min(Vertex[auxleaf.Vert_Hoja[2]][0],Vertex[auxleaf.Vert_Hoja[3]][0]));
+
+	auxleaf.Centro[0] = (max_x + min_x)/2;
 
 	//y1
-	max_y	=	max(max(Vertex[Hoja1.Vert_Hoja[0]][1],
-									Vertex[Hoja1.Vert_Hoja[1]][1]),
-				  		max(Vertex[Hoja1.Vert_Hoja[2]][1],
-									Vertex[Hoja1.Vert_Hoja[3]][1]));
-	
-	min_y	=	min(min(Vertex[Hoja1.Vert_Hoja[0]][1],
-									Vertex[Hoja1.Vert_Hoja[1]][1]),
-				  		min(Vertex[Hoja1.Vert_Hoja[2]][1],
-									Vertex[Hoja1.Vert_Hoja[3]][1]));
-
-	Hoja1.Centro[1]	=	(max_y + min_y) / 2;
+	max_y	=	max(max(Vertex[auxleaf.Vert_Hoja[0]][1],Vertex[auxleaf.Vert_Hoja[1]][1]),
+				  	max(Vertex[auxleaf.Vert_Hoja[2]][1],Vertex[auxleaf.Vert_Hoja[3]][1]));
+	
+	min_y	=	min(min(Vertex[auxleaf.Vert_Hoja[0]][1],Vertex[auxleaf.Vert_Hoja[1]][1]),
+				  	min(Vertex[auxleaf.Vert_Hoja[2]][1],Vertex[auxleaf.Vert_Hoja[3]][1]));
+
+	auxleaf.Centro[1]	=	(max_y + min_y) / 2;
 	
 	//z1
-	max_z	=	max(max(Vertex[Hoja1.Vert_Hoja[0]][2],
-									Vertex[Hoja1.Vert_Hoja[1]][2]),
-				  		max(Vertex[Hoja1.Vert_Hoja[2]][2],
-									Vertex[Hoja1.Vert_Hoja[3]][2]));
-	
-	min_z	=	min(min(Vertex[Hoja1.Vert_Hoja[0]][2],
-									Vertex[Hoja1.Vert_Hoja[1]][2]),
-				  		min(Vertex[Hoja1.Vert_Hoja[2]][2],
-									Vertex[Hoja1.Vert_Hoja[3]][2]));
-
-	Hoja1.Centro[2]	=	(max_z + min_z) / 2;
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-//  CALCULA LA NORMAL DE UNA HOJA
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::GetNormal(Hoja &aHoja)
+	max_z	=	max(max(Vertex[auxleaf.Vert_Hoja[0]][2],Vertex[auxleaf.Vert_Hoja[1]][2]),
+				  	max(Vertex[auxleaf.Vert_Hoja[2]][2],Vertex[auxleaf.Vert_Hoja[3]][2]));
+	
+	min_z	=	min(min(Vertex[auxleaf.Vert_Hoja[0]][2],Vertex[auxleaf.Vert_Hoja[1]][2]),
+				  	min(Vertex[auxleaf.Vert_Hoja[2]][2],Vertex[auxleaf.Vert_Hoja[3]][2]));
+
+	auxleaf.Centro[2]	=	(max_z + min_z) / 2;
+}
+
+
+//  calculate the normal vector of a leaf
+void TreeSimplifier::CalculateLeafNormal(Hoja &auxleaf)
 {
 	float onex, oney, onez;
@@ -281,18 +273,16 @@
 	float threex, threey, threez;
 
-	onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2];
-	twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2];
-	threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2];
-	
-	aHoja.Normal[0] = ((twoz-onez)*(threey-oney)) - ((twoy-oney)*(threez-onez));
-	aHoja.Normal[1] = ((twox-onex)*(threez-onez)) - ((threex-onex)*(twoz-onez));
-	aHoja.Normal[2] = ((threex-onex)*(twoy-oney)) - ((twox-onex)*(threey-oney));
-
-	
-}
-//--------------------------------------------------------------------------------------------------------------------------------
-//  CALCULA LA distancia de Hausdorff ( distancia entre nubes de puntos)
-//--------------------------------------------------------------------------------------------------------------------------------
-float TreeSimplifier::Hausdorff(Hoja &aHoja, Hoja& h2)
+	onex   = Vertex[auxleaf.Vert_Hoja[0]][0]; oney   = Vertex[auxleaf.Vert_Hoja[0]][1]; onez   = Vertex[auxleaf.Vert_Hoja[0]][2];
+	twox   = Vertex[auxleaf.Vert_Hoja[1]][0]; twoy   = Vertex[auxleaf.Vert_Hoja[1]][1]; twoz   = Vertex[auxleaf.Vert_Hoja[1]][2];
+	threex = Vertex[auxleaf.Vert_Hoja[2]][0]; threey = Vertex[auxleaf.Vert_Hoja[2]][1]; threez = Vertex[auxleaf.Vert_Hoja[2]][2];
+	
+	auxleaf.Normal[0] = ((twoz-onez)*(threey-oney)) - ((twoy-oney)*(threez-onez));
+	auxleaf.Normal[1] = ((twox-onex)*(threez-onez)) - ((threex-onex)*(twoz-onez));
+	auxleaf.Normal[2] = ((threex-onex)*(twoy-oney)) - ((twox-onex)*(threey-oney));	
+}
+
+
+//  calculate the Hausdorff distance (distance between point clouds)
+/*float TreeSimplifier::Hausdorff(Hoja &leaf1, Hoja& leaf2) const
 {
 	float onex, oney, onez;
@@ -306,18 +296,16 @@
 	float dist1, dist2, dist3, dist4, distmp, dista, distb, dist;
 
-	onex=Vertex[aHoja.Vert_Hoja[0]][0]; oney= Vertex[aHoja.Vert_Hoja[0]][1]; onez = Vertex[aHoja.Vert_Hoja[0]][2];
-	twox = Vertex[aHoja.Vert_Hoja[1]][0]; twoy = Vertex[aHoja.Vert_Hoja[1]][1]; twoz = Vertex[aHoja.Vert_Hoja[1]][2];
-	threex = Vertex[aHoja.Vert_Hoja[2]][0]; threey = Vertex[aHoja.Vert_Hoja[2]][1]; threez = Vertex[aHoja.Vert_Hoja[2]][2];
-	fourx = Vertex[aHoja.Vert_Hoja[3]][0]; foury = Vertex[aHoja.Vert_Hoja[3]][1]; fourz = Vertex[aHoja.Vert_Hoja[3]][2];
-	
-
-	x1 = Vertex[h2.Vert_Hoja[0]][0]; y1 = Vertex[h2.Vert_Hoja[0]][1]; z1 = Vertex[h2.Vert_Hoja[0]][2];
-	x2 = Vertex[h2.Vert_Hoja[1]][0]; y2 = Vertex[h2.Vert_Hoja[1]][1]; z2 = Vertex[h2.Vert_Hoja[1]][2];
-	x3 = Vertex[h2.Vert_Hoja[2]][0]; y3 = Vertex[h2.Vert_Hoja[2]][1]; z3 = Vertex[h2.Vert_Hoja[2]][2];
-	x4 = Vertex[h2.Vert_Hoja[3]][0]; y4 = Vertex[h2.Vert_Hoja[3]][1]; z4 = Vertex[h2.Vert_Hoja[3]][2];
-
-	// guardo las distancias mínimas de cada vértice a los 4 contrarios.
+	onex=Vertex[leaf1.Vert_Hoja[0]][0]; oney= Vertex[leaf1.Vert_Hoja[0]][1]; onez = Vertex[leaf1.Vert_Hoja[0]][2];
+	twox = Vertex[leaf1.Vert_Hoja[1]][0]; twoy = Vertex[leaf1.Vert_Hoja[1]][1]; twoz = Vertex[leaf1.Vert_Hoja[1]][2];
+	threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2];
+	fourx = Vertex[leaf1.Vert_Hoja[3]][0]; foury = Vertex[leaf1.Vert_Hoja[3]][1]; fourz = Vertex[leaf1.Vert_Hoja[3]][2];
+	
+
+	x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2];
+	x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2];
+	x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2];
+	x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2];
+
 	dist1 = distan ( onex, oney,onez,x1,y1,z1);
-	// vertice 1 con los 4 de la otra hoja
 
 	distmp = distan ( onex, oney,onez,x2,y2,z2);
@@ -330,6 +318,4 @@
 	if ( distmp < dist1) dist1 = distmp;
 
-	// vertice 2 con los 4 de la otra hoja
-
 	dist2 = distan ( twox, twoy,twoz,x1,y1,z1);
 	
@@ -343,5 +329,4 @@
 	if ( distmp < dist2) dist2 = distmp;
 
-	// vertice 3 con los 4 de la otra hoja
 
 	dist3 = distan ( threex, threey,threez,x1,y1,z1);
@@ -357,5 +342,4 @@
 
 
-	// vertice 4 con los 4 de la otra hoja
 
 	dist4 = distan ( fourx, foury,fourz,x1,y1,z1);
@@ -370,12 +354,8 @@
 	if ( distmp < dist4) dist4 = distmp;
 
-	//de entre estos cojo el máximo
 
 	dista =  max(dist1, max(dist2, max(dist3, dist4)));
 
-	//LO MISMO PERO A LA INVERSA
-
 	dist1 = distan ( x1,y1,z1, onex, oney, onez);
-	// vertice 1 con los 4 de la otra hoja
 
 	distmp = distan ( x1,y1,z1, twox, twoy, twoz);
@@ -388,7 +368,5 @@
 	if ( distmp < dist1) dist1 = distmp;
 
-	//2
 	dist2 = distan ( x2,y2,z2, onex, oney, onez);
-	// vertice 2 con los 4 de la otra hoja
 
 	distmp = distan ( x2,y2,z2, twox, twoy, twoz);
@@ -404,5 +382,4 @@
 		//3
 	dist3 = distan ( x3,y3,z3, onex, oney, onez);
-	// vertice 3 con los 4 de la otra hoja
 
 	distmp = distan ( x3,y3,z3, twox, twoy, twoz);
@@ -417,5 +394,4 @@
 		//4
 	dist4 = distan ( x4,y4,z4, onex, oney, onez);
-	// vertice 4 con los 4 de la otra hoja
 
 	distmp = distan ( x4,y4,z4, twox, twoy, twoz);
@@ -435,9 +411,145 @@
 	
 }
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// CALCULA LA DISTANCIA ENTRE HOJAS
-//--------------------------------------------------------------------------------------------------------------------------------
-
+*/
+
+//  Calculate the Hausdorff distance (distance between point clouds) (Optimized)
+float TreeSimplifier::HausdorffOptimized(const Hoja &leaf1, const Hoja& leaf2) const
+{
+	float onex, oney, onez;
+	float twox, twoy, twoz;
+	float threex, threey, threez;
+	float fourx, foury, fourz;
+	float x1, y1, z1;
+	float x2, y2, z2;
+	float x3, y3, z3;
+	float x4, y4, z4;
+	float dist1, dist2, dist3, dist4, distmp, dista, distb, dist;
+
+	onex   = Vertex[leaf1.Vert_Hoja[0]][0]; oney   = Vertex[leaf1.Vert_Hoja[0]][1]; onez   = Vertex[leaf1.Vert_Hoja[0]][2];
+	twox   = Vertex[leaf1.Vert_Hoja[1]][0]; twoy   = Vertex[leaf1.Vert_Hoja[1]][1]; twoz   = Vertex[leaf1.Vert_Hoja[1]][2];
+	threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2];
+	fourx  = Vertex[leaf1.Vert_Hoja[3]][0]; foury  = Vertex[leaf1.Vert_Hoja[3]][1]; fourz  = Vertex[leaf1.Vert_Hoja[3]][2];
+
+	x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2];
+	x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2];
+	x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2];
+	x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2];
+
+	// variables used to cache distances
+	float one1,one2,one3,one4, two1,two2,two3,two4, three1,three2,three3,three4, four1,four2,four3,four4;
+
+	// Store the minimal distances from each of the 4 vertices to the other 4 vertices
+	one1 = dist1 = distan ( onex, oney,onez,x1,y1,z1);
+	
+	one2 = distmp = distan ( onex, oney,onez,x2,y2,z2);
+	if ( distmp < dist1) dist1 = distmp;
+
+	one3 = distmp = distan ( onex, oney,onez,x3,y3,z3);
+	if ( distmp < dist1) dist1 = distmp;
+
+	one4 = distmp = distan ( onex, oney,onez,x4,y4,z4);
+	if ( distmp < dist1) dist1 = distmp;
+
+	
+	two1 = dist2 = distan ( twox, twoy,twoz,x1,y1,z1);
+	
+	two2 = distmp = distan ( twox, twoy,twoz,x2,y2,z2);
+	if ( distmp < dist2) dist2 = distmp;
+	
+	two3 = distmp = distan ( twox, twoy,twoz,x3,y3,z3);
+	if ( distmp < dist2) dist2 = distmp;
+	
+	two4 = distmp = distan ( twox, twoy,twoz,x4,y4,z4);
+	if ( distmp < dist2) dist2 = distmp;
+
+	
+	three1 = dist3 = distan ( threex, threey,threez,x1,y1,z1);
+	
+	three2 = distmp = distan ( threex, threey,threez,x2,y2,z2);
+	if ( distmp < dist3) dist3 = distmp;
+
+	three3 = distmp = distan ( threex, threey,threez,x3,y3,z3);
+	if ( distmp < dist3) dist3 = distmp;
+
+	three4 = distmp = distan ( threex, threey,threez,x4,y4,z4);
+	if ( distmp < dist3) dist3 = distmp;
+
+
+	four1 = dist4 = distan ( fourx, foury,fourz,x1,y1,z1);
+	
+	four2 = distmp = distan ( fourx, foury,fourz,x2,y2,z2);
+	if ( distmp < dist4) dist4 = distmp;
+
+	four3 = distmp = distan ( fourx, foury,fourz,x3,y3,z3);
+	if ( distmp < dist4) dist4 = distmp;
+	
+	four4 = distmp = distan ( fourx, foury,fourz,x4,y4,z4);
+	if ( distmp < dist4) dist4 = distmp;
+
+	// pick up the maximum value from those 4
+
+	dista =  max(dist1, max(dist2, max(dist3, dist4)));
+
+	// now use the cached distances to perform the reverse distances
+
+	dist1 = one1;  //distan ( x1,y1,z1, onex, oney, onez);
+
+	distmp = two1; //distan ( x1,y1,z1, twox, twoy, twoz);
+	if ( distmp < dist1) dist1 = distmp;
+
+	distmp =  three1; //distan ( x1,y1,z1, threex, threey, threez);
+	if ( distmp < dist1) dist1 = distmp;
+
+	distmp = four1; //distan ( x1,y1,z1, fourx, foury, fourz);
+	if ( distmp < dist1) dist1 = distmp;
+
+	//2
+	dist2 = one2; //distan ( x2,y2,z2, onex, oney, onez);
+
+	distmp = two2; //distan ( x2,y2,z2, twox, twoy, twoz);
+	if ( distmp < dist2) dist2 = distmp;
+
+	distmp = three2; //distan ( x2,y2,z2, threex, threey, threez);
+	if ( distmp < dist2) dist2 = distmp;
+
+	distmp = four2; //distan ( x2,y2,z2, fourx, foury, fourz);
+	if ( distmp < dist2) dist2 = distmp;
+
+
+		//3
+	dist3 = one3; //distan ( x3,y3,z3, onex, oney, onez);
+
+	distmp = two3; //distan ( x3,y3,z3, twox, twoy, twoz);
+	if ( distmp < dist3) dist3 = distmp;
+
+	distmp = three3; //distan ( x3,y3,z3, threex, threey, threez);
+	if ( distmp < dist3) dist3 = distmp;
+
+	distmp = four3; //distan ( x3,y3,z3, fourx, foury, fourz);
+	if ( distmp < dist3) dist3 = distmp;
+
+		//4
+	dist4 = one4; //distan ( x4,y4,z4, onex, oney, onez);
+
+	distmp = two4; //distan ( x4,y4,z4, twox, twoy, twoz);
+	if ( distmp < dist4) dist4 = distmp;
+
+	distmp = three4; //distan ( x4,y4,z4, threex, threey, threez);
+	if ( distmp < dist4) dist4 = distmp;
+
+	distmp = four4; //distan ( x4,y4,z4, fourx, foury, fourz);
+	if ( distmp < dist4) dist4 = distmp;
+
+	//
+	distb =  max(dist1, max(dist2, max(dist3, dist4)));
+
+	dist  = max ( dista, distb);
+	return ( dist);
+	
+}
+
+
+// Calculate the distance between leaves
+/*
 void TreeSimplifier::DistanciaEntreHojas(void)
 {
@@ -445,80 +557,70 @@
 	int j;
 
-	for ( int i=0;i<counth;i++)
-	{
-		if ( Hojasa[i].existe == true) // si la hoja aun existe
+	for ( int i=0;i<countLeaves;i++)
+	{
+		if ( Leaves[i].existe == true) // si la hoja aun existe
 		{
 			// inicializo para poder comparar
-			if ( i == (counth-1)) j = 0; 
+			if ( i == (countLeaves-1)) j = 0; 
 				else j = i+1;
-			while (Hojasa[j].existe == false) j++;
-			//dist = Hojasa[i].Distancia(Hojasa[j]);
-			dist = Hausdorff( Hojasa[i], Hojasa[j]);
-
-			Hojasa[i].hoja_cerca = j;
+			while (Leaves[j].existe == false) j++;
+			//dist = Leaves[i].Distancia(Leaves[j]);
+			dist = HausdorffOptimizado( Leaves[i], Leaves[j]);
+
+			Leaves[i].hoja_cerca = j;
 			// empiezo los calculos
-			for ( j =0; j<(counth-1);j++)
+			for ( j =0; j<(countLeaves-1);j++)
 			{
 				if ( j == i) 
 					break;
-				if ( Hojasa[j].existe == true) // si la hoja aun existe
+				if ( Leaves[j].existe == true) // si la hoja aun existe
 				{
-					distmp = Hausdorff(Hojasa[i], Hojasa[j]);
+					distmp = HausdorffOptimizado(Leaves[i], Leaves[j]);
 					if ( distmp < dist ) 
 					{
 						dist = distmp;
-						Hojasa[i].hoja_cerca = j;
+						Leaves[i].hoja_cerca = j;
 					}
 				}
 				
 			}
-			Hojasa[i].dist = dist;
-		}
-	}
-
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// DEVUELVE LA HOJA QUE TIENE UNA DISTANCIA MENOR
-//--------------------------------------------------------------------------------------------------------------------------------
-long int TreeSimplifier::MinimaDistancia ( void)
-{
-	float			mindist;
-	long int	cual;
-	int				i;
-
-	mindist =	0;
-	cual		=	-1;
-	i				=	0;
-	
-	//inicializo
-	while (Hojasa[i].existe != true)
-	{
+			Leaves[i].dist = dist;
+		}
+	}
+
+}*/
+
+// Returns the leaf which distance is the lowest
+long int TreeSimplifier::MinDistance(void)
+{
+	float		mindist=0.0f;
+	long int	which=-1;
+	int			i=0;
+
+/*	//init
+	while (Leaves[i].existe != true)
 		i++;
-	}
-	
-	mindist =	Hojasa[i].dist;
-	cual		=	i;
-	
-	//busco la minima
-	for (i = 0; i < counth; i++)
-	{
-		if (Hojasa[i].existe == true)
-		{
-			if ( mindist > Hojasa[i].dist)
+	
+	mindist = Leaves[i].dist;
+	which	= i;
+*/	
+	// search the minimum
+	for (i = 0; i < countLeaves; i++)
+	{
+		if (Leaves[i].existe)
+		{
+			if (mindist > Leaves[i].dist || which==-1)
 			{
-				mindist = Hojasa[i].dist;
-				cual = i;
+				mindist = Leaves[i].dist;
+				which = i;
 			}
 		}
 
 	}
-	return (cual);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// CALCULA LA COPLANARIDAD ENTRE HOJAS
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::CoplanarEntreHojas(FILE	*fp_coplanar)
+	return which;
+}
+
+// Calculate the coplanarity between leaves
+void TreeSimplifier::CoplanarBetweenLeaves(void)
 {
 	float	cop;
@@ -527,106 +629,92 @@
 	int 	j;
 
-	for ( i=0;i<counth;i++)
-	{
-		if ( Hojasa[i].existe == true) // si la hoja aun existe
-		{
-			// inicializo para poder comparar
-			if ( i == (counth-1))
+	for (i=0;i<countLeaves;i++)
+	{
+		if (Leaves[i].existe)
+		{
+			if (i == countLeaves-1)
+				j	=	0;
+			else
+				j =	i + 1;
+			
+			while (Leaves[j].existe == false)
+				j++;
+			
+			cop	= Leaves[i].Coplanaridad(Leaves[j]);
+			Leaves[i].hoja_cop	=	j;
+			
+			for (j=0; j<countLeaves-1; j++)
 			{
-				j	=	0;
-			}
-			else
-			{
-				j =	i + 1;
-			}
-			
-			while (Hojasa[j].existe == false)
-			{
-				j++;
-			}
-			
-			cop									=	Hojasa[i].Coplanaridad(Hojasa[j]);
-			Hojasa[i].hoja_cop	=	j;
-			
-			// empiezo los calculos
-			for (j = 0; j < (counth-1); j++)
-			{
-				// si la hoja aun existe.
-				if (( j != i) && (Hojasa[j].existe == true))
+				if (( j != i) && (Leaves[j].existe))
 				{
-					coptmp	=	Hojasa[i].Coplanaridad(Hojasa[j]);
-
-					// COJO EL MAS COPLANAR , CERCANO A 1.
+					coptmp	=	Leaves[i].Coplanaridad(Leaves[j]);
+
+					// Take the most coplanar: close to 1
 					if (coptmp > cop)
 					{
-						cop									=	coptmp;
-						Hojasa[i].hoja_cop	=	j;
+						cop	= coptmp;
+						Leaves[i].hoja_cop = j;
 					}
 				}
 			}
-			Hojasa[i].coplanar	=	1 - cop; //  8/6/01 LO INVIERTO
-		}
-	}
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// 
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::DosMayores(float *mayores, int	*indices)
+			Leaves[i].coplanar = 1 - cop;
+		}
+	}
+}
+
+void TreeSimplifier::TwoGreater(float *maj, int	*indices)
 {
 	float	m1;
 	int		i;
 
-	if	(mayores[0] < mayores[1])
-	{
-		m1					=	mayores[0];
-		mayores[0]	=	mayores[1];
-		mayores[1]	=	m1;
-
-		i						=	indices[0];
-		indices[0]	=	indices[1];
-		indices[1]	=	i;
-	}
-
-	if (mayores [2] < mayores [3])
-	{
-		m1					=	mayores[2];
-		mayores[2]	=	mayores[3];
-		mayores [3]	=	m1;
-
-		i						=	indices[2];
+	if	(maj[0] < maj[1])
+	{
+		m1	= maj[0];
+		maj[0] = maj[1];
+		maj[1] = m1;
+
+		i =	indices[0];
+		indices[0] = indices[1];
+		indices[1] = i;
+	}
+
+	if (maj[2] < maj[3])
+	{
+		m1	= maj[2];
+		maj[2] = maj[3];
+		maj[3]	= m1;
+		i	= indices[2];
+		indices[2] = indices[3];
+		indices[3] = i;
+	}
+
+	if  (maj[0] < maj[2])
+	{
+		m1		=	maj[0];
+		maj[0]	=	maj[2];
+		maj[2]	=	m1;
+		i		=	indices[0];
+		indices[0]	=	indices[2];
+		indices[2]	=	i;
+	}
+
+	if (maj[2] < maj[3])
+	{
+		m1		=	maj[2];
+		maj[2]	=	maj[3];
+		maj [3]	=	m1;
+
+		i			=	indices[2];
 		indices[2]	=	indices[3];
 		indices[3]	=	i;
 	}
 
-	if  (mayores[0] < mayores[2])
-	{
-		m1					=	mayores[0];
-		mayores[0]	=	mayores[2];
-		mayores[2]	=	m1;
-
-		i						=	indices[0];
-		indices[0]	=	indices[2];
-		indices[2]	=	i;
-	}
-
-	if (mayores [2] < mayores [3])
-	{
-		m1					=	mayores[2];
-		mayores[2]	=	mayores[3];
-		mayores [3]	=	m1;
-
-		i						=	indices[2];
-		indices[2]	=	indices[3];
-		indices[3]	=	i;
-	}
-
-	if (mayores [1] < mayores [2])
-	{
-		m1					=	mayores[1];
-		mayores[1]	=	mayores[2];
-		mayores [2]	=	m1;
-
-		i						= indices[1];
+	if (maj [1] < maj [2])
+	{
+		m1		=	maj[1];
+		maj[1]	=	maj[2];
+		maj [2]	=	m1;
+
+		i			= indices[1];
 		indices[1]	= indices[2];
 		indices[2]	= i;
@@ -634,55 +722,43 @@
 }
 
-//--------------------------------------------------------------------------------------------------------------------------------
-// 
-//--------------------------------------------------------------------------------------------------------------------------------
-//float TreeSimplifier::DiametroEsferaEnvolvente (FILE* fp_simplifica)
-float TreeSimplifier::DiametroEsferaEnvolvente()
+float TreeSimplifier::BoundingSphereDiameter(void) const
 {
 	float xmax, xmin, ymax, ymin, zmax, zmin;
-	float diametro, cx, cy, cz;
+	float diameter, cx, cy, cz;
 	int j;
 
-	//	2006-02-21.
-	float			percent;
-	long	int	update;
-
-	//inicializo al primero de los vértices de las hojas
-
-	xmax = Vertex[Hojasa[0].Vert_Hoja[0]][0];
+	// initialize all vertices to the first
+	xmax = Vertex[Leaves[0].Vert_Hoja[0]][0];
 	xmin = xmax;
 
-	ymax = Vertex[Hojasa[0].Vert_Hoja[0]][1];
+	ymax = Vertex[Leaves[0].Vert_Hoja[0]][1];
 	ymin = ymax;
 
-	zmax = Vertex[Hojasa[0].Vert_Hoja[0]][2];
+	zmax = Vertex[Leaves[0].Vert_Hoja[0]][2];
 	zmin = zmax;
 
-	// ahora busco los maximos y los minimos correspondientes
-
-
-	//	2006-02-21
-	update	=	counth / 20;
-	percent	=	0.5;
-	for (int i = 1; i < counth; i++)
-	{
-		//	2006-02-21
-		if (mUPB	&&	((i % update) == 0))
-		{
-			mUPB(percent);
-		}
+	// search for max and mins
+
+	int update_each	= countLeaves / 5;
+	for (int i = 1; i < countLeaves; i++)
+	{
+		static int ticks_since_last_update = 0;
+		if (mUPB && ticks_since_last_update>=update_each)
+		{
+			ticks_since_last_update=0;
+			mUPB(1);
+		}
+		ticks_since_last_update++;
 		
-		for ( j=0;j<4;j++)
-		{
+		for (j=0;j<4;j++)
+		{			
+			if ( xmax < Vertex[Leaves[i].Vert_Hoja[j]][0]) xmax = Vertex[Leaves[i].Vert_Hoja[j]][0];
+			if ( xmin > Vertex[Leaves[i].Vert_Hoja[j]][0]) xmin = Vertex[Leaves[i].Vert_Hoja[j]][0];
+
+			if ( ymax < Vertex[Leaves[i].Vert_Hoja[j]][1]) ymax = Vertex[Leaves[i].Vert_Hoja[j]][1];
+			if ( ymin > Vertex[Leaves[i].Vert_Hoja[j]][1]) ymin = Vertex[Leaves[i].Vert_Hoja[j]][1];
 			
-		if ( xmax < Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmax = Vertex[Hojasa[i].Vert_Hoja[j]][0];
-		if ( xmin > Vertex[Hojasa[i].Vert_Hoja[j]][0]) xmin = Vertex[Hojasa[i].Vert_Hoja[j]][0];
-
-		if ( ymax < Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymax = Vertex[Hojasa[i].Vert_Hoja[j]][1];
-		if ( ymin > Vertex[Hojasa[i].Vert_Hoja[j]][1]) ymin = Vertex[Hojasa[i].Vert_Hoja[j]][1];
-		
-		if ( zmax < Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmax = Vertex[Hojasa[i].Vert_Hoja[j]][2];
-		if ( zmin > Vertex[Hojasa[i].Vert_Hoja[j]][2]) zmin = Vertex[Hojasa[i].Vert_Hoja[j]][2];
-
+			if ( zmax < Vertex[Leaves[i].Vert_Hoja[j]][2]) zmax = Vertex[Leaves[i].Vert_Hoja[j]][2];
+			if ( zmin > Vertex[Leaves[i].Vert_Hoja[j]][2]) zmin = Vertex[Leaves[i].Vert_Hoja[j]][2];
 		}
 	}
@@ -692,24 +768,22 @@
 	cz = (zmax + zmin)/2;
 
-
-	diametro = ((xmax-xmin)*(xmax-xmin)) + ((ymax-ymin)*(ymax-ymin)) + ((zmax-zmin)*(zmax-zmin));
-
-return (diametro);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-//  normaliza las distancia
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::NormalizaDistancia (float diametro)
+	diameter = ((xmax-xmin)*(xmax-xmin)) + ((ymax-ymin)*(ymax-ymin)) + ((zmax-zmin)*(zmax-zmin));
+
+	return (diameter);
+}
+
+void TreeSimplifier::NormalizeDistance(float diameter)
 {
 	float dtmp;
-	for (int i=0; i<counth;i++)
-	{
-		dtmp = Hojasa[i].dist;
-		Hojasa[i].dist = dtmp / diametro;
+	for (int i=0; i<countLeaves;i++)
+	{
+		dtmp = Leaves[i].dist;
+		Leaves[i].dist = dtmp / diameter;
 		
 	}
 }
-
+/*
+
+	THIS FUNCTION IS OBSOLETE, AND NEEDS TO BE ERASED
 //--------------------------------------------------------------------------------------------------------------------------------
 //  establece el criterio como (K1 * dist + K2 * cop)/ K1+K2
@@ -721,28 +795,17 @@
 	int i, j, nhojasi, nhojasj;
 
-	//	2006-02-21
-	float			percent;
-	long	int	update;
-	
-	update	=	counth / 30;
-	percent	=	1;
-	
-	for ( i=0; i<counth;i++)
-	{
-		//	2005-02-21
-		if (mUPB	&&	((i % update) == 0))
-		{
-			mUPB(percent);
-		}
-		
-		if (Hojasa[i].existe == true)
+	int update_each	= countLeaves / 30;
+	
+	for ( i=0; i<countLeaves;i++)
+	{
+		if (Leaves[i].existe == true)
 		{
 			//incializo criterio a un numero elevado
-			Hojasa[i].criterio = 1000;
-			nhojasi = int(Hojasa[i].Cuantas_hojas);
+			Leaves[i].criterio = 1000;
+			nhojasi = int(Leaves[i].Cuantas_hojas);
 			//coplanaridad
-			for ( j =0; j<counth;j++)
+			for ( j =0; j<countLeaves;j++)
 			{
-				if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe
+				if (( j != i) && ( Leaves[j].existe == true)) // si la hoja aun existe
 				{
 					//17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS 
@@ -750,21 +813,21 @@
 					// ES COMO MÁXIMO 1
 
-					nhojasj = int(Hojasa[j].Cuantas_hojas);
+					nhojasj = int(Leaves[j].Cuantas_hojas);
 
 					if ( abs((nhojasi - nhojasj)) < 2)
 					{
 						//coplanaridad y lo invierto
-						coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]); 
+						coptmp2 = Leaves[i].Coplanaridad(Leaves[j]); 
 						coptmp = 1 - coptmp2;
 						//distancia y la normalizo
-						distmp2 = Hausdorff( Hojasa[i], Hojasa[j]); 
+						distmp2 = Hausdorff( Leaves[i], Leaves[j]); 
 						distmp = distmp2 / diametro;
 						// calculo el criterio para esa hoja
 						criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
 						//selecciono el criterio menor
-						if (Hojasa[i].criterio > criteriotmp) 
+						if (Leaves[i].criterio > criteriotmp) 
 						{
-							Hojasa[i].criterio = criteriotmp;
-							Hojasa[i].hoja_crit = j;
+							Leaves[i].criterio = criteriotmp;
+							Leaves[i].hoja_crit = j;
 						}
 					}
@@ -787,18 +850,18 @@
 	//ESTAN EN tres PROCEDIMIENTOS: COLAPSA, ESTABLECECRITERIO Y ESTABLECECRITERIO2
 	
-	for (i = 0; i < counth; i++)
-	{
-		if ((Hojasa[i].existe == true) && (i != hojanueva))
+	for (i = 0; i < countLeaves; i++)
+	{
+		if ((Leaves[i].existe == true) && (i != hojanueva))
 		{	
-			nhojasi = int(Hojasa[i].Cuantas_hojas);
+			nhojasi = int(Leaves[i].Cuantas_hojas);
 			//¿ SE HA DESACTIVADO LA HOJA_CRIT QUE GUARDABA LA HOJA?
-			if ( Hojasa[Hojasa[i].hoja_crit].existe == false)
+			if ( Leaves[Leaves[i].hoja_crit].existe == false)
 			{
-				Hojasa[i].criterio = 1000;
+				Leaves[i].criterio = 1000;
 
 				//coplanaridad
-				for ( j =0; j<counth;j++)
+				for ( j =0; j<countLeaves;j++)
 				{
-					if (( j != i) && ( Hojasa[j].existe == true)) // si la hoja aun existe
+					if (( j != i) && ( Leaves[j].existe == true)) // si la hoja aun existe
 					{
 						//17/09/01 ANTES DE CALCULAR NADA, COMPRUEBO QUE ESTAS DOS HOJAS 
@@ -806,5 +869,5 @@
 						// ES COMO MÁXIMO 1
 
-						nhojasj = int(Hojasa[j].Cuantas_hojas);
+						nhojasj = int(Leaves[j].Cuantas_hojas);
 
 						if ( abs((nhojasi - nhojasj)) < 2)
@@ -812,17 +875,17 @@
 
 							//coplanaridad y lo invierto
-							coptmp2 = Hojasa[i].Coplanaridad(Hojasa[j]); 
+							coptmp2 = Leaves[i].Coplanaridad(Leaves[j]); 
 							coptmp = 1 - coptmp2;	
 							//distancia y la normalizo	
-						//	distmp2 = Hojasa[i].Distancia(Hojasa[j]); 
-							distmp2 = Hausdorff( Hojasa[i],  Hojasa[j]); 
+						//	distmp2 = Leaves[i].Distancia(Leaves[j]); 
+							distmp2 = Hausdorff( Leaves[i],  Leaves[j]); 
 							distmp = distmp2 / diametro;
 							// calculo el criterio para esa hoja
 							criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
 							//selecciono el criterio menor
-							if (Hojasa[i].criterio > criteriotmp) 
+							if (Leaves[i].criterio > criteriotmp) 
 							{
-								Hojasa[i].criterio = criteriotmp;
-								Hojasa[i].hoja_crit = j;
+								Leaves[i].criterio = criteriotmp;
+								Leaves[i].hoja_crit = j;
 							}
 						}
@@ -832,22 +895,22 @@
 			else
 			{ // CALCULARE SI EL CRITERIO CON ESTA HOJA ES MENOR QUE EL ANTERIOR
-				nhojasj = int(Hojasa[hojanueva].Cuantas_hojas);
+				nhojasj = int(Leaves[hojanueva].Cuantas_hojas);
 
 				if ( abs((nhojasi - nhojasj)) < 2)
 				{
 					//coplanaridad y lo invierto
-					coptmp2 = Hojasa[i].Coplanaridad(Hojasa[hojanueva]); 
+					coptmp2 = Leaves[i].Coplanaridad(Leaves[hojanueva]); 
 					coptmp = 1 - coptmp2;
 					//distancia y la normalizo
-					//distmp2 = Hojasa[i].Distancia(Hojasa[hojanueva]); 
-					distmp2 = Hausdorff( Hojasa[i], Hojasa[hojanueva]); 
+					//distmp2 = Leaves[i].Distancia(Leaves[hojanueva]); 
+					distmp2 = Hausdorff( Leaves[i], Leaves[hojanueva]); 
 					distmp = distmp2 / diametro;
 					// calculo el criterio para esa hoja
 					criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
 					//selecciono el criterio menor
-					if (Hojasa[i].criterio > criteriotmp) 
+					if (Leaves[i].criterio > criteriotmp) 
 					{	
-						Hojasa[i].criterio = criteriotmp;
-						Hojasa[i].hoja_crit = hojanueva;
+						Leaves[i].criterio = criteriotmp;
+						Leaves[i].hoja_crit = hojanueva;
 					}
 				}
@@ -855,214 +918,208 @@
 		}
 	}
-}
-//--------------------------------------------------------------------------------------------------------------------------------
-// DEVUELVE LA HOJA QUE TIENE EL NUMERO EN EL CAMPO CRITERIO MENOR
-//--------------------------------------------------------------------------------------------------------------------------------
-
-long int TreeSimplifier::MinimoCriterio (void)
-{
-	float mincrit =0;
-	long int cual=-1;
-	int i=0;
-	
-	//inicializo
-	while (Hojasa[i].existe != true) i++;
-	mincrit = Hojasa[i].criterio;
-	cual =i;
-	//busco la minima
-	for ( i=0;i<counth;i++)
-
-	{
-		if (Hojasa[i].existe == true)
-		{
-			if ( mincrit> Hojasa[i].criterio)
+}*/
+
+
+
+// Gets the laf with the minimum criteria
+long int TreeSimplifier::MinCriteria (void)
+{
+	float mincrit=0.0f;
+	long int which=-1;
+		
+/*	while (Leaves[i].existe != true) i++;
+	mincrit = Leaves[i].criterio;
+	which =i;
+	*/
+	for (int i=0;i<countLeaves;i++)
+	{
+		if (Leaves[i].existe)
+		{
+			if (mincrit>Leaves[i].criterio || which==-1)
 			{
-				mincrit = Hojasa[i].criterio;
-				cual = i;
+				mincrit = Leaves[i].criterio;
+				which = i;
 			}
 		}
 		
 	}
-	return (cual);
-}
-
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// 
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::ElijeVertices(Hoja& Hoja1, Hoja& Hoja2, long int count)
-{
-	// criterio es el de los dos vertices más alejados del centro de la otra hoja
-	
+	return which;
+}
+
+
+void TreeSimplifier::ChooseVertices(Hoja& leaf1, Hoja& leaf2, long int count)
+{
 	float a,b,c;
 	float dist[4];
 	int indices[4];
 	
-	// primero de la primera hoja cojo los dos primeros vertices
-
-
-	a = Vertex[Hoja1.Vert_Hoja[0]][0];
-	b = Vertex[Hoja1.Vert_Hoja[0]][1];
-	c = Vertex[Hoja1.Vert_Hoja[0]][2];
-
-	dist[0] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
-		   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
-
-	
-	a = Vertex[Hoja1.Vert_Hoja[1]][0];
-	b = Vertex[Hoja1.Vert_Hoja[1]][1];
-	c = Vertex[Hoja1.Vert_Hoja[1]][2];
-
-	dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
-		   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
-
-	a = Vertex[Hoja1.Vert_Hoja[2]][0];
-	b = Vertex[Hoja1.Vert_Hoja[2]][1];
-	c = Vertex[Hoja1.Vert_Hoja[2]][2];
-
-	dist[2] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
-		   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
-
-
-	a = Vertex[Hoja1.Vert_Hoja[3]][0];
-	b = Vertex[Hoja1.Vert_Hoja[3]][1];
-	c = Vertex[Hoja1.Vert_Hoja[3]][2];
-
-	dist[3] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja2.Centro[1]-b)*(Hoja2.Centro[1]-b)) +
-		   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
+	a = Vertex[leaf1.Vert_Hoja[0]][0];
+	b = Vertex[leaf1.Vert_Hoja[0]][1];
+	c = Vertex[leaf1.Vert_Hoja[0]][2];
+
+	dist[0] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) +
+		   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c));
+
+	
+	a = Vertex[leaf1.Vert_Hoja[1]][0];
+	b = Vertex[leaf1.Vert_Hoja[1]][1];
+	c = Vertex[leaf1.Vert_Hoja[1]][2];
+
+	dist[1] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) +
+		   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c));
+
+	a = Vertex[leaf1.Vert_Hoja[2]][0];
+	b = Vertex[leaf1.Vert_Hoja[2]][1];
+	c = Vertex[leaf1.Vert_Hoja[2]][2];
+
+	dist[2] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) +
+		   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c));
+
+
+	a = Vertex[leaf1.Vert_Hoja[3]][0];
+	b = Vertex[leaf1.Vert_Hoja[3]][1];
+	c = Vertex[leaf1.Vert_Hoja[3]][2];
+
+	dist[3] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf2.Centro[1]-b)*(leaf2.Centro[1]-b)) +
+		   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c));
 
 	for ( int i=0;i<4;i++) indices[i]=i;
 
-	DosMayores(dist, indices);
-	
-	Hojasa[counth].Vert_Hoja[0] = Hoja1.Vert_Hoja[indices[0]]; 
-	Hojasa[counth].Vert_Hoja[1] = Hoja1.Vert_Hoja[indices[1]]; 
-	
-	// segunda hoja los dos ultimos vertices
-
-	
-	a = Vertex[Hoja2.Vert_Hoja[0]][0];
-	b = Vertex[Hoja2.Vert_Hoja[0]][1];
-	c = Vertex[Hoja2.Vert_Hoja[0]][2];
-
-	dist[0] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
-		   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
-
-	
-	a = Vertex[Hoja2.Vert_Hoja[1]][0];
-	b = Vertex[Hoja2.Vert_Hoja[1]][1];
-	c = Vertex[Hoja2.Vert_Hoja[1]][2];
-
-	dist[1] = ((Hoja2.Centro[0]-a)*(Hoja2.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
-		   ((Hoja2.Centro[2]-c)*(Hoja2.Centro[2]-c));
-
-	a = Vertex[Hoja2.Vert_Hoja[2]][0];
-	b = Vertex[Hoja2.Vert_Hoja[2]][1];
-	c = Vertex[Hoja2.Vert_Hoja[2]][2];
-
-	dist[2] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
-		   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
-
-
-	a = Vertex[Hoja2.Vert_Hoja[3]][0];
-	b = Vertex[Hoja2.Vert_Hoja[3]][1];
-	c = Vertex[Hoja2.Vert_Hoja[3]][2];
-
-	dist[3] = ((Hoja1.Centro[0]-a)*(Hoja1.Centro[0]-a)) + ((Hoja1.Centro[1]-b)*(Hoja1.Centro[1]-b)) +
-		   ((Hoja1.Centro[2]-c)*(Hoja1.Centro[2]-c));
+	TwoGreater(dist, indices);
+	
+	Leaves[countLeaves].Vert_Hoja[0] = leaf1.Vert_Hoja[indices[0]]; 
+	Leaves[countLeaves].Vert_Hoja[1] = leaf1.Vert_Hoja[indices[1]]; 
+	
+
+	
+	a = Vertex[leaf2.Vert_Hoja[0]][0];
+	b = Vertex[leaf2.Vert_Hoja[0]][1];
+	c = Vertex[leaf2.Vert_Hoja[0]][2];
+
+	dist[0] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) +
+		   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c));
+
+	
+	a = Vertex[leaf2.Vert_Hoja[1]][0];
+	b = Vertex[leaf2.Vert_Hoja[1]][1];
+	c = Vertex[leaf2.Vert_Hoja[1]][2];
+
+	dist[1] = ((leaf2.Centro[0]-a)*(leaf2.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) +
+		   ((leaf2.Centro[2]-c)*(leaf2.Centro[2]-c));
+
+	a = Vertex[leaf2.Vert_Hoja[2]][0];
+	b = Vertex[leaf2.Vert_Hoja[2]][1];
+	c = Vertex[leaf2.Vert_Hoja[2]][2];
+
+	dist[2] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) +
+		   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c));
+
+
+	a = Vertex[leaf2.Vert_Hoja[3]][0];
+	b = Vertex[leaf2.Vert_Hoja[3]][1];
+	c = Vertex[leaf2.Vert_Hoja[3]][2];
+
+	dist[3] = ((leaf1.Centro[0]-a)*(leaf1.Centro[0]-a)) + ((leaf1.Centro[1]-b)*(leaf1.Centro[1]-b)) +
+		   ((leaf1.Centro[2]-c)*(leaf1.Centro[2]-c));
 
 	for ( int i=0;i<4;i++) indices[i]=i;
 
-	DosMayores(dist, indices);
-	
-	Hojasa[counth].Vert_Hoja[2] = Hoja2.Vert_Hoja[indices[0]]; 
-	Hojasa[counth].Vert_Hoja[3] = Hoja2.Vert_Hoja[indices[1]]; 
-
-
-
-	
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// AÑADE HOJAS 
-//--------------------------------------------------------------------------------------------------------------------------------
-//long int TreeSimplifier::Colapsa (Geometry::TreeSimplificationSequence *tss, float diametro)
-long int TreeSimplifier::Colapsa(float diametro)
-{
-	long int i=0, cual=-1;
-	long int otra = -1;
-	float coptmp, coptmp2, distmp, distmp2, criteriotmp;
-//	char linea[250];
-
-//	cual=MinimaDistancia();
-	cual=MinimoCriterio();
-//	otra = Hojasa[cual].hoja_cerca; //para la distancia
-//	otra = Hojasa[cual].hoja_cop;
-	otra = Hojasa[cual].hoja_crit;
+	TwoGreater(dist, indices);
+	
+	Leaves[countLeaves].Vert_Hoja[2] = leaf2.Vert_Hoja[indices[0]]; 
+	Leaves[countLeaves].Vert_Hoja[3] = leaf2.Vert_Hoja[indices[1]]; 
+
+
+
+	
+}
+
+// Add leaves
+long int TreeSimplifier::Collapse(float diam)
+{
+	long int i=0, which=-1;
+	long int other = -1;
+	float coptmp, coptmp2, distmp, distmp2, criteriatmp;
+
+	which=MinCriteria();
+	other = Leaves[which].hoja_crit;
 
 	//desactivo las hojas cercanas
-	Hojasa[cual].existe = false;
-	Hojasa[otra].existe = false;
+	Leaves[which].existe = false;
+	Leaves[other].existe = false;
 	//creo la hoja nueva
 
-	Hojasa[counth].hoja_cerca = -1;
-	Hojasa[counth].dist = 0;
-	Hojasa[counth].hoja_cop = -1;
-	Hojasa[counth].coplanar = 0;
-
-	Hojasa[counth].Cuantas_hojas = Hojasa[cual].Cuantas_hojas + Hojasa[otra].Cuantas_hojas;
-	ElijeVertices(Hojasa[cual], Hojasa[otra], counth);
-	Centroh (Hojasa[counth]);
-	GetNormal ( Hojasa[counth]);
-
-	//18/09/01 
-	if (Hojasa[counth].Cuantas_hojas > 60 )
-	{
-			Hojasa[counth].existe = false;
-			activas--;
+	Leaves[countLeaves].hoja_cerca = -1;
+	Leaves[countLeaves].dist = 0;
+	Leaves[countLeaves].hoja_cop = -1;
+	Leaves[countLeaves].coplanar = 0;
+
+	Leaves[countLeaves].Cuantas_hojas = Leaves[which].Cuantas_hojas + Leaves[other].Cuantas_hojas;
+//	Leaves[countLeaves].Cuantas_hojas = 10;
+	ChooseVertices(Leaves[which], Leaves[other], countLeaves);
+	CalculateLeafCenter (Leaves[countLeaves]);
+	CalculateLeafNormal (Leaves[countLeaves]);
+
+	// find out the minimal octree node that can contain this leaf
+	LeafOctree *onode = GetMinOctreeNodeForLeaf(octree,Leaves[countLeaves]);
+	octree_owning_leaf[countLeaves] = onode;
+	onode->leaves.push_back(countLeaves);
+
+/*	if (Leaves[countLeaves].Cuantas_hojas > 60 )
+	{
+			Leaves[countLeaves].existe = false;
+			activeLeaves--;
 	}
 	else
-	{
-		//establezco el criterio para la hoja nueva
-     	Hojasa[counth].existe = true;
-		Hojasa[counth].criterio = 1000;
-		Hojasa[counth].id_triangulo[0] = counth*2;
-		Hojasa[counth].id_triangulo[1] = counth*2+1;
-
- 		//coplanaridad
-		for (int j = 0; j < (counth+1); j++)
-		{
-			if (( j != counth) && ( Hojasa[j].existe == true)) // si la hoja aun existe
+	{		*/
+     	Leaves[countLeaves].existe = true;
+		Leaves[countLeaves].criterio = 1000000.0f;
+		Leaves[countLeaves].id_triangulo[0] = countLeaves*2;
+		Leaves[countLeaves].id_triangulo[1] = countLeaves*2+1;
+
+ 		float area_leaf_i = CalculateLeafArea(Leaves[i])/diam;
+
+		for (int j = 0; j < (countLeaves+1); j++){
+/*		int visit_parents = VISIT_PARENTS_DEEP;
+		for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode && visit_parents>=0; octreenode=octreenode->parent, visit_parents--)
+		{
+			for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++)
 			{
-			//coplanaridad y lo invierto
-			coptmp2 = Hojasa[counth].Coplanaridad(Hojasa[j]); 
-			coptmp = 1 - coptmp2;
-			//distancia y la normalizo
-			//distmp2 = Hojasa[counth].Distancia(Hojasa[j]); 
-			distmp2 = Hausdorff(Hojasa[counth], Hojasa[j]); 
-			distmp = distmp2 / diametro;
-			// calculo el criterio para esa hoja
-			criteriotmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
-			//selecciono el criterio menor
-			if (Hojasa[counth].criterio > criteriotmp) 
-			{
-				Hojasa[counth].criterio = criteriotmp;
-				Hojasa[counth].hoja_crit = j;}
-			}
-		}
-	}	
+				int j = *it;*/
+
+				if (j != countLeaves && Leaves[j].existe)
+				{
+					coptmp2 = Leaves[countLeaves].Coplanaridad(Leaves[j]); 
+					coptmp = 1 - coptmp2;
+					//distmp2 = HausdorffOptimized(Leaves[countLeaves], Leaves[j]);
+					distmp2 = DistanceFromCenters(Leaves[countLeaves], Leaves[j]);
+					distmp = distmp2 / diam;
+					
+					criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
+					criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i;
+					criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas;
+					
+					if (Leaves[countLeaves].criterio > criteriatmp) 
+					{
+						Leaves[countLeaves].criterio = criteriatmp;
+						Leaves[countLeaves].hoja_crit = j;
+					}
+				}
+	//		}
+		}
+//	}	
 
 	// Crear el paso de simplificación
 	Geometry::TreeSimplificationSequence::Step pasosimp;
-	pasosimp.mV0=Hojasa[cual].id_triangulo[0];
-	pasosimp.mV1=Hojasa[cual].id_triangulo[1];
-	pasosimp.mT0=Hojasa[otra].id_triangulo[0];
-	pasosimp.mT1=Hojasa[otra].id_triangulo[1];
+	pasosimp.mV0=Leaves[which].id_triangulo[0];
+	pasosimp.mV1=Leaves[which].id_triangulo[1];
+	pasosimp.mT0=Leaves[other].id_triangulo[0];
+	pasosimp.mT1=Leaves[other].id_triangulo[1];
 
 	// Nuevos vértices
-	pasosimp.mNewQuad[0]=Hojasa[counth].Vert_Hoja[0];
-	pasosimp.mNewQuad[1]=Hojasa[counth].Vert_Hoja[1];
-	pasosimp.mNewQuad[2]=Hojasa[counth].Vert_Hoja[2];
-	pasosimp.mNewQuad[3]=Hojasa[counth].Vert_Hoja[3];
+	pasosimp.mNewQuad[0]=Leaves[countLeaves].Vert_Hoja[0];
+	pasosimp.mNewQuad[1]=Leaves[countLeaves].Vert_Hoja[1];
+	pasosimp.mNewQuad[2]=Leaves[countLeaves].Vert_Hoja[2];
+	pasosimp.mNewQuad[3]=Leaves[countLeaves].Vert_Hoja[3];
 
 	// Insertar el paso de simplificación
@@ -1070,50 +1127,490 @@
 
 	//incremento el numero de hojas
-	counth++;
-	activas--;
-	return (counth-1);//porque lo he incrementado en la linea de antes
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------
-// ESCRIBE EL mIndex EN EL MESH DE SALIDA
-//--------------------------------------------------------------------------------------------------------------------------------
-void TreeSimplifier::EscribeMesh(int idMeshLeaves) 
-{
-	// Calcular el número de indices después de simplificar
-	long int tamIndex	=	activas * 6; // Cada hoja tiene 6 índices
-
-	//	2006-02-21.
-	float			percent;
-	long	int	update;
-	
+	countLeaves++;
+	activeLeaves--;
+	return (countLeaves-1);//porque lo he incrementado en la linea de antes
+}
+
+void TreeSimplifier::BuildOutputMesh(int idMeshLeaves) 
+{
+	// Calculate the resulting index count after simplifying
+	long int tamIndex	=	activeLeaves * 6; // Each leaf has got 6 indices
+
 	delete [] mesh->mSubMesh[idMeshLeaves].mIndex;
 	mesh->mSubMesh[idMeshLeaves].mIndexCount=tamIndex;
 	mesh->mSubMesh[idMeshLeaves].mIndex=new Geometry::Index[tamIndex];
 
-	// Recorrer las hojas, comprobar las que están activas y copiar los índices al mesh.
-	Geometry::Index indice=0;
-
-	//	2006-02-21.
-	update	=	counth	/ 10;
-	percent	=	1;
-	
-	for (long j=0; j<counth;j++)
-	{
-		//	2006-02-21
-		if (mUPB	&&	((j % update) == 0))
-		{
-			mUPB(percent);
-		}
+	// Iterate through all active leaves and dump them to the final mesh
+	Geometry::Index index=0;
+
+	int update_each	= countLeaves / 10;
+	
+	for (long j=0; j<countLeaves;j++)
+	{
+		static int ticks_since_last_update = 0;
+		if (mUPB && ticks_since_last_update>=update_each)
+		{
+			ticks_since_last_update=0;
+			mUPB(1);
+		}
+		ticks_since_last_update++;
 		
-		if ( Hojasa[j].existe == true) // si la hoja aun existe
-		{
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice]=Hojasa[j].Vert_Hoja[0];
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice+1]=Hojasa[j].Vert_Hoja[1];
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice+2]=Hojasa[j].Vert_Hoja[2];
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice+3]=Hojasa[j].Vert_Hoja[2];
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice+4]=Hojasa[j].Vert_Hoja[1];
-			mesh->mSubMesh[idMeshLeaves].mIndex[indice+5]=Hojasa[j].Vert_Hoja[3];
-			indice=indice+6;
-		}
-	}
-}
+		if (Leaves[j].existe)
+		{
+//			if (index<6)
+//			{
+				mesh->mSubMesh[idMeshLeaves].mIndex[index]=Leaves[j].Vert_Hoja[0];
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+1]=Leaves[j].Vert_Hoja[1];
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+2]=Leaves[j].Vert_Hoja[2];
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+3]=Leaves[j].Vert_Hoja[2];
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+4]=Leaves[j].Vert_Hoja[1];
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+5]=Leaves[j].Vert_Hoja[3];
+/*			}
+			else
+			{
+				mesh->mSubMesh[idMeshLeaves].mIndex[index]=0;
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+1]=0;
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+2]=0;
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+3]=0;
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+4]=0;
+				mesh->mSubMesh[idMeshLeaves].mIndex[index+5]=0;
+			}*/
+			index=index+6;
+		}
+	}
+}
+
+LeafOctree* TreeSimplifier::CreateLeafOctree(int deep)
+{
+	LeafOctree *leafoctree = new LeafOctree;
+	leafoctree->parent=NULL;
+	leafoctree->left = Vertex[0][0];
+	leafoctree->right = Vertex[0][0];
+	leafoctree->bottom = Vertex[0][1];
+	leafoctree->top = Vertex[0][1];
+	leafoctree->front = Vertex[0][2];
+	leafoctree->back = Vertex[0][2];
+
+	// calcualte the limits of the octree
+	for (int i=0; i<vertex_count; i++)
+	{
+		if (leafoctree->left>Vertex[i][0])
+			leafoctree->left=Vertex[i][0];
+		if (leafoctree->right<Vertex[i][0])
+			leafoctree->right=Vertex[i][0];
+		if (leafoctree->bottom>Vertex[i][1])
+			leafoctree->bottom=Vertex[i][1];
+		if (leafoctree->top<Vertex[i][1])
+			leafoctree->top=Vertex[i][1];
+		if (leafoctree->front>Vertex[i][2])
+			leafoctree->front=Vertex[i][2];
+		if (leafoctree->back<Vertex[i][2])
+			leafoctree->back=Vertex[i][2];
+	}
+
+	// setup the initial leaves buffer
+	leafoctree->leaves.clear();
+	octree_owning_leaf=new LeafOctree*[countLeaves*2]; // *2 to reserve memory for all simplified leaves
+	for (int i=0; i<countLeaves; i++)
+	{
+		leafoctree->leaves.push_back(i);
+		octree_owning_leaf[i] = leafoctree;
+	}
+
+	// generate the octree given an arbitrary depth
+	RecursiveCreateLeafOctree(leafoctree,deep);
+
+	// fill the octree
+	RecursiveFillOctreeWithLeaves(leafoctree);
+
+	return leafoctree;
+}
+
+void TreeSimplifier::RecursiveCreateLeafOctree(LeafOctree *parent, int deep)
+{
+	for (int i=0; i<8; i++)
+	{
+		parent->children[i] = NULL;
+		if (deep>0)
+		{
+			LeafOctree *child = parent->children[i] = new LeafOctree;
+
+			child->parent = parent;
+			switch(i)
+			{
+			case 0: 
+				child->left=parent->left; 
+				child->right=(parent->left+parent->right)*0.5f;
+				child->bottom=(parent->bottom+parent->top)*0.5f; 
+				child->top=parent->top;
+				child->front=parent->front;
+				child->back=(parent->front+parent->back)*0.5f; break;
+			case 1: 
+				child->left=(parent->left+parent->right)*0.5f; 
+				child->right=parent->right;
+				child->bottom=(parent->bottom+parent->top)*0.5f; 
+				child->top=parent->top;
+				child->front=parent->front;
+				child->back=(parent->front+parent->back)*0.5f; break;
+			case 2: 
+				child->left=parent->left;
+				child->right=(parent->left+parent->right)*0.5f;
+				child->bottom=parent->bottom;
+				child->top=(parent->bottom+parent->top)*0.5f;
+				child->front=parent->front;
+				child->back=(parent->front+parent->back)*0.5f; break;
+			case 3: 
+				child->left=(parent->left+parent->right)*0.5f;
+				child->right=parent->right;
+				child->bottom=parent->bottom;
+				child->top=(parent->bottom+parent->top)*0.5f;
+				child->front=parent->front;
+				child->back=(parent->front+parent->back)*0.5f; break;
+			case 4: 
+				child->left=parent->left; 
+				child->right=(parent->left+parent->right)*0.5f;
+				child->bottom=(parent->bottom+parent->top)*0.5f; 
+				child->top=parent->top;
+				child->back=parent->back;
+				child->front=(parent->front+parent->back)*0.5f; break;
+			case 5: 
+				child->left=(parent->left+parent->right)*0.5f; 
+				child->right=parent->right;
+				child->bottom=(parent->bottom+parent->top)*0.5f; 
+				child->top=parent->top;
+				child->back=parent->back;
+				child->front=(parent->front+parent->back)*0.5f; break;
+			case 6: 
+				child->left=parent->left;
+				child->right=(parent->left+parent->right)*0.5f;
+				child->bottom=parent->bottom;
+				child->top=(parent->bottom+parent->top)*0.5f;
+				child->back=parent->back;
+				child->front=(parent->front+parent->back)*0.5f; break;
+			case 7: 
+				child->left=(parent->left+parent->right)*0.5f;
+				child->right=parent->right;
+				child->bottom=parent->bottom;
+				child->top=(parent->bottom+parent->top)*0.5f;
+				child->back=parent->back;
+				child->front=(parent->front+parent->back)*0.5f; break;
+			}
+			RecursiveCreateLeafOctree(parent->children[i],deep-1);
+		}
+	}
+
+}
+
+void TreeSimplifier::RecursiveFillOctreeWithLeaves(LeafOctree *o)
+{   
+	for (int i=0; i<8; i++)
+	{
+		LeafOctree *child = o->children[i];
+		if (child)
+		{
+			for (std::vector<int>::iterator it=o->leaves.begin(); it!=o->leaves.end(); )
+			{
+				int idleaf = *it;
+				int idv0 = Leaves[idleaf].Vert_Hoja[0];
+				int idv1 = Leaves[idleaf].Vert_Hoja[1];
+				int idv2 = Leaves[idleaf].Vert_Hoja[2];
+				int idv3 = Leaves[idleaf].Vert_Hoja[3];
+
+				float * v0 = Vertex[idv0];
+				float * v1 = Vertex[idv1];
+				float * v2 = Vertex[idv2];
+				float * v3 = Vertex[idv3];
+
+				// if the leaf fits completely inside a child, the child owns it
+				if (child->PointInsideOctree(v0[0],v0[1],v0[2]) &&
+					child->PointInsideOctree(v1[0],v1[1],v1[2]) &&
+					child->PointInsideOctree(v2[0],v2[1],v2[2]) &&
+					child->PointInsideOctree(v3[0],v3[1],v3[2]))
+				{
+					child->leaves.push_back(idleaf);
+					it = o->leaves.erase(it);
+					octree_owning_leaf[idleaf] = child;
+				}
+				else
+					it++; 
+			}
+			// recurse all valid children
+			RecursiveFillOctreeWithLeaves(o->children[i]);
+		}
+	}
+}
+
+void TreeSimplifier::SetCriteriaOptimized(float diam)
+{
+	float coptmp2, coptmp, distmp2, distmp, criteriatmp;
+	int i, j, nleavesi, nleavesj;
+
+	int update_each	= countLeaves / 20;
+	
+	for ( i=0; i<countLeaves;i++)
+	{
+		static int ticks_since_last_update = 0;
+		if (mUPB && ticks_since_last_update>=update_each)
+		{
+			ticks_since_last_update=0;
+			mUPB(1);
+		}
+		ticks_since_last_update++;
+		
+		if (Leaves[i].existe == true)
+		{
+			Leaves[i].criterio = 1000000.0f;
+			nleavesi = int(Leaves[i].Cuantas_hojas);
+ 			float area_leaf_i = CalculateLeafArea(Leaves[i])/diam;
+
+			// Use only the leaves which belong the the same octree node as leaf i or to its parents		
+			int visit_parents = VISIT_PARENTS_DEEP;
+			for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode; octreenode=octreenode->parent, visit_parents--)
+			{
+				for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++)
+				{
+					j = *it;
+//				for (j=0; j<countLeaves; j++)
+//				{
+					if (j!=i && Leaves[j].existe)
+					{
+						nleavesj = int(Leaves[j].Cuantas_hojas);
+
+	//					if ( abs((nleavesi - nleavesj)) < 2)
+	//					{							
+							coptmp2 = Leaves[i].Coplanaridad(Leaves[j]);
+							coptmp = 1 - coptmp2;
+
+							//distmp2 = HausdorffOptimized( Leaves[i], Leaves[j]); 
+							distmp2 = DistanceFromCenters(Leaves[i], Leaves[j]); 
+							distmp = distmp2 / diam;
+
+							//criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
+							criteriatmp = distmp;
+							// select the lowest
+							criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i;
+							criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas;
+							if (Leaves[i].criterio > criteriatmp)
+							{
+								Leaves[i].criterio = criteriatmp;
+								Leaves[i].hoja_crit = j;
+							}
+		//				}
+					}
+				}				
+			}
+		}
+	}
+}
+
+
+void TreeSimplifier::SetCriteria2Optimized(float diam, long int newleaf)
+{
+	float  coptmp2, coptmp, distmp2, distmp, criteriatmp;
+	int i, j, nleavesi, nleavesj;
+	
+	for (i = 0; i < countLeaves; i++)
+	{
+		if (Leaves[i].existe && i!=newleaf)
+		{	
+ 			float area_leaf_i = CalculateLeafArea(Leaves[i])/diam;
+			nleavesi = int(Leaves[i].Cuantas_hojas);
+			if ( Leaves[Leaves[i].hoja_crit].existe == false)
+			{
+				Leaves[i].criterio = 1000000.0f;
+
+				int visit_parents = VISIT_PARENTS_DEEP;
+				for (LeafOctree *octreenode = octree_owning_leaf[i]; octreenode; octreenode=octreenode->parent, visit_parents--)
+				{
+					for (std::vector<int>::iterator it=octreenode->leaves.begin(); it!=octreenode->leaves.end(); it++)
+					{
+						j = *it;
+	//			for (j=0; j<countLeaves; j++)
+	//			{
+						if (j!=i && Leaves[j].existe)
+						{
+							nleavesj = int(Leaves[j].Cuantas_hojas);
+
+//							if ( abs((nleavesi - nleavesj)) < 2)
+//							{
+								coptmp2 = Leaves[i].Coplanaridad(Leaves[j]); 
+								coptmp = 1 - coptmp2;	
+							
+							
+								//distmp2 = HausdorffOptimized( Leaves[i],  Leaves[j]); 
+								distmp2 = DistanceFromCenters( Leaves[i], Leaves[j]); 
+								distmp = distmp2 / diam;
+
+								criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
+								criteriatmp *= CalculateLeafArea(Leaves[j])/diam + area_leaf_i;
+								criteriatmp *= Leaves[j].Cuantas_hojas + Leaves[i].Cuantas_hojas;
+								
+								// select the leaf with the lowest criteria
+								if (Leaves[i].criterio > criteriatmp) 
+								{
+									Leaves[i].criterio = criteriatmp;
+									Leaves[i].hoja_crit = j;
+								}
+						//	}
+						}
+					}
+				}
+			}
+			else
+			{ 
+				nleavesj = int(Leaves[newleaf].Cuantas_hojas);
+
+//				if ( abs((nleavesi - nleavesj)) < 2)
+//				{
+					coptmp2 = Leaves[i].Coplanaridad(Leaves[newleaf]); 
+					coptmp = 1 - coptmp2;
+
+					//distmp2 = HausdorffOptimized( Leaves[i], Leaves[newleaf]); 
+					distmp2 = DistanceFromCenters( Leaves[i], Leaves[newleaf]); 
+					distmp = distmp2 / diam;
+					
+					criteriatmp = (( K1 * distmp * distmp ) + (K2 * coptmp * distmp))/ (K1 + K2);
+					criteriatmp *= CalculateLeafArea(Leaves[newleaf])/diam + area_leaf_i;
+					criteriatmp *= Leaves[newleaf].Cuantas_hojas + Leaves[i].Cuantas_hojas;
+					
+					if (Leaves[i].criterio > criteriatmp) 
+					{	
+						Leaves[i].criterio = criteriatmp;
+						Leaves[i].hoja_crit = newleaf;
+					}
+//				}
+			}
+		}
+	}
+}
+
+
+LeafOctree *TreeSimplifier::GetMinOctreeNodeForLeaf(LeafOctree *start, const Hoja &leaf)
+{
+	int idv0 = leaf.Vert_Hoja[0];
+	int idv1 = leaf.Vert_Hoja[1];
+	int idv2 = leaf.Vert_Hoja[2];
+	int idv3 = leaf.Vert_Hoja[3];
+
+	float * v0 = Vertex[idv0];
+	float * v1 = Vertex[idv1];
+	float * v2 = Vertex[idv2];
+	float * v3 = Vertex[idv3];
+
+	if (start->PointInsideOctree(v0[0],v0[1],v0[2]) &&
+		start->PointInsideOctree(v1[0],v1[1],v1[2]) &&
+		start->PointInsideOctree(v2[0],v2[1],v2[2]) &&
+		start->PointInsideOctree(v3[0],v3[1],v3[2]))
+	{
+		return start;
+	}
+
+	for (int i=0; i<8; i++)
+		if (start->children[i])
+		{
+			LeafOctree *selectedNode = GetMinOctreeNodeForLeaf(start->children[i],leaf);
+			if (selectedNode)
+				return selectedNode;
+		}
+
+	return NULL;
+}
+
+float TreeSimplifier::DistanceFromCenters(const Hoja &leaf1, const Hoja &leaf2) const
+{
+	float onex, oney, onez;
+	float twox, twoy, twoz;
+	float threex, threey, threez;
+	float fourx, foury, fourz;
+	float x1, y1, z1;
+	float x2, y2, z2;
+	float x3, y3, z3;
+	float x4, y4, z4;
+
+	onex   = Vertex[leaf1.Vert_Hoja[0]][0]; oney   = Vertex[leaf1.Vert_Hoja[0]][1]; onez   = Vertex[leaf1.Vert_Hoja[0]][2];
+	twox   = Vertex[leaf1.Vert_Hoja[1]][0]; twoy   = Vertex[leaf1.Vert_Hoja[1]][1]; twoz   = Vertex[leaf1.Vert_Hoja[1]][2];
+	threex = Vertex[leaf1.Vert_Hoja[2]][0]; threey = Vertex[leaf1.Vert_Hoja[2]][1]; threez = Vertex[leaf1.Vert_Hoja[2]][2];
+	fourx  = Vertex[leaf1.Vert_Hoja[3]][0]; foury  = Vertex[leaf1.Vert_Hoja[3]][1]; fourz  = Vertex[leaf1.Vert_Hoja[3]][2];
+
+	float center1x = (onex + twox + threex + fourx)*0.25f;
+	float center1y = (oney + twoy + threey + foury)*0.25f;
+	float center1z = (onez + twoz + threez + fourz)*0.25f;
+
+	x1 = Vertex[leaf2.Vert_Hoja[0]][0]; y1 = Vertex[leaf2.Vert_Hoja[0]][1]; z1 = Vertex[leaf2.Vert_Hoja[0]][2];
+	x2 = Vertex[leaf2.Vert_Hoja[1]][0]; y2 = Vertex[leaf2.Vert_Hoja[1]][1]; z2 = Vertex[leaf2.Vert_Hoja[1]][2];
+	x3 = Vertex[leaf2.Vert_Hoja[2]][0]; y3 = Vertex[leaf2.Vert_Hoja[2]][1]; z3 = Vertex[leaf2.Vert_Hoja[2]][2];
+	x4 = Vertex[leaf2.Vert_Hoja[3]][0]; y4 = Vertex[leaf2.Vert_Hoja[3]][1]; z4 = Vertex[leaf2.Vert_Hoja[3]][2];
+
+	float center2x = (x1 + x2 + x3 + x4)*0.25f;
+	float center2y = (y1 + y2 + y3 + y4)*0.25f;
+	float center2z = (z1 + z2 + z3 + z4)*0.25f;
+
+	return distan(center1x,center1y,center1z,center2x,center2y,center2z);
+}
+
+
+bool TreeSimplifier::PruneOctree(LeafOctree *octree)
+{
+	if (octree->HasChildren())
+	{
+		for (int i=0; i<8; i++)
+			if (octree->children[i])
+				if (PruneOctree(octree->children[i])) // if child was pruned, nullify it
+					octree->children[i]=NULL;			
+	}
+	else
+	{
+		if (octree->parent)
+		{
+			for (std::vector<int>::iterator it=octree->leaves.begin(); it!=octree->leaves.end(); it++)
+			{
+				int idleaf = *it;
+				octree->parent->leaves.push_back(idleaf);
+				octree_owning_leaf[idleaf] = octree->parent;
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
+void TreeSimplifier::CrossProduct(const float *v1, const float *v2, float *res) const
+{
+	res[0] = v1[1]*v2[2] - v1[2]*v2[1];
+	res[1] = v1[2]*v2[0] - v1[0]*v2[2];
+	res[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+float TreeSimplifier::SquaredModule(const float *v) const
+{
+	return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+
+float TreeSimplifier::CalculateLeafArea(Hoja &leaf) const
+{
+	int idv0 = leaf.Vert_Hoja[0];
+	int idv1 = leaf.Vert_Hoja[1];
+	int idv2 = leaf.Vert_Hoja[2];
+	int idv3 = leaf.Vert_Hoja[3];
+
+	float * v0 = Vertex[idv0];
+	float * v1 = Vertex[idv1];
+	float * v2 = Vertex[idv2];
+	float * v3 = Vertex[idv3];
+
+	float v1v0[3] = {v1[0]-v0[0],v1[1]-v0[1],v1[2]-v0[2]};
+	float v2v0[3] = {v2[0]-v0[0],v2[1]-v0[1],v2[2]-v0[2]};
+	float v2v1[3] = {v2[0]-v1[0],v2[1]-v1[1],v2[2]-v1[2]};
+	float v3v1[3] = {v3[0]-v1[0],v3[1]-v1[1],v3[2]-v1[2]};
+	
+	float cross1[3], cross2[3];
+
+	CrossProduct(v1v0,v2v0,cross1);
+	CrossProduct(v2v1,v3v1,cross2);
+
+	float mod1 = SquaredModule(cross1);
+	float mod2 = SquaredModule(cross2);
+
+	return mod1*0.5f + mod2*0.5f;
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 980)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1007)
@@ -363,5 +363,5 @@
 			</File>
 			<File
-				RelativePath=".\src\libs\auxiliar.h">
+				RelativePath=".\include\auxiliar.h">
 			</File>
 			<File
@@ -375,5 +375,5 @@
 			</File>
 			<File
-				RelativePath=".\src\libs\GeoBase.h">
+				RelativePath=".\include\GeoBase.h">
 			</File>
 			<File
Index: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 998)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 1007)
@@ -24,4 +24,7 @@
 	//	Deactive Lod tree visualization.
 	geoMeshView->deactiveLodTree();
+
+	geoMeshView->resetTextures();
+	BuildLoadTextureSubMeshMenu();
 
 	//	Repaint the window.
@@ -919,7 +922,4 @@
 			//	Show title.
 			mProcessTitle->label("Visualize LodTrees");
-
-			// set the submesh with triangle lists as the leaves submesh
-			geoMeshView->setLeavesSubMesh(geoMeshView->findLeavesSubMesh());
 
 			//	Show the Visulize LodTree panel.
@@ -1790,5 +1790,5 @@
 		for(int i=0; i<mGeoMesh->mSubMeshCount;i++)
 		{
-			char *cadena=new char[12];
+			char *cadena=new char[256];
 
 			if (geoMeshView->getLeavesSubMesh() >= 0)
@@ -2103,16 +2103,16 @@
     else
     {
-        // Simplificar hasta un número de vértices.
+        //	Simplificar hasta un número de vértices.
         uint32 v    =    (uint32)mMeshReduction->fvalue();
 
-        // Simplifica el geomesh -> Parámetro es un factor LOD [0,1].
+        //	Simplifica el geomesh -> Parámetro es un factor LOD [0,1].
         mMeshSimplifier->Simplify(v);
 
-        //    Deletes the previous mesh.
+        //	Deletes the previous mesh.
         delete mUndoMesh;
 
         mUndoMesh    =    new Mesh();
 
-        //    Sets the undo mesh.
+        //	Sets the undo mesh.
         *mUndoMesh    =    *mGeoMesh;
 
@@ -2121,5 +2121,5 @@
         mGeoMesh    =    mMeshSimplifier->GetMesh();
 
-        //    Visualize the mesh.
+        //	Visualize the mesh.
         geoMeshView->setMesh(mGeoMesh);
     }
@@ -2127,5 +2127,4 @@
     return    true;
 }
-
 
 //---------------------------------------------------------------------------
@@ -2382,6 +2381,5 @@
 
 	//	Sets the slider range.
-	mLodStripSlider->range(lodStripsLib->MaxLod(),
-										lodStripsLib->MinLod());
+	mLodStripSlider->range(lodStripsLib->MinLod(),lodStripsLib->MaxLod());
 
 	//	Pass to geomeshview the lod strips object.
@@ -2389,5 +2387,5 @@
 	
 	//	Puts the slider in the max position.
-	mLodStripSlider->value(lodStripsLib->MinLod());
+	//mLodStripSlider->value(lodStripsLib->MinLod());
 }
 
@@ -2521,7 +2519,4 @@
 			//	Restore simplification state.
 			simplificationState	=	NO_SIMPLIFICATION;
-
-			geoMeshView->resetTextures();
-			BuildLoadTextureSubMeshMenu();
 		}
 	}
Index: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoTool.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoTool.cpp	(revision 980)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoTool.cpp	(revision 1007)
@@ -4,4 +4,5 @@
 #endif
 
+#include <malloc.h>
 #include "GeoMeshViewUI.h"
 
@@ -15,4 +16,6 @@
 int main(int argc, char **argv)
 {
+	_set_sbh_threshold(1016);
+
 	interface	=	new GeoMeshViewUI(incrementa);
 	
Index: GTP/trunk/Lib/Geom/shared/GeoTool/mqslimSequence.txt
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/mqslimSequence.txt	(revision 986)
+++ 	(revision )
@@ -1,257 +1,0 @@
-h:\Proyectos\svn\gtp\trunk\lib\geom\shared\GeoTool/media/models/robot.mesh
-232 121 265 290 1 0.000007 & 111 136 233 305 234 238 237 291 266
-232 147 265 290 1 0.000007 &
-240 121 265 290 1 0.000007 &
-240 147 265 290 1 0.000007 &
-269 121 265 290 1 0.000007 &
-269 147 265 290 1 0.000007 &
-291 121 265 290 1 0.000007 &
-291 147 265 290 0 0.000007 &
-239 146 291 292 1 -0.000939 & 136 137 138 236 237 306 293
-241 146 291 292 1 -0.000939 &
-292 146 291 292 0 -0.000939 &
-59 58 63 148 1 0.003780 & 217 302 64 149 146
-59 154 63 148 1 0.003780 &
-152 58 63 148 1 0.003780 &
-152 154 63 148 0 0.003780 &
-110 109 103 106 0 0.004118 & 102 256 105 259 257 260 108 107
-214 60 218 303 1 -0.008405 & 64 149 105 259 217 302 300
-214 111 218 303 1 -0.008405 &
-214 155 218 303 1 -0.008405 &
-293 60 218 303 1 -0.008405 &
-293 111 218 303 1 -0.008405 &
-293 155 218 303 0 -0.008405 &
-260 108 256 258 0 -0.006323 & 102 104 255 262 257
-17 43 55 52 1 0.000000 & 41 44 51 45 10 19 56 18
-50 43 55 52 0 0.000000 &
-200 174 206 209 1 -0.019477 & 164 210 173 172 195 198 205 199
-200 207 206 209 0 -0.019477 &
-203 169 208 213 1 -0.019220 & 162 163 168 214 197 202 207
-203 209 208 213 0 -0.019220 &
-14 45 59 54 1 0.000000 & 43 48 53 8 9 14 60
-52 45 59 54 0 0.000000 &
-126 124 116 125 0 0.000000 & 114 268 115 118 272 269 270 279 124 117
-9 41 60 61 1 0.000000 & 38 43 39 49 6 15 14
-9 46 60 61 1 0.000000 &
-22 41 60 61 1 0.000000 &
-22 46 60 61 1 0.000000 &
-55 41 60 61 1 0.000000 &
-55 46 60 61 1 0.000000 &
-56 41 60 61 1 0.000000 &
-56 46 60 61 0 0.000000 &
-198 166 215 214 1 -0.011540 & 160 169 168 192 197 193 203
-198 179 215 214 1 -0.011540 &
-198 212 215 214 1 -0.011540 &
-198 213 215 214 1 -0.011540 &
-202 166 215 214 1 -0.011540 &
-202 179 215 214 1 -0.011540 &
-202 212 215 214 1 -0.011540 &
-202 213 215 214 0 -0.011540 &
-230 245 240 251 1 0.003830 & 250 241 232 304 239 233 234
-233 245 240 251 0 0.003830 &
-91 76 86 97 1 0.000000 & 78 150 85 79 80 96 87
-91 77 86 97 0 0.000000 &
-146 84 137 138 1 -0.003300 & 82 152 83 139 293 306 136 237 236
-146 87 137 138 1 -0.003300 &
-146 149 137 138 0 -0.003300 &
-121 78 136 111 1 0.000000 & 79 80 151 84 83 112 266 305 237 238 233 234
-121 88 136 111 1 0.000000 &
-121 120 136 111 1 0.000000 &
-121 148 136 111 1 0.000000 &
-147 78 136 111 1 0.000000 &
-147 88 136 111 1 0.000000 &
-147 120 136 111 1 0.000000 &
-147 148 136 111 0 0.000000 &
-24 42 51 50 1 0.000000 & 39 40 49 41 16 17 18
-49 42 51 50 0 0.000000 &
-199 181 204 205 1 -0.011531 & 170 171 172 193 194 203 195
-199 206 204 205 0 -0.011531 &
-18 47 62 56 1 0.000000 & 45 46 57 47 10 11 12
-53 47 62 56 0 0.000000 &
-204 173 210 216 1 -0.026965 & 164 165 166 199 200 211 201
-204 210 210 216 0 -0.026965 &
-44 13 53 58 1 -0.026568 & 8 21 20 42 47 48 57
-44 51 53 58 0 -0.026568 &
-170 201 207 212 1 0.000000 & 196 201 202 211 162 175 174
-208 201 207 212 0 0.000000 &
-281 145 295 289 0 -0.000578 & 135 141 139 294 293 140 282 287 283 288 307
-64 63 66 72 0 0.000031 & 65 70 71 74 73
-215 218 220 226 0 0.000000 & 228 227 219 224 225
-217 216 219 222 0 0.000000 & 224 223 228 221
-62 61 65 68 0 0.000707 & 74 67 70 69
-6 5 2 13 1 -0.009711 & 11 12 5 21 20
-6 19 2 13 1 -0.009711 &
-21 5 2 13 1 -0.009711 &
-21 19 2 13 0 -0.009711 &
-163 162 156 167 1 0.000000 & 159 175 174 165 166
-163 178 156 167 1 0.000000 &
-176 162 156 167 1 0.000000 &
-176 178 156 167 0 0.000000 &
-27 128 121 123 1 0.000000 & 117 122 124 120 22 23 110
-118 128 121 123 0 0.000000 &
-274 184 275 277 1 0.000000 & 176 177 264 271 276 278 274
-274 268 275 277 0 0.000000 &
-124 273 270 279 0 -0.009515 & 278 271 114 268 115 124 117 118 272 269
-2 1 0 7 1 0.011036 & 3 15 6 4 17 16
-2 8 0 7 1 0.011036 &
-2 23 0 7 1 0.011036 &
-11 1 0 7 1 0.011036 &
-11 8 0 7 1 0.011036 &
-11 23 0 7 0 0.011036 &
-158 157 154 161 1 0.000000 & 158 171 170 157 169 160
-158 168 154 161 1 0.000000 &
-167 157 154 161 1 0.000000 &
-167 168 154 161 1 0.000000 &
-180 157 154 161 1 0.000000 &
-180 168 154 161 0 0.000000 &
-60 58 64 217 1 0.000000 & 146 105 259 300
-60 154 64 217 1 0.000000 &
-111 58 64 217 1 0.000000 &
-111 154 64 217 1 0.000000 &
-155 58 64 217 1 0.000000 &
-155 154 64 217 0 0.000000 &
-75 133 134 153 1 0.000000 & 128 133 129 141 135 77 81
-82 133 134 153 1 0.000000 &
-143 133 134 153 0 0.000000 &
-107 275 272 280 1 -0.020915 & 271 276 101 126 104 118 255
-129 275 272 280 0 -0.020915 &
-186 187 178 179 1 0.012178 & 184 180 188 185 177 264 286 263
-267 187 178 179 1 0.012178 &
-285 187 178 179 0 0.012178 &
-30 29 24 25 1 0.000000 & 23 110 132 109 30 26 34 31
-30 115 24 25 1 0.000000 &
-30 141 24 25 0 0.000000 &
-227 235 235 307 1 0.000000 & 306 293 231 288
-227 290 235 307 1 0.000000 &
-236 235 235 307 1 0.000000 &
-236 290 235 307 1 0.000000 &
-289 235 235 307 1 0.000000 &
-289 290 235 307 0 0.000000 &
-197 193 189 198 0 0.000000 & 185 188 194 195 190 191 200 199
-36 40 35 44 0 0.016904 & 36 37 46 45 31 34 40 41
-153 58 146 300 1 0.000000 & 105 259 147 301
-153 154 146 300 0 0.000000 &
-32 31 26 27 1 0.000000 & 144 145 132 34 36
-32 140 26 27 0 0.000000 &
-161 160 155 163 1 0.000000 & 157 169 168 159 175 162
-161 172 155 163 1 0.000000 &
-171 160 155 163 1 0.000000 &
-171 172 155 163 0 0.000000 &
-4 3 1 9 1 0.024658 & 5 21 8 3 15 14
-4 12 1 9 1 0.024658 &
-15 3 1 9 1 0.024658 &
-15 12 1 9 0 0.024658 &
-76 90 85 87 1 0.006439 & 91 98 100 89 78 150 79 80 96
-76 93 85 87 1 0.006439 &
-77 90 85 87 1 0.006439 &
-77 93 85 87 0 0.006439 &
-245 244 239 241 1 0.010911 & 245 252 254 243 234 250 233 304 232
-245 246 239 241 0 0.010911 &
-164 159 173 158 1 0.000000 & 164 157 159 165 171 172
-164 175 173 158 1 0.000000 &
-182 159 173 158 1 0.000000 &
-182 175 173 158 0 0.000000 &
-0 7 4 19 1 -0.025617 & 17 18 10 3 5 11
-0 25 4 19 1 -0.025617 &
-16 7 4 19 1 -0.025617 &
-16 25 4 19 0 -0.025617 &
-150 136 140 142 0 0.000000 & 129 130 141 131 143 294 296
-79 78 79 151 1 0.000000 & 80 84 83 237 233 305 234 238 112 266 150 127
-79 88 79 151 1 0.000000 &
-79 120 79 151 1 0.000000 &
-79 148 79 151 1 0.000000 &
-131 78 79 151 1 0.000000 &
-131 88 79 151 1 0.000000 &
-131 120 79 151 1 0.000000 &
-131 148 79 151 0 0.000000 &
-123 125 115 119 1 -0.037328 & 124 120 113 114 128 130 129
-135 125 115 119 0 -0.037328 &
-127 275 118 126 0 0.000000 & 271 276 255 104 101 117 122
-272 271 269 273 1 0.000000 & 267 282 268 284 283 278 274
-272 279 269 273 0 0.000000 &
-47 20 57 12 1 -0.016787 & 20 45 46 47 10 11
-47 54 57 12 0 -0.016787 &
-173 177 211 166 1 -0.020105 & 174 164 199 165 200 201
-173 211 211 166 1 -0.020105 &
-210 177 211 166 1 -0.020105 &
-210 211 211 166 0 -0.020105 &
-166 165 203 160 1 -0.019565 & 170 193 169 168 197 192
-166 205 203 160 1 -0.019565 &
-179 165 203 160 1 -0.019565 &
-179 205 203 160 1 -0.019565 &
-212 165 203 160 1 -0.019565 &
-212 205 203 160 1 -0.019565 &
-213 165 203 160 1 -0.019565 &
-213 205 203 160 0 -0.019565 &
-41 10 49 6 1 -0.021466 & 16 38 43 39 14 15
-41 48 49 6 1 -0.021466 &
-46 10 49 6 1 -0.021466 &
-46 48 49 6 0 -0.021466 &
-201 195 196 201 0 0.018901 & 186 191 187 200 202 162 174 175
-228 231 304 281 1 -0.022534 & 233 305 231 288 232 287
-228 278 304 281 1 -0.022534 &
-277 231 304 281 1 -0.022534 &
-277 278 304 281 1 -0.022534 &
-288 231 304 281 1 -0.022534 &
-288 278 304 281 1 -0.022534 &
-294 231 304 281 1 -0.022534 &
-294 278 304 281 0 -0.022534 &
-183 192 183 184 0 0.000000 & 192 185 194 193 176 177 182
-37 13 47 42 1 0.000000 & 8 21 48 20 32 37 33 46
-37 51 47 42 0 0.000000 &
-35 28 29 30 0 -0.037207 & 22 23 28 38 31 40 39
-108 105 104 102 0 -0.000784 & 101 108 257 255 262
-112 58 105 147 1 0.000000 & 259 301 145 107 109 132
-112 154 105 147 1 0.000000 &
-113 58 105 147 1 0.000000 &
-113 154 105 147 1 0.000000 &
-117 58 105 147 1 0.000000 &
-117 154 105 147 1 0.000000 &
-139 58 105 147 1 0.000000 &
-139 154 105 147 0 0.000000 &
-191 185 182 187 1 0.000000 & 284 285 176 186 274 202 192 197
-191 194 182 187 1 0.000000 &
-191 276 182 187 1 0.000000 &
-191 283 182 187 1 0.000000 &
-196 185 182 187 1 0.000000 &
-196 194 182 187 1 0.000000 &
-196 276 182 187 1 0.000000 &
-196 283 182 187 0 0.000000 &
-83 84 152 139 1 0.000000 & 82 83 237 236 306 293 81 135
-83 87 152 139 1 0.000000 &
-83 149 152 139 1 0.000000 &
-144 84 152 139 1 0.000000 &
-144 87 152 139 1 0.000000 &
-144 149 152 139 0 0.000000 &
-26 34 28 33 1 0.029424 & 48 38 43 130 131 22 32 120
-26 39 28 33 1 0.029424 &
-38 34 28 33 1 0.029424 &
-38 39 28 33 1 0.029424 &
-130 34 28 33 1 0.029424 &
-130 39 28 33 1 0.029424 &
-137 34 28 33 1 0.029424 &
-137 39 28 33 0 0.029424 &
-188 187 286 180 1 0.000000 & 263 264 188 177 185 298 299 181
-286 187 286 180 0 0.000000 &
-109 261 257 260 0 0.000812 & 262 261 259 108 107
-74 122 133 127 1 0.000000 & 112 113 128 77 78 150
-74 134 133 127 1 0.000000 &
-132 122 133 127 1 0.000000 &
-132 134 133 127 1 0.000000 &
-142 122 133 127 1 0.000000 &
-142 134 133 127 1 0.000000 &
-156 122 133 127 1 0.000000 &
-156 134 133 127 0 0.000000 &
-190 189 190 181 1 0.000000 & 188 298 186 285 191 297
-284 189 190 181 0 0.000000 &
-119 273 268 114 0 0.000000 & 117 124 278 271 266 267 112 113
-220 219 221 253 1 -0.004992 & 223 249 245 252 228 227 229 230
-220 253 221 253 1 -0.004992 &
-220 257 221 253 1 -0.004992 &
-223 219 221 253 1 -0.004992 &
-223 253 221 253 1 -0.004992 &
-223 257 221 253 1 -0.004992 &
-258 219 221 253 1 -0.004992 &
-258 253 221 253 1 -0.004992 &
-258 257 221 253 0 -0.004992 &
-145 282 283 294 0 -0.016391 & 284 296 297 285 135 141 293 282 287 288
