Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 2291)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimplifier.h	(revision 2300)
@@ -24,22 +24,26 @@
 			float x,y,z;
 			inline _coord_(	float x	=	0.0f,
-					float y	=	0.0f,
-					float z	=	0.0f)
-			{ this->x = x; this->y = y; this->z = z; }
+											float y	=	0.0f,
+											float z	=	0.0f)
+			{
+				this->x = x;
+				this->y = y;
+				this->z = z;
+			}
 
 			inline _coord_(const _coord_ &f)
-			{
-				x	=	f.x;
-				y=f.y;
-				z=f.z;
-			}
-
-			inline _coord_ & operator=(const _coord_ &f)
 			{
 				x	=	f.x;
 				y	=	f.y;
 				z	=	f.z;
-
-				return *this;
+			}
+
+			inline _coord_ & operator=(const _coord_ &f)
+			{
+				x	=	f.x;
+				y	=	f.y;
+				z	=	f.z;
+
+				return	*this;
 			}
 
@@ -122,8 +126,8 @@
 
 			/// Starts the simplification process. Receives as a parameter the LOD factor in a range of [0,1]. This is a pure virtual method and must be overloaded in a derived class that implements a simplification algorithm.
-			virtual void Simplify(Geometry::Real)=0;
+			virtual int Simplify(Geometry::Real)=0;
 
 			/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. This is a pure virtual method and must be overloaded in a derived class that implements a simplification algorithm.
-			virtual void Simplify(Geometry::uint32)=0;
+			virtual int Simplify(Geometry::uint32)=0;
 
 			/// Returns the simplified mesh.
@@ -150,4 +154,8 @@
 			//	Sort mesh bones.
 			void	sortBones();
+
+		private:
+
+			void	eraseVoidSubMeshes(Mesh	*geoMesh);
 	};
 
@@ -190,4 +198,7 @@
 			void bonesReassignament();
 
+			//	Init VMI options.
+			int	init(void);
+
 		public:
 
@@ -206,8 +217,8 @@
 
 			/// 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 Simplify(Geometry::Real);
+			int	Simplify(Geometry::Real);
 
 			/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
-			void Simplify(Geometry::uint32);
+			int Simplify(Geometry::uint32);
 
 			// Returns the simplified mesh.
@@ -234,8 +245,8 @@
 
 			/// 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 Simplify(Geometry::Real);
+			int	Simplify(Geometry::Real);
 
 			/// Starts the simplification process. Receives as a parameter the number of vertices of the resulting mesh. Implements the Simplifier::Simplify method to perform an image based simplification.
-			void Simplify(Geometry::uint32);
+			int Simplify(Geometry::uint32);
 	};
 } // end of Geometry namespace;
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 2194)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/global.h	(revision 2300)
@@ -142,5 +142,5 @@
 extern char filename[MAX_CHAR];
 
-extern void init(void);
+extern int	init(void);
 
 extern void resetProjectedAreas(int **histogram, int numCameras);
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/vmi_simplifier.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/vmi_simplifier.h	(revision 2127)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/include/vmi_simplifier.h	(revision 2300)
@@ -2,5 +2,4 @@
 #include <stdlib.h>
 #include <time.h>
-
 #include "GL/glew.h"
 #ifdef _WIN32
@@ -15,2 +14,10 @@
 #include "buffers.h"
 
+#define NO_GL_ERROR						0x00
+#define	FRAMEBUFFER_ERROR			0x01
+#define	VERTEX_BUFFER_ERROR		0x02
+#define	OCCLUSION_QUERY_ERROR	0x04
+#define	IMAGING_ERROR					0x08
+#define	MULTITEXTURE_ERROR		0x10
+#define	SWAP_CONTROL_ERROR		0x20
+
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 2194)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/main.cpp	(revision 2300)
@@ -3,52 +3,52 @@
 namespace VMI 
 {
-GLMmodel *pmodel = NULL; // The .obj model
-
-GLubyte *pixels = NULL;
-
-Camera *cameras = NULL;
-int numCameras = 0;
-
-Color *colors = NULL;
-
-int **histogram = NULL;
-GLuint *queries = NULL;
-
-Mesh *mesh = NULL;
-
-GLdouble *initialIs = NULL;
-
-GLsizei width  = 256,
-        height = 256;
-
-GLboolean bEnableOffScreen = GL_TRUE,
-          bBeQuiet         = GL_FALSE,
-          bSaveLog         = GL_FALSE,
-          bLoadCamerasFromFile = GL_FALSE,
-          bRemoveRedundantVertices = GL_TRUE;
-
-int cameraType = 0,
-       numDemandedTriangles = 0;
-
-GLdouble radius = 1.3, fov = 60.0;
-
-char filename[MAX_CHAR] = {'\0'};
-
-GLuint fb, depth_rb, color_tex;
+	GLMmodel *pmodel = NULL; // The .obj model
+
+	GLubyte *pixels = NULL;
+
+	Camera *cameras = NULL;
+	int numCameras = 0;
+
+	Color *colors = NULL;
+
+	int **histogram = NULL;
+	GLuint *queries = NULL;
+
+	Mesh *mesh = NULL;
+
+	GLdouble *initialIs = NULL;
+
+	GLsizei width  = 256,
+					height = 256;
+
+	GLboolean bEnableOffScreen = GL_TRUE,
+						bBeQuiet         = GL_FALSE,
+						bSaveLog         = GL_FALSE,
+						bLoadCamerasFromFile = GL_FALSE,
+						bRemoveRedundantVertices = GL_TRUE;
+
+	int cameraType = 0,
+			numDemandedTriangles = 0;
+
+	GLdouble radius = 1.3, fov = 60.0;
+
+	char filename[MAX_CHAR] = {'\0'};
+
+	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;
-
-//	For progress update.
-Geometry::TIPOFUNC	mUPB;
+	VertexIL *interleave = NULL;
+#endif
+
+	GLuint vertex_buf = 0,
+				 color_buf = 0;
+
+	Vertex_ *buf_vertices = NULL;
+	Color   *buf_colors = NULL;
+
+	int vmiWin = 0;
+
+	//	For progress update.
+	Geometry::TIPOFUNC	mUPB;
 
 }
