Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 2090)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 2194)
@@ -60,6 +60,6 @@
 				Index mV0;
 				Index	mV1;
-				Index mT0;
-				Index	mT1;
+				int		mT0;
+				int		mT1;
 				float x;
 				float	y;
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 2194)
@@ -110,5 +110,5 @@
 			/// Class constructor. Retrieves a pointer to a valid Geometry::Mesh object to simplify.
 			MeshSimplifier(	const Geometry::Mesh	*,
-					Geometry::TIPOFUNC		upb=0);
+											Geometry::TIPOFUNC		upb=0);
 
 			/// Virtual class destructor.
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/buffers.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/buffers.h	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/buffers.h	(revision 2194)
@@ -1,4 +1,4 @@
-#ifndef __interleave_h_
-#define __interleave_h_
+#ifndef __buffers_h_
+#define __buffers_h_
 
 #include "GL/glut.h"
@@ -21,18 +21,12 @@
 } Vertex_;
 
-extern GLuint vertex_buf, color_buf;
-
-extern Vertex_ *buf_vertices;
-extern Color   *buf_colors;
-
-extern Vertex_ *pbuf_vertices;
-extern Color   *pbuf_colors;
-
-extern void saveVertexBuffer(Change *c, VertexIL *dest);
-extern void loadVertexBuffer(VertexIL *src, Change *c);
+extern VertexIL *saveVertexBuffer(Change *c, Vertex_ *verts, Color *cols);
+extern void loadVertexBuffer(VertexIL *src, Change *c, Vertex_ *verts, Color *cols);
+extern VertexIL *saveVertexBufferGPU(Change *c);
+extern void loadVertexBufferGPU(VertexIL *src, Change *c);
 
 extern VertexIL *setupInterleave(Mesh *mesh, Color *colors);
 extern void setupVertexArray(Mesh *mesh, Color *colors);
-extern void updateVertexArray(Mesh *mesh, Change *c);
+extern void updateVertexArray(Mesh *mesh, Change *c, Vertex_ *verts, Color *cols);
 extern void setupVertexBufferObjects(Mesh *mesh, Color *colors);
 extern void updateVertexBufferObjects(Mesh *mesh, Change *c);
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/mesh.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/mesh.h	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/mesh.h	(revision 2194)
@@ -13,5 +13,4 @@
 	  int *edges;
     int enable;
-		int	movable;	//	If vertex is part of a border.
 } Vertex;
 
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 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/simplify.h	(revision 2194)
@@ -28,7 +28,7 @@
 	extern void	initVertexMultimap(	Mesh *mesh,
 																	multimap<int,int> &vertexMultimap);
-	/////////////////////////////////////////////////////////////////////////////
+	/////////////////////////////////////////////////////////////////////////
 	//	Coordinates class.
-	/////////////////////////////////////////////////////////////////////////////
+	/////////////////////////////////////////////////////////////////////////
 	class _float3_
 	{
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/global.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/global.h	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/global.h	(revision 2194)
@@ -9,4 +9,5 @@
 #include "color.h"
 #include "change.h"
+#include "buffers.h"
 
 //	For progress update.
@@ -132,4 +133,9 @@
 extern GLsizei width, height;
 
+extern GLuint vertex_buf, color_buf;
+
+extern Vertex_ *buf_vertices;
+extern Color   *buf_colors;
+
 extern int vmiWin;
 
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 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/change.h	(revision 2194)
@@ -85,5 +85,5 @@
 
 	extern void modifyEdges(Mesh *mesh, Change *c);
-  extern int find(int *edges, int num, int v_);
+  extern int find(Mesh *mesh, int *edges, int num, int v_);
 	extern void updateEdgeAdj(Mesh *mesh, Change *c) ;
 
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/main.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/main.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/main.cpp	(revision 2194)
@@ -37,4 +37,14 @@
 GLuint fb, depth_rb, color_tex;
 
+#ifdef VERTEX_ARRAY_INTERLEAVE
+VertexIL *interleave = NULL;
+#endif
+
+GLuint vertex_buf = 0,
+       color_buf = 0;
+
+Vertex_ *buf_vertices = NULL;
+Color   *buf_colors = NULL;
+
 int vmiWin = 0;
 
@@ -48,114 +58,126 @@
 void VMI::init(void)
 {
-    // Clear color
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    
-    // Initialize viewing values
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    gluPerspective(fov, (GLdouble)width / height, 0.1, 40.0);
-    
-    //glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    
-    glShadeModel(GL_FLAT);
-    
-    glDisable(GL_BLEND);
-
-    glEnable(GL_CULL_FACE); // important
-
-    glEnable(GL_DEPTH_TEST);
-
-    if (GL_TRUE != glewIsSupported((const char*) "GL_EXT_framebuffer_object"))
-    {
-        fprintf(stderr,"GL_EXT_framebuffer_object extension is not available!\n");
-        exit(1);
-    } else {
-         // create objects
-        glGenFramebuffersEXT(1, &fb);        // frame buffer
-        glGenTextures(1, &color_tex);        // texture
-        glGenRenderbuffersEXT(1, &depth_rb); // render buffer
-        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
-
-        // initialize color texture
-        glBindTexture(GL_TEXTURE_2D, color_tex);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
-                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-        // texture parameters
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-        // attach texture to framebuffer color buffer
-        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-                                  GL_COLOR_ATTACHMENT0_EXT,
-                                  GL_TEXTURE_2D, color_tex, 0);
-        // initialize depth renderbuffer
-        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
-        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
-                                 GL_DEPTH_COMPONENT24, width, height);
-        // attach renderbuffer to framebuffer depth buffer
-        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
-                                     GL_DEPTH_ATTACHMENT_EXT,
-                                     GL_RENDERBUFFER_EXT, depth_rb);
-
-        // Check framebuffer completeness at the end of initialization.
-        CHECK_FRAMEBUFFER_STATUS();
-    }
-    /*if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_fragment_shader"))
-    {
-        fprintf(stderr,"GL_ARB_fragment_shader extension is not available!\n");
-    }
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_vertex_shader"))
-    {
-        fprintf(stderr,"GL_ARB_vertex_shader extension is not available!\n");
-    }
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_shader_objects"))
-    {
-        fprintf(stderr,"GL_ARB_shader_objects extension is not available!\n");
-    }*/
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_vertex_buffer_object"))
-    {
-        fprintf(stderr,"GL_ARB_vertex_buffer_object extension is not available!\n");
-    } else {
+	// Clear color
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+	// Initialize viewing values
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	gluPerspective(fov, (GLdouble)width / height, 0.1, 40.0);
+
+	//glPixelStorei(GL_PACK_ALIGNMENT, 1);
+	//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+	glShadeModel(GL_FLAT);
+
+	glDisable(GL_BLEND);
+
+	glEnable(GL_CULL_FACE); // important
+
+	glEnable(GL_DEPTH_TEST);
+
+	if (GL_TRUE != glewIsSupported((const char*) "GL_EXT_framebuffer_object"))
+	{
+		fprintf(stderr,
+						"GL_EXT_framebuffer_object extension is not available!\n");
+		exit(1);
+	}
+	else
+	{
+		// create objects
+		glGenFramebuffersEXT(1, &fb);        // frame buffer
+		glGenTextures(1, &color_tex);        // texture
+		glGenRenderbuffersEXT(1, &depth_rb); // render buffer
+		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+
+		// initialize color texture
+		glBindTexture(GL_TEXTURE_2D, color_tex);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+				GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+		// texture parameters
+		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+		// attach texture to framebuffer color buffer
+		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+				GL_COLOR_ATTACHMENT0_EXT,
+				GL_TEXTURE_2D, color_tex, 0);
+		// initialize depth renderbuffer
+		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
+		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+				GL_DEPTH_COMPONENT24, width, height);
+		// attach renderbuffer to framebuffer depth buffer
+		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+				GL_DEPTH_ATTACHMENT_EXT,
+				GL_RENDERBUFFER_EXT, depth_rb);
+
+		// Check framebuffer completeness at the end of initialization.
+		CHECK_FRAMEBUFFER_STATUS();
+	}
+	/*if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_fragment_shader"))
+		{
+		fprintf(stderr,"GL_ARB_fragment_shader extension is not available!\n");
+		}
+		if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_vertex_shader"))
+		{
+		fprintf(stderr,"GL_ARB_vertex_shader extension is not available!\n");
+		}
+		if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_shader_objects"))
+		{
+		fprintf(stderr,"GL_ARB_shader_objects extension is not available!\n");
+		}*/
+	if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_vertex_buffer_object"))
+	{
+		fprintf(stderr,
+				"GL_ARB_vertex_buffer_object extension is not available!\n");
+	}
+	else
+	{
 #ifdef VERTEX_BUFFER_OBJECTS
-        
-        glGenBuffersARB(1, &vertex_buf);
-        
-        glGenBuffersARB(1, &color_buf);
-#endif
-    }
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_occlusion_query"))
-    {
-        fprintf(stderr,"GL_ARB_occlusion_query extension is not available!\n");
-    } else {
+		glGenBuffersARB(1, &vertex_buf);
+
+		glGenBuffersARB(1, &color_buf);
+#endif
+	}
+
+	if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_occlusion_query"))
+	{
+		fprintf(stderr,
+				"GL_ARB_occlusion_query extension is not available!\n");
+	}
+	else
+	{
 #ifdef USE_OCCLUSION_QUERY
-        // Generate a list of occlusion queries
-        queries = (GLuint *)malloc(mesh->currentNumTriangles * sizeof(GLuint));
-        glGenQueriesARB(mesh->currentNumTriangles, queries);y
-#endif
-    }
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_imaging"))
-    {
-        fprintf(stderr,"GL_ARB_imaging extension is not available!\n");
-    }
-    if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_multitexture"))
-    {
-        fprintf(stderr,"GL_ARB_multitexture extension is not available!\n");
-    }
+		// Generate a list of occlusion queries
+		queries = (GLuint *)malloc(mesh->currentNumTriangles * sizeof(GLuint));
+		glGenQueriesARB(mesh->currentNumTriangles, queries);
+#endif
+	}
+
+	if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_imaging"))
+	{
+		fprintf(stderr,"GL_ARB_imaging extension is not available!\n");
+	}
+
+	if (GL_TRUE != glewIsSupported((const char*) "GL_ARB_multitexture"))
+	{
+		fprintf(stderr,"GL_ARB_multitexture extension is not available!\n");
+	}
+
 #ifdef _WIN32