@@ -56,6 +56,9 @@
 using namespace	VMI;
 
-void VMI::init(void)
-{
+int	VMI::init(void)
+{
+	//	Initialize error status.
+	int	error	=	NO_GL_ERROR;
+
 	// Clear color
 	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -81,5 +84,6 @@
 		fprintf(stderr,
 						"GL_EXT_framebuffer_object extension is not available!\n");
-		exit(1);
+		
+		error	=	error | FRAMEBUFFER_ERROR;
 	}
 	else
@@ -131,4 +135,6 @@
 		fprintf(stderr,
 				"GL_ARB_vertex_buffer_object extension is not available!\n");
+
+		error	=	error | VERTEX_BUFFER_ERROR;
 	}
 	else
@@ -144,5 +150,7 @@
 	{
 		fprintf(stderr,
-				"GL_ARB_occlusion_query extension is not available!\n");
+						"GL_ARB_occlusion_query extension is not available!\n");
+
+		error	=	error | OCCLUSION_QUERY_ERROR;
 	}
 	else
@@ -158,4 +166,6 @@
 	{
 		fprintf(stderr,"GL_ARB_imaging extension is not available!\n");
+
+		error	=	error | IMAGING_ERROR;
 	}
 
@@ -163,4 +173,6 @@
 	{
 		fprintf(stderr,"GL_ARB_multitexture extension is not available!\n");
+
+		error	=	error | MULTITEXTURE_ERROR;
 	}
 
@@ -169,4 +181,6 @@
 	{
 		fprintf(stderr,"WGL_EXT_swap_control extension is not available!\n");
+
+		error	=	error | SWAP_CONTROL_ERROR;
 	}
 #endif
@@ -180,16 +194,18 @@
 	// Set a different color for every triangle.
 	setColors4(colors, mesh->currentNumTriangles);