-    if (GL_TRUE != wglewIsSupported((const char*) "WGL_EXT_swap_control"))
-    {
-        fprintf(stderr,"WGL_EXT_swap_control extension is not available!\n");
-    }
-#endif
-    
-    // Allocate memory for the image pixels
-    pixels = (GLubyte *)malloc(width * height * 4 * sizeof(GLubyte));
-    
-    // Allocate memory for colors
-    colors = initColors(mesh->currentNumTriangles);
-
-    // Set a different color for every triangle 
-    setColors4(colors, mesh->currentNumTriangles);
+	if (GL_TRUE != wglewIsSupported((const char*) "WGL_EXT_swap_control"))
+	{
+		fprintf(stderr,"WGL_EXT_swap_control extension is not available!\n");
+	}
+#endif
+
+	// Allocate memory for the image pixels.
+	pixels = (GLubyte *)malloc(width * height * 4 * sizeof(GLubyte));
+
+	// Allocate memory for colors.
+	colors = initColors(mesh->currentNumTriangles);
+
+	// Set a different color for every triangle.
+	setColors4(colors, mesh->currentNumTriangles);
 }
 
@@ -246,5 +268,5 @@
 #endif
 #ifdef VERTEX_ARRAY_INTERLEAVE
-    glInterleavedArrays (GL_T2F_C4UB_V3F, 0, intertwined);
+    glInterleavedArrays (GL_T2F_C4UB_V3F, 0, interleave);
     glDrawArrays(GL_TRIANGLES, 0, mesh->currentNumTriangles * 3);
 #endif
@@ -444,9 +466,5 @@
 #ifdef VERTEX_BUFFER_OBJECTS
     glDeleteBuffersARB(1, &vertex_buf);
-    
     glDeleteBuffersARB(1, &color_buf);
-
-    //free(pbuf_vertices);
-    //free(pbuf_colors);
 
 		buf_vertices = NULL;
@@ -455,9 +473,13 @@
 #endif
 #ifdef VERTEX_ARRAY
-    //free(pbuf_vertices);
-    //free(pbuf_colors);
+    free(buf_vertices);
+    free(buf_colors);
 
 		buf_vertices = NULL;
     buf_colors = NULL;
+#endif
+#ifdef VERTEX_ARRAY_INTERLEAVE
+		free(interleave);
+		interleave = NULL;
 #endif
 
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 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/change.cpp	(revision 2194)
@@ -313,14 +313,11 @@
 }
 
-int VMI::find(int *edges, int num, int v_) {
+int VMI::find(Mesh *mesh, int *edges, int num, int v_) {
 	int i;
-
 	int u, v;
 
-
 	for(i=0; i<num; i++) {
 
 		u = mesh->edges[edges[i]].u;
-
 		v = mesh->edges[edges[i]].v;
 
@@ -333,5 +330,4 @@
 void VMI::updateEdgeAdj(Mesh *mesh, Change *c) {
 	int i;
-
 	int v, e;
 
@@ -346,5 +342,5 @@
 		else v = mesh->edges[e].u;
 		
-		if (!find(mesh->vertices[c->v].edges, mesh->vertices[c->v].numEdges, v))
+		if (!find(mesh, mesh->vertices[c->v].edges, mesh->vertices[c->v].numEdges, v))
 			addItem(mesh->vertices[c->v].edges, &mesh->vertices[c->v].numEdges, e);
 		else mesh->edges[e].enable = FALSE;
@@ -427,6 +423,11 @@
 				<<	endl;
 
+	if (c->numDel == 0)
+	{
+		step.mT0	=	 -1;
+		step.mT1	=	 -1;
+	}
 	//	If only one triangle has been deleted.
-	if (c->numDel == 1)
+	else if (c->numDel == 1)
 	{
 		step.mT0	=	c->deleted[0].id;
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/buffers.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/buffers.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/buffers.cpp	(revision 2194)
@@ -7,21 +7,13 @@
 #include "../include/global.h"
 
-namespace	VMI
-{
-Vertex_ *buf_vertices = NULL;
-Color   *buf_colors = NULL;
-
-Vertex_ *pbuf_vertices;
-Color   *pbuf_colors;
-
-GLuint vertex_buf = 0,
-       color_buf = 0;
-
-}
-
-using namespace	VMI;
-
-void VMI::saveVertexBuffer(Change *c, VertexIL *dest) {
-    int j, t, n = 0, m;
+using namespace VMI;
+
+
+
+VertexIL *VMI::saveVertexBuffer(Change *c, Vertex_ *verts, Color *cols) {
+    int i, j, t, n = 0, m;
+    VertexIL *dest;
+    
+    dest = (VertexIL *)malloc((c->numDel + c->numMod + 1) * 3 * sizeof(VertexIL));
     
     // Save vertex coordinates and color for deleted triangles
@@ -32,30 +24,14 @@
         m = 3 * t;
         
-        dest[n].x = buf_vertices[m + 0].x;
-        dest[n].y = buf_vertices[m + 0].y;
-        dest[n].z = buf_vertices[m + 0].z;
-        dest[n].a = buf_colors[m + 0].a;
-        dest[n].b = buf_colors[m + 0].b;
-        dest[n].r = buf_colors[m + 0].r;
-        dest[n].g = buf_colors[m + 0].g;
-        n++;
-        
-        dest[n].x = buf_vertices[m + 1].x;
-        dest[n].y = buf_vertices[m + 1].y;
-        dest[n].z = buf_vertices[m + 1].z;
-        dest[n].a = buf_colors[m + 1].a;
-        dest[n].b = buf_colors[m + 1].b;
-        dest[n].r = buf_colors[m + 1].r;
-        dest[n].g = buf_colors[m + 1].g;
-        n++;
-        
-        dest[n].x = buf_vertices[m + 2].x;
-        dest[n].y = buf_vertices[m + 2].y;
-        dest[n].z = buf_vertices[m + 2].z;
-        dest[n].a = buf_colors[m + 2].a;
-        dest[n].b = buf_colors[m + 2].b;
-        dest[n].r = buf_colors[m + 2].r;
-        dest[n].g = buf_colors[m + 2].g;
-        n++;
+		for (i=0; i<3; i++) {
+			dest[n].x = verts[m + i].x;
+			dest[n].y = verts[m + i].y;
+			dest[n].z = verts[m + i].z;
+			dest[n].a = cols[m + i].a;
+			dest[n].b = cols[m + i].b;
+			dest[n].r = cols[m + i].r;
+			dest[n].g = cols[m + i].g;
+			n++;
+		}
     }
     // Save vertex coordinates for modified triangles
@@ -66,24 +42,47 @@
         m = 3 * t;
         
-        dest[n].x = buf_vertices[m + 0].x;
-        dest[n].y = buf_vertices[m + 0].y;
-        dest[n].z = buf_vertices[m + 0].z;
-        n++;
-        
-        dest[n].x = buf_vertices[m + 1].x;
-        dest[n].y = buf_vertices[m + 1].y;
-        dest[n].z = buf_vertices[m + 1].z;
-        n++;
-        
-        dest[n].x = buf_vertices[m + 2].x;
-        dest[n].y = buf_vertices[m + 2].y;
-        dest[n].z = buf_vertices[m + 2].z;
-        n++;
-    }
-}
-
-void VMI::loadVertexBuffer(VertexIL *src, Change *c) {
-    int j, t, n = 0, m;
-    
+		for (i=0; i<3; i++) {
+			dest[n].x = verts[m + i].x;
+			dest[n].y = verts[m + i].y;
+			dest[n].z = verts[m + i].z;
+			n++;
+		}
+    }
+    
+    return dest;
+}
+
+VertexIL *VMI::saveVertexBufferGPU(Change *c) {
+    Vertex_ *verts;
+	Color *cols;
+    VertexIL *dest;
+    
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
+    // Map the buffer object
+	verts = (Vertex_ *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY);
+	
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, color_buf);
+    // Map the buffer object
+	cols = (Color *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY);
+	
+	// Update GPU buffers
+	dest = saveVertexBuffer(c, verts, cols);
+	
+	// Unmap buffers
+    glBindBuffer(GL_ARRAY_BUFFER_ARB, vertex_buf);
+    if (!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)) {
+        // Handle error case
+    }
+    glBindBuffer(GL_ARRAY_BUFFER_ARB, color_buf);
+    if (!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)) {
+        // Handle error case
+    }
+
+    return dest;
+}
+
+void VMI::loadVertexBuffer(VertexIL *src, Change *c, Vertex_ *verts, Color *cols) {
+    int i, j, t, n = 0, m;
+
     // Load vertex coordinates and color for deleted triangles
     for (j=0; j<c->numDel; j++) { 
@@ -92,31 +91,15 @@
         
         m = 3 * t;
-
-        buf_vertices[m + 0].x = src[n].x;
-        buf_vertices[m + 0].y = src[n].y;
-        buf_vertices[m + 0].z = src[n].z;
-        buf_colors[m + 0].a = src[n].a;
-        buf_colors[m + 0].b = src[n].b;
-        buf_colors[m + 0].r = src[n].r;
-        buf_colors[m + 0].g = src[n].g;
-        n++;
-
-        buf_vertices[m + 1].x = src[n].x;
-        buf_vertices[m + 1].y = src[n].y;
-        buf_vertices[m + 1].z = src[n].z;
-        buf_colors[m + 1].a = src[n].a;
-        buf_colors[m + 1].b = src[n].b;
-        buf_colors[m + 1].r = src[n].r;
-        buf_colors[m + 1].g = src[n].g;
-        n++;
-
-        buf_vertices[m + 2].x = src[n].x;
-        buf_vertices[m + 2].y = src[n].y;
-        buf_vertices[m + 2].z = src[n].z;
-        buf_colors[m + 2].a = src[n].a;
-        buf_colors[m + 2].b = src[n].b;
-        buf_colors[m + 2].r = src[n].r;
-        buf_colors[m + 2].g = src[n].g;
-        n++;
+		
+		for (i=0; i<3; i++) {
+			verts[m + i].x = src[n].x;
+			verts[m + i].y = src[n].y;
+			verts[m + i].z = src[n].z;
+			cols[m + i].a = src[n].a;
+			cols[m + i].b = src[n].b;
+			cols[m + i].r = src[n].r;
+			cols[m + i].g = src[n].g;
+			n++;
+		}
     }
     // Load vertex coordinates for modified triangles
@@ -126,19 +109,37 @@
         
         m = 3 * t;
-
-        buf_vertices[m + 0].x = src[n].x;
-        buf_vertices[m + 0].y = src[n].y;
-        buf_vertices[m + 0].z = src[n].z;
-        n++;
-
-        buf_vertices[m + 1].x = src[n].x;
-        buf_vertices[m + 1].y = src[n].y;
-        buf_vertices[m + 1].z = src[n].z;
-        n++;
-
-        buf_vertices[m + 2].x = src[n].x;
-        buf_vertices[m + 2].y = src[n].y;
-        buf_vertices[m + 2].z = src[n].z;
-        n++;
+		
+		for (i=0; i<3; i++) {
+			verts[m + i].x = src[n].x;
+			verts[m + i].y = src[n].y;
+			verts[m + i].z = src[n].z;
+			n++;
+		}
+    }
+}
+
+void VMI::loadVertexBufferGPU(VertexIL *src, Change *c) {
+	Vertex_ *verts;
+	Color *cols;
+    
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
+    // Map the buffer object
+	verts = (Vertex_ *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
+	
+    glBindBufferARB(GL_ARRAY_BUFFER_ARB, color_buf);
+    // Map the buffer object
+	cols = (Color *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
+	
+	// Update GPU buffers
+	loadVertexBuffer(src, c, verts, cols);
+	
+	// Unmap buffers
+    glBindBuffer(GL_ARRAY_BUFFER_ARB, vertex_buf);
+    if (!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)) {
+        // Handle error case
+    }
+    glBindBuffer(GL_ARRAY_BUFFER_ARB, color_buf);
+    if (!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)) {
+        // Handle error case
     }
 }