+
+	return error;
 }
 
 void VMI::applyHWAcceleration(void) {
-    
+
 #ifdef VERTEX_ARRAY_INTERLEAVE
-    setupInterleave(mesh, colors);
+	setupInterleave(mesh, colors);
 #endif
 #ifdef VERTEX_ARRAY
-    setupVertexArray(mesh, colors);
+	setupVertexArray(mesh, colors);
 #endif
 #ifdef VERTEX_BUFFER_OBJECTS
-    setupVertexBufferObjects(mesh, colors);
+	setupVertexBufferObjects(mesh, colors);
 #endif
 
@@ -197,14 +213,14 @@
 
 void VMI::updateHWAcceleration(Change *c) {
-   
+
 #ifdef VERTEX_ARRAY_INTERLEAVE
-    if (interleave != NULL) free(interleave);
-    interleave = setupInterleave(mesh, colors);
+	if (interleave != NULL) free(interleave);
+	interleave = setupInterleave(mesh, colors);
 #endif
 #ifdef VERTEX_ARRAY
-    updateVertexArray(mesh, c);
+	updateVertexArray(mesh, c);
 #endif
 #ifdef VERTEX_BUFFER_OBJECTS
-    updateVertexBufferObjects(mesh, c);
+	updateVertexBufferObjects(mesh, c);
 #endif
 
@@ -212,274 +228,275 @@
 
 void VMI::setOrthographicProjection(void) {
-    // Switch to projection mode
-    glMatrixMode(GL_PROJECTION);
-    // Save previous matrix which contains the 
-    // settings for the perspective projection
-    glPushMatrix();
-    // Reset matrix
-    glLoadIdentity();
-    glOrtho(0.0, (GLdouble)HISTOGRAM_SIZE, 0.0, (GLdouble)height, -1.0, 1.0);
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+	// Switch to projection mode
+	glMatrixMode(GL_PROJECTION);
+	// Save previous matrix which contains the 
+	// settings for the perspective projection
+	glPushMatrix();
+	// Reset matrix
+	glLoadIdentity();
+	glOrtho(0.0, (GLdouble)HISTOGRAM_SIZE, 0.0, (GLdouble)height, -1.0, 1.0);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
 }
 
 void VMI::resetPerspectiveProjection(void) {
-    // Set the current matrix to GL_PROJECTION
-    glMatrixMode(GL_PROJECTION);
-    // Restore previous settings
-    glPopMatrix();
-    // Get back to GL_MODELVIEW matrix
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+	// Set the current matrix to GL_PROJECTION
+	glMatrixMode(GL_PROJECTION);
+	// Restore previous settings
+	glPopMatrix();
+	// Get back to GL_MODELVIEW matrix
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
 }
 
 void VMI::renderBitmapString(float x, float y, void *font, char *string) {
-    char *c;
-    // Set position to start drawing fonts
-    glRasterPos2f(x, y);
-    // Loop all the characters in the string
-    for (c=string; *c != '\0'; c++)
-        glutBitmapCharacter(font, *c);
+	char *c;
+	// Set position to start drawing fonts
+	glRasterPos2f(x, y);
+	// Loop all the characters in the string
+	for (c=string; *c != '\0'; c++)
+		glutBitmapCharacter(font, *c);
 }
 
 void VMI::renderGeometry(void) {
 #ifdef IMMEDIATE_MODE
-    int i, v1, v2, v3;
-
-    // Immediate mode
-    glBegin (GL_TRIANGLES);
-    for (i=0; i<mesh->numTriangles; i++) {
-        if (mesh->triangles[i].enable == TRUE) {
-            
-            v1= mesh->triangles[i].indices[0];
-            v2= mesh->triangles[i].indices[1];
-            v3= mesh->triangles[i].indices[2];
-            
-            glColor4ub(colors[i].r, colors[i].g, colors[i].b, colors[i].a);
-            glVertex3f(mesh->vertices[v1].x, mesh->vertices[v1].y, mesh->vertices[v1].z);
-            glVertex3f(mesh->vertices[v2].x, mesh->vertices[v2].y, mesh->vertices[v2].z);
-            glVertex3f(mesh->vertices[v3].x, mesh->vertices[v3].y, mesh->vertices[v3].z);
-        }
-    }
-    glEnd();
+	int i, v1, v2, v3;
+
+	// Immediate mode
+	glBegin (GL_TRIANGLES);
+	for (i=0; i<mesh->numTriangles; i++) {
+		if (mesh->triangles[i].enable == TRUE) {
+
+			v1= mesh->triangles[i].indices[0];
+			v2= mesh->triangles[i].indices[1];
+			v3= mesh->triangles[i].indices[2];
+
+			glColor4ub(colors[i].r, colors[i].g, colors[i].b, colors[i].a);
+			glVertex3f(mesh->vertices[v1].x, mesh->vertices[v1].y, mesh->vertices[v1].z);
+			glVertex3f(mesh->vertices[v2].x, mesh->vertices[v2].y, mesh->vertices[v2].z);
+			glVertex3f(mesh->vertices[v3].x, mesh->vertices[v3].y, mesh->vertices[v3].z);
+		}
+	}
+	glEnd();
 #else
 #ifdef VERTEX_ARRAY
-    glDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
+	glDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
 #endif
 #ifdef VERTEX_ARRAY_INTERLEAVE
-    glInterleavedArrays (GL_T2F_C4UB_V3F, 0, interleave);
-    glDrawArrays(GL_TRIANGLES, 0, mesh->currentNumTriangles * 3);
+	glInterleavedArrays (GL_T2F_C4UB_V3F, 0, interleave);
+	glDrawArrays(GL_TRIANGLES, 0, mesh->currentNumTriangles * 3);
 #endif
 #ifdef VERTEX_BUFFER_OBJECTS
-    glDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
-#endif
-
-#endif
-}
+	glDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
+#endif
+
+#endif
+}
+
 void VMI::drawTexture(void) {
 
-    // Clear color and depth buffers
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-    setOrthographicProjection();
-
-    glEnable(GL_TEXTURE_2D);
-    glBindTexture(GL_TEXTURE_2D, color_tex);
-    glBegin(GL_QUADS);
-    
-    glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
-    glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); 
-    glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
-    glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
-
-    glEnd();
-    glFlush();
-    glDisable(GL_TEXTURE_2D);
-
-    resetPerspectiveProjection();
-
-    glutSwapBuffers();
+	// Clear color and depth buffers
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+	setOrthographicProjection();
+
+	glEnable(GL_TEXTURE_2D);
+	glBindTexture(GL_TEXTURE_2D, color_tex);
+	glBegin(GL_QUADS);
+
+	glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
+	glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); 
+	glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
+	glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
+
+	glEnd();
+	glFlush();
+	glDisable(GL_TEXTURE_2D);
+
+	resetPerspectiveProjection();
+
+	glutSwapBuffers();
 }
 
 void VMI::resetProjectedAreas(int **histogram, int numCameras) {
-    int i = 0;
-
-    // Reset the projected areas for all cameras
-    for (i=0; i<numCameras; i++)
-        resetSWHistogram(histogram[i], mesh->numTriangles);
+	int i = 0;
+
+	// Reset the projected areas for all cameras
+	for (i=0; i<numCameras; i++)
+		resetSWHistogram(histogram[i], mesh->numTriangles);
 }
 
 void VMI::getProjectedAreas(int **histogram, int numCameras)
 {
-    int i;
-
-    // draw to the frame buffer
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
-
-    //glDrawBuffer(GL_BACK);
-    //glReadBuffer(GL_BACK);
-
-    // Get the projected areas for all cameras
-    for (i=0; i<numCameras; i++) {
-        
-        // Clear color and depth buffers
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-        
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        
-        // Camera  i
-        gluLookAt(cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ,
-                  cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ,
-                  cameras[i].upX, cameras[i].upY, cameras[i].upZ);
-        
-        renderGeometry();
-        glFlush();
-        
-        ///////////////////////////////////////////////////////////////////////////
-        
-        resetSWHistogram(histogram[i], mesh->numTriangles);
-        
+	int i;
+
+	// draw to the frame buffer
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+
+	//glDrawBuffer(GL_BACK);
+	//glReadBuffer(GL_BACK);
+
+	// Get the projected areas for all cameras
+	for (i=0; i<numCameras; i++) {
+
+		// Clear color and depth buffers
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+
+		// Camera  i
+		gluLookAt(cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ,
+				cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ,
+				cameras[i].upX, cameras[i].upY, cameras[i].upZ);
+
+		renderGeometry();
+		glFlush();
+
+		///////////////////////////////////////////////////////////////////////
+
+		resetSWHistogram(histogram[i], mesh->numTriangles);
+
 #ifdef USE_OCCLUSION_QUERY
-        getSWHistoByOcclusionQuery(mesh, colors, histogram[i]);
+		getSWHistoByOcclusionQuery(mesh, colors, histogram[i]);
 #else // HYBRID_HW_SW_HISTOGRAM
-        getSWHistogram(histogram[i], pixels);
-#endif
-    }
-
-    // draw to the window, reading from the color texture
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
-    if (!bEnableOffScreen) drawTexture();
-    
-    ///////////////////////////////////////////////////////////////////////////
+		getSWHistogram(histogram[i], pixels);
+#endif
+	}
+
+	// draw to the window, reading from the color texture
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+	if (!bEnableOffScreen) drawTexture();
+
+	/////////////////////////////////////////////////////////////////////////
 }
 void VMI::getProjectedAreasWin(int **histogram, int numCameras, Change *c)
 {
-    int i, j, t, background;
-    int del_area, mod_area;
-    GLfloat min[3], max[3];
-
-    // draw to the frame buffer
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
-
-    //printChange(c);
-    getBoundingBox(c, min, max);
-    //printf("\n(%f,%f,%f)-(%f,%f,%f)\n", min[0], min[1], min[2], max[0], max[1], max[2]);
-    
-    // Update HW acceleration OpenGL Technique
-    updateHWAcceleration(c);
-
-    //glDrawBuffer(GL_BACK);
-    //glReadBuffer(GL_BACK);
-
-    // Get the projected areas for all cameras
-    for (i=0; i<numCameras; i++) {
-        
-        // Clear color and depth buffers
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-        
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        
-        // Camera  i
-        gluLookAt(cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ,
-                  cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ,
-                  cameras[i].upX, cameras[i].upY, cameras[i].upZ);
-        
-        renderGeometry();
-        glFlush();
-        
-        ///////////////////////////////////////////////////////////////////////////
-        background = histogram[i][0];
-        //printf("b: %d\n", histogram[i][0]);
-
-        del_area = 0;
-        mod_area = 0;
-
-        for (j=0; j<c->numDel; j++) {
-            t = c->deleted[j].id;
-            del_area += histogram[i][t + 1];
-
-            histogram[i][t + 1] = 0;
-        }
-
-        for (j=0; j<c->numMod; j++) {
-            t = c->modified[j].id;
-            del_area += histogram[i][t + 1];
-
-            histogram[i][t + 1] = 0;
-        }
-        
-        getSWHistogramWin(histogram[i], pixels, min, max, c); 
-
-        for (j=0; j<c->numMod; j++) {
-            t = c->modified[j].id;
-            mod_area += histogram[i][t + 1];
-
-            //printf("t%d: %d\n",t, histogram[i][t + 1]);
-        }
-        histogram[i][0] = background + (del_area - mod_area);
-        //printf("b: %d\n", histogram[i][0]);
-    }
-    //getchar();
-
-    // draw to the window, reading from the color texture
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-
-    if (!bEnableOffScreen) drawTexture();
-    
-    ///////////////////////////////////////////////////////////////////////////
+	int i, j, t, background;
+	int del_area, mod_area;
+	GLfloat min[3], max[3];
+
+	// draw to the frame buffer
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+
+	//printChange(c);
+	getBoundingBox(c, min, max);
+	//printf("\n(%f,%f,%f)-(%f,%f,%f)\n", min[0], min[1], min[2], max[0], max[1], max[2]);
+
+	// Update HW acceleration OpenGL Technique
+	updateHWAcceleration(c);
+
+	//glDrawBuffer(GL_BACK);
+	//glReadBuffer(GL_BACK);
+
+	// Get the projected areas for all cameras
+	for (i=0; i<numCameras; i++) {
+
+		// Clear color and depth buffers
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		glMatrixMode(GL_MODELVIEW);
+		glLoadIdentity();
+
+		// Camera  i
+		gluLookAt(cameras[i].eyeX, cameras[i].eyeY, cameras[i].eyeZ,
+				cameras[i].centerX, cameras[i].centerY, cameras[i].centerZ,
+				cameras[i].upX, cameras[i].upY, cameras[i].upZ);
+
+		renderGeometry();
+		glFlush();
+
+		////////////////////////////////////////////////////////////////////////
+		background = histogram[i][0];
+		//printf("b: %d\n", histogram[i][0]);
+
+		del_area = 0;
+		mod_area = 0;
+
+		for (j=0; j<c->numDel; j++) {
+			t = c->deleted[j].id;
+			del_area += histogram[i][t + 1];
+
+			histogram[i][t + 1] = 0;
+		}
+
+		for (j=0; j<c->numMod; j++) {
+			t = c->modified[j].id;
+			del_area += histogram[i][t + 1];
+
+			histogram[i][t + 1] = 0;
+		}
+
+		getSWHistogramWin(histogram[i], pixels, min, max, c); 
+
+		for (j=0; j<c->numMod; j++) {
+			t = c->modified[j].id;
+			mod_area += histogram[i][t + 1];
+
+			//printf("t%d: %d\n",t, histogram[i][t + 1]);
+		}
+		histogram[i][0] = background + (del_area - mod_area);
+		//printf("b: %d\n", histogram[i][0]);
+	}
+	//getchar();
+
+	// draw to the window, reading from the color texture
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+	if (!bEnableOffScreen) drawTexture();
+
+	////////////////////////////////////////////////////////////////////////
 }
 
 void VMI::freeMemory(void) {
 
-	  // Free memory
-    deleteMesh(mesh);
-
-    //glmDelete(pmodel);
-
-    free(pixels);
-
-    free(cameras);
-
-    free(colors);
-    
-    deleteHistogram(histogram, numCameras);
-
-    free(initialIs);
-    
-    glDeleteRenderbuffersEXT(1, &depth_rb);
-    
-    glDeleteRenderbuffersEXT(1, &color_tex);
-    
-    glDeleteFramebuffersEXT(1, &fb);
+	// Free memory
+	deleteMesh(mesh);
+
+	//glmDelete(pmodel);
+
+	free(pixels);
+
+	free(cameras);
+
+	free(colors);
+
+	deleteHistogram(histogram, numCameras);
+
+	free(initialIs);
+
+	glDeleteRenderbuffersEXT(1, &depth_rb);
+
+	glDeleteRenderbuffersEXT(1, &color_tex);
+
+	glDeleteFramebuffersEXT(1, &fb);
 #ifdef USE_OCCLUSION_QUERY
-    glDeleteQueriesARB(mesh->currentNumTriangles, queries);
-#endif
-
-		if (vmiWin != 0)
-		{
-			glutDestroyWindow(vmiWin);
-		}
+	glDeleteQueriesARB(mesh->currentNumTriangles, queries);
+#endif
+
+	if (vmiWin != 0)
+	{
+		glutDestroyWindow(vmiWin);
+	}
 
 #ifdef VERTEX_BUFFER_OBJECTS
-    glDeleteBuffersARB(1, &vertex_buf);
-    glDeleteBuffersARB(1, &color_buf);
-
-		buf_vertices = NULL;
-    buf_colors = NULL;
+	glDeleteBuffersARB(1, &vertex_buf);
+	glDeleteBuffersARB(1, &color_buf);
+
+	buf_vertices = NULL;
+	buf_colors = NULL;
 
 #endif
 #ifdef VERTEX_ARRAY
-    free(buf_vertices);
-    free(buf_colors);
-
-		buf_vertices = NULL;
-    buf_colors = NULL;
+	free(buf_vertices);
+	free(buf_colors);
+
+	buf_vertices = NULL;
+	buf_colors = NULL;
 #endif
 #ifdef VERTEX_ARRAY_INTERLEAVE
-		free(interleave);
-		interleave = NULL;
+	free(interleave);
+	interleave = NULL;
 #endif
 
@@ -494,5 +511,5 @@
 
 	histogram = NULL;
-  queries = NULL;
+	queries = NULL;
 
 	mesh = NULL;
@@ -516,5 +533,5 @@
 
 	// Apply HW acceleration OpenGL Technique
-  applyHWAcceleration();
+	applyHWAcceleration();
 
 	getProjectedAreas(histogram, numCameras);
@@ -555,7 +572,7 @@
 
 #ifdef SALIENCY
-    sprintf(s,"%s_%d_%d_%s_S.obj", filename, numCameras, mesh->currentNumTriangles, EXT);
+	sprintf(s,"%s_%d_%d_%s_S.obj", filename, numCameras, mesh->currentNumTriangles, EXT);
 #else
-    sprintf(s,"%s_%d_%d_%s.obj", filename, numCameras, mesh->currentNumTriangles, EXT);
+	sprintf(s,"%s_%d_%d_%s.obj", filename, numCameras, mesh->currentNumTriangles, EXT);
 #endif
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 2291)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 2300)
@@ -1465,137 +1465,4 @@
 
 //-------------------------------------------------------------------------