@@ -146,5 +147,5 @@
 void VMI::setupVertexArray(Mesh *mesh, Color *colors)
 {
-    int i, v1, v2, v3, n = 0;
+    int i, j, v, n = 0;
     GLubyte r, g, b, a;
 
@@ -153,5 +154,4 @@
 
     buf_vertices = (Vertex_ *)malloc(mesh->numTriangles * 3 * sizeof(Vertex_));
-
     buf_colors = (Color *)malloc(mesh->numTriangles * 3 * sizeof(Color));
 
@@ -167,71 +167,37 @@
 
     for (i=0; i<mesh->numTriangles; i++) {
-
-        v1= mesh->triangles[i].indices[0];
-        v2= mesh->triangles[i].indices[1];
-        v3= mesh->triangles[i].indices[2];
-        
-        if (mesh->triangles[i].enable == TRUE) {
-            
-            r = colors[i].r;
-            g = colors[i].g;
-            b = colors[i].b;
-            a = colors[i].a;
-            
-            buf_colors[n].r = r;
-            buf_colors[n].g = g;
-            buf_colors[n].b = b;
-            buf_colors[n].a = a;
-            buf_vertices[n].x = mesh->vertices[v1].x;
-            buf_vertices[n].y = mesh->vertices[v1].y;
-            buf_vertices[n].z = mesh->vertices[v1].z;
-            n++;
-            
-            buf_colors[n].r = r;
-            buf_colors[n].g = g;
-            buf_colors[n].b = b;
-            buf_colors[n].a = a;
-            buf_vertices[n].x = mesh->vertices[v2].x;
-            buf_vertices[n].y = mesh->vertices[v2].y;
-            buf_vertices[n].z = mesh->vertices[v2].z;
-            n++;
-            
-            buf_colors[n].r = r;
-            buf_colors[n].g = g;
-            buf_colors[n].b = b;
-            buf_colors[n].a = a;
-            buf_vertices[n].x = mesh->vertices[v3].x;
-            buf_vertices[n].y = mesh->vertices[v3].y;
-            buf_vertices[n].z = mesh->vertices[v3].z;
-            n++;
-        } else {
-         
-            buf_colors[n].r = 0;
-            buf_colors[n].g = 0;
-            buf_colors[n].b = 0;
-            buf_colors[n].a = 0;
-            buf_vertices[n].x = 0;
-            buf_vertices[n].y = 0;
-            buf_vertices[n].z = 0;
-            n++;
-            
-            buf_colors[n].r = 0;
-            buf_colors[n].g = 0;
-            buf_colors[n].b = 0;
-            buf_colors[n].a = 0;
-            buf_vertices[n].x = 0;
-            buf_vertices[n].y = 0;
-            buf_vertices[n].z = 0;
-            n++;
-            
-            buf_colors[n].r = 0;
-            buf_colors[n].g = 0;
-            buf_colors[n].b = 0;
-            buf_colors[n].a = 0;
-            buf_vertices[n].x = 0;
-            buf_vertices[n].y = 0;
-            buf_vertices[n].z = 0;
-            n++;
-        }
+		if (mesh->triangles[i].enable == TRUE) {
+
+			r = colors[i].r;
+			g = colors[i].g;
+			b = colors[i].b;
+			a = colors[i].a;
+			
+			for (j=0; j<3; j++) {
+				
+				v = mesh->triangles[i].indices[j];
+				
+				buf_colors[n].r = r;
+				buf_colors[n].g = g;
+				buf_colors[n].b = b;
+				buf_colors[n].a = a;
+				buf_vertices[n].x = mesh->vertices[v].x;
+				buf_vertices[n].y = mesh->vertices[v].y;
+				buf_vertices[n].z = mesh->vertices[v].z;
+				n++;
+			}
+		} else {
+			for (j=0; j<3; j++) {
+				
+				buf_colors[n].r = 0;
+				buf_colors[n].g = 0;
+				buf_colors[n].b = 0;
+				buf_colors[n].a = 0;
+				buf_vertices[n].x = 0;
+				buf_vertices[n].y = 0;
+				buf_vertices[n].z = 0;
+				n++;
+			}
+		}
     }
 #ifdef VERTEX_ARRAY
@@ -243,7 +209,4 @@
     glVertexPointer(3, GL_FLOAT, 0, buf_vertices);
 #endif
-
-    pbuf_colors = buf_colors;
-    pbuf_vertices = buf_vertices;
 }
 
@@ -253,5 +216,5 @@
     
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
-    glBufferDataARB(GL_ARRAY_BUFFER_ARB, mesh->numTriangles * 3 * 3 * sizeof(float), buf_vertices, GL_STATIC_DRAW_ARB); //upload data
+    glBufferDataARB(GL_ARRAY_BUFFER_ARB, mesh->numTriangles * 3 * sizeof(Vertex_), buf_vertices, GL_STATIC_DRAW_ARB); //upload data
 
     glVertexPointer(3, GL_FLOAT, 0,0);
@@ -265,48 +228,32 @@
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_COLOR_ARRAY);
-    
-    //free(buf_vertices);
-    //buf_vertices = NULL;
-    
-    //free(buf_colors);
-    //buf_colors = NULL;
-}
-
-void VMI::updateVertexArray(Mesh *mesh, Change *c)
-{
-    int i, v1, v2, v3, t, n;
+
+	free(buf_vertices);
+	buf_vertices = NULL;
+
+    free(buf_colors);
+	buf_colors =NULL;
+}
+
+void VMI::updateVertexArray(Mesh *mesh, Change *c, Vertex_ *verts, Color * cols)
+{
+    int i, j, v, t, n;
 
     // The deleted triangles are now in background color
     for (i=0; i<c->numDel; i++) {
         t = c->deleted[i].id;
-
+		
         n = t * 3;
-
-        buf_colors[n + 0].r = 0;
-        buf_colors[n + 0].g = 0;
-        buf_colors[n + 0].b = 0;
-        buf_colors[n + 0].a = 0;
-
-        buf_colors[n + 1].r = 0;
-        buf_colors[n + 1].g = 0;
-        buf_colors[n + 1].b = 0;
-        buf_colors[n + 1].a = 0;
-
-        buf_colors[n + 2].r = 0;
-        buf_colors[n + 2].g = 0;
-        buf_colors[n + 2].b = 0;
-        buf_colors[n + 2].a = 0;
-
-        buf_vertices[n + 0].x = 0;
-        buf_vertices[n + 0].y = 0;
-        buf_vertices[n + 0].z = 0;
-
-        buf_vertices[n + 1].x = 0;
-        buf_vertices[n + 1].y = 0;
-        buf_vertices[n + 1].z = 0;
-
-        buf_vertices[n + 2].x = 0;
-        buf_vertices[n + 2].y = 0;
-        buf_vertices[n + 2].z = 0;
+		
+		for (j=0; j<3; j++) {
+			cols[n + j].r = 0;
+			cols[n + j].g = 0;
+			cols[n + j].b = 0;
+			cols[n + j].a = 0;
+			
+			verts[n + j].x = 0;
+			verts[n + j].y = 0;
+			verts[n + j].z = 0;
+		}
     }
 
@@ -317,33 +264,29 @@
         n = t * 3;
 
-        v1= mesh->triangles[t].indices[0];
-        v2= mesh->triangles[t].indices[1];
-        v3= mesh->triangles[t].indices[2];
-
-        buf_vertices[n + 0].x = mesh->vertices[v1].x;
-        buf_vertices[n + 0].y = mesh->vertices[v1].y;
-        buf_vertices[n + 0].z = mesh->vertices[v1].z;
-
-        buf_vertices[n + 1].x = mesh->vertices[v2].x;
-        buf_vertices[n + 1].y = mesh->vertices[v2].y;
-        buf_vertices[n + 1].z = mesh->vertices[v2].z;
-
-        buf_vertices[n + 2].x = mesh->vertices[v3].x;
-        buf_vertices[n + 2].y = mesh->vertices[v3].y;
-        buf_vertices[n + 2].z = mesh->vertices[v3].z;
+		for (j=0; j<3; j++) {
+			
+			v= mesh->triangles[t].indices[j];
+			
+			verts[n + j].x = mesh->vertices[v].x;
+			verts[n + j].y = mesh->vertices[v].y;
+			verts[n + j].z = mesh->vertices[v].z;
+		}
     }
 }
 
 void VMI::updateVertexBufferObjects(Mesh *mesh, Change *c) {
+	Vertex_ *verts;
+	Color *cols;
     
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buf);
     // Map the buffer object