-//	Erase submeshes that have not indices.
-//-------------------------------------------------------------------------
-void	SimplificationMethod::eraseVoidSubMeshes(Mesh	*geoMesh)
-{
-	SubMesh	*geosubmesh;
-	size_t	valid_submesh_count;
-	size_t	submesh;
-
-	valid_submesh_count	=	0;
-
-	//	For each submesh.
-	for	(size_t	i	=	0; i < geoMesh->mSubMeshCount;	i++)
-	{
-		//	Debug.
-		cout	<<	"Indices of submesh "
-					<<	i
-					<<	": "
-					<<	geoMesh->mSubMesh[i].mIndexCount
-					<<	endl;
-
-		if ((geoMesh->mSubMesh[i].mIndexCount > 0)
-				||
-				(indexMeshLeaves == i))
-		{
-			valid_submesh_count++;
-		}
-	}
-
-	//	Reassign submesh count.
-	geoMesh->mSubMeshCount	=	valid_submesh_count;
-
-	//	Reserve memory for valid submeshes.
-	geosubmesh	=	new	SubMesh[valid_submesh_count];
-
-	submesh	=	0;
-	
-	//	For each submesh.
-	for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
-	{
-		//	If leaves submesh is found.
-		if (indexMeshLeaves == i)
-		{
-			geosubmesh[i].mStripCount	=	0;
-			geosubmesh[i].mStrip			=	NULL;
-
-			geosubmesh[i].mSharedVertexBuffer	=	false;
-
-			strcpy(	geosubmesh[i].mMaterialName,
-					mInitialMesh->mSubMesh[i].mMaterialName);
-
-			//	Copy submesh bones.
-			if (!mInitialMesh->mSubMesh[i].mBones.empty())
-			{
-				for (	size_t j = 0;
-						j < mInitialMesh->mSubMesh[i].mBones.size();
-						j++)
-				{
-					geosubmesh[i].mBones.push_back(mInitialMesh->
-							mSubMesh[i].mBones[j]);
-				}
-			}
-
-			//	Leaves mesh.
-			geosubmesh[i].mIndexCount	=	
-				mInitialMesh->mSubMesh[i].mIndexCount;
-
-			geosubmesh[i].mIndex	=
-				new Geometry::Index[geosubmesh[i].mIndexCount];
-
-			memcpy(	geosubmesh[i].mIndex,
-					mInitialMesh->mSubMesh[i].mIndex,
-					mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
-
-			//	Copy the leaves submesh vertices.
-			geosubmesh[i].mVertexBuffer	=
-				mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
-
-			//	Next valid submesh.
-			submesh++;
-		}
-		else if (geoMesh->mSubMesh[i].mIndexCount > 0)
-		{
-			geosubmesh[submesh].mSharedVertexBuffer	=
-									geoMesh->mSubMesh[i].mSharedVertexBuffer;
-
-			geosubmesh[submesh].mVertexBuffer	=	geoMesh->mVertexBuffer;
-
-			geosubmesh[submesh].mType				=	geoMesh->mSubMesh[i].mType;
-
-			geosubmesh[submesh].mStripCount	=	geoMesh->mSubMesh[i].mStripCount;
-
-			geosubmesh[submesh].mIndexCount	=	geoMesh->mSubMesh[i].mIndexCount;
-
-			//	Reserve memory for indices.
-			geosubmesh[submesh].mIndex	=
-													new Index[geosubmesh[submesh].mIndexCount];
-
-			//	Copy indices.
-			memcpy(	geosubmesh[submesh].mIndex,
-					geoMesh->mSubMesh[i].mIndex,
-					geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
-
-			//	Reserve memory for array of strips.
-			geosubmesh[submesh].mStrip	=
-				new Index*[geoMesh->mSubMesh[submesh].mStripCount];
-
-			//	Copy strip list of the submesh.
-			for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
-			{
-				geosubmesh[submesh].mStrip[j]	=	geoMesh->mSubMesh[i].mStrip[j];
-			}
-
-			strcpy(	geosubmesh[submesh].mMaterialName,
-					geoMesh->mSubMesh[i].mMaterialName);
-
-			for (size_t	j	=	0;	j < geoMesh->mSubMesh[i].mBones.size();	j++)
-			{
-				geosubmesh[submesh].mBones
-					.push_back(geoMesh->mSubMesh[i].mBones[j]);
-			}
-
-			//	Next valid submesh.
-			submesh++;
-		}
-	}
-
-	//	Delete submeshes.
-	delete	[]geoMesh->mSubMesh;
-
-	geoMesh->mSubMesh	=	geosubmesh;
-}
-
-//-------------------------------------------------------------------------
 //	Fill up vertices.
 //-------------------------------------------------------------------------
@@ -1878,7 +1745,4 @@
 Mesh	*	SimplificationMethod::GetMesh()
 {
-	//	Delete void submeshes.
-	eraseVoidSubMeshes(mGeoMesh);
-
 	return	mGeoMesh;
 }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 2291)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 2300)
@@ -191,6 +191,4 @@
 		void	addNewBoneAssignments();
 
-		void	eraseVoidSubMeshes(Mesh	*geoMesh);
-
 	public:
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 2291)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 2300)
@@ -42,8 +42,144 @@
 
 //-------------------------------------------------------------------------
+//	Erase submeshes that have not indices.
+//-------------------------------------------------------------------------
+void	MeshSimplifier::eraseVoidSubMeshes(Mesh	*geoMesh)
+{
+	SubMesh	*geosubmesh;
+	size_t	valid_submesh_count;
+	size_t	submesh;
+
+	valid_submesh_count	=	0;
+
+	//	For each submesh.
+	for	(size_t	i	=	0; i < geoMesh->mSubMeshCount;	i++)
+	{
+		//	Debug.
+		cout	<<	"Indices of submesh "
+					<<	i
+					<<	": "
+					<<	geoMesh->mSubMesh[i].mIndexCount
+					<<	endl;
+
+		if ((geoMesh->mSubMesh[i].mIndexCount > 0)
+				||
+				(indexMeshLeaves == i))
+		{
+			valid_submesh_count++;
+		}
+	}
+
+	//	Reassign submesh count.
+	geoMesh->mSubMeshCount	=	valid_submesh_count;
+
+	//	Reserve memory for valid submeshes.
+	geosubmesh	=	new	SubMesh[valid_submesh_count];
+
+	submesh	=	0;
+	
+	//	For each submesh.
+	for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
+	{
+		//	If leaves submesh is found.
+		if (indexMeshLeaves == i)
+		{
+			geosubmesh[i].mStripCount	=	0;
+			geosubmesh[i].mStrip			=	NULL;
+
+			geosubmesh[i].mSharedVertexBuffer	=	false;
+
+			strcpy(	geosubmesh[i].mMaterialName,
+					mInitialMesh->mSubMesh[i].mMaterialName);
+
+			//	Copy submesh bones.
+			if (!mInitialMesh->mSubMesh[i].mBones.empty())
+			{
+				for (	size_t j = 0;
+						j < mInitialMesh->mSubMesh[i].mBones.size();
+						j++)
+				{
+					geosubmesh[i].mBones.push_back(mInitialMesh->
+							mSubMesh[i].mBones[j]);
+				}
+			}
+
+			//	Leaves mesh.
+			geosubmesh[i].mIndexCount	=	
+				mInitialMesh->mSubMesh[i].mIndexCount;
+
+			geosubmesh[i].mIndex	=
+				new Geometry::Index[geosubmesh[i].mIndexCount];
+
+			memcpy(	geosubmesh[i].mIndex,
+					mInitialMesh->mSubMesh[i].mIndex,
+					mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
+
+			//	Copy the leaves submesh vertices.
+			geosubmesh[i].mVertexBuffer	=
+				mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
+
+			//	Next valid submesh.
+			submesh++;
+		}
+		else if (geoMesh->mSubMesh[i].mIndexCount > 0)
+		{
+			geosubmesh[submesh].mSharedVertexBuffer	=
+									geoMesh->mSubMesh[i].mSharedVertexBuffer;
+
+			geosubmesh[submesh].mVertexBuffer	=	geoMesh->mVertexBuffer;
+
+			geosubmesh[submesh].mType				=	geoMesh->mSubMesh[i].mType;
+
+			geosubmesh[submesh].mStripCount	=	geoMesh->mSubMesh[i].mStripCount;
+
+			geosubmesh[submesh].mIndexCount	=	geoMesh->mSubMesh[i].mIndexCount;
+
+			//	Reserve memory for indices.
+			geosubmesh[submesh].mIndex	=
+													new Index[geosubmesh[submesh].mIndexCount];
+
+			//	Copy indices.
+			memcpy(	geosubmesh[submesh].mIndex,
+					geoMesh->mSubMesh[i].mIndex,
+					geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
+
+			//	Reserve memory for array of strips.
+			geosubmesh[submesh].mStrip	=
+				new Index*[geoMesh->mSubMesh[submesh].mStripCount];
+
+			//	Copy strip list of the submesh.
+			for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
+			{
+				geosubmesh[submesh].mStrip[j]	=	geoMesh->mSubMesh[i].mStrip[j];
+			}
+
+			strcpy(	geosubmesh[submesh].mMaterialName,
+					geoMesh->mSubMesh[i].mMaterialName);
+
+			for (size_t	j	=	0;	j < geoMesh->mSubMesh[i].mBones.size();	j++)
+			{
+				geosubmesh[submesh].mBones
+					.push_back(geoMesh->mSubMesh[i].mBones[j]);
+			}
+
+			//	Next valid submesh.
+			submesh++;
+		}
+	}
+
+	//	Delete submeshes.
+	delete	[]geoMesh->mSubMesh;
+
+	geoMesh->mSubMesh	=	geosubmesh;
+}
+
+//-------------------------------------------------------------------------
 // Returns the simplified mesh.
 //-------------------------------------------------------------------------
 Mesh *	MeshSimplifier::GetMesh()
 {
+	//	Delete void submeshes.
+	eraseVoidSubMeshes(mGeoMesh);
+
 	return mGeoMesh;
 }
@@ -146,5 +282,5 @@
 // method to perform an image based simplification.
 //-------------------------------------------------------------------------
-void GeometryBasedSimplifier::Simplify(Real paramlod)
+int	GeometryBasedSimplifier::Simplify(Real paramlod)
 {
 	SimplificationMethod *m_qslim	=	new SimplificationMethod(mInitialMesh);
@@ -157,4 +293,6 @@
 
 	delete	m_qslim;
+
+	return	NO_GL_ERROR;
 }
 
@@ -165,5 +303,5 @@
 // perform an image based simplification.
 //-------------------------------------------------------------------------
-void GeometryBasedSimplifier::Simplify(uint32 numvertices)
+int	GeometryBasedSimplifier::Simplify(uint32 numvertices)
 {
 	SimplificationMethod *m_qslim	=	new SimplificationMethod(mInitialMesh);
@@ -176,4 +314,6 @@
 
 	delete m_qslim;
+
+	return	NO_GL_ERROR;
 }
 
@@ -235,4 +375,10 @@
 	//	Loads the vmi mesh structure for a geometry mesh given.
 	VMI::mesh = initMeshStructure(mGeoMesh);
+}
+
+//	Init VMI options.
+int	ViewPointDrivenSimplifier::init(void)
+{
+	int	error;
 
 	// RGB and Alpha.
@@ -245,5 +391,5 @@
 	glewInit();
 
-	VMI::init();
+	error	=	VMI::init();
 
 	if (VMI::bLoadCamerasFromFile == GL_FALSE)
@@ -256,4 +402,6 @@
 
 	VMI::initialIs	=	VMI::initIs(VMI::numCameras);
+
+	return	error;
 }
 
@@ -273,6 +421,10 @@
 ///	LOD factor in a range of [0,1]. Implements the
 ///	Simplifier::Simplify method to perform an image based simplification.
-void ViewPointDrivenSimplifier::Simplify(Real percent)
-{
+int ViewPointDrivenSimplifier::Simplify(Real percent)
+{
+	int error;
+
+	error	=	 init();
+
 	VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * percent);
 
@@ -284,20 +436,25 @@
 	}
 
-	VMI::display();
-
-	//	Cleans firts simplification.
-	VMI::freeMemory();
-
-	VMI::mesh =	initMeshStructure(mInitialMesh);
-
-	VMI::contractInitialMesh(VMI::mesh);
-
-	//	Load a geometry mesh for vmi mesh.
-	loadMesh();
-	
-	GetMeshSimpSequence();
-
-	//	Sort bones.
-	bonesReassignament();
+	if (error == NO_GL_ERROR)
+	{
+		VMI::display();
+
+		//	Cleans firts simplification.
+		VMI::freeMemory();
+
+		VMI::mesh =	initMeshStructure(mInitialMesh);
+
+		VMI::contractInitialMesh(VMI::mesh);
+
+		//	Load a geometry mesh for vmi mesh.
+		loadMesh();
+
+		GetMeshSimpSequence();
+
+		//	Sort bones.
+		bonesReassignament();
+	}
+
+	return	error;
 }
 