-	buf_vertices = ( Vertex_ *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
+	verts = (Vertex_ *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
 
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, color_buf);
     // Map the buffer object
-	buf_colors = (Color   *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
-
-    updateVertexArray(mesh, c);
+	cols = (Color *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
+
+	// Update GPU buffers
+    updateVertexArray(mesh, c, verts, cols);
 
     // Unmap buffers
@@ -360,5 +303,5 @@
 VertexIL *VMI::setupInterleave(Mesh *mesh, Color *colors)
 {
-    int i, v1, v2, v3, n = 0;
+    int i, j, v, n = 0;
     GLubyte r, g, b, a;
     VertexIL *interleave = NULL;
@@ -374,45 +317,25 @@
         
         if (mesh->triangles[i].enable == TRUE) {
-            v1= mesh->triangles[i].indices[0];
-            v2= mesh->triangles[i].indices[1];
-            v3= mesh->triangles[i].indices[2];
-            
-            r = colors[i].r;
+			
+			r = colors[i].r;
             g = colors[i].g;
             b = colors[i].b;
             a = colors[i].a;
-            
-            interleave[n].tx = 0.0f;
-            interleave[n].ty = 0.0f;
-            interleave[n].r = r;
-            interleave[n].g = g;
-            interleave[n].b = b;
-            interleave[n].a = a;
-            interleave[n].x = mesh->vertices[v1].x;
-            interleave[n].y = mesh->vertices[v1].y;
-            interleave[n].z = mesh->vertices[v1].z;
-            n++;
-            
-            interleave[n].tx = 0.0f;
-            interleave[n].ty = 0.0f;
-            interleave[n].r = r;
-            interleave[n].g = g;
-            interleave[n].b = b;
-            interleave[n].a = a;
-            interleave[n].x = mesh->vertices[v2].x;
-            interleave[n].y = mesh->vertices[v2].y;
-            interleave[n].z = mesh->vertices[v2].z;
-            n++;
-            
-            interleave[n].tx = 0.0f;
-            interleave[n].ty = 0.0f;
-            interleave[n].r = r;
-            interleave[n].g = g;
-            interleave[n].b = b;
-            interleave[n].a = a;
-            interleave[n].x = mesh->vertices[v3].x;
-            interleave[n].y = mesh->vertices[v3].y;
-            interleave[n].z = mesh->vertices[v3].z;
-            n++;
+			
+			for (j=0; j<3; j++) {
+				
+				v= mesh->triangles[i].indices[j];
+				
+				interleave[n].tx = 0.0f;
+				interleave[n].ty = 0.0f;
+				interleave[n].r = r;
+				interleave[n].g = g;
+				interleave[n].b = b;
+				interleave[n].a = a;
+				interleave[n].x = mesh->vertices[v].x;
+				interleave[n].y = mesh->vertices[v].y;
+				interleave[n].z = mesh->vertices[v].z;
+				n++;
+			}
         }
     }
@@ -435,31 +358,21 @@
 void VMI::updateAllColorInterleave(VertexIL *interleave, int num, Color *colors)
 {
-    int i, n = 0;
+    int i, j, n = 0;
     GLubyte r, g, b, a;
-
+	
     for (i=1; i<=num; i++) { // Triangles start at 1
-
+		
         r = colors[i].r;
         g = colors[i].g;
         b = colors[i].b;
         a = colors[i].a;
-
-        interleave[n].r = r;
-        interleave[n].g = g;
-        interleave[n].b = b;
-        interleave[n].a = a;
-        n++;
-
-        interleave[n].r = r;
-        interleave[n].g = g;
-        interleave[n].b = b;
-        interleave[n].a = a;
-        n++;
-
-        interleave[n].r = r;
-        interleave[n].g = g;
-        interleave[n].b = b;
-        interleave[n].a = a;
-        n++;
+		
+		for (j=0; j<3; j++) {
+			interleave[n].r = r;
+			interleave[n].g = g;
+			interleave[n].b = b;
+			interleave[n].a = a;
+			n++;
+		}
     }
 }
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/mesh.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/mesh.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/mesh.cpp	(revision 2194)
@@ -443,9 +443,12 @@
 }
 
-void VMI::deleteMesh(Mesh *mesh) {
+void VMI::deleteMesh(Mesh *mesh)
+{
 	int i;
 
-	if (NULL != mesh) {
-		for (i=0; i<mesh->numVertices; i++) {
+	if (NULL != mesh)
+	{
+		for (i=0; i<mesh->numVertices; i++)
+		{
 			if (mesh->vertices[i].triangles != NULL)
 				free(mesh->vertices[i].triangles);
@@ -453,6 +456,6 @@
 			if (mesh->vertices[i].edges != NULL)
 				free(mesh->vertices[i].edges);
-
 		}
+
 		if (mesh->vertices != NULL) free(mesh->vertices);
 		mesh->numVertices = 0;
@@ -550,6 +553,6 @@
     if (numVertices > 0) {
         // Add the first
-		list = mesh->vertices[vertices[0]].edges;
-		numEdges = mesh->vertices[vertices[0]].numEdges;
+		    list = mesh->vertices[vertices[0]].edges;
+		    numEdges = mesh->vertices[vertices[0]].numEdges;
 
         // Allocate memory
@@ -563,6 +566,6 @@
         for (i=1; i<numVertices; i++) {
 
-			list = mesh->vertices[vertices[i]].edges;
-		    numEdges = mesh->vertices[vertices[i]].numEdges;
+			      list = mesh->vertices[vertices[i]].edges;
+		        numEdges = mesh->vertices[vertices[i]].numEdges;
 
             // Reallocate memory
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 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/simplify.cpp	(revision 2194)
@@ -28,5 +28,5 @@
 vector<Geometry::Vector2>	VMI::vTexCoords;
 
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
 
 void VMI::bh_mydump(Mesh *mesh, bheap_t *h) {
@@ -56,5 +56,5 @@
 			exit(1);
 		}
-	}    
+	}
 }
 
@@ -73,6 +73,9 @@
 	for (i = 0; i <mesh->numEdges; i++) {
 
-		//	Update progress bar.
-		mUPB(percent);
+		if (mUPB)
+		{
+			//	Update progress bar.
+			mUPB(percent);
+		}
 
 		if (mesh->edges[i].enable == TRUE) {
@@ -226,35 +229,41 @@
 ///////////////////////////////////////////////////////////////////////////////
 
-void saveProjectedAreas(int **histogram, int numCameras, Change *c, int *dest) {
-	int i, j, t, n = 0;
-
-	for (j=0; j<c->numDel; j++) {
-
-		t = c->deleted[j].id;
-
-		for (i=0; i<numCameras; i++) {
-
-			dest[n] = histogram[i][t + 1];
-			n++;
-		}
-	}
-
-	for (j=0; j<c->numMod; j++) { 
-
-		t = c->modified[j].id;
-
-		for (i=0; i<numCameras; i++) {
-
-			dest[n] = histogram[i][t + 1];
-			n++;
-		}   
-	}
-
-	// Save background area
-	for (i=0; i<numCameras; i++) {
-
-		dest[n] = histogram[i][0];
-		n++;
-	}
+int *saveProjectedAreas(int **histogram, int numCameras, Change *c) {
+    int i, j, t, n = 0;
+    int *dest;
+    
+    // Allocate memory
+    dest = (int *)malloc((c->numDel + c->numMod + 1) * numCameras * sizeof(int));
+        
+    for (j=0; j<c->numDel; j++) { 
+        
+        t = c->deleted[j].id;
+
+        for (i=0; i<numCameras; i++) {
+            
+            dest[n] = histogram[i][t + 1];
+            n++;
+        }
+    }
+    
+    for (j=0; j<c->numMod; j++) { 
+        
+        t = c->modified[j].id;
+        
+        for (i=0; i<numCameras; i++) {
+            
+            dest[n] = histogram[i][t + 1];
+            n++;
+        }   
+    }
+
+    // Save background area
+    for (i=0; i<numCameras; i++) {
+        
+        dest[n] = histogram[i][0];
+        n++;
+    }
+    
+    return dest;
 }
 
@@ -365,11 +374,9 @@
         penalized = check_local_inversion(mesh, c);
 #endif
-		// Allocate memory
-		histoAux = (int *)malloc((c->numDel + c->numMod + 1) * numCameras * sizeof(int));
-
-#if defined(VERTEX_BUFFER_OBJECTS) || defined(VERTEX_ARRAY)
-        vb = (VertexIL *)malloc((c->numDel + c->numMod + 1) * 3 * sizeof(VertexIL));
-
-        saveVertexBuffer(c, vb);
+#ifdef VERTEX_ARRAY
+        vb = saveVertexBuffer(c, buf_vertices, buf_colors);
+#endif
+#ifdef VERTEX_BUFFER_OBJECTS
+        vb = saveVertexBufferGPU(c);
 #endif
 
@@ -388,5 +395,5 @@
 		}
 
-		saveProjectedAreas(histogram, numCameras, c, histoAux);
+		histoAux = saveProjectedAreas(histogram, numCameras, c);
     // Apply the edge collapse
 		doChange(mesh, c);
@@ -424,5 +431,5 @@
 		///////////////////////////////////////////////////////////////////////////////
 
-		saveProjectedAreas(histogram, numCameras, c, histoAux);
+		histoAux = saveProjectedAreas(histogram, numCameras, c);
 
 		doChange(mesh, c);
@@ -459,6 +466,10 @@
 		// Free memory
 		free(histoAux);
-#if defined(VERTEX_BUFFER_OBJECTS) || defined(VERTEX_ARRAY)
-        loadVertexBuffer(vb, c);
+#ifdef VERTEX_ARRAY
+		loadVertexBuffer(vb, c, buf_vertices, buf_colors);
+		free(vb);
+#endif
+#ifdef VERTEX_BUFFER_OBJECTS
+		loadVertexBufferGPU(vb, c);
         free(vb);
 #endif
@@ -499,5 +510,5 @@
 	e = bh_min(h);
 
-	while (!isValidEdge_(mesh, e)) {
+	while (!isValidEdge_(mesh, e) && (h->n >0)) {
 		/* delete invalid edge */
 		bh_delete(h, e);
@@ -510,5 +521,6 @@
 
 /* Get the mininum edge cost from the heap using lazy evaluation */
-int getMinEdge(Mesh *mesh, bheap_t *h) {
+int getMinEdge(Mesh *mesh, bheap_t *h)
+{
 	double cost;
 	int e;
@@ -517,5 +529,5 @@
 	e = getMinValidEdge(mesh, h);
 
-	while (bh_is_dirty(h, e)) {
+	while (bh_is_dirty(h, e) && (h->n >0)) {
 		/* delete edge from heap */
 		bh_delete(h, e);
@@ -560,5 +572,5 @@
 	if (bSaveLog == TRUE)
 	{
-#ifdef SALIENCY       
+#ifdef SALIENCY
 		sprintf(s,"%s_%s_S.log", filename, EXT);
 #else
@@ -573,5 +585,8 @@
 		if (!file)
 		{
-			fprintf(stderr, "simplifyModel() failed: can't open file \"%s\" to write.\n", s);
+			fprintf(stderr,
+							"simplifyModel() failed: can't open file \"%s\" to write.\n",
+							s);
+
 			exit(1);
 		}
@@ -592,5 +607,5 @@
 	printf("Starting simplification...\n");
 
-	while (mesh->currentNumTriangles > numDemandedTri /*&& cost == 0.0*/)
+	while (mesh->currentNumTriangles > numDemandedTri && (h->n >0)/*&& cost == 0.0*/)
 	{
 		// Get the edge that has the minimum cost
@@ -600,45 +615,55 @@
 		c = createChange(mesh, e);
 
-		// Apply the edge collapse
-		doChange(mesh, c);
-		//deleteVertexOfMap(mesh, c->u);
-
-		// Write Simplification sequence.
-		saveSimplificationSequence(c,0);
-
-		//contractTwinVertices(mesh, c->u, c->v); // vertex u is removed
-
-		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);
-
-		updateHWAcceleration(c);
-
-		// Get projected areas after the edge collapse
-		getProjectedAreas(histogram, numCameras);
-
-		computeCameraIs(histogram, numCameras, initialIs);
-
-		updateEdgeAdj(mesh, c);
-
-    modifyEdges(mesh, c);
-
-		// Update the heap according to the edge collapse
-		h = updateHeap(h, mesh, c);
-
-		mUPB((float)c->numDel * percent);
+		// Check whether edge collapse is a valid change
+		if (c->numDel > 0) {
+			// Apply the edge collapse
+			doChange(mesh, c);
+			//deleteVertexOfMap(mesh, c->u);
+
+			// Write Simplification sequence.
+			saveSimplificationSequence(c,0);
+
+			//contractTwinVertices(mesh, c->u, c->v); // vertex u is removed
+
+			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);
+
+			updateHWAcceleration(c);
+
+			// Get projected areas after the edge collapse
+			getProjectedAreas(histogram, numCameras);
+
+			computeCameraIs(histogram, numCameras, initialIs);
+
+			updateEdgeAdj(mesh, c);
+			modifyEdges(mesh, c);
+
+			// Update the heap according to the edge collapse
+			h = updateHeap(h, mesh, c);
+
+			if (mUPB)
+			{
+				mUPB((float)c->numDel * percent);
+			}
+		}
+		else
+		{
+			mesh->edges[e].enable = FALSE;
+			bh_delete(h, e);
+		}
 
 		deleteChange(c);
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/histogram.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/histogram.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/histogram.cpp	(revision 2194)
@@ -343,7 +343,7 @@
 
     w += (WIN_MARGIN * 2);
-    if (w > width)  w = width;
+    if (w + ox> width)  w = width - ox;
     h += (WIN_MARGIN * 2);
-    if (h > height) h = height;
+    if (h + oy> height) h = height - oy;
 
     //printf("(%d,%d)\n", ox, oy);
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 2089)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 2194)
@@ -230,6 +230,7 @@
 //	Contract a given pair
 //-------------------------------------------------------------------------
-void SimplificationMethod::do_contract(	simplif::Model& m,
-																				simplif::pair_info *auxpair)
+void SimplificationMethod::do_contract(	simplif::Model			&m,
+																				simplif::pair_info	*auxpair,
+																				int									obligatory)
 {
 	simplif::Vertex 		*v0			= auxpair->v0;
@@ -243,4 +244,7 @@
 	vertex_map_str			lb;
 	vertex_map_str			ub;
+
+	//	Stores the simplification step.
+	MeshSimplificationSequence::Step simplifstep;
 	
 	// V0 must be always the alive vertex
@@ -338,4 +342,11 @@
 
 	int del_index	=	0;
+
+	//	Initialize deleted triangles.
+	simplifstep.mT0	=	-1;
+	simplifstep.mT1	=	-1;
+
+	//	Sets obligatory flag.
+	simplifstep.obligatory	=	obligatory;
 
 	//	Clears faces list.
@@ -519,5 +530,7 @@
 				(vertexMultimap.find(f0) != vertexMultimap.end())
 				&&
-				(vertexMultimap.find(f1) != vertexMultimap.end()))
+				(vertexMultimap.find(f1) != vertexMultimap.end())
+				&&
+				((*pair->v0) != (*pair->v1)))
 		{
 			break;
@@ -551,7 +564,4 @@
 	candidate	=	pair->candidate;
 
-	//	First contract.
-	simplifstep.obligatory	=	0;
-
 	//	Debug.
 	cout	<<	"Contracting... "
@@ -559,8 +569,5 @@
 
 	//	Contract main pair.
-	do_contract(m, pair);
-
-	//	Twin contract and lonely vertex contract.
-	simplifstep.obligatory	=	1;
+	do_contract(m, pair, 0);
 
 	//	Attempt to maintain valid vertex information.
@@ -600,6 +607,8 @@
 	float								x,y,z;
 
+	/*
 	if ((*v0) != (*v1))
 	{
+	*/
 		//	Gets the vertex that is not the candidate.
 		if ((*v1) == candidate)
@@ -621,4 +630,12 @@
 			lonely_vert	=	m.vertex((*it).second);
 
+			//	Debug.
+			if ((*it).second == 10988)
+			{
+				cout	<<	"Lonely: "
+							<<	lonely_vert->vID
+							<<	endl;
+			}
+			
 			for (int	i	=	0;	i < lonely_vert->edgeUses().length();	i++)
 			{
@@ -671,5 +688,5 @@
 
 				//	Contract twin pair.
-				do_contract(m, pair);
+				do_contract(m, pair, 1);
 				M0.validVertCount--;
 			}
@@ -686,4 +703,22 @@
 				z	=	(*new_vert)[Z];
 
+				simplif::Vertex	*v;
+
+				//	Debug.
+				if (new_vert->vID == 10988)
+				{
+					cout	<<	"["
+								<<	x
+								<<	","
+								<<	y
+								<<	","
+								<<	z
+								<<	"]"
+								<<	endl;
+
+					
+					v	=	m.vertex(10988);
+				}
+
 				//	Adds new vertex to multimap.
 				vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
@@ -724,10 +759,32 @@
 				pair->notInHeap();
 
+				//	Debug.
+				cout	<<	"new: "
+							<<	new_vert->vID
+							<<	"("
+							<<	(*new_vert)[X]
+							<<	","
+							<<	(*new_vert)[Y]
+							<<	","
+							<<	(*new_vert)[Z]
+							<<	") lonely: "
+							<<	lonely_vert->vID
+							<<	"("
+							<<	(*lonely_vert)[X]
+							<<	","
+							<<	(*lonely_vert)[Y]
+							<<	","
+							<<	(*lonely_vert)[Z]
+							<<	")"
+							<<	endl;
+
 				//	Contract new pair.
-				do_contract(m, pair);
+				do_contract(m, pair, 1);
 				M0.validVertCount--;
 			}
 		}
-	}
+	/*
+	}
+	*/
 }
 
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 2087)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 2194)
@@ -36,4 +36,21 @@
 		}
 
+		/*
+		bool operator==(const _float3_	&f) const
+		{
+			float	F3_EPS;
+			float dx;
+			float dy;
+			float dz;
+			
+			F3_EPS	=	1e-12;
+			dx			=	x - f.x;
+			dy			=	y - f.y;
+			dz			=	z - f.z;
+
+			return (dx*dx + dy*dy + dz*dz) < F3_EPS;
+		}
+		*/
+
 		bool operator<(const _float3_ &f) const
 		{
@@ -73,7 +90,4 @@
 		MeshSimplificationSequence	*msimpseq;
 
-		//	Stores the simplification step.
-		MeshSimplificationSequence::Step simplifstep;
-
 		inline simplif::vert_info& vertex_info(simplif::Vertex *v)
 		{
@@ -100,5 +114,7 @@
 		void delete_pair(simplif::pair_info *pair);
 
-		void do_contract(simplif::Model& m, simplif::pair_info *pair);
+		void do_contract(	simplif::Model& 		m,
+											simplif::pair_info 	*pair,
+											int									obligatory);
 
 		bool decimate_quadric(simplif::Vertex *v, simplif::Mat4& Q);
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 2194)
@@ -224,6 +224,4 @@
 	VMI::vTexCoords	=	vTexCoords;
 
-	
-
 	mGeoMesh	=	new Mesh();
 
@@ -252,8 +250,10 @@
 
 	if (VMI::bLoadCamerasFromFile == GL_FALSE)
-		VMI::cameras = VMI::setCameras(VMI::radius, VMI::cameraType, &VMI::numCameras);
+		VMI::cameras = VMI::setCameras(	VMI::radius, 
+																		VMI::cameraType,
+																		&VMI::numCameras);
 
 	VMI::histogram	=	VMI::initHistogram(	VMI::mesh->currentNumTriangles,
-			VMI::numCameras);
+																				VMI::numCameras);
 
 	VMI::initialIs	=	VMI::initIs(VMI::numCameras);
@@ -272,6 +272,6 @@
 }
 
-/// Starts the simplification process. Receives as a parameter the 
-///	LOD factor in a range of [0,1]. Implements the 
+/// Starts the simplification process. Receives as a parameter the
+///	LOD factor in a range of [0,1]. Implements the
 ///	Simplifier::Simplify method to perform an image based simplification.
 void ViewPointDrivenSimplifier::Simplify(Real percent)
@@ -333,5 +333,5 @@
 
 	VMI::contractInitialMesh(VMI::mesh);
-
+	
 	//	Load a geometry mesh for vmi mesh.
 	loadMesh();
@@ -431,10 +431,9 @@
 		vmi_mesh->vertices[i].z = vertex_buffer->mPosition[i].z;
 
-		vmi_mesh->vertices[i].numTriangles = 0;
-		vmi_mesh->vertices[i].triangles = NULL;
-		vmi_mesh->vertices[i].numEdges = 0;
-		vmi_mesh->vertices[i].edges = NULL;
-		vmi_mesh->vertices[i].enable 	= GL_TRUE;
-		vmi_mesh->vertices[i].movable = GL_TRUE;
+		vmi_mesh->vertices[i].numTriangles	= 0;
+		vmi_mesh->vertices[i].triangles			= NULL;
+		vmi_mesh->vertices[i].numEdges			= 0;
+		vmi_mesh->vertices[i].edges					= NULL;
+		vmi_mesh->vertices[i].enable				= GL_TRUE;
 	}
 	
@@ -468,7 +467,10 @@
 			vmi_mesh->triangles[index].indices[2] = geosubmesh->mIndex[(3 * i) + 2];
 
-			vmi_mesh->triangles[index].area = computeTriangleArea(vmi_mesh->vertices, 
-					&vmi_mesh->triangles[index]);
-			computeTriangleNormal(vmi_mesh->vertices, &vmi_mesh->triangles[index]);
+			vmi_mesh->triangles[index].area = computeTriangleArea(
+																						vmi_mesh->vertices, 
+																						&vmi_mesh->triangles[index]);
+
+			computeTriangleNormal(vmi_mesh->vertices,
+														&vmi_mesh->triangles[index]);
 
 			vmi_mesh->triangles[index].saliency = 0.0;
@@ -482,5 +484,9 @@
 
 				// Reallocate memory for the new adjacent triangle.
-				vmi_mesh->vertices[v1].triangles = (int *)realloc(vmi_mesh->vertices[v1].triangles, (vmi_mesh->vertices[v1].numTriangles + 1) * sizeof(int));
+				vmi_mesh->vertices[v1].triangles = 
+											(int *)realloc(vmi_mesh->vertices[v1].triangles,
+											(vmi_mesh->vertices[v1].numTriangles + 1)
+											*
+											sizeof(int));
 
 				VMI::addItem(	(int *)vmi_mesh->vertices[v1].triangles,
@@ -503,6 +509,6 @@
 	// E = 3 T / 2
 	vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge)
-																		*
-																		vmi_mesh->numTriangles * 3);
+										*
+										vmi_mesh->numTriangles * 3);
 
 	if (vmi_mesh->edges == NULL)
@@ -554,17 +560,26 @@
 	vmi_mesh->numEdges = n;
 
-	for (i=0; i<vmi_mesh->numEdges; i++) {
+	for (i	=	0; i < vmi_mesh->numEdges; i++)
+	{
 		v1 = vmi_mesh->edges[i].u;
 		v2 = vmi_mesh->edges[i].v;
 
-		vmi_mesh->vertices[v1].edges = 
-			(int *)realloc(vmi_mesh->vertices[v1].edges, (vmi_mesh->vertices[v1].numEdges + 1) * sizeof(int));
+		vmi_mesh->vertices[v1].edges	=
+							(int *)realloc(vmi_mesh->vertices[v1].edges,
+							(vmi_mesh->vertices[v1].numEdges + 1) * sizeof(int));
+
 		// Adding edge i adjacent to vertex v1
-		VMI::addItem(vmi_mesh->vertices[v1].edges, &vmi_mesh->vertices[v1].numEdges, i);
-
-		vmi_mesh->vertices[v2].edges = 
-			(int *)realloc(vmi_mesh->vertices[v2].edges, (vmi_mesh->vertices[v2].numEdges + 1) * sizeof(int));
+		VMI::addItem(	vmi_mesh->vertices[v1].edges,
+									&vmi_mesh->vertices[v1].numEdges,
+									i);
+
+		vmi_mesh->vertices[v2].edges =
+								(int *)realloc(vmi_mesh->vertices[v2].edges,
+								(vmi_mesh->vertices[v2].numEdges + 1) * sizeof(int));
+
 		// Adding edge i adjacent to vertex v2
-		VMI::addItem(vmi_mesh->vertices[v2].edges, &vmi_mesh->vertices[v2].numEdges, i);
+		VMI::addItem(	vmi_mesh->vertices[v2].edges,
+									&vmi_mesh->vertices[v2].numEdges,
+									i);
 	}
 
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 2127)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 2194)
@@ -26,5 +26,5 @@
 	geoMeshView->deactiveLodTree();
 