@@ -308,11 +465,16 @@
 ///	an image based simplification.
 //-------------------------------------------------------------------------
-void ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
+int ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
 {
 	float	percent;
+	int 	error;
+
+	error	=	 init();
 
 	percent	=	(numVertices	*	100.0) / VMI::mesh->numVertices;
 
-	VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * (percent / 100));
+	VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles
+																		*
+																		(percent / 100));
 
 	if ((VMI::numDemandedTriangles == 0)
@@ -323,20 +485,25 @@
 	}
 
-	VMI::display();
-
-	//	Cleans firts simplification.
-	VMI::freeMemory();
-
-	VMI::mesh =	initMeshStructure(mInitialMesh);
-
-	VMI::contractInitialMesh(VMI::mesh);
-	
-	//	Load a geometry mesh for vmi mesh.
-	loadMesh();
-	
-	GetMeshSimpSequence();
-
-	//	Sort bones.
-	bonesReassignament();
+	if (error == NO_GL_ERROR)
+	{
+		VMI::display();
+
+		//	Cleans firts simplification.
+		VMI::freeMemory();
+
+		VMI::mesh =	initMeshStructure(mInitialMesh);
+
+		VMI::contractInitialMesh(VMI::mesh);
+
+		//	Load a geometry mesh for vmi mesh.
+		loadMesh();
+
+		GetMeshSimpSequence();
+
+		//	Sort bones.
+		bonesReassignament();
+	}
+
+	return	error;
 }
 
Index: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 2291)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 2300)
@@ -1119,4 +1119,7 @@
 					mGeoMesh	=	mesh_aux;
 
+					// Visualize mesh.
+					geoMeshView->setMesh(mGeoMesh);
+
 					//	Simplify the mesh object.
 					if(simplifyEdgeCollapse())
@@ -1172,5 +1175,4 @@
 					undo();
 
-
 					std::cout << "Simplificando tronco...";
 					std::cout << "OK!" << std::endl;
@@ -1184,4 +1186,7 @@
 					//	Gets the mesh Shared Vertex.
 					mGeoMesh	=	mesh_aux;
+
+					// Visualize mesh.
+					geoMeshView->setMesh(mGeoMesh);
 
 					//	Simplify the mesh object.
@@ -1198,5 +1203,5 @@
 				}
 				
-				break; 
+				break;
 
 			case	LODSTRIPS_AUTO:
@@ -1227,4 +1232,7 @@
 					//	Gets the mesh Shared Vertex.
 					mGeoMesh	=	mesh_aux;
+
+					// Visualize mesh.
+					geoMeshView->setMesh(mGeoMesh);
 
 					//	Simplify the mesh object.
@@ -2125,5 +2133,5 @@
 bool GeoMeshViewUI::simplifyEdgeCollapse()
 {
-	Real    percent;
+	int			error;
 
 	//	Free memory.
@@ -2133,5 +2141,5 @@
 	}
 