-	BuildLoadTextureSubMeshMenu();
+	//BuildLoadTextureSubMeshMenu();
 
 	//	Repaint the window.
@@ -1238,5 +1238,5 @@
 				break;
 
-				// Añadido 23-12-2005
+				// A?adido 23-12-2005
 			case	SELECT_LEAVES:
 
@@ -2160,6 +2160,6 @@
 	if (mPercent->value())
 	{
-		// Simplificación por porcentaje
-		if (mMeshReduction->fvalue() <= 100.0 && 
+		// Simplificaci?n por porcentaje
+		if (mMeshReduction->fvalue() <= 100.0 &&
 				mMeshReduction->fvalue() > 0.0)
 		{
@@ -2167,5 +2167,5 @@
 			percent	=	percent / 100.0;
 
-			//	Simplifica el geomesh -> Parámetro es un factor LOD [0,1].
+			//	Simplifica el geomesh -> Par?metro es un factor LOD [0,1].
 
 			mMeshSimplifier->Simplify(percent);
@@ -2193,8 +2193,8 @@
 	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);
 
@@ -2285,5 +2285,5 @@
 	secsimpl	=	mMeshSimplifier->GetSimplificationSequence();
 
-	// Nombre del mesh para guardar la secuencia de simplificación.
+	// Nombre del mesh para guardar la secuencia de simplificaci?n.
 	secsimpl->putMeshName(nombremesh); 
 	secsimpl->Save(Geometry::Serializer("SimplifSequence.txt",Serializer::WRITE));