-	//    If input field empty.
+	//	If input field empty.
 	if (mMeshReduction->fvalue() <= 0.0)
 	{
@@ -2161,6 +2169,4 @@
 	}
 
-	mMeshSimplifier->setMeshLeaves(idMeshLeaves);
-
 	if (mPercent->value())
 	{
@@ -2169,20 +2175,10 @@
 				mMeshReduction->fvalue() > 0.0)
 		{
-			percent	=	mMeshReduction->fvalue();
-			percent	=	percent / 100.0;
-
-			mMeshSimplifier->Simplify(percent);
-
-			//	Deletes the previous mesh.
-			delete mUndoMesh;
-
-			mUndoMesh	=	new Mesh();
-
-			//	Sets the undo mesh.
-			*mUndoMesh	=	*mGeoMesh;
-
-			delete    mGeoMesh;
-
-			mGeoMesh	=	mMeshSimplifier->GetMesh();
+			Real	value;
+
+			value	=	mMeshReduction->fvalue();
+			value	=	value / 100.0;
+
+			error	=	mMeshSimplifier->Simplify(value);
 		}
 		else
@@ -2197,8 +2193,12 @@
 	{
 		//	Simplification until number of vertices.
-		uint32 v	=	(uint32)mMeshReduction->fvalue();
-
-		mMeshSimplifier->Simplify(v);
-
+		uint32 value	=	(uint32)mMeshReduction->fvalue();
+
+		error	=	mMeshSimplifier->Simplify(value);
+	}
+
+	//	If no error happens.
+	if (error == NO_GL_ERROR)
+	{
 		//	Deletes the previous mesh.
 		delete mUndoMesh;
@@ -2209,7 +2209,57 @@
 		*mUndoMesh	=	*mGeoMesh;
 
-		delete	mGeoMesh;
+		delete    mGeoMesh;
 
 		mGeoMesh	=	mMeshSimplifier->GetMesh();
+	}
+	//	If and error happens.
+	else
+	{
+		char	error_message[512]="";
+
+		if ((error & FRAMEBUFFER_ERROR) == FRAMEBUFFER_ERROR)
+		{
+			strcat(	error_message,
+					"GL_EXT_framebuffer_object extension not found.\n");
+		}
+
+		if ((error & VERTEX_BUFFER_ERROR) == VERTEX_BUFFER_ERROR)
+		{
+			strcat(	error_message,
+					"GL_ARB_vertex_buffer_object extension not found.\n");
+		}
+
+		if ((error & OCCLUSION_QUERY_ERROR)
+				==
+				OCCLUSION_QUERY_ERROR)
+		{
+			strcat(	error_message,
+					"GL_ARB_occlusion_query extension not found.\n");
+		}
+
+		if ((error & IMAGING_ERROR) == IMAGING_ERROR)
+		{
+			strcat(	error_message,
+					"GL_ARB_imaging extension not found.\n");
+		}
+
+		if ((error & MULTITEXTURE_ERROR) == MULTITEXTURE_ERROR)
+		{
+			strcat(	error_message,
+					"GL_ARB_multitexture extension not found.\n");
+		}
+
+		if ((error & SWAP_CONTROL_ERROR) == SWAP_CONTROL_ERROR)
+		{
+			strcat(	error_message,
+					"WGL_EXT_swap_control extension not found.\n");
+		}
+
+		strcat(	error_message,
+						"\nUpdating the video card driver may resolve the problem.");
+
+		fltk::alert(error_message);
+
+		return	false;
 	}
 
@@ -2261,5 +2311,5 @@
 
 			mUndoMesh	=	new Mesh();
-			
+
 			//	Sets the undo mesh.
 			*mUndoMesh	=	*mGeoMesh;
@@ -2268,5 +2318,5 @@
 
 			mGeoMesh	=	mTreeSimplifier->GetMesh();
-			
+
 			geoMeshView->setMesh(mGeoMesh);
 		}
