Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodObject.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodObject.h	(revision 1058)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodObject.h	(revision 1526)
@@ -4,4 +4,6 @@
 namespace Geometry
 {
+	class IndexData;
+
 	class LodObject
 	{
@@ -13,4 +15,6 @@
 		uint32 GetUniqueID(void) const { return  uniqueID; }
 		virtual void GoToLod(Real)=0;
+		virtual Real GetCurrentLodFactor(void) const =0;
+		virtual Geometry::IndexData * GetIndexDataInterface(void)=0;
 
 	private:
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 1090)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 1526)
@@ -34,13 +34,14 @@
 	typedef	struct
 	{
-		unsigned	long	strip;
-		char						position;
-		char						vertexRepetition;
-		char						edgeRepetition;
+		unsigned	long	strip; // change this to uint32
+		char		position;
+		char		vertexRepetition;
+		char		edgeRepetition;
+		char		obligatory;
 	}	LODRegisterType;
 
 	typedef struct
 	{
-		float			Vertex[3];
+		float		Vertex[3];
 		SmallInt	Next;
 	} VertexType;
@@ -130,10 +131,10 @@
 
 			//	Copa STL vectors to C arrays.
-			void	CopyVectors2Arrays();
+			void	CopyVectors2Arrays(void);
 
 			//	Loads Mesh.
 			void	LoadStripMesh(const LodStripsLibraryData *, Mesh *geomesh);
 
-			Geometry::CREATEINDEXDATAFUNC create_index_data_func;
+//			Geometry::CREATEINDEXDATAFUNC create_index_data_func;
 
 			//	Strips vector.
@@ -146,13 +147,18 @@
 			//Number of strips in each submesh
 			int* mStripsSubmesh;
+			bool delete_indexdata;
+			int *submesh_x_strip;
+			Real lodFactor;
+			IndexData *dataRetrievalInterface;
+			uint32 current_triangle_count;
 
 		public:
 
-			IndexData *dataRetrievalInterface;
+			IndexData *GetIndexDataInterface(void){ return dataRetrievalInterface; }
 			
 			/**	Constructor, receives as a parameter the name of the file
 			 * 	including the multiresolution object.
 			*/
-			LodStripsLibrary(const LodStripsLibraryData *, Mesh *geomesh, CREATEINDEXDATAFUNC idfun=NULL);
+			LodStripsLibrary(const LodStripsLibraryData *, Mesh *geomesh, IndexData * userindexdata = NULL);
 
 			/// Destructor.
@@ -182,4 +188,7 @@
 			uint32 GetTotalStripCount(void) const { return mTotalStrips; }
 			uint32 GetSubMeshtripCount(int submeshid) const { return mStripsSubmesh[submeshid]; }
+			uint32 GetCurrentTriangleCount(void) const { return current_triangle_count; }
+
+			virtual Real GetCurrentLodFactor(void) const { return lodFactor; }
 	};
 }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h	(revision 1310)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h	(revision 1526)
@@ -15,39 +15,42 @@
 #include "GeoVector3.h"
 #include "GeoLodObject.h"
-#include <map>
-#include <vector>
 
 namespace Geometry
 {
-	class lodobj_dist_node_t
-	{
-	public:
-		lodobj_dist_node_t(float dist, LodObject *o):dist2cam(dist),lodobj(o){ must_recalculate_distance=false; }
-		float dist2cam;
-		LodObject *lodobj;
-		bool must_recalculate_distance;
-		bool operator < (const lodobj_dist_node_t &o) const { return (dist2cam < o.dist2cam); }
-	};
+	class NodeContainer;	
+	class lodobj_node_t;
 
 	class LodManager
 	{	
 	public:
-		LodManager(float near, float far, const Geometry::Vector3 &campos);
-		void AddLodObj(LodObject*, const Geometry::Vector3 &);
-		void UpdateLOD(void);
+		LodManager(Real near, Real far, const Geometry::Vector3 &campos, int numslots=10);
+		~LodManager(void);
+		void AddLodObj(const std::string &name, LodObject*, const Geometry::Vector3 &);
+		void UpdateLOD(uint32 currFPS, uint32 targetFPS=30);
 		void UpdateCamera(const Geometry::Vector3 &);
 		void UpdateLODObjectPos(LodObject*,const Geometry::Vector3 &);
+
+		bool always_calculate_lod; // if true, there is no instant LOD changing
+		bool force_highest_lod; // if set to true, all objects will be set to their highest level of detail
+
 	private:
-		std::vector<lodobj_dist_node_t> lodobj_dists; // key: dist2cam for efficient distance finding
-		std::map<uint32,Geometry::Vector3> lodobj_pos; // map key: LodObject UniqueID for efficient ID-based finding
-		unsigned int targetFPS;
-		Vector3 camera_pos;
-		bool camera_changed;
+		NodeContainer *lodobj_container;
+		uint32 lasttime;
+		bool camera_changed, node_added;
 		float near_range, far_range;
-		float CalculateDistToCamera(const Geometry::Vector3 &) const;
 		float SelectRandomDistance(void) const;
-		void RecalculateDist(lodobj_dist_node_t & node);
+		void ChangeLOD(lodobj_node_t*,Real);
+		void ReallyGoToLOD(lodobj_node_t*,Real);
+
+		lodobj_node_t * FindMostSimilarRealLOD(const std::string &, Real desired_lod);
+
+		void MakeDiscipleOf(lodobj_node_t *master, lodobj_node_t *disciple);
+		void MakeIndependent(lodobj_node_t*);
+		void RemoveDiscipleFrom(LodObject *master, LodObject *disciple);
+		void UpdateDisciples(lodobj_node_t *master);
+		void DeleteMeFromMyMastersDiscipleList(lodobj_node_t *);
+		void ChangeMaster(lodobj_node_t *orig, lodobj_node_t *newmaster);
 	};
-};
+}
 
 #endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoBase.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoBase.h	(revision 1070)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoBase.h	(revision 1526)
@@ -15,10 +15,10 @@
 {
 	//	Basic types.
-	typedef float 					Real;
-	typedef unsigned int		Index;
-	typedef	int							int32;
-	typedef unsigned int		uint32;
+	typedef float 			Real;
+	typedef unsigned int	Index;
+	typedef	int				int32;
+	typedef unsigned int	uint32;
 	typedef unsigned short	uint16;
-	typedef std::string			String;
+	typedef std::string		String;
 
 	//	Vertex Info.
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/leaf.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/leaf.h	(revision 1019)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/leaf.h	(revision 1526)
@@ -5,5 +5,5 @@
 {
 	public :
-    	int  vertsLeaf[4];// Array of pointers to vertices
+    	int  vertsLeaf[4]; // the four indices of the leaf
 		float  normal[3];
 		float  parentLeafCount;
@@ -30,5 +30,5 @@
 		Leaf (void); // default constructor
 		Leaf (const Leaf&); // Copy constructor
-		virtual ~Leaf (void); // Destructor
+//		virtual ~Leaf (void); // Destructor
 
 		float Distance (Leaf&);
@@ -36,3 +36,17 @@
 };
 
+// this class is used by the lodtreelibrary to represent a leaf
+class RuntimeLeaf
+{
+public:
+	RuntimeLeaf(void);
+	RuntimeLeaf (const RuntimeLeaf&); // Copy constructor
+
+   	int vertsLeaf[4]; // the four indices of the leaf
+	int childLeft;
+	int childRight;
+	int parent;
+	int root;
+};
+
 #endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/VertexData.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/VertexData.h	(revision 1325)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/VertexData.h	(revision 1526)
@@ -4,117 +4,21 @@
 namespace Geometry
 {
-	class VertexData
-	{
-	private:
-		unsigned int numverts;
-	public:
-		VertexData(unsigned int numv):numverts(numv){}
-		virtual ~VertexData(void){}
-
-		virtual void Begin(void)=0;
-		virtual void SetVertexCoord(unsigned int i, float x, float y, float z)=0;
-		virtual void SetVertexNormal(unsigned int i, float x, float y, float z)=0;
-		virtual void SetVertexTexCoord(unsigned int i, float x, float y)=0;
-		virtual void End(void)=0;	
-
-		virtual void GetVertexCoord(unsigned int i, float &x, float &y, float &z) const = 0;
-		virtual void GetVertexNormal(unsigned int i, float &x, float &y, float &z) const = 0;
-		virtual void GetVertexTexCoord(unsigned int i, float &x, float &y) const =0;
-
-		unsigned int GetNumVertices(void) const { return numverts; }
-	};
-
 	class IndexData
 	{
 	private:
-		unsigned int numinds, numvalidinds;
-		unsigned int current_submesh;
 	public:
-		IndexData(unsigned int numi):numinds(numi),numvalidinds(numi){ current_submesh=0; }
+		IndexData(void){}
 		virtual ~IndexData(void){}
 
-		virtual void Begin(void)=0;
+		virtual void Begin(unsigned int submesh, unsigned int numinds)=0;
 		virtual void SetIndex(unsigned int i, unsigned int index)=0;
 		virtual void End(void)=0;
 
-		virtual unsigned int GetIndex(unsigned int) const =0;
-		unsigned int GetNumMaxIndices(void) const { return numinds; }
-		unsigned int GetNumValidIndices(void) const { return numvalidinds; }
-		void SetNumValidIndices(unsigned int valid){ numvalidinds=valid; } // this should not be called from client applications
-		void SetCurrentSubmesh(unsigned int c){ current_submesh=c; }  // this should not be called from client applications
-		unsigned int GetCurrentSubmesh(void) const { return current_submesh; }
+		virtual void BorrowIndexData(const IndexData *)=0; // tells the application to use this IndexData. If the app must use its own IndexData the param will be NULL
 	};
 
-/*	class MultiIndexData
-	{
-	private:
-		unsigned int num_prims, num_total_inds, *num_max_inds, *num_valid_inds;
-	public:
-		MultiIndexData(unsigned int numprims, unsigned int *maxinds){
-			num_prims=numprims;
-			num_total_inds=0;
-			num_max_inds=new unsigned int[numprims];
-			num_valid_inds=new unsigned int[numprims];
-			for (unsigned int i=0; i<numprims; i++)
-			{
-				num_max_inds[i]=num_valid_inds[i]=maxinds[i];
-				num_total_inds += maxinds[i];
-			}
-		}
 
-		~MultiIndexData(void){
-			delete[] num_max_inds;
-			delete[] num_valid_inds;
-		}
-
-		virtual void Begin(void)=0;
-		virtual void SetIndex(unsigned int iprim, unsigned int i, unsigned int index)=0;
-		virtual void End(void)=0;
-
-		virtual unsigned int GetIndex(unsigned int iprim, unsigned int index) const =0;
-		unsigned int GetNumMaxIndices(unsigned int iprim) const { return num_max_inds[iprim]; }
-		unsigned int GetNumValidIndices(unsigned int iprim) const { return num_valid_inds[iprim]; }
-		void SetNumValidIndices(unsigned int iprim, unsigned int valid){ num_valid_inds[iprim]=valid; }
-		unsigned int GetNumPrims(void) const { return num_prims; }
-	};*/
-
-	typedef VertexData* CreateVertexDataFunc(unsigned int numv);
-	typedef CreateVertexDataFunc* CREATEVERTEXDATAFUNC;
-	typedef IndexData* CreateIndexDataFunc(unsigned int numi);
+/*	typedef IndexData* CreateIndexDataFunc(unsigned int numi);
 	typedef CreateIndexDataFunc* CREATEINDEXDATAFUNC;
-/*	typedef MultiIndexData* CreateMultiIndexDataFunc(unsigned int numprims, unsigned int *numi);
-	typedef CreateMultiIndexDataFunc* CREATEMULTIINDEXDATAFUNC;*/
-
-	class DefaultVertexData : public VertexData
-	{
-	private:
-		float *v, *n, *t;
-	public:
-		DefaultVertexData(unsigned int numv);
-		~DefaultVertexData(void);
-
-		virtual void Begin(void){}
-		virtual void SetVertexCoord(unsigned int i, float x, float y, float z){ 
-			v[i*3+0]=x; v[i*3+1]=y; v[i*3+2]=z; }
-		virtual void SetVertexNormal(unsigned int i, float x, float y, float z){
-			n[i*3+0]=x; n[i*3+1]=y; n[i*3+2]=z; }
-		virtual void SetVertexTexCoord(unsigned int i, float x, float y){ 
-			t[i*2+0]=x; t[i*2+1]=y; }
-
-		virtual void End(void){}
-
-		virtual void GetVertexCoord(unsigned int i, float &x, float &y, float &z) const { 
-			x=v[i*3+0]; 
-			y=v[i*3+1]; 
-			z=v[i*3+2];
-		}
-		virtual void GetVertexNormal(unsigned int i, float &x, float &y, float &z) const {x=n[i*3+0]; y=n[i*3+1]; z=n[i*3+2]; }
-		virtual void GetVertexTexCoord(unsigned int i, float &x, float &y) const {x=t[i*2+0]; y=t[i*2+1]; }
-
-		const float * GetVertexFloatBuffer(void) const { return v; }
-
-	};
-	VertexData *DefaultVertexDataCreator(unsigned int numv);
-
 
 	class DefaultIndexData : public IndexData
@@ -123,8 +27,9 @@
 		unsigned int *indices;
 	public:
-		DefaultIndexData(unsigned int numi);
+		DefaultIndexData(void){ indices=0; }
 		~DefaultIndexData(void);
 
-		virtual void Begin(void){}
+		virtual void Init(unsigned int);
+		virtual void Begin(unsigned int submesh, unsigned int numinds){}
 		virtual void SetIndex(unsigned int i, unsigned int index){ 
 			indices[i] = index; 
@@ -135,29 +40,7 @@
 			return indices[i];
 		}
-
+		virtual void BorrowIndexData(const IndexData *){}
 	};
-	IndexData *DefaultIndexDataCreator(unsigned int numi);
-
-/*	class DefaultMultiIndexData : public MultiIndexData
-	{
-	private:
-		unsigned int **indices;
-	public:
-		DefaultMultiIndexData(unsigned int numprims, unsigned int *numi);
-		~DefaultMultiIndexData(void);
-
-		virtual void Begin(void){}
-		virtual void SetIndex(unsigned int iprim, unsigned int i, unsigned int index){ 
-			indices[iprim][i] = index; 
-		}
-		virtual void End(void){}
-
-		virtual unsigned int GetIndex(unsigned int iprim, unsigned int i) const {
-			return indices[iprim][i];
-		}
-
-	};
-	MultiIndexData *DefaultMultiIndexDataCreator(unsigned int numprims, unsigned int *numi);
-*/
+	IndexData *DefaultIndexDataCreator(unsigned int numi);*/
 }
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 1007)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSimpSequence.h	(revision 1526)
@@ -28,4 +28,14 @@
 	\n
 	*/
+
+	//	Vertex info.
+	struct	GeoVertex
+	{
+		Index	id;
+		Index	bonefrom;
+		Vector3	position;
+		Vector2 texcoord;
+		Vector3 normal;
+	};
 
 	class MeshSimplificationSequence: public Serializable
@@ -60,6 +70,9 @@
 				//	Indicates the the step is obligatory to execute
 				//	joined width the following step.
-				unsigned int obligatorio;
+				unsigned int obligatory;
 			};
+
+			//	Vertices added in simplification.
+			std::vector<GeoVertex>	mNewVertices;
 
 			// Name of mesh.
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h	(revision 1090)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h	(revision 1526)
@@ -20,17 +20,8 @@
 	{
 	public:
-/*		LodTreeLibrary( const LodTreeLibrary &);
-		LodTreeLibrary(LodTreeLibrary*);*/
 		LodTreeLibrary(	const LodStripsLibraryData *,
 						const TreeSimplificationSequence *,
-						Geometry::Mesh *treeGeoMesh/*,
-						uint32 leafSubMeshID
-						/*std::string foliage_verts,
-						std::string foliage_leafs,
-						std::string foliage_simpl/*,
-						uint32 leafSubMeshID,
-						CREATEVERTEXDATAFUNC vdfun=NULL, 
-						CREATEINDEXDATAFUNC idfun=NULL,
-						CREATEMULTIINDEXDATAFUNC midfun=NULL*/); // throws a FileNotFound exception
+						Geometry::Mesh *treeGeoMesh,
+						Geometry::IndexData *user_indexdata);
 		~LodTreeLibrary(void);
 
@@ -48,4 +39,6 @@
 		// changes the lod of the entire object (trunk and leaves)
 		virtual void GoToLod(Real);
+		virtual Real GetCurrentLodFactor(void) const { return (currentFoliageLodFactor+trunk->GetCurrentLodFactor())*0.5f; }
+		virtual Geometry::IndexData * GetIndexDataInterface(void){ return dataRetrievalInterface; }
 
 		// new proposed functions
@@ -71,4 +64,7 @@
 		Geometry::LodStripsLibrary *trunk;
 		uint32 mLeavesSubMesh;
+		IndexData *dataRetrievalInterface;
+		bool delete_indexdata;
+		float currentFoliageLodFactor;
 	};
 }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/auxiliar.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/auxiliar.h	(revision 993)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/auxiliar.h	(revision 1526)
@@ -24,5 +24,5 @@
 {
 	uint32	strip;
-	char		nP,nL1,nL2,obligatory;
+	char	nP,nL1,nL2,obligatory;
 } LODData;
 #pragma pack()
@@ -37,5 +37,5 @@
 	float Normal[3];
 	float TexCoords[2];
-	unsigned int obligatorio;
+	unsigned int obligatory;
 	int numMesh;
 	uint32 Next;
@@ -55,5 +55,5 @@
 	uint32				vLSNext;
 	uint32				vLS;
-	unsigned int	obligatorio;
+	unsigned int	obligatory;
 	float					x;
 	char					*cambio;
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsConstructor.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsConstructor.h	(revision 1078)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsConstructor.h	(revision 1526)
@@ -124,5 +124,8 @@
 			//	Sort submesh bones.
 			void	sortBones();
-			
+
+			//	Add new vertices to mesh.
+			void AddNewVertices();
+	
 		public:
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 1325)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 1526)
@@ -15,8 +15,8 @@
 
 //-----------------------------------------------------------------------------
-//	Constructors.
-//-----------------------------------------------------------------------------
-LodStripsLibrary::LodStripsLibrary(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh, CREATEINDEXDATAFUNC idfun)
-:create_index_data_func(idfun?idfun:DefaultIndexDataCreator)
+//	Constructor.
+//-----------------------------------------------------------------------------
+LodStripsLibrary::LodStripsLibrary(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh, IndexData *userindexdata)
+//:dataRetrievalInterface(idfun?idfun:DefaultIndexDataCreator)
 {
 //	const	char	*name_of_file;
@@ -31,8 +31,13 @@
 	mGeoMesh = geomesh;
 
-	dataRetrievalInterface=NULL;
+	delete_indexdata=false;
+	dataRetrievalInterface=userindexdata;
+	
 	indices_x_submesh = NULL;
 	offsets_x_submesh = NULL;
 	mStripsSubmesh = NULL;
+	submesh_x_strip = NULL;
+	lodFactor=1.0f;
+	current_triangle_count=0;
 	
 	//	Loads the Level Of Detail file.
@@ -51,10 +56,10 @@
 
 //-----------------------------------------------------------------------------
-//	Destroyer.
+//	Destructor
 //-----------------------------------------------------------------------------
 LodStripsLibrary::~LodStripsLibrary()
 {
 	delete	[] mStrips;
-	if (dataRetrievalInterface)
+	if (delete_indexdata)
 		delete dataRetrievalInterface;
 	if (indices_x_submesh)
@@ -64,4 +69,6 @@
 	if (mStripsSubmesh)
 		delete[] mStripsSubmesh;
+	if (submesh_x_strip)
+		delete[] submesh_x_strip;
 }
 
@@ -75,26 +82,28 @@
 void LodStripsLibrary::GoToLod(float lodfactor)
 {
-	register	int							j;
-	register	int							offset;
-	long			int							i;
-	long			int							k;
-	long			int							b_change_ok	=	1;
-	unsigned long	int					lod;
-	long			int							t;
-	long			int							r;
-	long			int							next;
-	long			int							el1;
-	long			int							el2;
-	long			int							total_changes;
-	long			int							totalR;
-	SmallIntVector						*strip;
+	register	int				j;
+	register	int				offset;
+	long			int			i;
+	long			int			k;
+	long			int			b_change_ok	=	1;
+	unsigned long	int			lod;
+	long			int			t;
+	long			int			r;
+	long			int			next;
+	long			int			el1;
+	long			int			el2;
+	long			int			total_changes;
+	long			int			totalR;
+	SmallIntVector				*strip;
 	SmallIntVector::iterator	start;
-	uint32										return_value;
+
+	if (lodfactor<0.0f) lodfactor=0.0f;
+	if (lodfactor>1.0f) lodfactor=1.0f;
 
 	uint32 newLOD = (uint32)((1.0f - lodfactor) * mLods);
+
+	lodFactor=lodfactor;
+	LODRegisterType * lastLOD = mCurrentRegLOD;
     
-	//	Initialize the return value to the current LOD.
-	return_value	=	mCurrentLod;
-
 	if (newLOD != mCurrentLod)
 	{
@@ -103,7 +112,7 @@
 			//	Forwards.
 			//	Increments LOD.
-			for (lod = mCurrentLod; lod < newLOD; lod++)
-			{
-				next						=	mVertex[lod];
+			for (lod = mCurrentLod; lod < newLOD || lastLOD->obligatory==1; lod++)
+			{
+				next			=	mVertex[lod];
 				total_changes	=	mPChanges[lod];
 
@@ -111,7 +120,8 @@
 				{
 					//	Strip change.
-					t			=	mCurrentRegLOD->strip; 
+					t		=	mCurrentRegLOD->strip; 
 					strip	=	&(mStrips[t]);
 					start	=	strip->begin();				
+					int stripsize_ini = strip->size();
 				
 					//	Position.
@@ -120,6 +130,5 @@
 					for (j = totalR - 1; j >= 0; j--)
 					{
-						start[*mCurrentData]	=	next;
-						
+						start[*mCurrentData]	=	next;						
 						++mCurrentData;
 					}
@@ -160,7 +169,11 @@
 					}
 
+					lastLOD = mCurrentRegLOD;
 					mCurrentRegLOD++;
 					
 					mStripsChanges[t]	=	1;
+
+					int stripsize_end = strip->size();
+					indices_x_submesh[submesh_x_strip[t]] -= (stripsize_ini - stripsize_end);
 				
 				}
@@ -177,5 +190,5 @@
 			
 			//	Decrements LOD.
-			for (lod = mCurrentLod; lod > newLOD; lod--)
+			for (lod = mCurrentLod; lod > newLOD || lastLOD->obligatory==1; lod--)
 			{
 				total_changes	=	mPChanges[lod - 1];
@@ -186,4 +199,5 @@
 					strip	=	&(mStrips[t]);
 					start	=	mStrips[t].begin();
+					int stripsize_ini = strip->size();
 
 					//	L2.
@@ -232,9 +246,14 @@
 					}
 					
+					lastLOD = mCurrentRegLOD;
 					mCurrentRegLOD--;
 					mStripsChanges[t]	=	1;
+
+					int stripsize_end = strip->size();
+					indices_x_submesh[submesh_x_strip[t]] += (stripsize_end - stripsize_ini);
+
 				}			
 				
-				//	Update LOD.
+				//	Update LOD.				
 				mCurrentLod	=	lod - 1;
 			}
@@ -359,5 +378,5 @@
 //	Copy a STL vector to a C array.
 //-----------------------------------------------------------------------------
-void LodStripsLibrary::CopyVectors2Arrays()
+void LodStripsLibrary::CopyVectors2Arrays(void)
 {
 	SmallInt 					max;
@@ -400,6 +419,10 @@
 	//	Copy strips.
 //	unsigned int numDegenerated = 2*mTotalStrips - 2;
-	dataRetrievalInterface=create_index_data_func(total_strip_size/*+numDegenerated*/); // temporal!
-	dataRetrievalInterface->Begin();
+//	dataRetrievalInterface=create_index_data_func(total_strip_size,indexdata_user_data); // temporal!
+
+//	dataRetrievalInterface->Init(total_strip_size);
+/*	dataRetrievalInterface->numinds=total_strip_size;
+	dataRetrievalInterface->numvalidinds=total_strip_size;*/
+//	dataRetrievalInterface->Begin();
 
 	unsigned	int	ii = 0;
@@ -410,5 +433,5 @@
 		{
 			mStrips[i].push_back(mFileStrips[i][j]);
-			dataRetrievalInterface->SetIndex(ii,mFileStrips[i][j]);
+//			dataRetrievalInterface->SetIndex(ii,mFileStrips[i][j]);
 		}
 		
@@ -416,5 +439,5 @@
 		mStripsChanges[i]	=	0;
 	}
-	dataRetrievalInterface->End();
+//	dataRetrievalInterface->End();
 
 	for (unsigned	int	i = 0; i < mData.size(); i++)
@@ -459,12 +482,23 @@
 	indices_x_submesh = new int[geomesh->mSubMeshCount];
 	offsets_x_submesh = new int[geomesh->mSubMeshCount];
+
+	int totaltiras = 0;
+	for (unsigned int submesh = 0; submesh < geomesh->mSubMeshCount; submesh++)
+		for (unsigned int strip = 0; strip < geomesh->mSubMesh[submesh].mStripCount; strip++)
+			totaltiras++;
+
+	submesh_x_strip = new int[totaltiras];
+
+	int istrip = 0;
 	for (unsigned int submesh	=	0; submesh < geomesh->mSubMeshCount; submesh++)
 	{
 		geoSubMesh	=	&geomesh->mSubMesh[submesh];
+		indices_x_submesh[submesh] = 0;
 
 		//	For each one of the strips.
-		for (unsigned int strip = 0; strip < geoSubMesh->mStripCount; strip++)
+		for (unsigned int strip = 0; strip < geoSubMesh->mStripCount; strip++, istrip++)
 		{
 			// Insert an empty strip.
+			submesh_x_strip[istrip] = submesh;
 			t++;
 			strip_aux.clear();
@@ -499,5 +533,5 @@
 			int i;
 			i	= 0;
-			indices_x_submesh[submesh] = 0;
+			
 			if (submesh==0)
 				offsets_x_submesh[submesh] = 0;
@@ -592,7 +626,5 @@
 	
 	for (unsigned int i = 0; i < mLods; i++)
-	{
 		mPChanges[i] = p_changes[i];
-	}
 
 	mTotalVertices		=	int(mFileVertices.size());
@@ -603,5 +635,4 @@
 	//Copy the data to the structure we will use
 	CopyVectors2Arrays();
-//	}
 }
 
@@ -610,11 +641,12 @@
 	unsigned	int	ii	=	0;
 	
-	dataRetrievalInterface->Begin();
-
 	int	counter	= 0;
 	int	target_submesh	= 0;
 	size_t	strip_count	= 0;
-
-	dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
+	unsigned int ii_submesh = 0;
+
+	dataRetrievalInterface->Begin(target_submesh, indices_x_submesh[target_submesh]);
+
+//	dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
 
 	for (unsigned	int	i	=	0;	i < mTotalStrips;	i++,	strip_count++)
@@ -622,5 +654,5 @@
 		if (strip_count >= mGeoMesh->mSubMesh[target_submesh].mStripCount)
 		{
-			indices_x_submesh[target_submesh] = counter;
+//			indices_x_submesh[target_submesh] = counter;
 
 			if (target_submesh==0)
@@ -634,9 +666,12 @@
 
 			target_submesh++;
-			dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
+			ii_submesh = 0;
+//			dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
+			dataRetrievalInterface->End();
+			dataRetrievalInterface->Begin(target_submesh, indices_x_submesh[target_submesh]);
 		}
 		
 		int lastindex = -1;
-		for (SmallIntVector::iterator it=mStrips[i].begin(); it!=mStrips[i].end(); it++, ii++)
+		for (SmallIntVector::iterator it=mStrips[i].begin(); it!=mStrips[i].end(); it++, ii++, ii_submesh++)
 		{
 /*			// repeat the first index of the strip: degenerate
@@ -649,5 +684,5 @@
 			}*/
 			lastindex=*it;
-			dataRetrievalInterface->SetIndex(ii,*it);
+			dataRetrievalInterface->SetIndex(ii_submesh,*it);
 			counter++;
 		}
@@ -658,10 +693,10 @@
 		ii++;*/
 
-		dataRetrievalInterface->SetNumValidIndices(ii);
+//		dataRetrievalInterface->SetNumValidIndices(ii);
 	}
 
 	if (strip_count >= mGeoMesh->mSubMesh[target_submesh].mStripCount)
 	{
-		indices_x_submesh[target_submesh] = counter;
+//		indices_x_submesh[target_submesh] = counter;
 		if (target_submesh==0)
 			offsets_x_submesh[target_submesh] = 0;
@@ -673,5 +708,5 @@
 		strip_count = 0;
 		target_submesh++;
-		dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
+//		dataRetrievalInterface->SetCurrentSubmesh(target_submesh);
 	}
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp	(revision 1309)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp	(revision 1526)
@@ -12,81 +12,375 @@
 #include "GeoLodManager.h"
 #include "GeoLodObject.h"
-#include <algorithm>
-/*
+#include "VertexData.h"
+#include <ntls.h>
+#include <map>
+
+using namespace Geometry;
+
+//#define MINIMUM_VALID_LOD_SIMILARITY 0.1f
+
+
 namespace Geometry
 {
-
-
-	class lodobj_idpos_node_t
+	class lodobj_node_t : public Moveable<lodobj_node_t>
 	{
 	public:
-		lodobj_idpos_node_t(LodObject *o):lodobj(o),must_recalculate_distance(true),dist2cam(0.0f){}
+		lodobj_node_t(const std::string &nam, float dist, LodObject *o):dist2cam(dist),lodobj(o),name(nam){ must_recalculate_distance=false; to_update=0; master=NULL; lodfactor=o->GetCurrentLodFactor(); precalpos=-1; }
+		lodobj_node_t(const lodobj_node_t &n){ operator=(n); }
+		float dist2cam;
 		LodObject *lodobj;
-		float dist2cam; // used to index the lodobj in the other map
-		bool operator < (const lodobj_idpos_node_t &o) const { return (lodobj->GetUniqueID()<o.lodobj->GetUniqueID()); }
+		bool must_recalculate_distance;
+		uint32 to_update;
+		bool operator < (const lodobj_node_t &o) const { return (dist2cam < o.dist2cam); }
+		void operator = (const lodobj_node_t &n){ dist2cam=n.dist2cam; lodobj=n.lodobj; must_recalculate_distance=n.must_recalculate_distance; master=n.master; lodfactor=n.lodfactor; precalpos=-1; name=n.name; }
+
+		lodobj_node_t * master;
+		VectorMap<uint32,lodobj_node_t*> disciples;
+		float lodfactor; // virtual lod factor (the lodfactor it seems, not its real internal lodfactor)
+		int precalpos;
+		std::string name;
 	};
-}*/
-
-using namespace Geometry;
-
-LodManager::LodManager(float near, float far, const Geometry::Vector3 &campos)
-:targetFPS(30),camera_changed(true),camera_pos(campos),
- near_range(near),far_range(far)
-{
-	// make the lodobj_dists vector into a heap
-	make_heap(lodobj_dists.begin(),lodobj_dists.end());
-}
-
-void Geometry::LodManager::AddLodObj(LodObject * o, const Geometry::Vector3 &p)
-{
-	float dist = CalculateDistToCamera(p);
-	lodobj_dists.push_back(lodobj_dist_node_t(dist,o));
-	push_heap(lodobj_dists.begin(),lodobj_dists.end());
-//	lodobj_dists[dist] = lodobj_dist_node_t(o);
+
+	class NodeContainer
+	{
+	public:
+		Vector<lodobj_node_t> lodobj_dists;
+		std::map<uint32,Geometry::Vector3> lodobj_pos; // map key: LodObject UniqueID for efficient ID-based finding
+		Vector3 camera_pos;
+
+		int num_lod_sim;
+
+		NodeContainer(const Geometry::Vector3 &campos)
+			:camera_pos(campos){
+		}
+
+		~NodeContainer(void){
+			for (VectorMap<std::string,lodobj_node_t**>::Iterator it = precalculated_lods.Begin(); 
+																  it != precalculated_lods.End(); it ++)
+			{
+				lodobj_node_t **nodes = *it;
+				delete[] nodes;
+			}
+		}
+
+		void RecalculateDist(lodobj_node_t & node){
+			std::map<uint32,Vector3>::iterator posit = lodobj_pos.find(node.lodobj->GetUniqueID());
+			assert(posit!=lodobj_pos.end());
+			const Vector3 & pos = posit->second;
+
+			node.dist2cam = CalculateDistToCamera(pos);
+		}
+
+		float CalculateDistToCamera(const Geometry::Vector3 &p) const
+		{
+			Geometry::Vector3 v = camera_pos - p;
+			float distquad = v.length();
+			return distquad;
+		}
+
+		lodobj_node_t * & GetPrecalculatedLOD(const std::string &name, int ipos){
+			int foundpos = precalculated_lods.Find(name);
+			if (foundpos==-1)
+			{
+				lodobj_node_t **new_precalculated_lods=new lodobj_node_t*[num_lod_sim+1]; // +1 is done to include the highest lod (1.0)
+				for (int i=0; i<num_lod_sim+1; i++)
+					new_precalculated_lods[i]=NULL;
+				precalculated_lods.Add(name) = new_precalculated_lods;
+				return new_precalculated_lods[ipos];
+			}
+			else
+			{
+				return precalculated_lods[foundpos][ipos];
+			}
+		}
+
+		uint32 lod2precalpos(Real lodfactor){ 
+			return (uint32)(num_lod_sim*lodfactor); 
+		}
+
+	private:
+		// the following is an array of precalculated lods
+		// for 10 precalculated lods each element is in order [0.1, 0.2, 0.3, 0.4, 0.5, ...]
+		// for 100 precalculated lods each element is in order [0.01, 0.02, 0.03, 0.04, 0.05, ...]
+		// the funcion lod2precalpos translates a LOD factor to a position in the array
+		VectorMap<std::string,lodobj_node_t**> precalculated_lods;
+
+	};
+}
+
+LodManager::LodManager(Real near, Real far, const Geometry::Vector3 &campos, int numslots)
+:lasttime(0),camera_changed(true),node_added(false),
+ near_range(near),far_range(far),
+ always_calculate_lod(false),force_highest_lod(false)
+{
+	lodobj_container=new NodeContainer(campos);
+	lodobj_container->num_lod_sim = numslots;
+}
+
+LodManager::~LodManager(void)
+{
+	delete lodobj_container;
+//	delete[] precalculated_lods;
+}
+
+void Geometry::LodManager::AddLodObj(const std::string &name, LodObject * o, const Geometry::Vector3 &p)
+{
+	float dist = lodobj_container->CalculateDistToCamera(p);
+	lodobj_node_t auxnode(name,dist,o);
+	
+	lodobj_container->lodobj_dists.Add(auxnode);
+	Sort(lodobj_container->lodobj_dists);
+
 	UpdateLODObjectPos(o,p);
-}
-
-
-void Geometry::LodManager::UpdateLOD(void)
-{
-	if (!lodobj_dists.empty())
+	node_added=true;
+}
+
+
+void Geometry::LodManager::UpdateLOD(uint32 currFPS, uint32 targetFPS)
+{
+	if (!lodobj_container->lodobj_dists.IsEmpty())
 	{
 		// update distances to the camera
-		bool must_resort = false;
-		for (std::vector<lodobj_dist_node_t>::iterator it=lodobj_dists.begin(); it!=lodobj_dists.end(); it++)
-		{			
-			lodobj_dist_node_t & node = *it;
-			if (camera_changed || node.must_recalculate_distance)
-			{
-				RecalculateDist(node);
-				must_resort=true;
-			}
-		}
-		if (must_resort)
-			sort_heap(lodobj_dists.begin(),lodobj_dists.end());
-
-		// select a tree to change its LOD
-	//	float random_dist = SelectRandomDistance();
-	//	std::map<float,Geometry::lodobj_dist_node_t>::iterator nearest = lodobj_dists.upper_bound(random_dist);
-
-		// the begining of the list is the greater element (greater dist)		
-		lodobj_dist_node_t & node = lodobj_dists.front();
+		if (camera_changed || node_added)
+		{
+			bool must_resort = false;
+			for (Vector<lodobj_node_t>::Iterator it=lodobj_container->lodobj_dists.Begin(); 
+												 it!=lodobj_container->lodobj_dists.End(); 
+												 it++)
+			{			
+				lodobj_node_t & node = *it;
+				if (node.must_recalculate_distance || camera_changed || node_added)
+				{
+					lodobj_container->RecalculateDist(node);
+					must_resort=true;
+				}
+			}
+/*			if (must_resort)
+				Sort(lodobj_container->lodobj_dists);*/
+		}
+
+		// the end of the list is the greater element (greater dist)	
+/*		if (currFPS < targetFPS - 5)
+		{
+			Vector<lodobj_node_t>::Iterator selnode;
+			for (selnode=lodobj_container->lodobj_dists.End()-1; selnode!=lodobj_container->lodobj_dists.Begin()-1; selnode--)
+			{			
+			// NO HAY QUE USAR CURRENT LOD FACTOR SINO lodobj_container->lodobj_lodfactor
+				if (selnode->lodobj->GetCurrentLodFactor()>0.00001f)
+				{
+					if (selnode->to_update==0)
+						break;
+					else
+						selnode->to_update--;
+				}
+			}
+
+			if (selnode!=lodobj_container->lodobj_dists.Begin()-1)
+			{
+				// EL DECREMENTO O EL NUMERO DE DECREMENTOS TIENE QUE VENIR EN FUNCION DE LA DIFERENCIA DE FPS
+				// NO HAY QUE USAR CURRENT LOD FACTOR SINO lodobj_container->lodobj_lodfactor
+				selnode->lodobj->GoToLod(selnode->lodobj->GetCurrentLodFactor()-0.02f); 
+				selnode->to_update=10; // ESTO DEBE ASIGNARSE BASADO EN LA DISTANCIA A LA CAMARA!
+			}
+		}
+		if (currFPS > targetFPS + 5)
+		{
+			Vector<lodobj_node_t>::Iterator selnode;
+			for (selnode=lodobj_container->lodobj_dists.Begin(); selnode!=lodobj_container->lodobj_dists.End(); selnode++)
+			{			
+			// NO HAY QUE USAR CURRENT LOD FACTOR SINO lodobj_container->lodobj_lodfactor
+				if (selnode->lodobj->GetCurrentLodFactor()<0.99999f)
+				{
+					if (selnode->to_update==0)
+						break;
+					else
+						selnode->to_update--;
+				}
+			}
+
+			if (selnode!=lodobj_container->lodobj_dists.End())
+			{
+			// NO HAY QUE USAR CURRENT LOD FACTOR SINO lodobj_container->lodobj_lodfactor
+				selnode->lodobj->GoToLod(selnode->lodobj->GetCurrentLodFactor()+0.02f);
+				selnode->to_update=10; // ESTO DEBE ASIGNARSE BASADO EN LA DISTANCIA A LA CAMARA!
+			}
+		}*/
+
+		if (camera_changed)
+		{
+			// por ahora solo sacar el lod basado en la camara
+			for (Vector<lodobj_node_t>::Iterator it = lodobj_container->lodobj_dists.Begin(); 
+												 it != lodobj_container->lodobj_dists.End();  it ++)
+			{
+				float lodfactor = - ((it->dist2cam - near_range) / (far_range - near_range));
+				if (lodfactor < 0.0f)
+					lodfactor = 0.0f;
+				if (lodfactor > 1.0f)
+					lodfactor = 1.0f;
+
+				if (force_highest_lod)
+					lodfactor = 1.0f;
+
+				ChangeLOD(it,lodfactor);
+			}
+		}							   
 	}
 	camera_changed=false;
-}
-
-void Geometry::LodManager::RecalculateDist(lodobj_dist_node_t & node)
-{
-	std::map<uint32,Vector3>::iterator posit = lodobj_pos.find(node.lodobj->GetUniqueID());
-	assert(posit!=lodobj_pos.end());
-	const Vector3 & pos = posit->second;
-
-	node.dist2cam = CalculateDistToCamera(pos);
-}
-
+	node_added=false;
+}
+
+void Geometry::LodManager::ChangeLOD(lodobj_node_t *lodobjnode, Real lodfactor)
+{
+	LodObject *lodobj = lodobjnode->lodobj;
+
+	if (always_calculate_lod)
+	{
+		lodobj->GoToLod(lodfactor);
+		return;
+	}
+	
+	// if the lodfactor is exactly 1.0 its level of detail must be always regenerated (for closeups)
+	if (lodfactor<1.0f)
+	{
+		// if the desired lod is very similar to the previous one,
+		// then there is no need to change the level of detail at all
+//		float sim = fabsf(lodfactor - lodobjnode->lodfactor);
+//		if (sim <= MINIMUM_VALID_LOD_SIMILARITY)
+//			return; // do not change anything if the lod is very similar!
+		int desiredpos = lodobj_container->lod2precalpos(lodfactor);
+		int mypos = lodobj_container->lod2precalpos(lodobjnode->lodfactor);
+		if (mypos==desiredpos)
+			return;
+	}
+
+	lodobj_node_t *found_node = FindMostSimilarRealLOD(lodobjnode->name,lodfactor);
+
+	if (found_node && found_node->lodobj->GetUniqueID()!=lodobj->GetUniqueID())
+	{
+		// DEBUG
+		assert(found_node->master==NULL);
+
+//		float sim = fabsf(lodfactor - found_node->lodfactor);
+//		if (sim <= MINIMUM_VALID_LOD_SIMILARITY)
+		int desiredpos = lodobj_container->lod2precalpos(lodfactor);
+		int foundpos = lodobj_container->lod2precalpos(found_node->lodfactor);
+		if (foundpos==desiredpos)
+		{
+			lodobj->GetIndexDataInterface()->BorrowIndexData(found_node->lodobj->GetIndexDataInterface());
+			MakeDiscipleOf(found_node,lodobjnode);
+		}
+		else
+			ReallyGoToLOD(lodobjnode,lodfactor);
+	}
+	else
+		ReallyGoToLOD(lodobjnode,lodfactor);
+
+	lodobjnode->lodfactor = lodfactor;
+}
+
+void Geometry::LodManager::DeleteMeFromMyMastersDiscipleList(lodobj_node_t *lodobjnode)
+{
+	// if I have a master...
+	if (lodobjnode->master)
+		lodobjnode->master->disciples.RemoveKey(lodobjnode->lodobj->GetUniqueID());	
+}
+
+
+void Geometry::LodManager::MakeIndependent(lodobj_node_t *lodobjnode)
+{
+	DeleteMeFromMyMastersDiscipleList(lodobjnode);
+
+	// next, delete my master
+	lodobjnode->master=NULL;
+}
+
+void Geometry::LodManager::MakeDiscipleOf(lodobj_node_t *master_node, lodobj_node_t *disciple_node)
+{
+	ChangeMaster(disciple_node, master_node);
+
+	// delete my disciples
+	disciple_node->disciples.Clear();
+
+	// first remove me from my master's disciple list
+	DeleteMeFromMyMastersDiscipleList(disciple_node);
+
+	master_node->disciples.GetAdd(disciple_node->lodobj->GetUniqueID()) = disciple_node;
+
+	// set master
+	disciple_node->master = master_node;
+
+	// no one must take me as a master!
+	if (disciple_node->precalpos!=-1)
+	{		
+//		lodobj_container->precalculated_lods[disciple_node->precalpos] = NULL;
+		lodobj_container->GetPrecalculatedLOD(master_node->name,disciple_node->precalpos) = NULL;
+		disciple_node->precalpos = -1;
+	}
+}
+
+void Geometry::LodManager::ChangeMaster(lodobj_node_t *lodobj, lodobj_node_t *newmaster)
+{
+	// delete me from my disciples' master list
+	for (VectorMap<uint32,lodobj_node_t*>::Iterator it = lodobj->disciples.Begin(); it != lodobj->disciples.End(); it++)
+	{
+		lodobj_node_t * auxnode = *it;
+		assert(auxnode->master->lodobj->GetUniqueID() == lodobj->lodobj->GetUniqueID());
+//		auxnode->master = NULL;
+		// chanbge the master to the new one
+		auxnode->master = newmaster;
+
+		// add the new disciple to the new master
+		if (newmaster)
+			newmaster->disciples.GetAdd(auxnode->lodobj->GetUniqueID()) = auxnode;
+	}	
+}
+
+
+void Geometry::LodManager::UpdateDisciples(lodobj_node_t *master_node)
+{
+	for (VectorMap<uint32,lodobj_node_t*>::Iterator it= master_node->disciples.Begin(); it!= master_node->disciples.End(); it++)
+	{
+		lodobj_node_t *disciple_node = *it;
+		disciple_node->lodobj->GetIndexDataInterface()->BorrowIndexData(master_node->lodobj->GetIndexDataInterface());
+		disciple_node->lodfactor = master_node->lodobj->GetCurrentLodFactor(); // we can use currentlodfactor here because the master is supposed to be at its REAL level of detail
+	}
+}
+
+void Geometry::LodManager::ReallyGoToLOD(lodobj_node_t *lodobjnode, Real lodfactor)
+{
+	lodobjnode->lodobj->GoToLod(lodfactor);
+
+	MakeIndependent(lodobjnode);
+	UpdateDisciples(lodobjnode);
+
+	// store the precalculated lod in the table
+	int i = lodobj_container->lod2precalpos(lodfactor);
+
+	assert(i>=0 && i<=lodobj_container->num_lod_sim); // <= por lo del +1
+
+	if (lodobjnode->precalpos != -1)
+		//lodobj_container->precalculated_lods[lodobjnode->precalpos] = NULL;
+		lodobj_container->GetPrecalculatedLOD(lodobjnode->name,lodobjnode->precalpos) = NULL;
+
+//	lodobj_container->precalculated_lods[i] = lodobjnode;
+	lodobj_container->GetPrecalculatedLOD(lodobjnode->name,i) = lodobjnode;
+
+	lodobjnode->precalpos = i;
+}
+
+
+lodobj_node_t * Geometry::LodManager::FindMostSimilarRealLOD(const std::string &name, Real desired_lod)
+{
+	uint32 i = lodobj_container->lod2precalpos(desired_lod);
+	assert(i>=0 && i<=lodobj_container->num_lod_sim); // <= por lo del +1
+//	lodobj_node_t *obj = lodobj_container->precalculated_lods[i];
+	lodobj_node_t *obj = lodobj_container->GetPrecalculatedLOD(name,i);
+
+	return obj;
+}
 
 void Geometry::LodManager::UpdateCamera(const Geometry::Vector3 &p)
 {
-	camera_pos = p;
+	lodobj_container->camera_pos = p;
 	camera_changed = true;
 }
@@ -94,12 +388,7 @@
 void Geometry::LodManager::UpdateLODObjectPos(LodObject *o, const Geometry::Vector3 &p)
 {
-	lodobj_pos[o->GetUniqueID()] = p;
-}
-
-
-float Geometry::LodManager::CalculateDistToCamera(const Geometry::Vector3 &p) const
-{
-	return camera_pos.dotProduct(p);
-}
+	lodobj_container->lodobj_pos[o->GetUniqueID()] = p;
+}
+
 
 float Geometry::LodManager::SelectRandomDistance(void) const
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp	(revision 1083)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp	(revision 1526)
@@ -10,19 +10,27 @@
 // Parameters --> None
 //--------------------------------------------------------------------------------------------------------------------------------
-Foliage::Foliage(const Geometry::SubMesh *leavesSubMesh, const Geometry::TreeSimplificationSequence * simpSeq, Geometry::CREATEVERTEXDATAFUNC vdfun, Geometry::CREATEINDEXDATAFUNC idfun): 
+Foliage::Foliage(int leavessubmeshID, 
+				 const Geometry::SubMesh *leavesSubMesh, 
+				 const Geometry::TreeSimplificationSequence * simpSeq/*,
+				 Geometry::CREATEVERTEXDATAFUNC vdfun*/): 
 Acth(NULL),
-create_vertex_data_func(vdfun==NULL?Geometry::DefaultVertexDataCreator:vdfun),
-create_index_data_func(idfun==NULL?Geometry::DefaultIndexDataCreator:idfun),
-vertexdata(NULL), Leaves(NULL), MinDet(NULL)
+//create_vertex_data_func(vdfun==NULL?Geometry::DefaultVertexDataCreator:vdfun),
+//create_index_data_func(idfun==NULL?Geometry::DefaultIndexDataCreator:idfun),
+/*vertexdata(NULL),*/ Leaves(NULL), MinDet(NULL)
 {
 	begin = final = -1;
-
-	ReadVertices(leavesSubMesh);
+//	indexdata=NULL;
+
+//	ReadVertices(leavesSubMesh);
+	int countv= int(leavesSubMesh->mVertexBuffer->mVertexCount);
+	Leaves = new RuntimeLeaf[countv*2];
+	TotalVerts = countv;
+
 	ReadLeafs(leavesSubMesh);
 	if (!ReadSimpSeq(simpSeq)) exit(1);
 	FillRoot();
-	CalculateTexCoordsAndNorms();
-
-	indexdata->SetNumValidIndices(0);
+//	CalculateTexCoordsAndNorms();
+
+//	indexdata->SetNumValidIndices(0);
 
 	int h=0;
@@ -44,4 +52,5 @@
 	final = leafCount-1;
 	active_leaf_count = leafCount;
+	leavesSubMeshID=leavessubmeshID;
 }
 
@@ -51,6 +60,6 @@
 Foliage::~Foliage (void)
 {
-	if (vertexdata) delete vertexdata;
-	if (indexdata) delete indexdata;
+//	if (vertexdata) delete vertexdata;
+//	if (indexdata) delete indexdata;
 	delete[] Leaves;
 	delete MinDet;
@@ -222,5 +231,5 @@
 
  }
-
+/*
 void Foliage::ReadVertices(const Geometry::SubMesh *submesh)
 {
@@ -228,5 +237,5 @@
 	vertexdata = create_vertex_data_func(2*countv);
 	Leaves = new Leaf[countv*2];
-	indexdata = create_index_data_func(countv*2*3); // 3 indices x 2 triangulos x hoja
+	//indexdata = create_index_data_func(countv*2*3); // 3 indices x 2 triangulos x hoja
 	
 	vertexdata->Begin();
@@ -249,8 +258,4 @@
 	float twox, twoy, twoz;
 	float threex, threey, threez;
-
-/*	Vertices[aHoja.vertsLeaf[0]].GetCoordinates (onex, oney, onez);
-	Vertices[aHoja.vertsLeaf[1]].GetCoordinates(twox, twoy, twoz);
-	Vertices[aHoja.vertsLeaf[2]].GetCoordinates (threex, threey, threez);*/
 
 	vertexdata->GetVertexCoord(aleaf.vertsLeaf[0],onex,oney,onez);
@@ -286,5 +291,5 @@
 	res[2]=v[2]/module;
 }
-
+*/
 void Foliage::ReadLeafs(const Geometry::SubMesh *submesh)
 {
@@ -297,7 +302,7 @@
 		Leaves[h].vertsLeaf[2] = submesh->mIndex[h*6+2];
 		Leaves[h].vertsLeaf[3] = submesh->mIndex[h*6+5];
-		Leaves[h].visible = 0;
-
-		GetNormalH ( Leaves[h]);
+//		Leaves[h].visible = 0;
+
+//		GetNormalH ( Leaves[h]);
 	}
 }
@@ -316,7 +321,7 @@
 		Leaves[tn].vertsLeaf[3] = it->mNewQuad[3];
 
-		Leaves[tn].visible = 0;
-
-		GetNormalH  (Leaves[tn]);
+//		Leaves[tn].visible = 0;
+
+//		GetNormalH  (Leaves[tn]);
 
 		tv1 = it->mV0/2;
@@ -433,5 +438,5 @@
 }
 
-void Foliage::CalculateTexCoordsAndNorms(void)
+/*void Foliage::CalculateTexCoordsAndNorms(void)
 {	
 	vertexdata->Begin();
@@ -453,5 +458,5 @@
 	vertexdata->End();
 }
-
+*/
 Foliage::Foliage(const Foliage *ar)
 {
@@ -465,6 +470,6 @@
 	TotalVerts=ar->TotalVerts;
 
-	create_vertex_data_func=ar->create_vertex_data_func;
-	create_index_data_func=ar->create_index_data_func;
+/*	create_vertex_data_func=ar->create_vertex_data_func;
+//	create_index_data_func=ar->create_index_data_func;
 	vertexdata=create_vertex_data_func(ar->vertexdata->GetNumVertices());
 	vertexdata->Begin(); 
@@ -477,18 +482,18 @@
 		vertexdata->SetVertexNormal(i,va,vb,vc);
 	}
-	vertexdata->End();
-	indexdata=create_index_data_func(ar->indexdata->GetNumMaxIndices());
-	indexdata->Begin(); 
+	vertexdata->End();*/
+/*	indexdata=create_index_data_func(ar->indexdata->GetNumMaxIndices());
+	indexdata->Begin(ar->leavesSubMeshID,indexdata->GetNumMaxIndices());
 	for (unsigned int i=0; i<indexdata->GetNumMaxIndices(); i++) 
 		indexdata->SetIndex(i,ar->indexdata->GetIndex(i));
-	indexdata->End();
-
-	Leaves=new Leaf[vertexdata->GetNumVertices()];
+	indexdata->End();*/
+
+	Leaves=new RuntimeLeaf[TotalVerts];
 //	for (unsigned int i=0; i<vertexdata->GetNumVertices(); i++) 
 //		Leaves[i]=ar->Leaves[i];
-	memcpy(Leaves,ar->Leaves,sizeof(Leaf)*vertexdata->GetNumVertices());
+	memcpy(Leaves,ar->Leaves,sizeof(Leaf)*TotalVerts);
 
 	// esto no sé si devería haber akí
-	indexdata->SetNumValidIndices(0);
+//	indexdata->SetNumValidIndices(0);
 
 	int h=0;
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/Leaf.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/Leaf.cpp	(revision 1026)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/Leaf.cpp	(revision 1526)
@@ -10,5 +10,5 @@
 	vertsLeaf[0] = vertsLeaf[1] = vertsLeaf[2] = vertsLeaf[3] =0; 
 	center[0] = center[1] = center[2] = 0;
-	normal[0] = normal[1] = normal[2] = 0;
+//	normal[0] = normal[1] = normal[2] = 0;
 	leafNear=-1;
 	parentLeafCount = 1;
@@ -40,5 +40,5 @@
 	for ( int i=0;i<3;i++){
 		center[i] = aLeaf.center[i];
-		normal[i] = aLeaf.normal[i];
+//		normal[i] = aLeaf.normal[i];
 	}
 	for (i = 0L; i < 4; i++)
@@ -53,10 +53,21 @@
 
 
+RuntimeLeaf::RuntimeLeaf(void) 
+{	
+	vertsLeaf[0] = vertsLeaf[1] = vertsLeaf[2] = vertsLeaf[3] = 0;
+	parent = root = childLeft = childRight = -1;
+}
 
 //--------------------------------------------------------------------------------------------------------------------------------
-// Destructor. We must deallocate the memory allocated for pointers to vertices and edges
+// Copy constructor
 //--------------------------------------------------------------------------------------------------------------------------------
-Leaf::~Leaf (void)
+RuntimeLeaf::RuntimeLeaf (const RuntimeLeaf& aLeaf)
 {
+	for (int i = 0L; i < 4; i++)
+		vertsLeaf[i] = aLeaf.vertsLeaf[i]; 
+	parent = aLeaf.parent;
+	childLeft = aLeaf.childLeft;
+	childRight = aLeaf.childRight;
+	root = aLeaf.root;
 }
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/VertexData.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/VertexData.cpp	(revision 1105)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/VertexData.cpp	(revision 1526)
@@ -1,54 +1,19 @@
 #include "VertexData.h"
 
-Geometry::DefaultVertexData::DefaultVertexData(unsigned int numv):Geometry::VertexData(numv)
+/*
+void Geometry::DefaultIndexData::Init(unsigned int numi)
 {
-	v = new float[numv*3];
-	n = new float[numv*3];
-	t = new float[numv*2];
-}
-Geometry::DefaultVertexData::~DefaultVertexData(void)
-{
-/*	delete[] v;
-	delete[] n;
-	delete[] t;*/
-}
-
-Geometry::VertexData *Geometry::DefaultVertexDataCreator(unsigned int numv)
-{ 
-	return new DefaultVertexData(numv); 
-}
-
-
-Geometry::DefaultIndexData::DefaultIndexData(unsigned int numi):Geometry::IndexData(numi)
-{
-	indices = new unsigned int[numi];	
+	indices = new unsigned int[numi];
 }
 Geometry::DefaultIndexData::~DefaultIndexData(void)
 {
-/*	delete[] indices;*/
 }
 
 Geometry::IndexData *Geometry::DefaultIndexDataCreator(unsigned int numi)
 { 
-	return new DefaultIndexData(numi); 
+	IndexData *ret = new DefaultIndexData();
+//	ret->Init(numi);
+	return ret;
 }
 
-
-/*Geometry::DefaultMultiIndexData::DefaultMultiIndexData(unsigned int numprims, unsigned int *numi):Geometry::MultiIndexData(numprims,numi)
-{
-	indices = new unsigned int*[numprims];	
-	for (unsigned int i=0; i<numprims; i++)
-		indices[i]=new unsigned int[numi[i]];
-}
-Geometry::DefaultMultiIndexData::~DefaultMultiIndexData(void)
-{
-	for (unsigned int i=0; i<GetNumPrims(); i++)
-		delete[] indices[i];
-	delete[] indices;
-}
-
-Geometry::MultiIndexData *Geometry::DefaultMultiIndexDataCreator(unsigned int numprims, unsigned int *numi)
-{ 
-	return new DefaultMultiIndexData(numprims,numi); 
-}
 */
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h	(revision 1083)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h	(revision 1526)
@@ -26,6 +26,10 @@
 		int begin, final;
 		int active_leaf_count;
+		int leavesSubMeshID;
 
-		Foliage (const Geometry::SubMesh *, const Geometry::TreeSimplificationSequence *, Geometry::CREATEVERTEXDATAFUNC vdfun=NULL, Geometry::CREATEINDEXDATAFUNC idfun=NULL);
+		Foliage (	int leavesSubMeshID, 
+					const Geometry::SubMesh *, 
+					const Geometry::TreeSimplificationSequence *	);
+
 		Foliage (const Foliage *);
 		virtual ~Foliage (void); // Destructor
@@ -33,8 +37,5 @@
 		void CalculateLOD(int nhojas);
 
-		Geometry::VertexData *vertexdata;
-		Geometry::IndexData *indexdata;
-
-		Leaf   *Leaves;
+		RuntimeLeaf   *Leaves;
 		ActiveLeafNode  *MinDet; // first active leaf
 		int leafCount;
@@ -45,6 +46,4 @@
 
 	private:
-		Geometry::CREATEVERTEXDATAFUNC create_vertex_data_func;		
-		Geometry::CREATEINDEXDATAFUNC create_index_data_func;
 
 		bool IsActive( int num) const;
@@ -59,12 +58,4 @@
 		bool ReadSimpSeq(const Geometry::TreeSimplificationSequence *); /// returns true when successful
 		void FillRoot(void);
-
-		void GetNormalH (Leaf&);
-
-		void CrossProduct(const float *v1, const float *v2, float *res);
-		void Normalize(const float *v, float *res);
-//		void CalculaNormalesVertice(void);
-		void CalculateTexCoordsAndNorms(void);
-
 };
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.cxx
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.cxx	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.cxx	(revision 1526)
@@ -17,7 +17,7 @@
 int Model::in_Vertex(const Vec3& p)
 {
-    Vertex *v = newVertex(p[X], p[Y], p[Z]);
-    bounds.addPoint(p);
-    return vertCount() - 1;
+	Vertex *v = newVertex(p[X], p[Y], p[Z]);
+	bounds.addPoint(p);
+	return vertCount() - 1;
 }
 
@@ -36,9 +36,9 @@
 int Model::in_Face(int a, int b, int c, int n1, int n2, int n3, int t1, int t2, int t3)
 {
-    Vertex *v1 = vertices(a-1);
-    Vertex *v2 = vertices(b-1);
-    Vertex *v3 = vertices(c-1);
-	
-    Face *t = newFace(v1, v2, v3);
+	Vertex *v1 = vertices(a-1);
+	Vertex *v2 = vertices(b-1);
+	Vertex *v3 = vertices(c-1);
+
+	Face *t = newFace(v1, v2, v3);
 
 	t->normals[0] = n1;
@@ -55,9 +55,9 @@
 int Model::miin_Face(int a, int b, int c)
 {
-    Vertex *v1 = vertices(a-1);
-    Vertex *v2 = vertices(b-1);
-    Vertex *v3 = vertices(c-1);
-	
-    Face *t = newFace(v1, v2, v3);
+	Vertex *v1 = vertices(a);
+	Vertex *v2 = vertices(b);
+	Vertex *v3 = vertices(c);
+
+	Face *t = newFace(v1, v2, v3);
 
 	t->normals[0] = a;
@@ -75,11 +75,14 @@
 int Model::in_FColor(const Vec3& c)
 {
-    Face *f = faces(faces.length()-1);
-
-    if( !f->props )
-	f->props = new FProp;
-
-    f->props->color = c;
-    return 0;
+	Face *f = faces(faces.length()-1);
+
+	if( !f->props )
+	{
+		f->props = new FProp;
+	}
+
+	f->props->color = c;
+
+	return 0;
 }
 #endif
@@ -88,11 +91,13 @@
 int Model::in_VColor(const Vec3& c)
 {
-    Vertex *v = vertices(vertices.length()-1);
-
-    if( !v->props )
-	v->props = new VProp;
-
-    v->props->color = c;
-    return 0;
+	Vertex *v = vertices(vertices.length()-1);
+
+	if( !v->props )
+	{
+		v->props = new VProp;
+	}
+
+	v->props->color = c;
+	return 0;
 }
 #endif
@@ -100,27 +105,29 @@
 Vec3 Model::synthesizeNormal(Vertex *v)
 {
-    Vec3 n(0,0,0);
-    int n_count = 0;
-
-    edge_buffer& edges = v->edgeUses();
-    for(int i=0; i<edges.length(); i++)
-    {
-	face_buffer& faces = edges(i)->faceUses();
-
-	for(int j=0; j<faces.length(); j++)
-	{
-	    n += faces(j)->plane().normal();
-	    n_count++;
-	}
-    }
-
-    if( n_count )
-	n /= (real)n_count;
-    else
-    {
+	Vec3 n(0,0,0);
+	int n_count = 0;
+
+	edge_buffer& edges = v->edgeUses();
+	for(int i=0; i<edges.length(); i++)
+	{
+		face_buffer& faces = edges(i)->faceUses();
+
+		for(int j=0; j<faces.length(); j++)
+		{
+			n += faces(j)->plane().normal();
+			n_count++;
+		}
+	}
+
+	if( n_count )
+	{
+		n /= (real)n_count;
+	}
+	else
+	{
 		std::cerr << "Vertex with no normals!!: " << v->uniqID;
 		std::cerr << " / " << v->tempID << std::endl;
-    }
-    return n;
+	}
+	return n;
 }
 
@@ -138,59 +145,62 @@
 Vertex *Model::newVertex(real x, real y, real z)
 {
-    Vertex *v = new Vertex(x, y, z);
-
-    v->vID = v->uniqID = vertices.add(v);
-
-/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
-		*logfile << "v " << x << " " << y << " " << z << std::endl;
-*/
-    validVertCount++;
-
-    return v;
+	Vertex *v = new Vertex(x, y, z);
+
+	v->vID = v->uniqID = vertices.add(v);
+
+	/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
+	 *logfile << "v " << x << " " << y << " " << z << std::endl;
+	 */
+	validVertCount++;
+
+	return v;
 }
 
 Edge *Model::newEdge(Vertex *a, Vertex *b)
 {
-    Edge *e = new Edge(a, b);
-
-    e->uniqID = edges.add(e);
-    e->sym()->uniqID = e->uniqID;
-
-    validEdgeCount++;
-
-    return e;
+	Edge *e = new Edge(a, b);
+
+	e->uniqID = edges.add(e);
+	e->sym()->uniqID = e->uniqID;
+
+	validEdgeCount++;
+
+	return e;
 }
 
 static Edge *get_edge(Model *m, Vertex *org, Vertex *v)
 {
-    edge_buffer& edge_uses = org->edgeUses();
-
-    for(int i=0; i<edge_uses.length(); i++)
-	if( edge_uses(i)->dest() == v )
-	    return edge_uses(i);
-
-    Edge *e = m->newEdge(org, v);
-
-    return e;
-}
-
+	edge_buffer& edge_uses = org->edgeUses();
+
+	for (int i=0; i<edge_uses.length(); i++)
+	{
+		if ( edge_uses(i)->dest() == v )
+		{
+			return edge_uses(i);
+		}
+	}
+
+	Edge *e = m->newEdge(org, v);
+
+	return e;
+}
 
 Face *Model::newFace(Vertex *v1, Vertex *v2, Vertex *v3)
 {
-    Edge *e0 = get_edge(this, v1, v2);   // v1->edgeTo(m, v2);
-    Edge *e1 = get_edge(this, v2, v3);   // v2->edgeTo(m, v3);
-    Edge *e2 = get_edge(this, v3, v1);   // v3->edgeTo(m, v1);
-  
-    Face *t = new Face(e0, e1, e2);
-
-    t->uniqID = faces.add(t);
-
-/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
-	*logfile << "f " << v1->uniqID+1 << " "
-	<< v2->uniqID+1 << " " << v3->uniqID+1 << std::endl;
-*/
-    validFaceCount++;
-
-    return t;
+	Edge *e0 = get_edge(this, v1, v2);   // v1->edgeTo(m, v2);
+	Edge *e1 = get_edge(this, v2, v3);   // v2->edgeTo(m, v3);
+	Edge *e2 = get_edge(this, v3, v1);   // v3->edgeTo(m, v1);
+
+	Face *t = new Face(e0, e1, e2);
+
+	t->uniqID = faces.add(t);
+
+	/*    if( logfile && selected_output&OUTPUT_MODEL_DEFN )
+	 *logfile << "f " << v1->uniqID+1 << " "
+	 << v2->uniqID+1 << " " << v3->uniqID+1 << std::endl;
+	 */
+	validFaceCount++;
+
+	return t;
 }
 
@@ -198,43 +208,45 @@
 void Model::killVertex(Vertex *v)
 {
-    if( v->isValid() )
-    {
-/*	if( logfile && selected_output&OUTPUT_CONTRACTIONS )
-		*logfile << "v- " << v->uniqID+1 << std::endl;
-*/
-	v->kill();
-	validVertCount--;
-    }
+	if( v->isValid() )
+	{
+		/*	if( logfile && selected_output&OUTPUT_CONTRACTIONS )
+		 *logfile << "v- " << v->uniqID+1 << std::endl;
+		 */
+		v->kill();
+		validVertCount--;
+	}
 }
 
 void Model::killEdge(Edge *e)
 {
-    if( e->isValid() )
-    {
-	e->kill();
-	validEdgeCount--;
-    }
+	if( e->isValid() )
+	{
+		e->kill();
+		validEdgeCount--;
+	}
 }
 
 void Model::killFace(Face *f)
 {
-    if( f->isValid() )
-    {
-/*	if( logfile && selected_output&OUTPUT_CONTRACTIONS )
-		*logfile << "f- " << f->uniqID+1 << std::endl;
-*/
-	f->kill();
-	validFaceCount--;
-    }
+	if( f->isValid() )
+	{
+		/*	if( logfile && selected_output&OUTPUT_CONTRACTIONS )
+		 *logfile << "f- " << f->uniqID+1 << std::endl;
+		 */
+		f->kill();
+		validFaceCount--;
+	}
 }
 
 void Model::reshapeVertex(Vertex *v, real x, real y, real z)
 {
-    v->set(x, y, z);
+	v->set(x, y, z);
 
 #ifdef LOG_LOWLEVEL_OPS
-    if( logfile )
-	*logfile << "v! " << v->uniqID+1 << " "
-		 << x << " " << y << " " << z << endl;
+	if( logfile )
+	{
+		*logfile << "v! " << v->uniqID+1 << " "
+			<< x << " " << y << " " << z << endl;
+	}
 #endif
 }
@@ -242,13 +254,13 @@
 void Model::remapVertex(Vertex *from, Vertex *to)
 {
-    from->remapTo(to);
+	from->remapTo(to);
 
 #ifdef LOG_LOWLEVEL_OPS
-    if( logfile )
-	*logfile << "v> " << from->uniqID+1 << " " << to->uniqID+1 << endl;
-#endif
-}
-
-
+	if( logfile )
+	{
+		*logfile << "v> " << from->uniqID+1 << " " << to->uniqID+1 << endl;
+	}
+#endif
+}
 
 void Model::contract(Vertex *v1,
@@ -257,92 +269,94 @@
 		     face_buffer& changed)
 {
-    int i;
-
-/*    if( logfile && selected_output&OUTPUT_CONTRACTIONS )
-    {
-	*logfile << "v% (" << v1->uniqID+1;
+	int i;
+
+	/*    if( logfile && selected_output&OUTPUT_CONTRACTIONS )
+				{
+	 *logfile << "v% (" << v1->uniqID+1;
+	 for(i=0; i<rest.length(); i++)
+	 *logfile << " " << rest(i)->uniqID+1;
+
+	 *logfile << ") " << to[X] << " " << to[Y] << " " << to[Z] << std::endl;
+	 }
+	 */
+
+	//
+	// Collect all the faces that are going to be changed
+	//
+	contractionRegion(v1, rest, changed);
+
+	reshapeVertex(v1, to[X], to[Y], to[Z]);
+
 	for(i=0; i<rest.length(); i++)
-	    *logfile << " " << rest(i)->uniqID+1;
-	
-	*logfile << ") " << to[X] << " " << to[Y] << " " << to[Z] << std::endl;
-    }
-*/
-
-    //
-    // Collect all the faces that are going to be changed
-    //
-    contractionRegion(v1, rest, changed);
-
-    reshapeVertex(v1, to[X], to[Y], to[Z]);
-
-    for(i=0; i<rest.length(); i++)
+	{
 		rest(i)->remapTo(v1);
-
-    removeDegeneracy(changed);
+	}
+
+	removeDegeneracy(changed);
 }
 
 void Model::maybeFixFace(Face *F)
 {
-    //
-    // Invalid faces do not need to be fixed.
+	//
+	// Invalid faces do not need to be fixed.
 #ifdef SAFETY
-    assert( F->isValid() );
-#endif
-
-    Vertex *v0=F->vertex(0); Vertex *v1=F->vertex(1); Vertex *v2=F->vertex(2);
-    Edge *e0 = F->edge(0); Edge *e1 = F->edge(1); Edge *e2 = F->edge(2);
-
-    bool a=(v0 == v1),  b=(v0 == v2),  c=(v1 == v2);
-
-    if( a && c )
-    {
-	// This triangle has been reduced to a point
-	killEdge(e0);
-	killEdge(e1);
-	killEdge(e2);
-
-	killFace(F);
-    }
-    //
-    // In the following 3 cases, the triangle has become an edge
-    else if( a )
-    {
-	killEdge(e0);
-	e1->remapTo(e2->sym());
-	killFace(F);
-    }
-    else if( b )
-    {
-	killEdge(e2);
-	e0->remapTo(e1->sym());
-	killFace(F);
-    }
-    else if( c )
-    {
-	killEdge(e1);
-	e0->remapTo(e2->sym());
-	killFace(F);
-    }
-    else
-    {
-	// This triangle remains non-degenerate
-/*		// SUS: recalcular la normal en los triangulos cambiados no degenerados
-
-		simplif::Vertex * auxv0 = F->vertex(0);
-		simplif::Vertex * auxv1 = F->vertex(1);
-		simplif::Vertex * auxv2 = F->vertex(2);
-		simplif::Vec3 vd1(auxv1->operator[](simplif::X) - auxv0->operator[](simplif::X), 
-						auxv1->operator[](simplif::Y) - auxv0->operator[](simplif::Y),
-						auxv1->operator[](simplif::Z) - auxv0->operator[](simplif::Z));
-		simplif::Vec3 vd2(auxv2->operator[](simplif::X) - auxv0->operator[](simplif::X), 
-						auxv2->operator[](simplif::Y) - auxv0->operator[](simplif::Y),
-						auxv2->operator[](simplif::Z) - auxv0->operator[](simplif::Z));
-
-		simplif::unitize(vd1);
-		simplif::unitize(vd2);
-
-		simplif::Vec3 vn = vd1 ^ vd2;
-		simplif::unitize(vn);
-		
+	assert( F->isValid() );
+#endif
+
+	Vertex *v0=F->vertex(0); Vertex *v1=F->vertex(1); Vertex *v2=F->vertex(2);
+	Edge *e0 = F->edge(0); Edge *e1 = F->edge(1); Edge *e2 = F->edge(2);
+
+	bool a=(v0 == v1),  b=(v0 == v2),  c=(v1 == v2);
+
+	if( a && c )
+	{
+		// This triangle has been reduced to a point
+		killEdge(e0);
+		killEdge(e1);
+		killEdge(e2);
+
+		killFace(F);
+	}
+	//
+	// In the following 3 cases, the triangle has become an edge
+	else if( a )
+	{
+		killEdge(e0);
+		e1->remapTo(e2->sym());
+		killFace(F);
+	}
+	else if( b )
+	{
+		killEdge(e2);
+		e0->remapTo(e1->sym());
+		killFace(F);
+	}
+	else if( c )
+	{
+		killEdge(e1);
+		e0->remapTo(e2->sym());
+		killFace(F);
+	}
+	else
+	{
+		// This triangle remains non-degenerate
+		/*		// SUS: recalcular la normal en los triangulos cambiados no degenerados
+
+					simplif::Vertex * auxv0 = F->vertex(0);
+					simplif::Vertex * auxv1 = F->vertex(1);
+					simplif::Vertex * auxv2 = F->vertex(2);
+					simplif::Vec3 vd1(auxv1->operator[](simplif::X) - auxv0->operator[](simplif::X), 
+					auxv1->operator[](simplif::Y) - auxv0->operator[](simplif::Y),
+					auxv1->operator[](simplif::Z) - auxv0->operator[](simplif::Z));
+					simplif::Vec3 vd2(auxv2->operator[](simplif::X) - auxv0->operator[](simplif::X), 
+					auxv2->operator[](simplif::Y) - auxv0->operator[](simplif::Y),
+					auxv2->operator[](simplif::Z) - auxv0->operator[](simplif::Z));
+
+					simplif::unitize(vd1);
+					simplif::unitize(vd2);
+
+					simplif::Vec3 vn = vd1 ^ vd2;
+					simplif::unitize(vn);
+
 		//auxf->vertex_normals[0] = vn;
 		//auxf->vertex_normals[1] = vn;
@@ -358,32 +372,38 @@
 		F->vertex_normals[2][simplif::Z] = vn[simplif::Z];*/
 
-    }
+	}
 }
 
 void Model::removeDegeneracy(face_buffer& changed)
 {
-    for(int i=0; i<changed.length(); i++)
+	for(int i=0; i<changed.length(); i++)
+	{
 		maybeFixFace(changed(i));
+	}
 }
 
 void Model::contractionRegion(Vertex *v1,
-			      const vert_buffer& vertices,
-			      face_buffer& changed)
-{
-    changed.reset();
-
-    //
-    // First, reset the marks on all reachable vertices
-    int i;
-
-    untagFaceLoop(v1);
-    for(i=0; i<vertices.length(); i++)
+			      									const vert_buffer& vertices,
+			      									face_buffer& changed)
+{
+	changed.reset();
+
+	// First, reset the marks on all reachable vertices
+	int i;
+
+	untagFaceLoop(v1);
+
+	for(i	=	0; i < vertices.length(); i++)
+	{
 		untagFaceLoop(vertices(i));
-
-    //
-    // Now, pick out all the unique reachable faces
-    collectFaceLoop(v1, changed);
-    for(i=0; i<vertices.length(); i++)
+	}
+
+	// Now, pick out all the unique reachable faces
+	collectFaceLoop(v1, changed);
+
+	for(i	=	0; i < vertices.length(); i++)
+	{
 		collectFaceLoop(vertices(i), changed);
+	}
 }
 
@@ -391,15 +411,15 @@
 void Model::contractionRegion(Vertex *v1, Vertex *v2, face_buffer& changed)
 {
-    changed.reset();
-
-    //
-    // Clear marks on all reachable faces
-    untagFaceLoop(v1);
-    untagFaceLoop(v2);
-
-    //
-    // Collect all the unique reachable faces
-    collectFaceLoop(v1, changed);
-    collectFaceLoop(v2, changed);
+	changed.reset();
+
+	//
+	// Clear marks on all reachable faces
+	untagFaceLoop(v1);
+	untagFaceLoop(v2);
+
+	//
+	// Collect all the unique reachable faces
+	collectFaceLoop(v1, changed);
+	collectFaceLoop(v2, changed);
 }
 
@@ -408,27 +428,20 @@
 {
 #ifdef SAFETY
-    assert( v1 != v2);
-#endif
-
-/*    if( logfile && selected_output&OUTPUT_CONTRACTIONS )
-	*logfile << "v% (" << v1->uniqID+1 << " " << v2->uniqID+1 << ") "
-		 << to[X] << " "
-		 << to[Y] << " "
-		 << to[Z] << std::endl;
-*/
-    //
-    // Collect all the faces that are going to be changed
-    //
-    contractionRegion(v1, v2, changed);
-
-    reshapeVertex(v1, to[X], to[Y], to[Z]);
-
-    //
-    // Map v2 ---> v1.  This accomplishes the topological change that we want.
-    v2->remapTo(v1);
-
-    removeDegeneracy(changed);
-}
-
+	assert( v1 != v2);
+#endif
+	//
+	// Collect all the faces that are going to be changed
+	//
+	contractionRegion(v1, v2, changed);
+
+	reshapeVertex(v1, to[X], to[Y], to[Z]);
+
+	// Map v2 ---> v1.  This accomplishes the topological change that we want.
+	v2->remapTo(v1);
+
+//	std::cout << "Contract(QslimInds): " << v2->validID() << " --> " << v1->validID() << std::endl;
+
+	removeDegeneracy(changed);
+}
 
 /*
@@ -494,2 +507,3 @@
 }
 */
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Buffer.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Buffer.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Buffer.h	(revision 1526)
@@ -25,6 +25,6 @@
 		inline int length() const { return fill; }
 		inline int maxLength() const { return len; }
+		inline void setFill(int l){fill	=	l;}
 	};
-
 
 	template<class T>
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Heap.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Heap.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Heap.h	(revision 1526)
@@ -16,31 +16,31 @@
 	class Heapable
 	{
-	private:
-		int token;
+		private:
 
-	public:
-		Heapable() { notInHeap(); }
+			int token;
 
-		inline int isInHeap() { return token!=NOT_IN_HEAP; }
-		inline void notInHeap() { token = NOT_IN_HEAP; }
-		inline int getHeapPos() { return token; }
-		inline void setHeapPos(int t) { token=t; }
+		public:
+
+			Heapable() { notInHeap(); }
+
+			inline int isInHeap() { return token!=NOT_IN_HEAP; }
+			inline void notInHeap() { token = NOT_IN_HEAP; }
+			inline int getHeapPos() { return token; }
+			inline void setHeapPos(int t) { token=t; }
 	};
 
+	class heap_node
+	{
+		public:
+			float import;
+			Heapable *obj;
 
-	class heap_node {
-	public:
-		float import;
-		Heapable *obj;
-
-		heap_node() { obj=NULL; import=0.0; }
-		heap_node(Heapable *t, float i=0.0) { obj=t; import=i; }
-		heap_node(const heap_node& h) { import=h.import; obj=h.obj; }
+			heap_node() { obj=NULL; import=0.0; }
+			heap_node(Heapable *t, float i=0.0) { obj=t; import=i; }
+			heap_node(const heap_node& h) { import=h.import; obj=h.obj; }
 	};
 
-
-
-	class Heap : public array<heap_node> {
-
+	class Heap : public array<heap_node>
+	{
 		//
 		// The actual size of the heap.  array::length()
@@ -57,9 +57,8 @@
 		void downheap(int i);
 
-	public:
+		public:
 
 		Heap() { size=0; }
 		Heap(int s) : array<heap_node>(s) { size=0; }
-
 
 		void insert(Heapable *, float);
@@ -67,11 +66,22 @@
 
 		heap_node *extract();
+
+		//	Overhead method.
+		heap_node *extract(int i);
+
 		heap_node *top() { return size<1 ? (heap_node *)NULL : &ref(0); }
 		heap_node *kill(int i);
+
+		//	Gets heap size.
+		int	getSize(){return	size;}
+
+		//	Gets element at position i.
+		heap_node	*getElement(int i){return	&ref(i);}
+
 	};
 
 }
 
-
 // GFXTOOLS_HEAP_INCLUDED
 #endif
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Array.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Array.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/Array.h	(revision 1526)
@@ -8,77 +8,76 @@
 {
 	template<class T>
-	class array {
-	protected:
-		T *data;
-		int len;
-	public:
-		array() { data=NULL; len=0; }
-		array(int l) { init(l); }
-		~array() { f_r_e_e(); }
+		class array
+		{
+			protected:
+				T *data;
+				int len;
+			public:
+				array() { data=NULL; len=0; }
+				array(int l) { init(l); }
+				~array() { f_r_e_e(); }
 
+				inline void init(int l);
+				inline void f_r_e_e();
+				inline void resize(int l);
 
-		inline void init(int l);
-		inline void f_r_e_e();
-		inline void resize(int l);
+				inline T& ref(int i);
+				inline T& operator[](int i) { return data[i]; }
+				inline T& operator()(int i) { return ref(i); }
 
-		inline T& ref(int i);
-		inline T& operator[](int i) { return data[i]; }
-		inline T& operator()(int i) { return ref(i); }
+				inline const T& ref(int i) const;
+				inline const T& operator[](int i) const { return data[i]; }
+				inline const T& operator()(int i) const { return ref(i); }
 
-		inline const T& ref(int i) const;
-		inline const T& operator[](int i) const { return data[i]; }
-		inline const T& operator()(int i) const { return ref(i); }
-
-
-		inline int length() const { return len; }
-		inline int maxLength() const { return len; }
-	};
+				inline int length() const { return len; }
+				inline int maxLength() const { return len; }
+		};
 
 	template<class T>
-	inline void array<T>::init(int l)
-	{
-		data = new T[l];
-		len = l;
-	}
+		inline void array<T>::init(int l)
+		{
+			data = new T[l];
+			len = l;
+		}
 
 	template<class T>
-	inline void array<T>::f_r_e_e()
-	{
-		if( data )
+		inline void array<T>::f_r_e_e()
 		{
-		delete[] data;
-		data = NULL;
+			if( data )
+			{
+				delete[] data;
+				data = NULL;
+			}
 		}
-	}
 
 	template<class T>
-	inline T& array<T>::ref(int i)
-	{
-	#ifdef SAFETY
-		assert( data );
-		assert( i>=0 && i<len );
-	#endif
-		return data[i];
-	}
+		inline T& array<T>::ref(int i)
+		{
+#ifdef SAFETY
+			assert( data );
+			assert( i>=0 && i<len );
+#endif
+			return data[i];
+		}
 
 	template<class T>
-	inline const T& array<T>::ref(int i) const
-	{
-	#ifdef SAFETY
-		assert( data );
-		assert( i>=0 && i<len );
-	#endif
-		return data[i];
-	}
+		inline const T& array<T>::ref(int i) const
+		{
+#ifdef SAFETY
+			assert( data );
+			assert( i>=0 && i<len );
+#endif
+			return data[i];
+		}
 
 	template<class T>
-	inline void array<T>::resize(int l)
-	{
-		T *old = data;
-		data = new T[l];
-		data = (T *)memcpy(data,old,MIN(len,l)*sizeof(T));
-		len = l;
-		delete[] old;
-	}
+		inline void array<T>::resize(int l)
+		{
+			T *old = data;
+			data = new T[l];
+			data = (T *)memcpy(data,old,MIN(len,l)*sizeof(T));
+			len = l;
+			delete[] old;
+		}
 }
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/heap.cxx
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/heap.cxx	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/tools/heap.cxx	(revision 1526)
@@ -7,115 +7,127 @@
 void Heap::swap(int i,int j)
 {
-    heap_node tmp = ref(i);
+	heap_node tmp = ref(i);
 
-    ref(i) = ref(j);
-    ref(j) = tmp;
+	ref(i) = ref(j);
+	ref(j) = tmp;
 
-    ref(i).obj->setHeapPos(i);
-    ref(j).obj->setHeapPos(j);
+	ref(i).obj->setHeapPos(i);
+	ref(j).obj->setHeapPos(j);
 }
 
 void Heap::upheap(int i)
 {
-    if( i==0 ) return;
+	if( i==0 ) return;
 
-    if( ref(i).import > ref(parent(i)).import ) {
-        swap(i,parent(i));
-        upheap(parent(i));
-    }
+	if( ref(i).import > ref(parent(i)).import )
+	{
+		swap(i,parent(i));
+		upheap(parent(i));
+	}
 }
 
 void Heap::downheap(int i)
 {
-    if (i>=size) return;        // perhaps just extracted the last
+	if (i>=size) return;        // perhaps just extracted the last
 
-    int largest = i,
-        l = left(i),
-        r = right(i);
+	int largest = i,
+			l = left(i),
+			r = right(i);
 
-    if( l<size && ref(l).import > ref(largest).import ) largest = l;
-    if( r<size && ref(r).import > ref(largest).import ) largest = r;
+	if( l<size && ref(l).import > ref(largest).import ) largest = l;
+	if( r<size && ref(r).import > ref(largest).import ) largest = r;
 
-    if( largest != i ) {
-        swap(i,largest);
-        downheap(largest);
-    }
+	if( largest != i ) {
+		swap(i,largest);
+		downheap(largest);
+	}
 }
-
-
 
 void Heap::insert(Heapable *t,float v)
 {
-    if( size == maxLength() )
-    {
-	std::cerr << "NOTE: Growing heap from " << size << " to " << 2*size << std::endl;
-	resize(2*size);
-    }
+	if( size == maxLength() )
+	{
+		std::cerr << "NOTE: Growing heap from " << size << " to " << 2*size << std::endl;
+		resize(2*size);
+	}
 
-    int i = size++;
+	int i = size++;
 
-    ref(i).obj = t;
-    ref(i).import = v;
+	ref(i).obj = t;
+	ref(i).import = v;
 
-    ref(i).obj->setHeapPos(i);
+	ref(i).obj->setHeapPos(i);
 
-    upheap(i);
+	upheap(i);
 }
 
 void Heap::update(Heapable *t,float v)
 {
-    int i = t->getHeapPos();
+	int i = t->getHeapPos();
 
-    if( i >= size )
-    {
+	if( i >= size )
+	{
 		std::cerr << "WARNING: Attempting to update past end of heap!" << std::endl;
 		return;
-    }
-    else if( i == NOT_IN_HEAP )
-    {
+	}
+	else if( i == NOT_IN_HEAP )
+	{
 		std::cerr << "WARNING: Attempting to update object not in heap!" << std::endl;
 		return;
-    }
+	}
 
-    float old=ref(i).import;
-    ref(i).import = v;
+	float old=ref(i).import;
+	ref(i).import = v;
 
-    if( v<old )
-        downheap(i);
-    else
-        upheap(i);
+	if( v<old )
+		downheap(i);
+	else
+		upheap(i);
 }
-
-
 
 heap_node *Heap::extract()
 {
-    if( size<1 ) return 0;
+	if( size<1 ) return 0;
 
-    swap(0,size-1);
-    size--;
+	swap(0,size-1);
+	size--;
 
-    downheap(0);
+	downheap(0);
 
-    ref(size).obj->notInHeap();
+	ref(size).obj->notInHeap();
 
-    return &ref(size);
+	return &ref(size);
+}
+
+//	Overhead method.
+heap_node *Heap::extract(int i)
+{
+	if( size<1 ) return 0;
+
+	swap(i,size-1);
+	size--;
+
+	downheap(i);
+
+	ref(size).obj->notInHeap();
+
+	return &ref(size);
 }
 
 heap_node *Heap::kill(int i)
 {
-    if( i>=size )
+	if( i>=size )
 		std::cerr << "WARNING: Attempt to delete invalid heap node." << std::endl;
 
-    swap(i, size-1);
-    size--;
-    ref(size).obj->notInHeap();
+	swap(i, size-1);
+	size--;
+	ref(size).obj->notInHeap();
 
-    if( ref(i).import < ref(size).import )
+	if( ref(i).import < ref(size).import )
 		downheap(i);
-    else
+	else
 		upheap(i);
 
+	return &ref(size);
+}
 
-    return &ref(size);
-}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.cxx
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.cxx	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.cxx	(revision 1526)
@@ -85,7 +85,4 @@
 }
 
-
-
-
 ////////////////////////////////////////////////////////////////////////
 //
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/gfx/geom/3D.h	(revision 1526)
@@ -63,5 +63,4 @@
 	};
 
-
 	//
 	// A triangular face in 3D (ie. a 2-simplex in E3)
@@ -94,6 +93,4 @@
 }
 
-
-
 // GFXGEOM_3D_INCLUDED
 #endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/simplif.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/simplif.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/simplif.h	(revision 1526)
@@ -12,13 +12,13 @@
 	class pair_info : public Heapable
 	{
-	public:
-		Vertex *v0, *v1;
+		public:
+			Vertex *v0, *v1;
 
-		Vec3 candidate;
-		real cost;
+			Vec3 candidate;
+			real cost;
 
-		pair_info(Vertex *a,Vertex *b) { v0=a; v1=b; cost=HUGE; }
+			pair_info(Vertex *a,Vertex *b) { v0=a; v1=b; cost=HUGE; }
 
-		bool isValid() { return v0->isValid() && v1->isValid(); }
+			bool isValid() { return v0->isValid() && v1->isValid(); }
 	};
 
@@ -27,12 +27,13 @@
 	class vert_info
 	{
-	public:
+		public:
 
-		pair_buffer pairs;
+			pair_buffer pairs;
 
-		Mat4 Q;
-		real norm;
+			Mat4 Q;
+			real norm;
 
-		vert_info() : Q(Mat4::zero) { pairs.init(2); norm=0.0; }
+			vert_info() : Q(Mat4::zero) { pairs.init(2); norm=0.0; }
 	};
 }
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp	(revision 1526)
@@ -6,4 +6,5 @@
 using namespace std;
 using namespace Geometry;
+using	namespace	simplif;
 
 #include <gfx/geom/ProxGrid.h>
@@ -13,5 +14,5 @@
 //	Constructor
 //---------------------------------------------------------------------------
-SimplificationMethod::SimplificationMethod(const Mesh *m) 
+SimplificationMethod::SimplificationMethod(const Mesh *m)
 {
 	objmesh							=	m;
@@ -19,4 +20,7 @@
 	first_index_submesh	=	new unsigned int[objmesh->mSubMeshCount];
 	indexMeshLeaves			=	-1;
+
+	//	Create simplification sequence.
+	msimpseq	=	new MeshSimplificationSequence();
 }
 
@@ -41,15 +45,18 @@
 	simplif::vert_info& v1_info = vertex_info(v1);
 
-	simplif::Mat4 Q = v0_info.Q + v1_info.Q;
-	simplif::real norm = v0_info.norm + v1_info.norm;
+	simplif::Mat4 Q 		=	v0_info.Q + v1_info.Q;
+	simplif::real norm	=	v0_info.norm + v1_info.norm;
 
 	auxpair->cost = simplif::quadrix_pair_target(Q, v0, v1, auxpair->candidate);
 
-	if( simplif::will_weight_by_area )
+	if ( simplif::will_weight_by_area )
+	{
 		auxpair->cost /= norm;
-
-	if( simplif::will_preserve_mesh_quality )
+	}
+
+	if ( simplif::will_preserve_mesh_quality )
+	{
 		auxpair->cost += pair_mesh_penalty(M0, v0, v1, auxpair->candidate);
-
+	}
 
 	//
@@ -57,5 +64,5 @@
 	//          the heap is implemented as a MAX heap.
 	//
-	if( auxpair->isInHeap() )
+	if ( auxpair->isInHeap() )
 	{
 		heap->update(auxpair, (float)-auxpair->cost);
@@ -70,19 +77,40 @@
 //	Reasign the new vertex to the adequate face
 //---------------------------------------------------------------------------
-int SimplificationMethod::predict_face(simplif::Face& F, simplif::Vertex *v1, simplif::Vertex *v2, simplif::Vec3& vnew, simplif::Vec3& f1, simplif::Vec3& f2, simplif::Vec3& f3)
+int SimplificationMethod::predict_face(	simplif::Face& F,
+																				simplif::Vertex *v1,
+																				simplif::Vertex *v2,
+																				simplif::Vec3& vnew,
+																				simplif::Vec3& f1,
+																				simplif::Vec3& f2,
+																				simplif::Vec3& f3)
 {
 	int nmapped = 0;
 
 	if( F.vertex(0) == v1 || F.vertex(0) == v2 )
-	{ f1 = vnew;  nmapped++; }
-	else f1 = *F.vertex(0);
+	{
+		f1 = vnew;  nmapped++;
+	}
+	else
+	{
+		f1 = *F.vertex(0);
+	}
 
 	if( F.vertex(1) == v1 || F.vertex(1) == v2 )
-	{ f2 = vnew;  nmapped++; }
-	else f2 = *F.vertex(1);
+	{
+		f2 = vnew;  nmapped++;
+	}
+	else
+	{
+		f2 = *F.vertex(1);
+	}
 
 	if( F.vertex(2) == v1 || F.vertex(2) == v2 )
-	{ f3 = vnew;  nmapped++; }
-	else f3 = *F.vertex(2);
+	{
+		f3 = vnew;  nmapped++;
+	}
+	else
+	{
+		f3 = *F.vertex(2);
+	}
 
 	return nmapped;
@@ -93,7 +121,10 @@
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M, simplif::Vertex *v1, simplif::Vertex *v2, simplif::Vec3& vnew)
+simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M, simplif::Vertex *v1,
+																		 simplif::Vertex *v2,
+																		 simplif::Vec3& vnew)
 {
 	static simplif::face_buffer changed;
+
 	changed.reset();
 
@@ -103,5 +134,5 @@
 	simplif::real Nmin = 0;
 
-	for(int i=0; i<changed.length(); i++)
+	for (int i	=	0; i < changed.length(); i++)
 	{
 		simplif::Face& F = *changed(i);
@@ -114,7 +145,11 @@
 		{
 			simplif::Plane Pnew(f1, f2, f3);
+
 			simplif::real delta =  Pnew.normal() * F.plane().normal();
 
-			if( Nmin > delta ) Nmin = delta;
+			if( Nmin > delta )
+			{
+				Nmin = delta;
+			}
 		}
 	}
@@ -122,7 +157,11 @@
 	//return (-Nmin) * MESH_INVERSION_PENALTY;
 	if( Nmin < 0.0 )
+	{
 		return MESH_INVERSION_PENALTY;
+	}
 	else
+	{
 		return 0.0;
+	}
 }
 
@@ -130,5 +169,6 @@
 //	Returns true if the givens vertices are a valid pair
 //---------------------------------------------------------------------------
-bool SimplificationMethod::check_for_pair(simplif::Vertex *v0, simplif::Vertex *v1)
+bool SimplificationMethod::check_for_pair(simplif::Vertex *v0,
+																					simplif::Vertex *v1)
 {
 	const simplif::pair_buffer& pairs = vertex_info(v0).pairs;
@@ -137,5 +177,7 @@
 	{
 		if( pairs(i)->v0==v1 || pairs(i)->v1==v1 )
+		{
 			return true;
+		}
 	}
 
@@ -146,5 +188,6 @@
 //	Create a new pair with two given vertices
 //---------------------------------------------------------------------------
-simplif::pair_info *SimplificationMethod::new_pair(simplif::Vertex *v0, simplif::Vertex *v1)
+simplif::pair_info *SimplificationMethod::new_pair(	simplif::Vertex *v0,
+																										simplif::Vertex *v1)
 {
 	simplif::vert_info& v0_info = vertex_info(v0);
@@ -152,4 +195,5 @@
 
 	simplif::pair_info *pair = new simplif::pair_info(v0,v1);
+
 	v0_info.pairs.add(pair);
 	v1_info.pairs.add(pair);
@@ -169,6 +213,8 @@
 	v1_info.pairs.remove(v1_info.pairs.find(auxpair));
 
-	if( auxpair->isInHeap() )
+	if ( auxpair->isInHeap() )
+	{
 		heap->kill(auxpair->getHeapPos());
+	}
 
 	delete auxpair;
@@ -178,54 +224,59 @@
 //	Contract a given pair
 //---------------------------------------------------------------------------
-void SimplificationMethod::do_contract(simplif::Model& m, simplif::pair_info *auxpair)
-{
-	simplif::Vertex *v0 = auxpair->v0;  simplif::Vertex *v1 = auxpair->v1;
+void SimplificationMethod::do_contract(	simplif::Model& m,
+																				simplif::pair_info *auxpair)
+{
+	simplif::Vertex *v0					= auxpair->v0;
+	simplif::Vertex *v1					= auxpair->v1;
 	simplif::vert_info& v0_info = vertex_info(v0);
 	simplif::vert_info& v1_info = vertex_info(v1);
-	simplif::Vec3 vnew = auxpair->candidate;
+	simplif::Vec3 vnew					= auxpair->candidate;
+
 	int i;
+	
+	// V0 must be always the alive vertex
+	// V1 must be always the removed vertex
+	if (vnew == (*v0))
+	{
+		//	Simplification step.
+		simplifstep.mV0 = v0->vID;
+		simplifstep.mV1 = v1->vID;
+	}
+	else
+	{
+		//	Simplification step.
+		simplifstep.mV0 = v1->vID;
+		simplifstep.mV1 = v0->vID;
+		v0->vID = v1->vID;
+	}
 
 	// Make v0 be the new vertex
-	v0_info.Q += v1_info.Q;
-	v0_info.norm += v1_info.norm;
+	v0_info.Q		+= v1_info.Q;
+	v0_info.norm	+= v1_info.norm;
 
 	simplif::Vec3 p(vnew);
-	simplif::Vec3 v0antes(v0->operator[](simplif::X),v0->operator[](simplif::Y),v0->operator[](simplif::Z));
-
-	// Find the edge to remove (before remove it (contract()))
-	simplif::Edge *econ=NULL;
-	bool finded = false;
-	for (i=0; i<v0->edgeUses().length(); i++)
-	{		
-		econ = v0->edgeUses()(i);
-		if (v1->vID == econ->org()->vID || v1->vID == econ->dest()->vID)
-		{
-			finded = true;
-			break;
-		}
-	}
-
-	assert(finded);
-
-
-	// Perform the actual contraction
+/*	simplif::Vec3 v0antes(v0->operator[](simplif::X),
+						  v0->operator[](simplif::Y),
+						  v0->operator[](simplif::Z));*/
+
+	//	Perform the actual contraction.
 	static simplif::face_buffer changed;
+
 	changed.reset();
 	m.contract(v0, v1, vnew, changed);
 
-	// Stores the simplification step
-	MeshSimplificationSequence::Step simplifstep;
-	simplif::Vec3 vdesp = p - v0antes;
-
-	// Stores the displacement in the simplification step
-	simplifstep.x=(float)vdesp[simplif::X];
-	simplifstep.y = (float)vdesp[simplif::Y];
-	simplifstep.z = (float)vdesp[simplif::Z];
-	
-	//	Submeshes which pertains each vertex
-	simplifstep.mV1 = v0->validID(); 
-
-	//	The simplification method returns as v1 the dead vertex.
-	simplifstep.mV0 = v1->validID();
+	std::cout << "Simp seq: " << simplifstep.mV1 << " --> " << simplifstep.mV0 << std::endl;
+
+/*	simplif::Vec3 vdesp = p - v0antes;
+
+	//	Stores the displacement in the simplification step.
+	simplifstep.x	=	(float)vdesp[X];
+	simplifstep.y = (float)vdesp[Y];
+	simplifstep.z = (float)vdesp[Z];*/
+
+	//	Stores the displacement in the simplification step.
+	simplifstep.x =	(float)0.0f;
+	simplifstep.y = (float)0.0f;
+	simplifstep.z = (float)0.0f;
 
 	//	Number of triangles that are removed in this simplification step.
@@ -242,32 +293,36 @@
 	int del_index	=	0;
 
-	// mModfaces y mT0, mT1 of simplifstep stores the triangles id's -> geomesh has not triangles id's
-	for (i=0; i<changed.length(); i++)
-	{
-		simplif::Face *auxface = changed(i);
+	//	Clears faces list.
+	simplifstep.mModfaces.clear();
+
+	//	mModfaces y mT0, mT1 of simplifstep stores 
+	//	the triangles id's -> geomesh has not triangles id's.
+	for (i	=	0;	i < changed.length();	i++)
+	{
+		simplif::Face *auxface	=	changed(i);
 
 		if (auxface->isValid())
 		{
-			// Modified triangles
+			//	Modified triangles.
 			simplifstep.mModfaces.push_back(auxface->validID());
 		}
 		else
 		{
-			// Removed triangles
-			if (_numDelTris==1) 
-			{
-				simplifstep.mT0=auxface->validID();
-				simplifstep.mT1=auxface->validID();
+			//	Removed triangles.
+			if (_numDelTris == 1)
+			{
+				simplifstep.mT0	=	auxface->validID();
+				simplifstep.mT1	=	auxface->validID();
 			}
 			else
 			{
-				if(del_index==0)
+				if(del_index == 0)
 				{
-					simplifstep.mT0=auxface->validID();
+					simplifstep.mT0	=	auxface->validID();
 					del_index++;
 				}
 				else
 				{
-					simplifstep.mT1=auxface->validID();
+					simplifstep.mT1	=	auxface->validID();
 				}
 			}
@@ -275,19 +330,23 @@
 	}
 
-	decim_data.push_back(simplifstep); // Simplification sequence that make reference to the simplification method sequence
+	//	Simplification sequence that make reference to the 
+	//	simplification method sequence.
+	//decim_data.push_back(simplifstep);
+
+	//	Adds new simplification step.
+	msimpseq->mSteps.push_back(simplifstep);
 
 #ifdef SUPPORT_VCOLOR
-	//
-	// If the vertices are colored, color the new vertex
-	// using the average of the old colors.
+	//	If the vertices are colored, color the new vertex
+	//	using the average of the old colors.
 	v0->props->color += v1->props->color;
 	v0->props->color /= 2;
 #endif
 
-	// Remove the pair that we just contracted
+	//	Remove the pair that we just contracted.
 	delete_pair(auxpair);
 
-	// Recalculate pairs associated with v0
-	for(i=0; i<v0_info.pairs.length(); i++)
+	//	Recalculate pairs associated with v0.
+	for (i	=	0;	i < v0_info.pairs.length();	i++)
 	{
 		simplif::pair_info *p = v0_info.pairs(i);
@@ -295,42 +354,60 @@
 	}
 
-	// Process pairs associated with now dead vertex
-	static simplif::pair_buffer condemned(6); // collect condemned pairs for execution
+	//	Process pairs associated with now dead vertex.
+	//	Collect condemned pairs for execution.
+	static simplif::pair_buffer condemned(6);
+
 	condemned.reset();
 
-	for(i=0; i<v1_info.pairs.length(); i++)
+	for (i	=	0;	i < v1_info.pairs.length(); i++)
 	{
 		simplif::pair_info *p = v1_info.pairs(i);
 
 		simplif::Vertex *u;
-		if( p->v0 == v1 )      
+
+		if( p->v0 == v1 )
+		{
 			u = p->v1;
-		else 
-			if( p->v1 == v1)  
+		}
+		else
+		{
+			if( p->v1 == v1)
+			{
 				u = p->v0;
+			}
 			else
+			{
 				std::cerr << "YOW!  This is a bogus pair." << endl;
-
-		if( !check_for_pair(u, v0) )
-		{
-			p->v0 = v0;
-			p->v1 = u;
+			}
+		}
+
+		if ( !check_for_pair(u, v0) )
+		{
+			p->v0	=	v0;
+			p->v1	=	u;
+
 			v0_info.pairs.add(p);
 			compute_pair_info(p);
 		}
 		else
+		{
 			condemned.add(p);
-	}
-
-	for(i=0; i<condemned.length(); i++)
+		}
+	}
+
+	for (i	=	0;	i < condemned.length();	i++)
+	{
 		// Do you have any last requests?
 		delete_pair(condemned(i));
-	v1_info.pairs.reset(); // safety precaution
-
-}
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-bool SimplificationMethod::decimate_quadric(simplif::Vertex *v, simplif::Mat4& Q)
+	}
+
+	//	Safety precaution.
+	v1_info.pairs.reset();
+}
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+bool SimplificationMethod::decimate_quadric(simplif::Vertex *v,
+																						simplif::Mat4& Q)
 {
 	if( vinfo.length() > 0 )
@@ -340,5 +417,7 @@
 	}
 	else
+	{
 		return false;
+	}
 }
 
@@ -347,4 +426,296 @@
 //---------------------------------------------------------------------------
 void SimplificationMethod::decimate_contract(simplif::Model& m)
+{
+	simplif::heap_node	*top;
+	simplif::pair_info	*pair;
+	simplif::Vertex		*v0;
+	simplif::Vertex		*v1;
+	simplif::Vec3		candidate;
+
+	for (;;)
+	{
+		top	=	heap->extract();
+		
+		if (!top)
+		{
+			return;
+		}
+		
+		pair	=	(simplif::pair_info *)top->obj;
+
+		//	Remove all the vertices of the removed edges.
+		bool	sharededge	=	false;
+		
+		for (int	i	=	0;	i < pair->v0->edgeUses().length();	i++)
+		{
+			simplif::Edge	*econ	=	pair->v0->edgeUses()(i);
+			
+			if (pair->v1->vID == econ->org()->vID
+					||
+					pair->v1->vID == econ->dest()->vID)
+			{
+				sharededge	=	true;
+				break;
+			}
+		}
+
+		if (pair->isValid() && sharededge)
+		{
+			break;
+		}
+
+		//	Deletes repetitions of pair in heap.
+		delete_pair(pair);
+	}
+
+	//	Copy pair.
+	v0	=	new Vertex(	pair->v0->operator[](0),
+										pair->v0->operator[](1),
+										pair->v0->operator[](2));
+	v0->uniqID = pair->v0->uniqID;
+	
+	v1	=	new Vertex(	pair->v1->operator[](0),
+										pair->v1->operator[](1),
+										pair->v1->operator[](2));
+
+	v1->uniqID = pair->v1->uniqID;
+
+	candidate	=	pair->candidate;
+
+	//	First contract.
+	simplifstep.obligatory	=	0;
+
+	//	Debug.
+	cout	<<	"Contracting..."	<<	endl;
+
+	//	Contract main pair.
+	do_contract(m, pair);
+
+	//	Twin contract and lonely vertex contract.
+	simplifstep.obligatory	=	1;
+
+	//	Attempt to maintain valid vertex information.
+	M0.validVertCount--;
+
+	//	Find an edge of the same coordinates and different vertex identifiers.
+	removeTwinEdges(m,v0,v1,candidate);
+
+	//	Move vertex of non twin edges.
+	contractLonelyVertices(m,v0,v1,candidate);
+
+	//	Free Memory.
+	delete	v0;
+	delete	v1;
+}
+
+//---------------------------------------------------------------------------
+//	Contract lonely vertex that has the same coords that the contracted one.
+//---------------------------------------------------------------------------
+void	SimplificationMethod::contractLonelyVertices(	simplif::Model	&m,	simplif::Vertex	*v0,
+																			simplif::Vertex	*v1,
+																			simplif::Vec3	candidate)
+{
+	bool				lonely_vertex_found;
+	simplif::Vertex		*vert;
+	simplif::Vertex		*new_vert;
+	simplif::Vertex		*lonely_vert;
+	simplif::Edge		*edge;
+	simplif::heap_node	*top;
+	simplif::pair_info	*pair;
+	simplif::vert_info	new_vert_info;
+	Geometry::GeoVertex	vertex_added;
+	simplif::Vertex		*take_bone_from_vert;
+
+	//	Gets the vertex that is not the candidate.
+	if ((*v0) == candidate)
+	{
+		vert = v1;
+		take_bone_from_vert = v0;
+	}
+	else if ((*v1) == candidate)
+	{
+		vert = v0;
+		take_bone_from_vert = v1;
+	}
+
+	//	For all vertex.
+	for (int	i = 0; i < heap->getSize();	i++)
+	{
+		//	Initialize lonely vertex flag.
+		lonely_vertex_found	=	false;
+
+		//	Gets the current pair.
+		top		=	heap->getElement(i);
+		pair	=	(simplif::pair_info *)top->obj;
+
+		if (pair->v0->isValid() && (*vert) == (*pair->v0))
+		{
+			lonely_vert	=	pair->v0;
+			lonely_vertex_found	=	true;
+		}
+		else if (pair->v1->isValid() && (*vert) == (*pair->v1))
+		{
+			lonely_vert	=	pair->v1;
+			lonely_vertex_found	=	true;
+		}
+
+		//	If a lonely vertex is found. Creates new vertex and contract.
+		if (lonely_vertex_found)
+		{
+			new_vert	=	m.newVertex(candidate[X],candidate[Y],candidate[Z]);	
+			edge		=	m.newEdge(new_vert,lonely_vert);
+
+            // We assume here the there are the same number of vertices and texture coordinates and normals
+
+			// assign a texture coordinate for the vbertex
+			simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->validID());
+			m.in_TexCoord(newtexcoord);
+
+			// assign a normal coordinate for the vbertex
+			simplif::Vec3 newnormal = m.normal(lonely_vert->validID());
+			m.in_Normal(newnormal);
+
+			//	Adds new vertex information to simplification sequence.
+			vertex_added.id			=	new_vert->vID;
+			vertex_added.bonefrom	=	take_bone_from_vert->vID;
+			vertex_added.position	=	Vector3(candidate[X],candidate[Y],candidate[Z]);
+
+			simplif::Vec2 tc = m.texcoord(new_vert->validID());
+			vertex_added.texcoord	=	Vector2(tc[X],tc[Y]);
+
+			simplif::Vec3 vn = m.normal(new_vert->validID());
+			vertex_added.normal		=	Vector3(vn[X],vn[Y],vn[Z]);
+
+			msimpseq->mNewVertices.push_back(vertex_added);
+
+			pair			=	new_pair(new_vert,lonely_vert);
+			pair->candidate	=	candidate;
+
+			pair->notInHeap();
+/*			vinfo(new_vert->validID()).Q		=	vinfo(lonely_vert->validID()).Q;
+			vinfo(new_vert->validID()).norm	=	vinfo(lonely_vert->validID()).norm;*/
+
+			//	Debug.
+			cout	<<	"Contracting new pair..."	<<	endl;
+
+			//	Contract twin pair.
+			do_contract(m, pair);
+			M0.validVertCount--;
+		}
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Find a twin edge of the given one.
+//---------------------------------------------------------------------------
+void SimplificationMethod::removeTwinEdges(	simplif::Model	&m,
+																						simplif::Vertex	*v0,
+																						simplif::Vertex	*v1,
+																						simplif::Vec3		candidate)
+{
+	bool								twin_found;
+	simplif::heap_node	*top;
+	simplif::pair_info	*pair;
+	simplif::Vertex			*aux_vert;
+
+	//	Find a twin edge in heap.
+	for (int	i	=	0;	i < heap->getSize(); i++)
+	{
+		//	Initialize twin flag.
+		twin_found	=	false;
+
+		//	Gets the current pair.
+		top		=	heap->getElement(i);
+		pair	=	(simplif::pair_info *)top->obj;
+
+		if (pair->v0->isValid()==false || pair->v1->isValid()==false)
+			continue; 
+
+		if (v0->operator[](0) == pair->v0->operator[](0)
+				&&
+				v0->operator[](1) == pair->v0->operator[](1)
+				&&
+				v0->operator[](2) == pair->v0->operator[](2))
+		{
+			if (v1->operator[](0) == pair->v1->operator[](0)
+					&&
+					v1->operator[](1) == pair->v1->operator[](1)
+					&&
+					v1->operator[](2) == pair->v1->operator[](2))
+			{
+				//	Debug.
+				cout	<<	"Twin contracted (NO Swap)..."	<<	endl;
+
+				//	Active twin flag.
+				twin_found	= true;
+			}
+		}
+		else
+		{
+			//	If there is a twin edge in reverse order.
+			if (v0->operator[](0) == pair->v1->operator[](0)
+					&&
+					v0->operator[](1) == pair->v1->operator[](1)
+					&&
+					v0->operator[](2) == pair->v1->operator[](2))
+			{
+				if (v1->operator[](0) == pair->v0->operator[](0)
+						&&
+						v1->operator[](1) == pair->v0->operator[](1)
+						&&
+						v1->operator[](2) == pair->v0->operator[](2))
+				{
+					//	Debug.
+					cout	<<	"Twin contracted (Swap)..."	<<	endl;
+
+					//	Swap.
+					aux_vert	=	pair->v0;
+					pair->v0	=	pair->v1;
+					pair->v1	=	aux_vert;
+
+					//	Active twin flag.
+					twin_found	=	true;
+				}
+			}
+		}
+
+		//	If a twin edge has been found.
+		if (twin_found)
+		{
+			//	Extract twin edge from heap.
+			top		=	heap->extract(i);
+			pair	=	(simplif::pair_info *)top->obj;
+
+			//	Copy candidate.
+			pair->candidate	=	candidate;
+
+			//	Contract twin pair.
+			do_contract(m, pair);
+			i--;
+			M0.validVertCount--;
+		}
+	}
+}
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
+{
+	simplif::vert_info& info = vertex_info(v);
+
+	simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
+
+    if( simplif::will_weight_by_area )
+		{
+			err /= info.norm;
+		}
+
+    return err;
+}
+
+//---------------------------------------------------------------------------
+//	Extract the minimum cost of the the valid nodes (not simplified)
+//---------------------------------------------------------------------------
+simplif::real SimplificationMethod::decimate_min_error()
 {
 	simplif::heap_node *top;
@@ -353,62 +724,17 @@
 	for(;;)
 	{
-		top = heap->extract();
-		if( !top ) return;
+		top = heap->top();
+		
+		if( !top )
+		{
+			return -1.0;
+		}
+
 		pair = (simplif::pair_info *)top->obj;
 
-		//Remove all the vertices of the removed edges
-		bool sharededge= false;
-		for (int i=0; i<pair->v0->edgeUses().length(); i++)
-		{		
-			simplif::Edge *econ = pair->v0->edgeUses()(i);
-			if (pair->v1->vID == econ->org()->vID || pair->v1->vID == econ->dest()->vID)
-			{
-				sharededge= true;
-				break;
-			}
-
-		}
-
-		if( pair->isValid() && sharededge)
+		if( pair->isValid() )
+		{
 			break;
-
-		delete_pair(pair);
-	}
-
-	do_contract(m, pair);
-
-	M0.validVertCount--;  // Attempt to maintain valid vertex information
-}
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
-{
-	simplif::vert_info& info = vertex_info(v);
-
-	simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
-
-    if( simplif::will_weight_by_area )
-		err /= info.norm;
-
-    return err;
-}
-
-//---------------------------------------------------------------------------
-//	Extract the minimum cost of the the valid nodes (not simplified)
-//---------------------------------------------------------------------------
-simplif::real SimplificationMethod::decimate_min_error()
-{
-	simplif::heap_node *top;
-	simplif::pair_info *pair;
-
-	for(;;)
-	{
-		top = heap->top();
-		if( !top ) return -1.0;
-		pair = (simplif::pair_info *)top->obj;
-
-		if( pair->isValid() )
-			break;
+		}
 
 		top = heap->extract();
@@ -442,49 +768,63 @@
 	int i,j;
 
-	vinfo.init(m.vertCount());
-
-	if( simplif::will_use_vertex_constraint )
-		for(i=0; i<m.vertCount(); i++)
-		{
-			simplif::Vertex *v = m.vertex(i);
-			if( v->isValid() )
+	//	Reserve memory for vert_info array.
+	vinfo.init(m.vertCount()*10);
+
+	if (simplif::will_use_vertex_constraint)
+	{
+		//	For each vertex, calculate contraints.
+		for	(i	=	0;	i < m.vertCount();	i++)
+		{
+			simplif::Vertex	*v	=	m.vertex(i);
+			
+			if (v->isValid())
+			{
 				vertex_info(v).Q = simplif::quadrix_vertex_constraint(*v);
-		}
-
-	for(i=0; i<m.faceCount(); i++)
-		if( m.face(i)->isValid() )
-		{
-			if( simplif::will_use_plane_constraint )
+			}
+		}
+	}
+
+	//	Sets the fill value of the vinfo buffer.
+	//vinfo.setFill(m.vertCount());
+
+	//	For each face, recalculate constraints.
+	for (i	=	0;	i < m.faceCount();	i++)
+	{
+		if (m.face(i)->isValid())
+		{
+			if (simplif::will_use_plane_constraint)
 			{
 				simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
 				simplif::real norm = 0.0;
 
-				if( simplif::will_weight_by_area )
+				if (simplif::will_weight_by_area)
 				{
-					norm = m.face(i)->area();
-					Q *= norm;
+					norm	=		m.face(i)->area();
+					Q			*=	norm;
 				}
 
-				for(j=0; j<3; j++)
+				for (j	=	0;	j < 3;	j++)
 				{
-					vertex_info(m.face(i)->vertex(j)).Q += Q;
-					vertex_info(m.face(i)->vertex(j)).norm += norm;
-
+					vertex_info(m.face(i)->vertex(j)).Q			+=	Q;
+					vertex_info(m.face(i)->vertex(j)).norm	+=	norm;
 				}
 			}
 		}
-
-	if( simplif::will_constrain_boundaries )
-	{
-		for(i=0; i<m.edgeCount(); i++)
-			if( m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)) )
+	}
+
+	if (simplif::will_constrain_boundaries)
+	{
+		//	For each edge, recalculate constraints.
+		for (i	=	0;	i < m.edgeCount();	i++)
+		{
+			if (m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)))
 			{
 				simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
 				simplif::real norm = 0.0;
 
-				if( simplif::will_weight_by_area )
+				if (simplif::will_weight_by_area)
 				{
-					norm = simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
-					B *= norm;
+					norm	=		simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
+					B			*=	norm;
 				}
 
@@ -495,12 +835,16 @@
 				vertex_info(m.edge(i)->dest()).norm += norm;
 			}
-	}
-
+		}
+	}
+
+	//	Create heap.
 	heap = new simplif::Heap(m.validEdgeCount);
 
 	int pair_count = 0;
 
-	for(i=0; i<m.edgeCount(); i++)
-		if( m.edge(i)->isValid() )
+	//	For each edge, add pairs to heap.
+	for (i	=	0;	i < m.edgeCount();	i++)
+	{
+		if (m.edge(i)->isValid())
 		{
 			simplif::pair_info *pair = new_pair(m.edge(i)->org(), m.edge(i)->dest());
@@ -509,33 +853,42 @@
 			pair_count++;
 		}
-
-	if( limit<0 )
-	{
-		limit = m.bounds.radius * 0.05;
-	}
-	proximity_limit = limit * limit;
-	if( proximity_limit > 0 )
+	}
+
+	if (limit < 0)
+	{
+		limit	=	m.bounds.radius * 0.05;
+	}
+	
+	proximity_limit	=	limit * limit;
+	
+	if (proximity_limit > 0)
 	{
 		simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
-		for(i=0; i<m.vertCount(); i++)
+		
+		//	Add points to grid.
+		for (i	=	0;	i < m.vertCount();	i++)
+		{
 			grid.addPoint(m.vertex(i));
+		}
 
 		simplif::buffer<simplif::Vec3 *> nearby(32);
-		for(i=0; i<m.vertCount(); i++)
+		
+		//	For each vertex.
+		for (i	=	0;	i < m.vertCount();	i++)
 		{
 			nearby.reset();
 			grid.proximalPoints(m.vertex(i), nearby);
 
-			for(j=0; j<nearby.length(); j++)
+			for (j	=	0;	j < nearby.length();	j++)
 			{
 				simplif::Vertex *v1 = m.vertex(i);
 				simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
 
-				if( v1->isValid() && v2->isValid() )
+				if (v1->isValid() && v2->isValid())
 				{
 #ifdef SAFETY
 					assert(pair_is_valid(v1,v2));
 #endif
-					if( !check_for_pair(v1,v2) )
+					if (!check_for_pair(v1,v2))
 					{
 						simplif::pair_info *pair = new_pair(v1,v2);
@@ -544,5 +897,4 @@
 					}
 				}
-
 			}
 		}
@@ -555,9 +907,7 @@
 void SimplificationMethod::simplifmethod_init(void)
 {
-	int i;
-
 	// Change mesh structure.
-	geomesh2simplifModel();
-
+	generateSimplifModel();
+		
 	M0.bounds.complete();
 
@@ -566,16 +916,22 @@
 	initialFaceCount = M0.faceCount();
 
-	// Get rid of degenerate faces
-	for(i=0; i<M0.faceCount(); i++)
-		if( !M0.face(i)->plane().isValid() )
+	// Get rid of degenerate faces.
+	for (int	i	=	0;	i < M0.faceCount();	i++)
+	{
+		if (!M0.face(i)->plane().isValid())
+		{
 			M0.killFace(M0.face(i));
+		}
+	}
 
 	M0.removeDegeneracy(M0.allFaces());
 
-	// Get rid of unused vertices
-	for(i=0; i<M0.vertCount(); i++)
-	{
-		if( M0.vertex(i)->edgeUses().length() == 0 )
+	// Get rid of unused vertices.
+	for (int	i	=	0;	i < M0.vertCount();	i++)
+	{
+		if (M0.vertex(i)->edgeUses().length() == 0)
+		{
 			M0.vertex(i)->kill();
+		}
 	}
 }
@@ -598,13 +954,23 @@
 	}
 
-	for (std::vector<MeshSimplificationSequence::Step>::iterator it= decim_data.begin(); it!=decim_data.end(); it++)
+	/*
+	for (	std::vector<MeshSimplificationSequence::Step>::iterator
+				it	=	decim_data.begin();
+				it != decim_data.end();
+				it++)
 	{
 		it->mModfaces.clear();
 	}
+	
 	decim_data.clear();
-
-	while( M0.validFaceCount > finalfaces/*simplif::face_target*/
-			&& M0.validFaceCount > 1
-			&& decimate_min_error() < simplif::error_tolerance ) 
+	*/
+
+	//	Debug.
+	cout	<<	"M0.validFaceCount: "	<<	M0.validFaceCount	<<	endl;
+	cout	<<	"finalfaces: "				<<	finalfaces				<<	endl;
+	
+	while ( M0.validFaceCount > finalfaces/*simplif::face_target*/
+					&& M0.validFaceCount > 1
+					&& decimate_min_error() < simplif::error_tolerance )
 	{
 		decimate_contract(M0);
@@ -636,5 +1002,7 @@
 	previousValidVertCount	=	0;
 
-	percent	=	(float)(2.0 * 100.0) /(float)((M0.validFaceCount - numvertices / 3.0));
+	percent	=	(float)(2.0 * 100.0)
+						/
+						(float)((M0.validFaceCount - numvertices / 3.0));
 
 	//	Update progress bar.
@@ -644,9 +1012,19 @@
 	}
 
-	for (std::vector<MeshSimplificationSequence::Step>::iterator it= decim_data.begin(); it!=decim_data.end(); it++)
+	/*
+	for (	std::vector<MeshSimplificationSequence::Step>::iterator
+				it	=	decim_data.begin();
+				it != decim_data.end();
+				it++)
 	{
 		it->mModfaces.clear();
 	}
+	
 	decim_data.clear();
+	*/
+
+	//	Debug.
+	cout	<<	"M0.validVertCount:	"	<<	M0.validVertCount	<<	endl;
+	cout	<<	"numvertices:	"	<<	numvertices	<<	endl;
 
 	while(	M0.validVertCount > numvertices	/*simplif::face_target*/
@@ -680,8 +1058,22 @@
 {
 	public:
+
 		float x,y,z;
-		_float3_(float x=0.0f, float y=0.0f, float z=0.0f){ this->x = x; this->y = y; this->z = z; }
-		_float3_(const _float3_ &f){ x=f.x; y=f.y; z=f.z; }
-		_float3_ & operator=(const _float3_ &f){ x=f.x; y=f.y; z=f.z; return *this; }
+
+		_float3_(float x=0.0f, float y=0.0f, float z=0.0f)
+		{
+			this->x = x; this->y = y; this->z = z;
+		}
+
+		_float3_(const _float3_ &f)
+		{
+			x=f.x; y=f.y; z=f.z;
+		}
+
+		_float3_ & operator=(const _float3_ &f)
+		{
+			x=f.x; y=f.y; z=f.z; return *this;
+		}
+
 		bool operator<(const _float3_ &f) const 
 		{ 
@@ -696,237 +1088,85 @@
 };
 
-
-//---------------------------------------------------------------------------
-//Unify the model to work with it
-//The vertices that have the same space coordinates are stored as an unique vertex
-//in order to avoid holes in the simplification
-//The necessary information to store correctly the decimation data is stored
-//---------------------------------------------------------------------------
-void SimplificationMethod::geomesh2simplifModel(void)
-{
-	std::map<_float3_,int> vertices_map; //Unique vertices (without repetitions) from all the submeshes
-	unsigned int num_final_verts = 0; //Number of unique vertices from all the submeshes
-
-	int num_final_verts2=0;
-	int num_repeated_verts=0;
-
-	int simplifindex;
-	for (size_t i=0; i<objmesh->mSubMeshCount; i++) //For all the submeshes
-	{
-		if (i	!=	indexMeshLeaves)
-		{
-			//If the model has texture information
-			if (objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo & VERTEX_TEXCOORDS) 
-			{
-				//For all the vertices of each submesh
-				for (size_t j=0; j<objmesh->mSubMesh[i].mVertexBuffer->mVertexCount; j++) 
-				{
-					_float3_ auxvert(objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x, 
+//---------------------------------------------------------------------------
+//	Generate simplification model.
+//---------------------------------------------------------------------------
+void	SimplificationMethod::generateSimplifModel(void)
+{
+	int	face_index	=	0;
+
+	//	For each submesh.
+	bool added_vertices = false;
+	for (size_t	i =	0;	i	<	objmesh->mSubMeshCount;	i++)
+	{
+		//	If is not a tree leaves submesh.
+		if (i != indexMeshLeaves)
+		{
+			//	For all the vertices of each submesh.
+			for (	size_t	j	=	0;
+					j < objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
+					j++)
+			{
+				//	If the vertex is not in vertices_map, then is added.
+				M0.in_Vertex(simplif::Vec3(
+							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
 							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z);
-
-					std::map<_float3_,int>::iterator mit = vertices_map.find(auxvert);
-					if (mit==vertices_map.end())
-					{
-						//If the vertex is not in vertices_map, then is added
-						simplifindex=M0.in_Vertex(simplif::Vec3(objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x, 
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
-						M0.in_Normal(simplif::Vec3(objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x, 
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
-
-						M0.in_TexCoord(simplif::Vec2(objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x, 
-									objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
-						vertices_map[auxvert] = num_final_verts;
-						num_final_verts ++;
-
-						std::vector<int> v;
-						submeshmap[simplifindex]=v;
-						submeshmap[simplifindex].push_back((int)i); //Add the index of the mesh that contains the vertex
-						std::vector<int> v2;
-						vertexbuffermap[simplifindex]=v2;
-						vertexbuffermap[simplifindex].push_back((int)j); //Add the index of vertex in the submesh
-
-						// Debug
-						num_final_verts2++;
-					}
-					else
-					{
-						//the vertex is already in vertices_map, so store the reference of the first one with the same space coodinates
-						simplifindex = mit->second;
-						submeshmap[simplifindex].push_back((int)i); //Submeshes that contains the vertex
-						vertexbuffermap[simplifindex].push_back((int)j); //Indices of the vertex buffers that contains the vertex
-
-						// Debug
-						num_repeated_verts++;
-					}	
-				}
-			}
-			else //the model has not texture information
-			{ 
-				//For all the vertices of each submesh
-				for (size_t j=0; j<objmesh->mSubMesh[i].mVertexBuffer->mVertexCount; j++) 
-				{
-					_float3_ auxvert(objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x, 
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
-							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z);
-
-					std::map<_float3_,int>::iterator mit = vertices_map.find(auxvert);
-					if (mit==vertices_map.end())
-					{
-						//If the vertex is not in vertices_map, then is added
-						simplifindex=M0.in_Vertex(simplif::Vec3(objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x, 
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
-									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
-						M0.in_Normal(simplif::Vec3(objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x, 
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
-									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
-						M0.in_TexCoord(simplif::Vec2(0.0,0.0));
-						vertices_map[auxvert] = num_final_verts;
-						num_final_verts ++;
-
-						std::vector<int> v;
-						submeshmap[simplifindex]=v;
-						submeshmap[simplifindex].push_back((int)i); //Add the index of the mesh that contains the vertex
-						std::vector<int> v2;
-						vertexbuffermap[simplifindex]=v2;
-						vertexbuffermap[simplifindex].push_back((int)j); //Add the index of vertex in the submesh
-					}
-					else
-					{
-						//the vertex is already in vertices_map, so store the reference of the first one with the same space coodinates
-						simplifindex = mit->second;
-						submeshmap[simplifindex].push_back((int)i); //Submeshes that contains the vertex
-						vertexbuffermap[simplifindex].push_back((int)j); //Indices of the vertex buffers that contains the vertex
-					}	
-				}
-			}
-			if (objmesh->mSubMesh[i].mSharedVertexBuffer)
-			{
-				printf("Shared break");
-				break;
-			}
-		}
-	}
-
-	//Create the faces
-	unsigned int base_index=0;
-
-	number_of_triangles=0; //Number of triangles of the model
-	int face_index=0;
-
-	int index_in_vertices_map0,index_in_vertices_map1,index_in_vertices_map2;
-	for (size_t i=0; i<objmesh->mSubMeshCount; i++) //For all the submeshes
-	{ 
-		if (i!=indexMeshLeaves)
-		{
-			for (Index j=0; j<objmesh->mSubMesh[i].mIndexCount; j+=3) 
-			{
-				//+1 is required because the first index in the simplification method is 1
-				//Index of the vertex in vertices_map
-				Index indice0=objmesh->mSubMesh[i].mIndex[j];
-				_float3_ auxvert0(objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice0].x, 
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice0].y,
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice0].z);
-				index_in_vertices_map0=vertices_map[auxvert0] + 1;
-
-				Index indice1=objmesh->mSubMesh[i].mIndex[j+1];
-				_float3_ auxvert1(objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice1].x, 
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice1].y,
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice1].z);
-				index_in_vertices_map1=vertices_map[auxvert1] + 1;
-
-				Index indice2=objmesh->mSubMesh[i].mIndex[j+2];
-				_float3_ auxvert2(objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice2].x, 
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice2].y,
-						objmesh->mSubMesh[i].mVertexBuffer->mPosition[indice2].z);
-				index_in_vertices_map2=vertices_map[auxvert2] + 1;
-
-				//Create a triangle with its indices in vertices_map
-				face_index=M0.miin_Face(index_in_vertices_map0,index_in_vertices_map1,index_in_vertices_map2);
-
-				//igeo allows to identify the submesh that contains the triangle
-				M0.face(face_index)->igeo=(int)i;
-			}
-		}
-	}
-	number_of_triangles=face_index;
-}
-
-
-//---------------------------------------------------------------------------
-//Wrties a file with the vertices, triangles and the simplification sequence
-//---------------------------------------------------------------------------
-void SimplificationMethod::WriteOBJ(void)
-{
-	MeshSimplificationSequence::Step stepaux;
-	vector<int> v0,v1,submesh0,submesh1;
-	std::ofstream obj("salida.lod");
-	obj << "begin" << std::endl;
-	//vertices
-	for (size_t i=0; i<objmesh->mSubMeshCount; i++) 
-	{
-		for (size_t j=0; j<objmesh->mSubMesh[i].mVertexBuffer->mVertexCount; j++) 
-		{	
-			obj << "v " <<  objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x << " " <<
-				objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y << " " <<
-				objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z << " " << std::endl;
-		}
-	}
-
-
-	//faces
-	for (size_t i=0; i<objmesh->mSubMeshCount; i++) 
-	{
-		for (size_t j=0; j<objmesh->mSubMesh[i].mIndexCount; j=j+3) 
-		{	
-			obj << "f " <<  objmesh->mSubMesh[i].mIndex[j]+1 << " " << 
-				objmesh->mSubMesh[i].mIndex[j+1]+1 << " " << 
-				objmesh->mSubMesh[i].mIndex[j+2]+1 << std::endl;
-		}
-	}
-
-	obj << "end" << std::endl;
-
-	for (unsigned i=0; i<decim_data.size(); i++) 
-	{
-		stepaux = decim_data.operator [](i);
-		v0=vertexbuffermap[stepaux.mV0];  //vertexbuffer index
-		submesh0=submeshmap[stepaux.mV0]; //displacement for each submesh
-		v1=vertexbuffermap[stepaux.mV1];
-		submesh1=submeshmap[stepaux.mV1];
-		for (unsigned j=0; j<v0.size(); j++)
-		{
-			for (unsigned k=0; k<v1.size(); k++) 
-			{
-				//obtain the index of the VertexBuffer of each submesh and the displacemente by submesh
-				obj << "v% " << v1.operator [](k)+first_index_submesh[submesh1.operator [](k)] << 
-					" " << v0.operator [](j)+first_index_submesh[submesh0.operator [](j)] << " " << 
-					stepaux.x << " " << stepaux.y << " " << stepaux.z << " " << stepaux.mT0 << " " <<
-					stepaux.mT1 << " & ";
-				if (stepaux.mModfaces.size()>0) 
-				{
-					unsigned int ii=0;
-					for (ii=0; ii<stepaux.mModfaces.size()-1; ii++) 
-					{
-						obj << stepaux.mModfaces.operator [](ii) << " ";
-					}
-					obj << stepaux.mModfaces.operator [](ii) << std::endl;
-				}
-				else 
-				{ 
-					obj << std::endl; 
-				}					
-			}
-		}
-	}
-	obj.close();
-}
-
-//---------------------------------------------------------------------------
-//simplifmethod_init is executed to do some initalizations
-//simplifmethod_run is executed to do the decimation
-//Then, the simpified model is created and the decimation information is returned
+							objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
+
+				M0.in_Normal(simplif::Vec3(
+							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
+							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
+							objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
+
+				M0.in_TexCoord(simplif::Vec2(
+							objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
+							objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
+
+				added_vertices = true;
+			}
+		}	
+		
+		//	If is shared vertex buffer object.
+		if (objmesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
+		{
+			printf("Shared break");
+			break;
+		}
+	}
+
+	//	For each submesh.
+	for (size_t	i = 0;	i < objmesh->mSubMeshCount;	i++)
+	{
+		if (i != indexMeshLeaves)
+		{
+			for (Index	j	=	0;	j < objmesh->mSubMesh[i].mIndexCount;	j	+=	3)
+			{
+				//	+1 is required because the first index in the
+				//	simplification method is 1
+				//	Index of the vertex in vertices_map.
+				Index index0	=		objmesh->mSubMesh[i].mIndex[j];
+				
+				Index index1	=		objmesh->mSubMesh[i].mIndex[j + 1];
+				
+				Index index2	=		objmesh->mSubMesh[i].mIndex[j + 2];
+				
+				//	Create a triangle with its indices in vertices_map.
+				face_index	=	M0.miin_Face(
+						index0,
+						index1,
+						index2);
+
+				//	igeo allows to identify the submesh that contains the triangle.
+				M0.face(face_index)->igeo	=	(int)i;
+			}
+		}
+	}
+	number_of_triangles	=	face_index;
+}
+
+//---------------------------------------------------------------------------
+//	simplifmethod_init is executed to do some initalizations
+//	simplifmethod_run is executed to do the decimation
+//	Then, the simpified model is created and the decimation 
+//	information is returned.
 //---------------------------------------------------------------------------
 MeshSimplificationSequence *SimplificationMethod::Decimate(	float lod,
@@ -938,10 +1178,10 @@
 	if (simpliftype == 0)
 	{
-		//Percentage option
+		//	Percentage option.
 		simplifmethod_run((int)(number_of_triangles*lod),upb);
 	}
 	else
 	{
-		//Number of vertices option
+		//	Number of vertices option.
 		simplifmethod_runv((int)lod,upb);
 	}
@@ -953,6 +1193,8 @@
 	typedef std::vector<int> REPINDLIST;
 
-	MAPAINDIND *unique_verts_inds_by_geo = new MAPAINDIND[objmesh->mSubMeshCount]; 
-	REPINDLIST *ver_inds_rep_by_geo 	= new REPINDLIST[objmesh->mSubMeshCount]; 
+	MAPAINDIND *unique_verts_inds_by_geo =
+														new MAPAINDIND[objmesh->mSubMeshCount];
+
+	REPINDLIST *ver_inds_rep_by_geo	= new REPINDLIST[objmesh->mSubMeshCount];
 
 	//	Index counter by submesh.
@@ -964,6 +1206,6 @@
 	}
 
-
 	//	Construct the model.
+	std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
 	for (int	i = 0;	i < M0.faceCount();	i++)
 	{
@@ -976,25 +1218,37 @@
 
 			//	Insert to each submesh its triangles.
-			std::map<int,int>::iterator findit = unique_verts_inds_by_geo[igeo].find(auxface->vertex(0)->validID());
+			std::map<int,int>::iterator findit =
+				unique_verts_inds_by_geo[igeo].find(auxface->vertex(0)->validID());
+			
 			if (findit == unique_verts_inds_by_geo[igeo].end())
 			{
 				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(0)->validID()] = inextvert[igeo];
+				unique_verts_inds_by_geo[igeo][auxface->vertex(0)->validID()] =
+																														inextvert[igeo];
+				
 				inextvert[igeo]++;
-			}			
-			findit = unique_verts_inds_by_geo[igeo].find(auxface->vertex(1)->validID());
+			}
+
+			findit =
+				unique_verts_inds_by_geo[igeo].find(auxface->vertex(1)->validID());
+			
 			if (findit == unique_verts_inds_by_geo[igeo].end())
 			{
 				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(1)->validID()] = inextvert[igeo];
+				unique_verts_inds_by_geo[igeo][auxface->vertex(1)->validID()] =
+																														inextvert[igeo];
 				inextvert[igeo]++;
-			}			
-			findit = unique_verts_inds_by_geo[igeo].find(auxface->vertex(2)->validID());
+			}
+			
+			findit = 
+				unique_verts_inds_by_geo[igeo].find(auxface->vertex(2)->validID());
+			
 			if (findit == unique_verts_inds_by_geo[igeo].end())
 			{
 				//	If it is not added... add and map it.
-				unique_verts_inds_by_geo[igeo][auxface->vertex(2)->validID()] = inextvert[igeo];
+				unique_verts_inds_by_geo[igeo][auxface->vertex(2)->validID()] = 
+																														inextvert[igeo];
 				inextvert[igeo]++;
-			}			
+			}
 
 			//	Total number of indices by submesh.
@@ -1043,8 +1297,9 @@
 	bool copiedShared = false;
 
+	//	For each submesh.
 	for (size_t	i = 0;	i < objmesh->mSubMeshCount;	i++)
 	{
-		mGeoMesh->mSubMesh[i].mStripCount					=	0;
-		mGeoMesh->mSubMesh[i].mStrip							=	NULL;
+		mGeoMesh->mSubMesh[i].mStripCount	=	0;
+		mGeoMesh->mSubMesh[i].mStrip			=	NULL;
 
 		mGeoMesh->
@@ -1060,5 +1315,5 @@
 			{
 				mGeoMesh->mSubMesh[i].mBones.push_back(objmesh->
-						mSubMesh[i].mBones[j]);
+																				mSubMesh[i].mBones[j]);
 			}
 		}
@@ -1068,6 +1323,7 @@
 			//	Indices vectors.
 			mGeoMesh->mSubMesh[i].mIndexCount	=	ver_inds_rep_by_geo[i].size();
+			
 			mGeoMesh->mSubMesh[i].mIndex			=	new Index[mGeoMesh->
-				mSubMesh[i].mIndexCount];
+																						mSubMesh[i].mIndexCount];
 
 			//	Store the indices.
@@ -1075,5 +1331,8 @@
 			{
 				//	Obtain the indices that point at VertexBuffer.
-				mGeoMesh->mSubMesh[i].mIndex[j]	=	unique_verts_inds_by_geo[i].operator [](ver_inds_rep_by_geo[i].operator [](j));
+				mGeoMesh->mSubMesh[i].mIndex[j]	=
+					unique_verts_inds_by_geo[i].
+								operator [](ver_inds_rep_by_geo[i].
+								operator [](j));
 			}
 
@@ -1096,11 +1355,19 @@
 			}
 
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount	=	unique_verts_inds_by_geo[i].size();
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo	=	objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount	=
+																	unique_verts_inds_by_geo[i].size();
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo	=
+											objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
 
 			//	Allocate memory for position, normal and texutre coordinates.
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition	=	new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal		=	new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords	=	new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition	=
+						new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal		=
+						new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords	=
+						new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
 
 			for (	MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
@@ -1114,16 +1381,22 @@
 				//	Vertex coordinate.
 				//	Construction of the submeshes.
-				Vector3 v3((Real)M0.vertex(isrc)->operator [](0),
-						(Real)M0.vertex(isrc)->operator [](1),
-						(Real)M0.vertex(isrc)->operator [](2));
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]=v3;
+				Vector3 v3(	(Real)M0.vertex(isrc)->operator [](0),
+										(Real)M0.vertex(isrc)->operator [](1),
+										(Real)M0.vertex(isrc)->operator [](2));
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]	=	v3;
 
 				//	Normal coordinates.
-				Vector3 v3n((Real)M0.normal(isrc)(0), (Real)M0.normal(isrc)(1), (Real)M0.normal(isrc)(2));
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]=v3n;
+				Vector3 v3n(	(Real)M0.normal(isrc)(0),
+											(Real)M0.normal(isrc)(1),
+											(Real)M0.normal(isrc)(2));
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]	=	v3n;
 
 				//	Texture coordinates.
-				Vector2 v2((Real)M0.texcoord(isrc)(0), (Real)M0.texcoord(isrc)(1));
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]=v2;
+				Vector2 v2(	(Real)M0.texcoord(isrc)(0),
+										(Real)M0.texcoord(isrc)(1));
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]	=	v2;
 			}
 		}
@@ -1131,22 +1404,32 @@
 		{
 			//	Leaves mesh.
-			mGeoMesh->mSubMesh[i].mIndexCount=objmesh->mSubMesh[i].mIndexCount;
-			mGeoMesh->mSubMesh[i].mIndex=new Index[mGeoMesh->mSubMesh[i].mIndexCount];
+			mGeoMesh->mSubMesh[i].mIndexCount	=	objmesh->mSubMesh[i].mIndexCount;
+			
+			mGeoMesh->mSubMesh[i].mIndex	=		new Index[mGeoMesh->mSubMesh[i].mIndexCount];
 
 			//	Copy the leaves submesh indexes.
-			for (unsigned int j=0; j<mGeoMesh->mSubMesh[i].mIndexCount; j++)
+			for (unsigned int	j	=	0;	j < mGeoMesh->mSubMesh[i].mIndexCount;	j++)
 			{	
-				mGeoMesh->mSubMesh[i].mIndex[j]=objmesh->mSubMesh[i].mIndex[j];
+				mGeoMesh->mSubMesh[i].mIndex[j]	=	objmesh->mSubMesh[i].mIndex[j];
 			}
 
 			//	Copy the leaves submesh vertices.
-			mGeoMesh->mSubMesh[i].mVertexBuffer=new VertexBuffer();
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount=objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo=objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
+			mGeoMesh->mSubMesh[i].mVertexBuffer	=	new VertexBuffer();
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount	=
+														objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo	=
+														objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
 
 			//	Allocate memory for position, normal and texture coordinates.
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition=new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal=new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
-			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords=new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition	=
+							new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal	=
+							new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
+			
+			mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords	=
+							new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
 
 			for (	unsigned int j = 0;
@@ -1155,16 +1438,29 @@
 			{
 				//	Position.
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x=objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y=objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z=objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x	=
+									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y	=
+									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z	=
+									objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
 
 				//	Normals.
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x=objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y=objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z=objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x	=
+									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y	=
+									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z	=
+									objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
 
 				//	Textures.
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x=objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
-				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y=objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x	=
+									objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
+				
+				mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y	=
+									objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
 			}
 		}
@@ -1176,5 +1472,5 @@
 
 	//	Store the simplification steps in MeshSimplificationSequence.
-	int acum	=	0;
+	int	acum	=	0;
 
 	for (size_t i	=	0; i < objmesh->mSubMeshCount; i++)
@@ -1192,64 +1488,9 @@
 	}
 
-	MeshSimplificationSequence::Step stepaux, newstep;
-	vector<int> v0,v1,submesh0,submesh1;
-	MeshSimplificationSequence *msimpseq;
-
-	msimpseq	=	new MeshSimplificationSequence();
-
-	for (unsigned i = 0;	i < decim_data.size();	i++) 
-	{
-		stepaux		=	decim_data.operator [](i);
-		v0				=	vertexbuffermap[stepaux.mV0];  // vertexbuffer index
-		submesh0	=	submeshmap[stepaux.mV0]; // displacement by submesh
-		v1				=	vertexbuffermap[stepaux.mV1];
-		submesh1	=	submeshmap[stepaux.mV1];
-
-		for (unsigned j = 0;	j < v0.size();	j++)
-		{
-			for (unsigned k = 0;	k < v1.size(); k++)
-			{
-				//	Obtain the submesh index in VertexBuffer
-				//	and the displacement by submesh
-				newstep.mV0	=	v0.operator [](j)+first_index_submesh[submesh0.operator [](j)];
-				newstep.mV1	=	v1.operator [](k)+first_index_submesh[submesh1.operator [](k)];
-				newstep.x		=	stepaux.x;
-				newstep.y		=	stepaux.y;
-				newstep.z		=	stepaux.z;
-
-				// mT0 y mT1 are unique triangles identifiers
-				// returned by the simplification method
-				newstep.mT0	=	stepaux.mT0;
-				newstep.mT1	=	stepaux.mT1;
-
-				if (j == v0.size() - 1 && k == v1.size() - 1)
-				{
-					newstep.obligatorio	=	0;
-				}
-				else
-				{
-					newstep.obligatorio	=	1;
-				}
-
-				if (j == 0 && k == 0)
-				{
-					//	First simplification step.
-					//	unique triangle identifiers 
-					//	returned by the simplification method.
-					newstep.mModfaces	=	stepaux.mModfaces;
-				}
-				else 
-				{
-					std::vector<Index>	vvacio;
-
-					newstep.mModfaces	=	vvacio;
-				}
-
-				msimpseq->mSteps.push_back(newstep);
-			}
-		}
-	}
-
-	// WriteOBJ();
+	vector<int>	v0;
+	vector<int>	v1;
+	vector<int>	submesh0;
+	vector<int>	submesh1;
+
 	return msimpseq;
 }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/uppalloc.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/uppalloc.cpp	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/uppalloc.cpp	(revision 1526)
@@ -0,0 +1,280 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stddef.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define LLOG(x)
+#define LTIMING(x)
+#define ASSERT(x) assert(x)
+
+namespace upp
+{
+
+typedef unsigned char  byte;
+typedef unsigned short word;
+typedef unsigned int   dword;
+
+struct BlockInfo {
+	BlockInfo *link;
+};
+
+struct PageLink {
+	PageLink  *bucket_next;
+	PageLink  *bucket_prev;
+	PageLink  *free_next;
+	PageLink  *free_prev;
+
+	void LinkSelf() {
+		bucket_next = bucket_prev = free_next = free_prev = this;
+	}
+	void UnlinkBucket() {
+		bucket_prev->bucket_next = bucket_next;
+		bucket_next->bucket_prev = bucket_prev;
+		bucket_next = bucket_prev = this;
+	}
+	void InsertBucket(PageLink *lnk) {
+		lnk->bucket_prev = this;
+		lnk->bucket_next = bucket_next;
+		bucket_next->bucket_prev = lnk;
+		bucket_next = lnk;
+	}
+	void UnlinkFree() {
+		free_prev->free_next = free_next;
+		free_next->free_prev = free_prev;
+		free_next = free_prev = this;
+	}
+	void InsertFree(PageLink *lnk) {
+		lnk->free_prev = this;
+		lnk->free_next = free_next;
+		free_next->free_prev = lnk;
+		free_next = lnk;
+	}
+};
+
+struct PageInfo : public PageLink {
+	BlockInfo *freelist;
+	byte      *memory;
+	word       freecount;
+	word       blockcount;
+	word       magnitude;
+	word       size;
+	
+	void Format(int m) {
+		LTIMING("Format");
+		ASSERT(m >= 0 && m <= 128);
+		magnitude = word(m);
+		size = word(4 * m);
+		byte *p = memory;
+		byte *e = memory + 2048 - size;
+		blockcount = 0;
+		freelist = NULL;
+		while(p <= e) {
+			((BlockInfo *)p)->link = freelist;
+			freelist = (BlockInfo *)p;
+			p += size;
+			blockcount++;
+		}
+		freecount = blockcount;
+	}
+};
+
+
+typedef PageInfo *MemBook[512];
+
+MemBook  nullbook[1];
+MemBook *memmap[2048];
+
+PageInfo *NewPage()
+{
+	LTIMING("NewPage");
+	LLOG("Acquiring new page");
+	static int ci = 32;
+	static PageInfo *chunk;
+	if(ci >= 32) {
+		LLOG("**** Acquiring new 64KB block");
+		dword ptr = (dword)malloc(33 * 2048);
+		if(!ptr) return 0;
+		dword a = (ptr + 2047) & ~2047;
+		if(a - ptr >= 1024)
+			chunk = (PageInfo *)ptr;
+		else
+			chunk = (PageInfo *)(a + 32 * 2048);
+		byte *p = (byte *)a;
+		for(int i = 0; i < 32; i++) {
+			chunk[i].LinkSelf();
+			chunk[i].memory = p;
+			p += 2048;
+		}
+		ci = 0;
+	}
+	PageInfo *p = chunk + ci++;
+	int pgi = ((dword)p->memory >> 11);
+	int bi = pgi >> 9;
+	pgi &= 511;
+	if(memmap[bi] == nullbook) {
+		memmap[bi] = (MemBook *)malloc(sizeof(MemBook));
+		memset(memmap[bi], 0, sizeof(MemBook));
+	}
+	(*memmap[bi])[pgi] = p;
+	return p;
+}
+
+
+#define InitLink2(a, n)         { a + n, a + n, a + n, a + n }, \
+                                { a + n + 1, a + n + 1, a + n + 1, a + n + 1 }
+#define InitLink4(a, n)         InitLink2(a, n),   InitLink2(a,   n + 2)
+#define InitLink8(a, n)         InitLink4(a, n),   InitLink4(a,   n + 4)
+#define InitLink16(a, n)        InitLink8(a, n),   InitLink8(a,   n + 8)
+#define InitLink32(a, n)        InitLink16(a, n),  InitLink16(a,  n + 16)
+#define InitLink64(a, n)        InitLink32(a, n),  InitLink32(a,  n + 32)
+
+PageLink bucket[129] = {
+	InitLink64(bucket, 0),
+	InitLink64(bucket, 64),
+	{ bucket + 128, bucket + 128, bucket + 128, bucket + 128 }
+};
+
+PageLink free_bucket[129] = {
+	InitLink64(free_bucket, 0),
+	InitLink64(free_bucket, 64),
+	{ free_bucket + 128, free_bucket + 128, free_bucket + 128, free_bucket + 128 }
+};
+
+PageLink emptylist[1] = {
+	{ emptylist, emptylist, emptylist, emptylist }
+};
+
+byte size_magnitude[513];
+
+
+void GenerateMagnitudeTable(int *s)
+{
+	int size = 0;
+	int magnitude = *s / 4;
+	while(size <= 512) {
+		ASSERT(*s);
+		if(size > *s) {
+			s++;
+			magnitude = *s / 4;
+		}
+		size_magnitude[size] = byte(magnitude);
+		size++;
+	}
+	ASSERT(*s == 512);
+}
+
+
+void *Alloc(size_t size)
+{
+	LTIMING("Alloc");
+	LLOG("Alloc(" << size << ")");
+	if(size <= 512) {
+		int m = size_magnitude[size];
+		PageLink& bm = bucket[m];
+		PageInfo *page = (PageInfo *)bm.bucket_next;
+		BlockInfo *q;
+		if(page != &bm) {
+			ASSERT(page->freecount > 0 && page->freecount < page->blockcount);
+			LLOG("Allocating from page " << Dump(page));
+			q = page->freelist;
+			page->freelist = q->link;
+			if(--page->freecount == 0) {
+				LLOG("Page exhausted " << Dump(page));
+				page->UnlinkBucket();
+			}
+			return q;
+		}
+		page = (PageInfo *)free_bucket[m].bucket_next;	
+		if(page != &free_bucket[m]) {
+			LLOG("Next empty bucket page " << Dump(page));
+			ASSERT(page->freecount == page->blockcount);
+			page->UnlinkFree();
+			page->UnlinkBucket();
+			bm.InsertBucket(page);
+			q = page->freelist;
+			page->freelist = q->link;
+			if(--page->freecount == 0)
+				page->UnlinkBucket();
+			return q;
+		}
+		page = (PageInfo *)emptylist->free_next;
+		if(page != emptylist) {
+			ASSERT(page->freecount == page->blockcount);
+			LLOG("Recycling page " << Dump(page));
+			page->UnlinkFree();
+			page->UnlinkBucket();
+		}
+		else {
+			static bool init;
+			if(!init) {
+				init = true;
+				static int mtable1[] = { 4, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112,
+			                             128, 144, 168, 200, 256, 336, 408, 512 };
+				GenerateMagnitudeTable(mtable1);
+				for(int i = 0; i < 2048; i++)
+					memmap[i] = nullbook;
+				m = size_magnitude[size];
+			}
+			page = NewPage();
+			if (page == 0) return 0;
+
+		}
+		page->Format(m);
+		LLOG("Formated page " << Dump(page));
+		bucket[m].InsertBucket(page);
+		q = page->freelist;
+		page->freelist = q->link;
+		page->freecount--;
+		return q;
+	}
+	void *q = malloc(size);
+	return q;
+}
+
+
+void Free(void *ptr)
+{
+	int pgi = ((dword)ptr >> 11);
+	PageInfo *page = (*memmap[pgi >> 9])[pgi & 511];
+	if(page) {
+		ASSERT(((dword)ptr & 2047) % page->size == 0);
+		BlockInfo *b = (BlockInfo *)ptr;
+		b->link = page->freelist;
+		page->freelist = b;
+		if(page->bucket_next == page) {
+			LLOG("Putting to bucket " << Dump(page));
+			bucket[page->magnitude].InsertBucket(page);
+		}
+		LLOG("Freeing in page " << Dump(page));
+		if(++page->freecount == page->blockcount) {
+			page->UnlinkBucket();
+			free_bucket[page->magnitude].InsertBucket(page);
+			emptylist->InsertFree(page);
+			LLOG("Moving to empty " << Dump(page));
+		}
+		ASSERT(page->freecount <= page->blockcount);
+	}
+	else
+		free(ptr);
+}
+
+}//namespace upp
+
+#undef LLOG
+#undef LTIMING
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.h	(revision 1526)
@@ -0,0 +1,427 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <int size>
+class RawVector {
+protected:
+	struct Data {
+		byte filler[size];
+	};
+
+	Data    *vector;
+	int      items;
+	int      alloc;
+
+	void     RawFree();
+	Data    *Alloc(int n)            { return (Data *) NTL_RAW_ALLOC(n * sizeof(Data)); }
+	void     Realloc(int newalloc);
+
+	void     Chk() const             { ASSERT(items >= 0); }
+	void     Pick(pick_ RawVector& v);
+	void     SetPicked(pick_ RawVector& v) {
+		RawVector& pick = (RawVector&)(v);
+		pick.items = -1;
+		pick.vector = NULL;
+	}
+
+	void     Expand();
+
+	void     RawInsert(int q, int count);
+	void     RawInsertPick(int i, pick_ RawVector<size>& v);
+
+	void    *RawAdd()                { Chk(); if(items >= alloc) Expand();
+		                               return vector + items++; }
+
+	int      RawGetIndex(const void *item) const;
+
+	RawVector()                      { vector = NULL; items = alloc = 0; }
+
+	void     RawReserve(int xtra);
+	void     RawSwap(RawVector& b);
+};
+
+template <class T>
+class Vector : public RawVector<sizeof(T)>
+               , Moveable< Vector<T> >
+               , DeepCopyOption< Vector<T> > {
+	typedef RawVector<sizeof(T)> B;
+
+	void     Free();
+	void     __DeepCopy(const Vector& src);
+	T&       Get(int i) const        { ASSERT(i >= 0 && i < B::items); return (T&)B::vector[i]; }
+	void     Chk() const             { B::Chk(); }
+	void     Expand()                { B::Expand(); }
+
+public:
+	T&       Add();
+	void     Add(const T& x)         { DeepCopyConstruct(B::RawAdd(), x); }
+	void     AddPick(pick_ T& x)     { ::new(B::RawAdd()) T(x); }
+	void     AddN(int n);
+	const T& operator[](int i) const { return Get(i); }
+	T&       operator[](int i)       { return Get(i); }
+	int      GetCount() const        { Chk(); return B::items; }
+	bool     IsEmpty() const         { Chk(); return B::items == 0; }
+	void     Trim(int n);
+	void     SetCount(int n);
+	void     SetCount(int n, const T& init);
+	void     SetCountR(int n);
+	void     SetCountR(int n, const T& init);
+	void     Clear();
+
+	T&       At(int i)                  { if(i >= B::items) SetCountR(i + 1); return (*this)[i]; }
+	T&       At(int i, const T& x)      { if(i >= B::items) SetCountR(i + 1, x); return (*this)[i]; }
+
+	void     Shrink()                   { B::Realloc(B::items); }
+	void     Reserve(int n)             { B::RawReserve(n); }
+	int      GetAlloc() const           { return B::alloc; }
+
+	void     Set(int i, const T& x, int count = 1);
+	void     Remove(int i, int count = 1);
+	void     Remove(const int *sorted_list, int n);
+	void     Remove(const Vector<int>& sorted_list);
+	void     InsertN(int i, int count = 1);
+	T&       Insert(int i)           { InsertN(i); return Get(i); }
+	void     Insert(int i, const T& x, int count = 1);
+	void     Insert(int i, const Vector& x);
+	void     Insert(int i, const Vector& x, int offset, int count);
+	void     InsertPick(int i, pick_ Vector& x)    { B::RawInsertPick(i, x); }
+	void     Append(const Vector& x)               { Insert(GetCount(), x); }
+	void     Append(const Vector& x, int o, int c) { Insert(GetCount(), x, o, c); }
+	void     AppendPick(pick_ Vector& x)           { B::RawInsertPick(GetCount(), x); }
+	int      GetIndex(const T& item) const         { return B::RawGetIndex(&item); }
+
+	void     Drop(int n = 1)         { ASSERT(n <= GetCount()); Trim(B::items - n); }
+	T&       Top()                   { ASSERT(GetCount()); return Get(B::items - 1); }
+	const T& Top() const             { ASSERT(GetCount()); return Get(B::items - 1); }
+	T        Pop()                   { T h = Top(); Drop(); return h; }
+
+	operator T*()                    { return (T*)B::vector; }
+	operator const T*() const        { return (T*)B::vector; }
+
+	Vector&  operator<<(const T& x)  { Add(x); return *this; }
+	Vector&  operator|(pick_ T& x)   { AddPick(x); return *this; }
+
+#ifdef UPP
+	void     Serialize(Stream& s)    { StreamContainer(s, *this); }
+#endif
+
+	Vector()                         {}
+	~Vector()                        { AssertMoveable<T>(); Free(); }
+
+// Pick assignment & copy. Picked source can only Clear(), ~Vector(), operator=, operator <<=
+	Vector(pick_ Vector& v)          { B::Pick(v); }
+	void operator=(pick_ Vector& v)  { Free(); B::Pick(v); }
+	bool IsPicked() const            { return B::items < 0; }
+
+// Deep copy
+	Vector(const Vector& v, int)     { __DeepCopy(v); }
+
+// Standard container interface
+	typedef T        ValueType;
+	typedef T       *Iterator;
+	typedef const T *ConstIterator;
+
+	ConstIterator    Begin() const          { return (T*)B::vector; }
+	ConstIterator    End() const            { return (T*)B::vector + B::items; }
+	ConstIterator    GetIter(int i) const   { ASSERT(i >= 0 && i <= B::items); return Begin() + i; }
+	Iterator         Begin()                { return (T*)B::vector; }
+	Iterator         End()                  { return (T*)B::vector + B::items; }
+	Iterator         GetIter(int i)         { ASSERT(i >= 0 && i <= B::items); return Begin() + i; }
+
+// Optimalizations
+	friend void Swap(Vector& a, Vector& b)                     { a.B::RawSwap(b); }
+	friend void Append(Vector& dst, const Vector& src)         { dst.Append(src); }
+
+//obsolete names
+	T&       DoIndex(int i)             { return At(i); }
+	T&       DoIndex(int i, const T& x) { return At(i, x); }
+
+	STL_VECTOR_COMPATIBILITY(Vector<T>)
+};
+
+template <class T>
+class Array : Moveable< Array<T> >, DeepCopyOption< Array<T> > {
+protected:
+	Vector<void *> vector;
+
+	void     Free();
+	void     __DeepCopy(const Array& v);
+	T&       Get(int i) const                           { return *(T *)vector[i]; }
+	void     Del(void **ptr, void **lim)                { while(ptr < lim) delete (T *) *ptr++; }
+	void     Init(void **ptr, void **lim)               { while(ptr < lim) *ptr++ = new T; }
+	void     Init(void **ptr, void **lim, const T& x)   { while(ptr < lim) *ptr++ = DeepCopyNew(x); }
+
+public:
+	T&       Add()                      { T *q = new T; vector.Add(q); return *q; }
+	void     Add(const T& x)            { vector.Add(DeepCopyNew(x)); }
+	void     AddPick(pick_ T& x)        { vector.Add(new T(x)); }
+	T&       Add(T *newt)               { vector.Add(newt); return *newt; }
+	const T& operator[](int i) const    { return Get(i); }
+	T&       operator[](int i)          { return Get(i); }
+	int      GetCount() const           { return vector.GetCount(); }
+	bool     IsEmpty() const            { return vector.IsEmpty(); }
+	void     Trim(int n);
+	void     SetCount(int n);
+	void     SetCount(int n, const T& init);
+	void     SetCountR(int n);
+	void     SetCountR(int n, const T& init);
+	void     Clear()                    { Free(); vector.Clear(); }
+
+	T&       At(int i)                  { if(i >= GetCount()) SetCountR(i + 1); return Get(i); }
+	T&       At(int i, const T& x)      { if(i >= GetCount()) SetCountR(i + 1, x); return Get(i); }
+
+	void     Shrink()                   { vector.Shrink(); }
+	void     Reserve(int xtra)          { vector.Reserve(xtra); }
+	int      GetAlloc() const           { return vector.GetAlloc(); }
+
+	void     Set(int i, const T& x, int count = 1);
+	void     Remove(int i, int count = 1);
+	void     Remove(const int *sorted_list, int n);
+	void     Remove(const Vector<int>& sorted_list);
+	void     InsertN(int i, int count = 1);
+	T&       Insert(int i)              { InsertN(i); return Get(i); }
+	void     Insert(int i, const T& x, int count = 1);
+	void     Insert(int i, const Array& x);
+	void     Insert(int i, const Array& x, int offset, int count);
+	void     Append(const Array& x)               { Insert(GetCount(), x); }
+	void     Append(const Array& x, int o, int c) { Insert(GetCount(), x, o, c); }
+	void     InsertPick(int i, pick_ Array& x);
+	void     AppendPick(pick_ Array& x)           { Insert(GetCount(), x); }
+	int      GetIndex(const T& item) const;
+	void     Swap(int i1, int i2)       { ::Swap(vector[i1], vector[i2]); }
+	void     Move(int i1, int i2);
+
+	T       *Detach(int i)              { T *t = &Get(i); vector.Remove(i); return t; }
+	T&       Set(int i, T *newt)        { delete (T *)vector[i]; vector[i] = newt; return *newt; }
+	void     Insert(int i, T *newt);
+
+	void     Drop(int n = 1)            { Trim(GetCount() - n); }
+	T&       Top()                      { return Get(GetCount() - 1); }
+	const T& Top() const                { return Get(GetCount() - 1); }
+//	T        Pop()                      { T h = Top(); Drop(); return h; } // msvc bug
+	T       *PopDetach()                { return (T *) vector.Pop(); }
+
+	void     Swap(Array& b)             { vector.Swap(b.vector); }
+
+	Array& operator<<(const T& x)       { Add(x); return *this; }
+	Array& operator<<(T *newt)          { Add(newt); return *this; }
+	Array& operator|(pick_ T& x)        { AddPick(x); return *this; }
+
+	bool     IsPicked() const           { return vector.IsPicked(); }
+
+#ifdef UPP
+	void     Serialize(Stream& s)       { StreamContainer(s, *this); }
+#endif
+
+	Array()                             {}
+	~Array()                            { Free(); }
+
+// Pick assignment & copy. Picked source can only Clear(), ~Vector(), operator=, operator<<=
+	Array(pick_ Array& v) : vector(v.vector)  {}
+	void operator=(pick_ Array& v)            { Free(); vector = v.vector; }
+
+// Deep copy
+	Array(const Array& v, int)          { __DeepCopy(v); }
+
+	class Iterator;
+
+	class ConstIterator {
+	protected:
+		T **ptr;
+		ConstIterator(T **p)                    { ptr = p; }
+
+		friend class Array<T>;
+		struct NP { int dummy; };
+
+	public:
+		const T& operator*() const              { return **ptr; }
+		const T *operator->() const             { return *ptr; }
+		const T& operator[](int i) const        { return *ptr[i]; }
+
+		ConstIterator& operator++()             { ptr++; return *this; }
+		ConstIterator& operator--()             { ptr--; return *this; }
+		ConstIterator  operator++(int)          { ConstIterator t = *this; ++*this; return t; }
+		ConstIterator  operator--(int)          { ConstIterator t = *this; --*this; return t; }
+
+		ConstIterator& operator+=(int i)        { ptr += i; return *this; }
+		ConstIterator& operator-=(int i)        { ptr -= i; return *this; }
+
+		ConstIterator operator+(int i) const    { return ptr + i; }
+		ConstIterator operator-(int i) const    { return ptr - i; }
+
+		int  operator-(ConstIterator x) const   { return ptr - x.ptr; }
+
+		bool operator==(ConstIterator x) const  { return ptr == x.ptr; }
+		bool operator!=(ConstIterator x) const  { return ptr != x.ptr; }
+		bool operator<(ConstIterator x) const   { return ptr < x.ptr; }
+		bool operator>(ConstIterator x) const   { return ptr > x.ptr; }
+		bool operator<=(ConstIterator x) const  { return ptr <= x.ptr; }
+		bool operator>=(ConstIterator x) const  { return ptr >= x.ptr; }
+
+		operator bool() const                   { return ptr; }
+
+		ConstIterator()                         {}
+		ConstIterator(NP *null)                 { ASSERT(null == NULL); ptr = NULL; }
+	};
+
+	class Iterator : public ConstIterator {
+		friend class Array<T>;
+		Iterator(T **p) : ConstIterator(p)      {}
+		typedef ConstIterator B;
+		struct NP { int dummy; };
+
+	public:
+		T& operator*()                          { return **B::ptr; }
+		T *operator->()                         { return *B::ptr; }
+		T& operator[](int i)                    { return *B::ptr[i]; }
+
+		const T& operator*() const              { return **B::ptr; }
+		const T *operator->() const             { return *B::ptr; }
+		const T& operator[](int i) const        { return *B::ptr[i]; }
+
+		Iterator& operator++()                  { B::ptr++; return *this; }
+		Iterator& operator--()                  { B::ptr--; return *this; }
+		Iterator  operator++(int)               { Iterator t = *this; ++*this; return t; }
+		Iterator  operator--(int)               { Iterator t = *this; --*this; return t; }
+
+		Iterator& operator+=(int i)             { B::ptr += i; return *this; }
+		Iterator& operator-=(int i)             { B::ptr -= i; return *this; }
+
+		Iterator operator+(int i) const         { return B::ptr + i; }
+		Iterator operator-(int i) const         { return B::ptr - i; }
+
+		int      operator-(Iterator x) const    { return B::operator-(x); }
+
+		Iterator()                               {}
+		Iterator(NP *null) : ConstIterator(null) {}
+
+	//G++
+	//	friend void IterSwap(Iterator a, Iterator b) { ::Swap(*a.ptr, *b.ptr); }
+	};
+
+// Standard container interface
+	typedef T        ValueType;
+	Iterator         Begin()                    { return (T **)vector.Begin(); }
+	Iterator         End()                      { return (T **)vector.End(); }
+	Iterator         GetIter(int pos)           { return (T **)vector.GetIter(pos); }
+	ConstIterator    Begin() const              { return (T **)vector.Begin(); }
+	ConstIterator    End() const                { return (T **)vector.End(); }
+	ConstIterator    GetIter(int pos) const     { return (T **)vector.GetIter(pos); }
+
+// Optimalization
+	friend void Swap(Array& a, Array& b)                   { ::Swap(a.vector, b.vector); }
+	//GCC forced move from Iterator, ugly workaround
+private:
+	static void IterSwap0(Iterator a, Iterator b)          { ::Swap(*a.ptr, *b.ptr); }
+public:
+	friend void IterSwap(Iterator a, Iterator b)           { Array<T>::IterSwap0(a, b); }
+
+//obsolete names
+	T&       DoIndex(int i)             { return At(i); }
+	T&       DoIndex(int i, const T& x) { return At(i, x); }
+
+	STL_VECTOR_COMPATIBILITY(Array<T>)
+};
+
+template<class T, int NBLK = 16>
+class Segtor : Moveable< Segtor<T, NBLK> >, DeepCopyOption< Segtor<T, NBLK> > {
+protected:
+	struct Block {
+		byte item[NBLK][sizeof(T)];
+	};
+
+	Array<Block> block;
+	int          items;
+
+	void  DoRange(unsigned beg, unsigned end, void (*fn)(T*, const T*));
+	void  Fill(unsigned beg, unsigned end, const T& x);
+	T&    Get(int i) const {
+		ASSERT(i >= 0 && i < items);
+		return *(T*) block[unsigned(i) / NBLK].item[unsigned(i) % NBLK];
+	}
+	void *Add0()				     {
+		int blk = unsigned(items) / NBLK, ndx = unsigned(items) % NBLK;
+		if(ndx == 0) block.Add(); items++;
+		return block[blk].item[ndx];
+	}
+	void  Del(int n)              { if(n < items) DoRange(n, items, DestroyArray); }
+	void  Init(int n)             { if(n > items) DoRange(items, n, ConstructArray); items = n; }
+	void  Init(int n, const T& x) { if(n > items) Fill(items, n, x); items = n; }
+	void  Free();
+
+public:
+	T&       Add()                          { return *::new(Add0()) T; }
+	void     Add(const T& x)                { DeepCopyConstruct(Add0(), x); }
+	void     AddPick(pick_ T& x)            { ::new(Add0()) T; }
+	T&       operator[](int i)              { return Get(i); }
+	const T& operator[](int i) const        { return Get(i); }
+	int      GetCount() const               { return items; }
+	bool     IsEmpty() const                { return items == 0; }
+	void     SetCount(int n);
+	void     SetCount(int n, const T& init);
+	void     Clear();
+	T&       At(int i)                      { if(i >= items) SetCount(i + 1); return Get(i); }
+	T&       At(int i, const T& x)          { if(i >= items) SetCount(i + 1, x); return Get(i); }
+	void     Shrink()                       { block.Shrink(); }
+	void     Reserve(int xtra)              { block.Reserve((xtra + NBLK - 1) / NBLK); }
+	int      GetAlloc() const               { return block.GetAlloc() * NBLK; }
+
+	void     Set(int i, const T& x, int count = 1);
+	int      GetIndex(const T& item) const;
+
+	void     Drop(int n = 1)                { ASSERT(n <= GetCount()); SetCount(GetCount() - n); }
+	T&       Top()                          { ASSERT(GetCount()); return Get(GetCount() - 1); }
+	const T& Top() const                    { ASSERT(GetCount()); return Get(GetCount() - 1); }
+	T        Pop()                          { T h = Top(); Drop(); return h; }
+
+	void     Swap(Segtor& b)                { block.Swap(b.block); Swap(items, b.items); }
+
+	Segtor& operator<<(const T& x)          { Add(x); return *this; }
+	Segtor& operator|(pick_ T& x)           { AddPick(x); return *this; }
+
+	bool     IsPicked() const               { return block.IsPicked(); }
+
+#ifdef UPP
+	void     Serialize(Stream& s)           { StreamContainer(s, *this); }
+#endif
+
+	Segtor()                                { items = 0; }
+	Segtor(pick_ Segtor& s) : block(s.block), items(s.items) {}
+	Segtor(const Segtor& s, int);
+	~Segtor();
+
+// Standard iterators
+	typedef ConstIIterator<Segtor> ConstIterator;
+	typedef IIterator<Segtor>      Iterator;
+
+// Standard container interface
+	typedef T        ValueType;
+	ConstIterator    Begin() const              { return ConstIterator(*this, 0); }
+	ConstIterator    End() const                { return ConstIterator(*this, items); }
+	ConstIterator    GetIter(int pos) const     { return ConstIterator(*this, pos); }
+	Iterator         Begin()                    { return Iterator(*this, 0); }
+	Iterator         End()                      { return Iterator(*this, items); }
+	Iterator         GetIter(int pos)           { return Iterator(*this, pos); }
+
+// Optimizations
+	friend void Swap(Segtor& a, Segtor& b)      { a.Swap(b); }
+
+//obsolete names
+	T&       DoIndex(int i)             { return At(i); }
+	T&       DoIndex(int i, const T& x) { return At(i, x); }
+
+// traits
+	STL_VECTOR_COMPATIBILITY(Segtor<T _cm_ NBLK>)
+};
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.hpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.hpp	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Vcont.hpp	(revision 1526)
@@ -0,0 +1,718 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <int size>
+void RawVector<size>::Realloc(int newalloc)
+{
+	ASSERT(newalloc >= items);
+	Chk();
+	if(newalloc == alloc) return;
+	Data *newvector = newalloc ? Alloc(newalloc) : NULL;
+	if(vector) {
+		memcpy(newvector, vector, items * sizeof(Data));
+		RawFree();
+	}
+	vector = newvector;
+	alloc = newalloc;
+}
+
+template <int size>
+void RawVector<size>::Expand()
+{
+#ifdef _DEBUG
+	Realloc(ntl_max(2 * alloc, 1));
+#else
+	Realloc(ntl_max(2 * alloc, size == 4 ? 8 : 1));
+#endif
+}
+
+template <int size>
+void RawVector<size>::RawFree()
+{
+	NTL_RAW_FREE(vector, size, sizeof(T));
+}
+
+template <int size>
+void RawVector<size>::Pick(pick_ RawVector& v)
+{
+	vector = v.vector;
+	items = v.items;
+	alloc = v.alloc;
+	SetPicked(v);
+}
+
+template <int size>
+int  RawVector<size>::RawGetIndex(const void *item) const
+{
+	Chk();
+	if(vector == NULL) return -1;
+	int n = (const Data *)item - vector;
+	return n >= 0 && n < items ? n : -1;
+}
+
+template <int size>
+void RawVector<size>::RawSwap(RawVector<size>& b)
+{
+	::Swap(items, b.items);
+	::Swap(alloc, b.alloc);
+	::Swap(vector, b.vector);
+}
+
+template <int size>
+void RawVector<size>::RawReserve(int n)
+{
+	if(n > alloc)
+		Realloc(n);
+}
+
+template <int size>
+void RawVector<size>::RawInsert(int q, int count)
+{
+	Chk();
+	ASSERT(q >= 0 && q <= items);
+	if(!count) return;
+	if(items + count > alloc) {
+		Data *newvector = Alloc(alloc = alloc + ntl_max(alloc, count));
+		if(vector) {
+			memcpy(newvector, vector, q * sizeof(Data));
+			memcpy(newvector + q + count, vector + q, (items - q) * sizeof(Data));
+			RawFree();
+		}
+		vector = newvector;
+	}
+	else
+		memmove(vector + q + count, vector + q, (items - q) * sizeof(Data));
+	items += count;
+}
+
+template <int size>
+void RawVector<size>::RawInsertPick(int i, pick_ RawVector<size>& v) {
+	Chk();
+	v.Chk();
+	if(v.items) {
+		RawInsert(i, v.items);
+		memcpy(vector + i, v.vector, size * v.items);
+	}
+	const_cast< RawVector<size>& >(v).RawFree();
+	SetPicked(v);
+}
+
+// ------------------
+
+template <class T>
+void Vector<T>::Free() {
+	if(B::vector && B::items >= 0)
+		DestroyArray((T *)B::vector, (T *)B::vector + B::items);
+	B::RawFree();
+}
+
+template <class T>
+void Vector<T>::Clear() {
+	if(B::vector && B::items >= 0)
+		SetCount(0);
+	else {
+		B::alloc = B::items = 0;
+		B::vector = NULL;
+	}
+}
+
+template <class T>
+void Vector<T>::__DeepCopy(const Vector& src) {
+	src.Chk();
+	B::items = B::alloc = src.B::items;
+	if(src.vector) {
+		B::vector = B::Alloc(B::alloc);
+		DeepCopyConstructArray((T *)B::vector, (T *)src.B::vector,
+		                       (T *)src.B::vector + B::items);
+	}
+	else
+		B::vector = NULL;
+}
+
+template <class T> inline
+T&  Vector<T>::Add()
+{
+	if(B::items >= B::alloc) Expand();
+	T *p = ::new(B::vector + B::items) T;
+	B::items++;
+	return *p;
+}
+
+template <class T> inline
+void Vector<T>::AddN(int n)
+{
+	ASSERT(n >= 0);
+	if(B::items + n <= B::alloc) {
+		const TYPENAME Vector<T>::Data *w = B::vector + B::items;
+		B::items += n;
+		while(n--)
+			::new((void *)w++) T;
+	}
+	else
+		SetCountR(B::items + n);
+}
+
+template <class T>
+void Vector<T>::Trim(int n)
+{
+	ASSERT(n >= 0 && n <= B::items);
+	DestroyArray((T*)B::vector + n, (T*)B::vector + B::items);
+	B::items = n;
+}
+
+template <class T>
+void Vector<T>::SetCount(int n) {
+	Chk();
+	ASSERT(n >= 0);
+	if(n == B::items) return;
+	if(n < B::items)
+		Trim(n);
+	else {
+		if(n > B::alloc) B::Realloc(n);
+		ConstructArray((T*)B::vector + B::items, (T*)B::vector + n);
+		B::items = n;
+	}
+}
+
+template <class T>
+void Vector<T>::SetCount(int n, const T& init) {
+	Chk();
+	ASSERT(n >= 0);
+	if(n == B::items) return;
+	if(n < B::items)
+		DestroyArray((T*)B::vector + n, (T*)B::vector + B::items);
+	else {
+		if(n > B::alloc) B::Realloc(n);
+		DeepCopyConstructFill((T*)B::vector + B::items, (T*)B::vector + n, init);
+	}
+	B::items = n;
+}
+
+template <class T>
+void Vector<T>::SetCountR(int n) {
+	Chk();
+	if(n + B::items > B::alloc)
+		B::Realloc(B::alloc + ntl_max(B::alloc, n));
+	SetCount(n);
+}
+
+template <class T>
+void Vector<T>::SetCountR(int n, const T& init) {
+	Chk();
+	if(n + B::items > B::alloc)
+		B::Realloc(B::alloc + ntl_max(B::alloc, n));
+	SetCount(n, init);
+}
+
+template <class T>
+void Vector<T>::Remove(int q, int count) {
+	Chk();
+	ASSERT(q >= 0 && q <= B::items - count && count >= 0);
+	if(count == 0) return;
+	DestroyArray((T*)B::vector + q, (T*)B::vector + q + count);
+//G++
+	memmove((T*)B::vector + q, (T*)B::vector + q + count, (B::items - q - count) * sizeof(T));
+//	memmove((T*)vector + q, (T*)vector + q + count, (items - q - count) * sizeof(Data));
+	B::items -= count;
+}
+
+template <int size>
+class Data_S_ {
+	byte filler[size];
+};
+
+template <class T>
+void Vector<T>::Remove(const int *sorted_list, int n)
+{
+	Chk();
+	if(!n) return;
+	int pos = *sorted_list;
+	int npos = pos;
+	for(;;) {
+		ASSERT(pos < B::items);
+		if(pos == *sorted_list) {
+			((T*)B::vector + pos)->T::~T();
+			pos++;
+			sorted_list++;
+			if(--n == 0) break;
+			ASSERT(*sorted_list >= pos);
+		}
+		else
+			*((Data_S_<sizeof(T)>*)B::vector + npos++)
+				= *((Data_S_<sizeof(T)>*)B::vector + pos++);
+	}
+	while(pos < B::items)
+		*((Data_S_<sizeof(T)>*)B::vector + npos++) = *((Data_S_<sizeof(T)>*)B::vector + pos++);
+	B::items = npos;
+}
+
+template <class T>
+void Vector<T>::Remove(const Vector<int>& v)
+{
+	Remove(v, v.GetCount());
+}
+
+template <class T>
+void Vector<T>::InsertN(int q, int count) {
+	ASSERT(count >= 0);
+	B::RawInsert(q, count);
+	ConstructArray((T*) B::vector + q, (T*)B::vector + q + count);
+}
+
+template <class T>
+void Vector<T>::Insert(int q, const T& x, int count) {
+	if(!count) return;
+	B::RawInsert(q, count);
+	DeepCopyConstructFill((T*)B::vector + q, (T*)B::vector + q + count, x);
+}
+
+template <class T>
+void Vector<T>::Insert(int q, const Vector& x, int offset, int count) {
+	if(!count) return;
+	ASSERT(offset >= 0 && count >= 0 && offset + count <= x.GetCount());
+	B::RawInsert(q, count);
+	DeepCopyConstructArray((T*)B::vector + q, (T*)x.B::vector + offset,
+	                       (T*)x.B::vector + offset + count);
+}
+
+template <class T>
+void Vector<T>::Insert(int q, const Vector& x) {
+	if(!x.GetCount()) return;
+	Insert(q, x, 0, x.GetCount());
+}
+
+template <class T>
+void Vector<T>::Set(int i, const T& x, int count) {
+	Chk();
+	ASSERT(i >= 0 && count >= 0);
+	if(count == 0) return;
+	DoIndex(i + count - 1);
+	Fill((T*)B::vector + i, (T*)B::vector + i + count, x);
+}
+
+// ------------------
+
+template <class T>
+void Array<T>::Free() {
+	if(IsPicked()) return;
+	for(int i = 0; i < vector.GetCount(); i++)
+		delete (T *) vector[i];
+}
+
+template <class T>
+void Array<T>::__DeepCopy(const Array<T>& v) {
+	int n = v.GetCount();
+	vector.SetCount(n);
+	for(int i = 0; i < n; i++)
+		vector[i] = DeepCopyNew(v[i]);
+}
+
+template <class T>
+void  Array<T>::Trim(int n)
+{
+	ASSERT(n >= 0 && n <= GetCount());
+	Del(vector.Begin() + n, vector.End());
+	vector.Trim(n);
+}
+
+template <class T>
+void Array<T>::SetCount(int n) {
+	ASSERT(n >= 0);
+	int  lc = vector.GetCount();
+	Del(vector.Begin() + n, vector.End());
+	vector.SetCount(n);
+	Init(vector.Begin() + lc, vector.Begin() + n);
+}
+
+template <class T>
+void Array<T>::SetCount(int n, const T& init) {
+	ASSERT(n >= 0);
+	int  lc = vector.GetCount();
+	Del(vector.Begin() + n, vector.End());
+	vector.SetCount(n);
+	Init(vector.Begin() + lc, vector.Begin() + n, init);
+}
+
+template <class T>
+void Array<T>::SetCountR(int n) {
+	ASSERT(n >= 0);
+	int  lc = vector.GetCount();
+	Del(vector.Begin() + n, vector.End());
+	vector.SetCountR(n);
+	Init(vector.Begin() + lc, vector.Begin() + n);
+}
+
+template <class T>
+void Array<T>::SetCountR(int n, const T& init) {
+	ASSERT(n >= 0);
+	int  lc = vector.GetCount();
+	Del(vector.Begin() + n, vector.End());
+	vector.SetCountR(n);
+	Init(vector.Begin() + lc, vector.Begin() + n, init);
+}
+
+template <class T>
+int  Array<T>::GetIndex(const T& item) const {
+	for(void * const *ptr = vector.Begin(); ptr < vector.End(); ptr++)
+		if(*ptr == (void *)&item) return ptr - vector.Begin();
+	return -1;
+}
+
+template <class T>
+void Array<T>::Move(int i1, int i2) {
+	void *q = vector[i1];
+	vector.Remove(i1);
+	vector.Insert(i2) = q;
+}
+
+template <class T>
+void Array<T>::Remove(int i, int count) {
+	ASSERT(i + count <= GetCount() && count >= 0 && i >= 0);
+	Del(vector.Begin() + i, vector.Begin() + i + count);
+	vector.Remove(i, count);
+}
+
+template <class T>
+void Array<T>::Remove(const int *sorted_list, int n)
+{
+	const int *q = sorted_list;
+	const int *e = sorted_list + n;
+	while(q < e) {
+		ASSERT(*q >= 0 && *q < GetCount());
+		delete (T *)vector[*q++];
+	}
+	vector.Remove(sorted_list, n);
+}
+
+template <class T>
+void Array<T>::Remove(const Vector<int>& sorted_list)
+{
+	Remove(sorted_list, sorted_list.GetCount());
+}
+
+template <class T>
+void Array<T>::Set(int i, const T& x, int count) {
+	ASSERT(i >= 0 && count >= 0);
+	if(i + count >= GetCount())
+		SetCountR(i + count);
+	for(void **ptr = vector.Begin() + i; ptr < vector.Begin() + i + count; ptr++) {
+		delete (T *) *ptr;
+		*ptr = new T(x);
+	}
+}
+
+template <class T>
+void Array<T>::InsertN(int i, int count) {
+	ASSERT(i >= 0 && count >= 0);
+	vector.InsertN(i, count);
+	Init(vector.Begin() + i, vector.Begin() + i + count);
+}
+
+template <class T>
+void Array<T>::Insert(int i, const T& x, int count) {
+	vector.InsertN(i, count);
+	Init(vector.Begin() + i, vector.Begin() + i + count, x);
+}
+
+template <class T>
+void Array<T>::Insert(int i, T *newt) {
+	vector.InsertN(i, 1);
+	vector[i] = newt;
+}
+
+template <class T>
+void Array<T>::Insert(int i, const Array& x) {
+	Insert(i, x, 0, x.GetCount());
+}
+
+template <class T>
+void Array<T>::Insert(int i, const Array& x, int offset, int count) {
+	vector.InsertN(i, count);
+	for(int q = 0; q < count; q++)
+		vector[q + i] = DeepCopyNew(x[q + offset]);
+}
+
+template <class T>
+void Array<T>::InsertPick(int i, pick_ Array& x) {
+	Array xx = x;
+	int cx = xx.GetCount();
+	vector.InsertN(i, cx);
+	for(int q = 0; q < cx; q++)
+		vector[q + i] = x.vector[q];
+}
+
+// ------------------
+
+template <class T, int NBLK>
+Segtor<T, NBLK>::Segtor(const Segtor& s, int) {
+	items = s.items;
+	block.SetCount((items + NBLK - 1) / NBLK);
+	int q = items / NBLK;
+	int r = items % NBLK;
+	int i;
+	for(i = 0; i < q; i++) {
+		T *a = (T *) s.block[i].item;
+		DeepCopyConstructArray((T *) block[i].item, a, a + NBLK);
+	}
+	if(r) {
+		T *a = (T *) s.block[q].item;
+		DeepCopyConstructArray((T *) block[i].item, a, a + r);
+	}
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::Free() {
+	int q = items / NBLK;
+	int r = items % NBLK;
+	int i;
+	for(i = 0; i < q; i++) {
+		T *a = (T *) block[i].item;
+		DestroyArray(a, a + NBLK);
+	}
+	if(r) {
+		T *a = (T *) block[i].item;
+		DestroyArray(a, a + r);
+	}
+}
+
+template <class T, int NBLK>
+Segtor<T, NBLK>::~Segtor() {
+	if(IsPicked()) return;
+	Free();
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::DoRange(unsigned beg, unsigned end, void (*fn)(T*, const T*)) {
+	ASSERT(beg <= end);
+	int bblk = beg / NBLK, bidx = beg % NBLK;
+	int eblk = end / NBLK, eidx = end % NBLK;
+	if(eblk == block.GetCount()) {
+		ASSERT(eidx == 0);
+		eblk--;
+		eidx = NBLK;
+	}
+	ASSERT(eblk < block.GetCount());
+	T *tp = (T *)block[bblk].item;
+	if(bblk != eblk) {
+		(*fn)(tp + bidx, tp + NBLK);
+		while(++bblk < eblk) {
+			tp = (T *)block[bblk].item;
+			(*fn)(tp, tp + NBLK);
+		}
+		tp = (T *)block[bblk].item;
+		(*fn)(tp, tp + eidx);
+	}
+	else
+		(*fn)(tp + bidx, tp + eidx);
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::Fill(unsigned beg, unsigned end, const T& x) {
+	ASSERT(beg <= end);
+	int bblk = beg / NBLK, bidx = beg % NBLK;
+	int eblk = end / NBLK, eidx = end % NBLK;
+	if(eblk == block.GetCount()) {
+		ASSERT(eidx == 0);
+		eblk--;
+		eidx = NBLK;
+	}
+	ASSERT(eblk < block.GetCount());
+	T *tp = (T *)block[bblk].item;
+	if(bblk != eblk) {
+		DeepCopyConstructFill(tp + bidx, tp + NBLK, x);
+		while(++bblk < eblk) {
+			tp = (T *)block[bblk].item;
+			DeepCopyConstructFill(tp, tp + NBLK, x);
+		}
+		tp = (T *)block[bblk].item;
+		DeepCopyConstructFill(tp, tp + eidx, x);
+	}
+	else
+		DeepCopyConstructFill(tp + bidx, tp + eidx, x);
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::SetCount(int n) {
+	Del(n);
+	block.SetCount((n + NBLK - 1) / NBLK);
+	Init(n);
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::SetCount(int n, const T& init) {
+	Del(n);
+	block.SetCount((n + NBLK - 1) / NBLK);
+	Init(n, init);
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::Clear() {
+	if(!IsPicked())
+		Free();
+	items = 0;
+	block.Clear();
+}
+
+template <class T, int NBLK>
+void Segtor<T, NBLK>::Set(int i, const T& x, int count) {
+	ASSERT(i >= 0 && count >= 0);
+	DoIndex(i + count - 1);
+	Iterator q(*this, i);
+	while(count--)
+		*q++ = x;
+}
+
+template <class T, int NBLK>
+int Segtor<T, NBLK>::GetIndex(const T& item) const {
+	for(int i = 0; i < block.GetCount(); i++) {
+		T *q = (T *) block[i].item;
+		if(&item >= q && &item < q + NBLK)
+			return &item - q + NBLK * i;
+	}
+	return -1;
+}
+
+// ------------------
+
+template <class T>
+void BiVector<T>::ReAlloc(int newalloc) {
+	ASSERT(items <= newalloc && items >= 0);
+	T *newvector = newalloc ? (T *) NTL_RAW_ALLOC(newalloc * sizeof(T)) : NULL;
+	if(items) {
+		int end = start + items;
+		if(end <= alloc)
+			memcpy(newvector, vector + start, (end - start) * sizeof(T));
+		else {
+			memcpy(newvector, vector + start, (alloc - start) * sizeof(T));
+			memcpy(newvector + alloc - start, vector, (end - alloc) * sizeof(T));
+		}
+		NTL_RAW_FREE(vector, items, sizeof(T));
+	}
+	vector = newvector;
+	alloc = newalloc;
+	start = 0;
+}
+
+template <class T>
+void BiVector<T>::DeepCopy0(const BiVector& src) {
+	alloc = items = src.items;
+	vector = alloc ? (T *) NTL_RAW_ALLOC((alloc * sizeof(T))) : NULL;
+	if(items) {
+		int end = src.start + src.items;
+		if(end <= src.alloc)
+			DeepCopyConstructArray(vector, src.vector + src.start, src.vector + end);
+		else {
+			DeepCopyConstructArray(vector, src.vector + src.start, src.vector + src.alloc);
+			DeepCopyConstructArray(vector + src.alloc - src.start, src.vector,
+				                   src.vector + end - src.alloc);
+		}
+	}
+	start = 0;
+}
+
+template <class T>
+void BiVector<T>::Clear() {
+	Free();
+	start = items = alloc = 0;
+
+	vector = NULL;
+}
+
+template <class T>
+void BiVector<T>::Add0() {
+	ASSERT(items >= 0);
+	if(items >= alloc)
+		ReAlloc(ntl_max(2 * items, 4));
+	items++;
+}
+
+template <class T>
+void BiVector<T>::Shrink() {
+	ASSERT(items >= 0);
+	if(items < alloc)
+		ReAlloc(items);
+}
+
+template <class T>
+void BiVector<T>::Reserve(int n) {
+	ASSERT(items >= 0);
+	n += items;
+	if(n > alloc)
+		ReAlloc(n);
+}
+
+template <class T>
+void BiVector<T>::Free() {
+	if(vector && items >= 0) {
+		int end = start + items;
+		if(end <= alloc)
+			DestroyArray(vector + start, vector + end);
+		else {
+			DestroyArray(vector + start, vector + alloc);
+			DestroyArray(vector, vector + end - alloc);
+		}
+		NTL_RAW_FREE(vector, items, sizeof(T));
+	}
+}
+
+#ifdef UPP
+template <class T>
+void BiVector<T>::Serialize(Stream& s) {
+	int n = items;
+	s / n;
+	if(s.IsLoading()) {
+		Clear();
+		while(n--)
+			s % AddTail();
+	}
+	else
+		for(int i = 0; i < items; i++)
+			s % operator[](i);
+}
+#endif
+
+// ------------------
+
+template <class T>
+void BiArray<T>::Free() {
+	if(!bv.IsPicked())
+		for(int i = 0; i < GetCount(); i++)
+			delete (T *) bv[i];
+}
+
+template <class T>
+void BiArray<T>::DeepCopy0(const BiArray<T>& v) {
+	int n = v.GetCount();
+	bv.Clear();
+	bv.Reserve(v.GetCount());
+	for(int i = 0; i < n; i++)
+		bv.AddTail() = DeepCopyNew(v[i]);
+}
+
+#ifdef UPP
+template <class T>
+void BiArray<T>::Serialize(Stream& s) {
+	int n = bv.GetCount();
+	s / n;
+	if(s.IsLoading()) {
+		Clear();
+		while(n--)
+			s % AddTail();
+	}
+	else
+		for(int i = 0; i < bv.GetCount(); i++)
+			s % operator[](i);
+}
+#endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Map.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Map.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Map.h	(revision 1526)
@@ -0,0 +1,201 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class K, class T, class V, class HashFn>
+class AMap {
+protected:
+	Index<K, HashFn> key;
+	V                value;
+
+public:
+	void     Add(const K& k, const T& x)            { key.Add(k); value.Add(x); }
+	void     AddPick(const K& k, pick_ T& x)        { key.Add(k); value.AddPick(x); }
+	T&       Add(const K& k)                        { key.Add(k); return value.Add(); }
+
+	int      Find(const K& k, unsigned h) const     { return key.Find(k, h); }
+	int      Find(const K& k) const                 { return key.Find(k); }
+	int      FindNext(int i) const                  { return key.FindNext(i); }
+	int      FindLast(const K& k, unsigned h) const { return key.FindLast(k, h); }
+	int      FindLast(const K& k) const             { return key.FindLast(k); }
+	int      FindPrev(int i) const                  { return key.FindPrev(i); }
+
+	int      FindAdd(const K& k);
+	int      FindAdd(const K& k, const T& init);
+	int      FindAddPick(const K& k, pick_ T& init);
+
+	void     Put(const K& k, const T& x);
+	void     PutPick(const K& k, pick_ T& x);
+	T&       Put(const K& k);
+
+	int      FindPut(const K& k);
+	int      FindPut(const K& k, const T& init);
+	int      FindPutPick(const K& k, pick_ T& init);
+
+	T&       Get(const K& k)                     { return value[Find(k)]; }
+	const T& Get(const K& k) const               { return value[Find(k)]; }
+	const T& Get(const K& k, const T& d) const   { int i = Find(k); return i >= 0 ? value[i] : d; }
+
+	T&       GetAdd(const K& k);
+
+	T&       GetAdd(const K& k, const T& x);
+	T&       GetAddPick(const K& k, pick_ T& x);
+
+	T&       GetPut(const K& k);
+
+	T&       GetPut(const K& k, const T& x);
+	T&       GetPutPick(const K& k, pick_ T& x);
+
+	void     SetKey(int i, const K& k)           { key.Set(i, k); }
+
+	T       *FindPtr(const K& k)       { int i = Find(k); return i >= 0 ? &value[i] : NULL; }
+	const T *FindPtr(const K& k) const { int i = Find(k); return i >= 0 ? &value[i] : NULL; }
+
+	T&       operator()(const K& k)                   { return Get(k); }
+	const T& operator()(const K& k) const             { return Get(k); }
+	const T& operator()(const K& k, const T& d) const { return Get(k, d); }
+
+	void     Unlink(int i)                            { key.Unlink(i); }
+	int      UnlinkKey(const K& k, unsigned h)        { return key.UnlinkKey(k, h); }
+	int      UnlinkKey(const K& k)                    { return key.UnlinkKey(k); }
+	bool     IsUnlinked(int i) const                  { return key.IsUnlinked(i); }
+
+	T&       Insert(int i, const K& k)             { key.Insert(i, k); return value.Insert(i); }
+	void     Insert(int i, const K& k, const T& x) { key.Insert(i, k); value.Insert(i, x); }
+	void     Remove(int i)                         { key.Remove(i); value.Remove(i); }
+	void     Remove(const int *sl, int n)          { key.Remove(sl, n); value.Remove(sl, n); }
+	void     Remove(const Vector<int>& sl)         { Remove(sl, sl.GetCount()); }
+	int      RemoveKey(const K& k);
+
+	const T& operator[](int i) const               { return value[i]; }
+	T&       operator[](int i)                     { return value[i]; }
+	int      GetCount() const                      { return value.GetCount(); }
+	bool     IsEmpty() const                       { return value.IsEmpty(); }
+	void     Clear()                               { key.Clear(); value.Clear(); }
+	void     Shrink()                              { value.Shrink(); key.Shrink(); }
+	void     Reserve(int xtra)                     { value.Reserve(xtra); key.Reserve(xtra); }
+	int      GetAlloc() const                      { return value.GetAlloc(); }
+
+	void     Drop(int n = 1)                       { key.Drop(n); value.Drop(n); }
+	T&       Top()                                 { return value.Top(); }
+	const T& Top() const                           { return value.Top(); }
+	const K& TopKey() const                        { return key.Top(); }
+//	T        Pop()                                 { T h = Top(); Drop(); return h; }
+	K        PopKey()                              { K h = TopKey(); Drop(); return h; }
+
+	const K& GetKey(int i) const                   { return key[i]; }
+
+#ifdef UPP
+	void     Serialize(Stream& s);
+#endif
+
+	void     Swap(AMap& x)                         { ::Swap(value, x.value);
+	                                                 ::Swap(key, x.key); }
+	const Index<K>&  GetIndex() const              { return key; }
+	Index<K>         PickIndex()                   { return key; }
+
+	const Vector<K>& GetKeys() const               { return key.GetKeys(); }
+	Vector<K>        PickKeys()                    { return key.PickKeys(); }
+
+	const V&         GetValues() const             { return value; }
+	V                PickValues()                  { return value; }
+
+	AMap()                                         {}
+	AMap(const AMap& s, int) : value(s.value, 0), key(s.key, 0) {}
+	AMap(pick_ Index<K>& ndx, pick_ V& val) : key(ndx), value(val) {}
+	AMap(pick_ Vector<K>& ndx, pick_ V& val) : key(ndx), value(val) {}
+
+	typedef K        KeyType;
+	typedef typename Index<K>::ConstIterator KeyConstIterator;
+
+	KeyConstIterator KeyBegin() const                             { return key.Begin(); }
+	KeyConstIterator KeyEnd() const                               { return key.End(); }
+	KeyConstIterator KeyGetIter(int pos) const                    { return key.GetIter(pos); }
+
+	typedef T                          ValueType;
+	typedef typename V::ConstIterator  ConstIterator;
+	typedef typename V::Iterator       Iterator;
+
+	Iterator         Begin()                                      { return value.Begin(); }
+	Iterator         End()                                        { return value.End(); }
+	Iterator         GetIter(int pos)                             { return value.GetIter(pos); }
+	ConstIterator    Begin() const                                { return value.Begin(); }
+	ConstIterator    End() const                                  { return value.End(); }
+	ConstIterator    GetIter(int pos) const                       { return value.GetIter(pos); }
+
+	friend int     GetCount(const AMap& v)                        { return v.GetCount(); }
+};
+
+template <class K, class T, class HashFn = StdHash<K> >
+class VectorMap : public AMap< K, T, Vector<T>, HashFn >,
+                  Moveable<VectorMap<K, T, HashFn> >,
+                  DeepCopyOption<VectorMap<K, T, HashFn> > {
+    typedef AMap< K, T, Vector<T>, HashFn > B;
+public:
+	T        Pop()                            { T h = B::Top(); B::Drop(); return h; }
+
+	VectorMap(const VectorMap& s, int) : AMap<K, T, Vector<T>, HashFn>(s, 1) {}
+	VectorMap(pick_ Index<K>& ndx, pick_ Vector<T>& val) : AMap<K, T, Vector<T>, HashFn>(ndx, val) {}
+	VectorMap(pick_ Vector<K>& ndx, pick_ Vector<T>& val) : AMap<K, T, Vector<T>, HashFn>(ndx, val) {}
+	VectorMap()                                                       {}
+
+	friend void    Swap(VectorMap& a, VectorMap& b)      { a.B::Swap(b); }
+
+	typedef typename AMap< K, T, Vector<T>, HashFn >::ConstIterator ConstIterator; // GCC bug (?)
+	typedef typename AMap< K, T, Vector<T>, HashFn >::Iterator      Iterator; // GCC bug (?)
+	STL_MAP_COMPATIBILITY(VectorMap<K _cm_ T _cm_ HashFn>)
+};
+
+template <class K, class T, class HashFn = StdHash<K> >
+class ArrayMap : public AMap< K, T, Array<T>, HashFn >,
+                 Moveable< ArrayMap<K, T, HashFn> >,
+                 DeepCopyOption< ArrayMap<K, T, HashFn> > {
+	typedef AMap< K, T, Array<T>, HashFn > B;
+public:
+	void      Add(const K& k, const T& x)                { B::Add(k, x); }
+	T&        Add(const K& k)                            { return B::Add(k); }
+	void      Add(const K& k, T *ptr)                    { B::key.Add(k); B::value.Add(ptr); }
+
+	void      Set(int i, T *ptr)                         { B::value.Set(i, ptr); }
+	T        *PopDetach()                                { B::key.Drop(); return B::value.PopDetach(); }
+
+	ArrayMap(const ArrayMap& s, int) : AMap<K, T, Array<T>, HashFn>(s, 1) {}
+	ArrayMap(pick_ Index<K>& ndx, pick_ Array<T>& val) : AMap<K, T, Array<T>, HashFn>(ndx, val) {}
+	ArrayMap(pick_ Vector<K>& ndx, pick_ Array<T>& val) : AMap<K, T, Array<T>, HashFn>(ndx, val) {}
+	ArrayMap()                                           {}
+
+	friend void    Swap(ArrayMap& a, ArrayMap& b)        { a.B::Swap(b); }
+
+	typedef typename AMap< K, T, Array<T>, HashFn >::ConstIterator ConstIterator; // GCC bug (?)
+	typedef typename AMap< K, T, Array<T>, HashFn >::Iterator      Iterator; // GCC bug (?)
+	STL_MAP_COMPATIBILITY(ArrayMap<K _cm_ T _cm_ HashFn>)
+};
+
+template <class K, class T, int NBLK = 16, class HashFn = StdHash<K> >
+class SegtorMap : public AMap< K, T, Segtor<T, NBLK>, HashFn >,
+                  Moveable< SegtorMap<K, T, NBLK, HashFn> >,
+                  DeepCopyOption< SegtorMap<K, T, NBLK, HashFn > > {
+	typedef AMap< K, T, Segtor<T, NBLK>, HashFn > B;
+public:
+	SegtorMap(const SegtorMap& s, int) : AMap<K, T, Segtor<T, NBLK>, HashFn>(s, 1) {}
+	SegtorMap(pick_ Index<K>& ndx, pick_ Segtor<T>& val) : AMap<K, T, Segtor<T, NBLK>, HashFn>(ndx, val) {}
+	SegtorMap(pick_ Vector<K>& ndx, pick_ Segtor<T>& val) : AMap<K, T, Segtor<T, NBLK>, HashFn>(ndx, val) {}
+	SegtorMap()                                              {}
+
+	friend void Swap(SegtorMap& a, SegtorMap& b)             { a.B::Swap(b); }
+
+	typedef typename B::ConstIterator ConstIterator; // GCC bug (?)
+	typedef typename B::Iterator      Iterator; // GCC bug (?)
+	STL_MAP_COMPATIBILITY(SegtorMap<K _cm_ T _cm_ NBLK _cm_ HashFn>)
+};
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/BiCont.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/BiCont.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/BiCont.h	(revision 1526)
@@ -0,0 +1,158 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+class BiVector : Moveable< BiVector<T> >, DeepCopyOption< BiVector<T> > {
+protected:
+	T          *vector;
+	int         start;
+	mutable int items;
+	int         alloc;
+
+	int      EI() const              { return (start + items - 1) % alloc; }
+	void     ReAlloc(int newalloc);
+	void     Add0();
+	void     DeepCopy0(const BiVector& src);
+	T       *AddHead0()              { Add0(); return &vector[start = (start + alloc - 1) % alloc]; }
+	T       *AddTail0()              { Add0(); return &vector[EI()]; }
+	void     Free();
+	void     Pick(pick_ BiVector& x) { vector = x.vector; start = x.start; items = x.items;
+	                                   alloc = x.alloc; x.items = -1; }
+	void     Copy(T *dst, int start, int count) const;
+
+public:
+	int      GetCount() const        { return items; }
+	bool     IsEmpty() const         { return items == 0; }
+	void     Clear();
+
+	T&       AddHead()               { return *new(AddHead0()) T; }
+	T&       AddTail()               { return *new(AddTail0()) T; }
+	void     AddHead(const T& x)     { new(AddHead0()) T(x); }
+	void     AddTail(const T& x)     { new(AddTail0()) T(x); }
+	void     AddHeadPick(pick_ T& x) { new(AddHead0()) T(x); }
+	void     AddTailPick(pick_ T& x) { new(AddTail0()) T(x); }
+	T&       Head()                  { ASSERT(items > 0); return vector[start]; }
+	T&       Tail()                  { ASSERT(items > 0); return vector[EI()]; }
+	const T& Head() const            { ASSERT(items > 0); return vector[start]; }
+	const T& Tail() const            { ASSERT(items > 0); return vector[EI()]; }
+	void     DropHead()              { (&Head())->T::~T(); items--; start = (start + 1) % alloc; }
+	void     DropTail()              { (&Tail())->T::~T(); items--; }
+
+	T&       operator[](int i)       { ASSERT(i >= 0 && i < items);
+	                                   return vector[(start + i) % alloc]; }
+	const T& operator[](int i) const { ASSERT(i >= 0 && i < items);
+	                                   return vector[(start + i) % alloc]; }
+	void     Shrink();
+	void     Reserve(int n);
+	int      GetAlloc() const        { return alloc; }
+
+#ifdef UPP
+	void     Serialize(Stream& s);
+#endif
+
+	bool     IsPicked()                         { return items < 0; }
+
+	BiVector(const BiVector& src, int)          { DeepCopy0(src); }
+	BiVector(pick_ BiVector& src)               { Pick(src); }
+	void operator=(pick_ BiVector& src)         { Free(); Pick(src); }
+	BiVector()                                  { start = items = alloc = 0; vector = NULL; }
+	~BiVector()                                 { AssertMoveable<T>(); Free(); }
+
+	typedef ConstIIterator<BiVector> ConstIterator;
+	typedef IIterator<BiVector>      Iterator;
+
+	typedef T        ValueType;
+
+	ConstIterator    Begin() const              { return ConstIterator(*this, 0); }
+	ConstIterator    End() const                { return ConstIterator(*this, GetCount()); }
+	ConstIterator    GetIter(int pos) const     { return ConstIterator(*this, pos); }
+	Iterator         Begin()                    { return Iterator(*this, 0); }
+	Iterator         End()                      { return Iterator(*this, GetCount()); }
+	Iterator         GetIter(int pos)           { return Iterator(*this, pos); }
+
+	friend void Swap(BiVector& a, BiVector& b)  { ::Swap(a.vector, b.vector);
+	                                              ::Swap(a.start, b.start);
+	                                              ::Swap(a.items, b.items);
+	                                              ::Swap(a.alloc, b.alloc); }
+
+	STL_BI_COMPATIBILITY(BiVector<T>)
+};
+
+template <class T>
+class BiArray : Moveable< BiArray<T> >, DeepCopyOption< BiArray<T> > {
+protected:
+	BiVector<void *> bv;
+
+	void     Free();
+	void     DeepCopy0(const BiArray<T>& v);
+
+public:
+	int      GetCount() const              { return bv.GetCount(); }
+	bool     IsEmpty() const               { return GetCount() == 0; }
+	void     Clear()                       { Free(); bv.Clear(); }
+
+	T&       AddHead()                     { T *q = new T; bv.AddHead(q); return *q; }
+	T&       AddTail()                     { T *q = new T; bv.AddTail(q); return *q; }
+	void     AddHead(const T& x)           { bv.AddHead(new T(x)); }
+	void     AddTail(const T& x)           { bv.AddTail(new T(x)); }
+	void     AddHeadPick(pick_ T& x)       { bv.AddHead(new T(x)); }
+	void     AddTailPick(pick_ T& x)       { bv.AddTail(new T(x)); }
+	void     AddHead(T *newt)              { bv.AddHead(newt); }
+	void     AddTail(T *newt)              { bv.AddTail(newt); }
+	T&       Head()                        { return *(T *) bv.Head(); }
+	T&       Tail()                        { return *(T *) bv.Tail(); }
+	const T& Head() const                  { return *(const T *) bv.Head(); }
+	const T& Tail() const                  { return *(const T *) bv.Tail(); }
+	void     DropHead()                    { delete (T*) bv.Head(); bv.DropHead(); }
+	void     DropTail()                    { delete (T*) bv.Tail(); bv.DropTail(); }
+	T       *DetachHead()                  { T *q = (T*) bv.Head(); bv.DropHead(); return q; }
+	T       *DetachTail()                  { T *q = (T*) bv.Tail(); bv.DropTail(); return q; }
+
+	T&       operator[](int i)             { return *(T *) bv[i]; }
+	const T& operator[](int i) const       { return *(const T *) bv[i]; }
+
+	void     Shrink()                      { bv.Shrink(); }
+	void     Reserve(int n)                { bv.Reserve(n); }
+	int      GetAlloc() const              { return bv.GetAlloc(); }
+
+#ifdef UPP
+	void     Serialize(Stream& s);
+#endif
+
+	bool     IsPicked() const                { return bv.IsPicked(); }
+
+	BiArray(const BiArray& v, int)           { DeepCopy0(v); }
+
+	BiArray(pick_ BiArray& src) : bv(src.bv) {}
+	void operator=(pick_ BiArray& src)       { Free(); bv = src.bv; }
+	BiArray()                                {}
+	~BiArray()                               { Free(); }
+
+	typedef ConstIIterator<BiArray> ConstIterator;
+	typedef IIterator<BiArray>      Iterator;
+
+	typedef T        ValueType;
+
+	ConstIterator    Begin() const              { return ConstIterator(*this, 0); }
+	ConstIterator    End() const                { return ConstIterator(*this, GetCount()); }
+	ConstIterator    GetIter(int pos) const     { return ConstIterator(*this, pos); }
+	Iterator         Begin()                    { return Iterator(*this, 0); }
+	Iterator         End()                      { return Iterator(*this, GetCount()); }
+	Iterator         GetIter(int pos)           { return Iterator(*this, pos); }
+
+	friend void Swap(BiArray& a, BiArray& b)    { ::Swap(a.bv, b.bv); }
+
+	STL_BI_COMPATIBILITY(BiArray<T>)
+};
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Other.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Other.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Other.h	(revision 1526)
@@ -0,0 +1,233 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef UPP
+template <class T>
+T& Single() {
+	static T *p;
+	if(!p) {
+		CriticalSection::LockMain __;
+		if(!p) {
+			static T o;
+			p = &o;
+		}
+	}
+	return *p;
+}
+#endif
+
+template <class T>
+class One : Moveable< One<T> >, DeepCopyOption< One<T> > {
+	mutable T  *ptr;
+
+	void        Free()                     { if(ptr && ptr != (T*)1) delete ptr; }
+	void        Chk() const                { ASSERT(ptr != (T*)1); }
+	void        ChkP() const               { Chk(); ASSERT(ptr); }
+	void        Pick(pick_ One<T>& data)   { T *p = data.ptr; data.ptr = (T*)1; ptr = p; }
+
+public:
+	void        Attach(T *data)            { Free(); ptr = data; }
+	T          *Detach() pick_             { ChkP(); T *t = ptr; ptr = NULL; return t; }
+	T          *operator-() pick_          { return Detach(); }
+	void        Clear()                    { Free(); ptr = NULL; }
+
+	void        operator=(T *data)         { Attach(data); }
+	void        operator=(pick_ One<T>& d) { Free(); Pick(d); }
+
+	const T    *operator->() const         { ChkP(); return ptr; }
+	T          *operator->()               { ChkP(); return ptr; }
+	const T    *operator~() const          { Chk(); return ptr; }
+	T          *operator~()                { Chk(); return ptr; }
+	const T&    operator*() const          { ChkP(); return *ptr; }
+	T&          operator*()                { ChkP(); return *ptr; }
+
+	bool        IsPicked() const           { return ptr == (T*)1; }
+	bool        IsEmpty() const            { Chk(); return !ptr; }
+
+	operator bool() const                  { return ptr; }
+
+	One()                                  { ptr = NULL; }
+	One(T *newt)                           { ptr = newt; }
+	One(pick_ One<T>& p)                   { Pick(p); }
+	One(const One<T>& p, int)              { ptr = p.IsEmpty() ? NULL : DeepCopyNew(*p); }
+	~One()                                 { Free(); }
+};
+
+//# System dependent
+template <class T>
+class Mitor : Moveable< Mitor<T> > {
+	union {
+		mutable unsigned   count;
+		mutable Vector<T> *vector;
+	};
+	byte elem0[sizeof(T)];
+	
+	T&        Get(int i) const;
+	void      Pick(pick_ Mitor& m);
+	void      Copy(const Mitor& m);
+	void      Chk() const               { ASSERT(count != 2); }
+
+public:
+	T&        operator[](int i)         { return Get(i); }
+	const T&  operator[](int i) const   { return Get(i); }
+	int       GetCount() const;
+	T&        Add();
+	void      Add(const T& x);
+	void      Clear();
+	void      Shrink();
+	
+	Mitor(pick_ Mitor& m)               { Pick(m); }
+	void operator=(pick_ Mitor& m)      { Clear(); Pick(m); }
+
+	Mitor(Mitor& m, int)                { Copy(m); }
+	void operator<<=(const Mitor& m)    { Clear(); Copy(m); }
+
+	Mitor()                             { count = 0; }
+	~Mitor()                            { Clear(); }
+};
+
+template <class T>
+T& Mitor<T>::Get(int i) const
+{
+	ASSERT(i >= 0 && i < GetCount());
+	return i == 0 ? *(T*)elem0 : (*const_cast<Vector<T>*>(vector))[i - 1];
+}
+
+template <class T>
+void Mitor<T>::Pick(pick_ Mitor& m)
+{
+	m.Chk();
+	vector = m.vector;
+	memcpy(&elem0, &m.elem0, sizeof(T));
+	m.count = 2;
+}
+
+template <class T>
+void Mitor<T>::Copy(const Mitor& m)
+{
+	m.Chk();
+	if(m.count > 0)
+		DeepCopyConstruct((T*)elem0, m.elem0);
+	if(m.count > 1)
+		vector = new Vector<T>(m.vector, 1);
+}
+
+template <class T>
+int Mitor<T>::GetCount() const
+{
+	Chk();
+	return count > 1 ? vector->GetCount() + 1 : count;
+}
+
+template <class T>
+T& Mitor<T>::Add()
+{
+	Chk();
+	if(count == 0) {
+		count = 1;
+		return *new(elem0) T;
+	}
+	if(count == 1)
+		vector = new Vector<T>;
+	return vector->Add();
+}
+
+template <class T>
+void Mitor<T>::Add(const T& x)
+{
+	Chk();
+	if(count == 0) {
+		count = 1;
+		new((T*) elem0) T(x);
+	}
+	else {
+		if(count == 1)
+			vector = new Vector<T>;
+		vector->Add(x);
+	}
+}
+
+template <class T>
+void Mitor<T>::Clear()
+{
+	if(count > 2)
+		delete vector;
+	if(count && count != 2)
+		((T*)elem0)->T::~T();
+	count = 0;
+}
+
+template <class T>
+void Mitor<T>::Shrink()
+{
+	if(count > 2)
+		vector->Shrink();
+}
+
+//#
+template <class T, int N = 1>
+class Link {
+protected:
+	T *prev[N];
+	T *next[N];
+
+	void LPN(int i)                      { prev[i]->next[i] = next[i]->prev[i] = (T *)this; }
+
+public:
+	T       *GetPtr()                    { return (T *) this; }
+	const T *GetPtr() const              { return (const T *) this; }
+	T       *GetNext(int i = 0)          { return next[i]; }
+	T       *GetPrev(int i = 0)          { return prev[i]; }
+	const T *GetNext(int i = 0) const    { return next[i]; }
+	const T *GetPrev(int i = 0) const    { return prev[i]; }
+
+	void LinkSelf(int i = 0)             { next[i] = prev[i] = (T *)this; }
+	void LinkSelfAll()                   { for(int i = 0; i < N; i++) LinkSelf(i); }
+	void Unlink(int i = 0)               { next[i]->prev[i] = prev[i]; prev[i]->next[i] = next[i];
+	                                       LinkSelf(i); }
+	void UnlinkAll()                     { for(int i = 0; i < N; i++) Unlink(i); }
+	void LinkBefore(Link *n, int i = 0)  { next[i] = (T *)n; prev[i] = next[i]->prev[i]; LPN(i); }
+	void LinkAfter(Link *p, int i = 0)   { prev[i] = (T *)p; next[i] = prev[i]->next[i]; LPN(i); }
+
+	T   *InsertNext(int i = 0)           { T *x = new T; x->LinkAfter(this, i); return x; }
+	T   *InsertPrev(int i = 0)           { T *x = new T; x->LinkBefore(this, i); return x; }
+
+	void DeleteList(int i = 0)           { while(next[i] != GetPtr()) delete next[i]; }
+
+	bool InList(int i = 0) const         { return next[i] != GetPtr(); }
+	bool IsEmpty(int i = 0) const        { return !InList(i); }
+
+	Link()                               { LinkSelfAll(); }
+	~Link()                              { UnlinkAll(); }
+
+private:
+	Link(const Link&);
+	void operator=(const Link&);
+
+public:
+#ifdef _DEBUG
+	void Dump() {
+		for(T *t = GetNext(); t != this; t = t->GetNext())
+			LOG(t);
+		LOG("-------------------------------------");
+	}
+#endif
+};
+
+template <class T, int N = 1>
+class LinkOwner : public Link<T, N> {
+public:
+	~LinkOwner()                         { Link<T, N>::DeleteList(); }
+};
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Algo.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Algo.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Algo.h	(revision 1526)
@@ -0,0 +1,1071 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+inline int sgn(T a) { return a > 0 ? 1 : a < 0 ? -1 : 0; }
+
+template <class T>
+inline T tabs(T a) { return (a >= 0 ? a : -a); }
+
+template <class T>
+inline int cmp(const T& a, const T& b) { return a > b ? 1 : a < b ? -1 : 0; }
+
+template <class I>
+void Reverse(I start, I end)
+{
+	if(start != end && --end != start)
+		do
+			IterSwap(start, end);
+		while(++start != end && --end != start);
+}
+
+template <class C>
+void Reverse(C& container)
+{
+	Reverse(container.Begin(), container.End());
+}
+
+template <class T, class V>
+void Sum(V& sum, T ptr, T end)
+
+{
+	while(ptr != end)
+		sum += *ptr++;
+}
+
+template <class T>
+typename T::ValueType Sum(const T& c)
+{
+	typename T::ValueType sum;
+	Sum(sum, c.Begin(), c.End());
+	return sum;
+}
+
+template <class T>
+typename T::ValueType Sum(const T& c, const typename T::ValueType& init)
+{
+	typename T::ValueType sum = init;
+	Sum(sum, c.Begin(), c.End());
+	return sum;
+}
+
+template <class T>
+typename T::ValueType Sum0(const T& c)
+{
+	typename T::ValueType sum = 0;
+	Sum(sum, c.Begin(), c.End());
+	return sum;
+}
+
+template <class T>
+T MinElement(T ptr, T end)
+{
+	ASSERT(ptr != end);
+	T min = ptr;
+	while(++ptr != end)
+		if(*ptr < *min) min = ptr;
+	return min;
+}
+
+template <class T>
+const typename T::ValueType& Min(const T& c)
+{
+	return *MinElement(c.Begin(), c.End());
+}
+
+template <class T>
+T MaxElement(T ptr, T end)
+{
+	ASSERT(ptr != end);
+	T max = ptr;
+	while(++ptr != end)
+		if(*max < *ptr) max = ptr;
+	return max;
+}
+
+template <class T>
+const typename T::ValueType& Max(const T& c)
+{
+	return *MaxElement(c.Begin(), c.End());
+}
+
+template<class T>
+struct StdEqual
+{
+	bool operator () (const T& a, const T& b) const { return a == b; }
+};
+
+template<class T>
+struct StdLess {
+	bool operator () (const T& a, const T& b) const { return a < b; }
+};
+
+template<class T>
+struct StdGreater
+{
+	bool operator () (const T& a, const T& b) const { return a > b; }
+};
+
+template <class T, class C>
+bool Compare(T ptr1, T end1, T ptr2, T end2, const C& compare)
+{
+	for(; ptr1 != end1 && ptr2 != end2; ++ptr1, ++ptr2)
+		if(!compare(*ptr1, *ptr2)) return false;
+	return ptr1 == end1 && ptr2 == end2;
+}
+
+template <class T, class C>
+bool Compare(const T& c1, const T& c2, const C& compare)
+{
+	return Compare(c1.Begin(), c1.End(), c2.Begin(), c2.End(), compare);
+}
+
+template <class T>
+bool Compare(const T& c1, const T& c2)
+{
+	typedef typename T::ValueType VT;
+	return Compare(c1, c2, StdEqual<VT>());
+}
+
+template <class T, class V, class C>
+T Find(T ptr, T end, const V& value, const C& equal)
+{
+	while(ptr != end) {
+		if(equal(*ptr, value)) return ptr;
+		ptr++;
+	}
+	return NULL;
+}
+
+template <class T, class V>
+T Find(T ptr, T end, const V& value)
+{
+	return Find(ptr, end, value, StdEqual<T>());
+}
+
+template <class T, class V, class C>
+int FindIndex(const T& cont, const V& value, const C& equal)
+{
+	for(int i = 0; i < cont.GetCount(); i++)
+		if(equal(cont[i], value)) return i;
+	return -1;
+}
+
+template <class T, class V>
+int FindIndex(const T& cont, const V& value)
+{
+	typedef typename T::ValueType VT;
+	return FindIndex(cont, value, StdEqual<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+// BinFind
+
+template <class I, class K, class L>
+int BinFindIndex(I begin, I end, const K& key, const L& less)
+{
+	if(begin == end)
+		return 0;
+	int min = 0;
+	int max = end - begin;
+
+	while(min < max)
+	{
+		int mid = (max + min) >> 1;
+		if(less(*(begin + mid), key))
+			min = mid + 1;
+		else
+			max = mid;
+	}
+	return min;
+}
+
+template <class C, class K, class L>
+inline int BinFindIndex(const C& container, const K& key, const L& less)
+{
+	return BinFindIndex(container.Begin(), container.End(), key, less);
+}
+
+template <class C, class K>
+inline int BinFindIndex(const C& container, const K& key)
+{
+	typedef typename C::ValueType VT;
+	return BinFindIndex(container, key, StdLess<VT>());
+}
+
+template <class I, class K, class L>
+inline I BinFind(I begin, I end, const K& key, const L& less)
+{
+	return begin + BinFindIndex(begin, end, key, less);
+}
+
+template <class C, class K, class L>
+inline typename C::ConstIterator BinFind(const C& container, const K& key, const L& less)
+{
+	return BinFind(container.Begin(), container.End(), key, less);
+}
+
+template <class C, class K>
+inline typename C::ConstIterator BinFind(const C& container, const K& key)
+{
+	typedef typename C::ValueType VT;
+	return BinFind(container, key, StdLess<VT>());
+}
+
+// -------------------------------------------------------------------
+
+template <class C, class T, class L>
+int FindLowerBound(const C& v, int pos, int count, const T& val, const L& less)
+{
+	while(count > 0) {
+		int half = count >> 1;
+		int m = pos + half;
+		if(less(v[m], val)) {
+			pos = m + 1;
+			count = count - half - 1;
+		}
+		else
+			count = half;
+	}
+	return pos;
+}
+
+template <class I, class T, class L>
+I FindLowerBoundIter(I begin, I end, const T& val, const L& less)
+{
+	return begin + FindLowerBound(begin, 0, end - begin, val, less);
+}
+
+template <class I, class T>
+I FindLowerBoundIter(I begin, I end, const T& val)
+{
+	return begin + FindLowerBound(begin, 0, end - begin, val, StdLess<T>());
+}
+
+template <class C, class T, class L>
+int FindLowerBound(const C& v, const T& val, const L& less)
+{
+	return FindLowerBound(v, 0, v.GetCount(), val, less);
+}
+
+template <class C, class T>
+int FindLowerBound(const C& v, const T& val)
+{
+	return FindLowerBound(v, val, StdLess<TYPENAME C::ValueType>());
+}
+
+template <class C, class T, class L>
+int FindUpperBound(const C& v, int pos, int count, const T& val, const L& less)
+{
+	while(count > 0) {
+		int half = count >> 1;
+		int m = pos + half;
+		if(less(val, v[m]))
+			count = half;
+		else {
+			pos = m + 1;
+			count = count - half - 1;
+		}
+	}
+	return pos;
+}
+
+template <class I, class T, class L>
+I FindUpperBoundIter(I begin, I end, const T& val, const L& less)
+{
+	return begin + FindUpperBound(begin, 0, end - begin, val, less);
+}
+
+template <class I, class T>
+I FindUpperBoundIter(I begin, I end, const T& val)
+{
+	return begin + FindUpperBound(begin, 0, end - begin, val, StdLess<T>());
+}
+
+template <class C, class T, class L>
+int FindUpperBound(const C& v, const T& val, const L& less)
+{
+	return FindUpperBound(v, 0, v.GetCount(), val, less);
+}
+
+template <class C, class T>
+int FindUpperBound(const C& v, const T& val)
+{
+	return FindUpperBound(v, val, StdLess<TYPENAME C::ValueType>());
+}
+
+template <class C, class T, class L>
+int FindBinary(const C& v, const T& val, int pos, int count, const L& less)
+{
+	int i = FindLowerBound(v, pos, count, val, less);
+	return i < count && !less(val, v[i]) ? i : -1;
+}
+
+template <class I, class T, class L>
+I FindBinaryIter(I begin, I end, const T& val, const L& less)
+{
+	int q = FindUpperBound(begin, begin, end, val, less);
+	return q < 0 ? NULL : begin + q;
+}
+
+template <class I, class T>
+I FindBinaryIter(I begin, I end, const T& val)
+{
+	return FindBinaryIter(begin, end, val, StdLess<T>());
+}
+
+template <class C, class T, class L>
+int FindBinary(const C& v, const T& val, const L& less)
+{
+	return FindBinary(v, val, 0, v.GetCount(), less);
+}
+
+template <class C, class T>
+int FindBinary(const C& v, const T& val)
+{
+	return FindBinary(v, val, StdLess<TYPENAME C::ValueType>());
+}
+
+//////////////////////////////////////////////////////////////////////
+// BinFindComp
+
+template <class I, class K, class X>
+int BinFindCompIndex(I begin, I end, const K& key, const X& comp)
+{
+	if(begin == end) // empty array
+		return 0;
+	int min = 0;
+	int max = end - begin;
+	while(min < max)
+	{
+		int mid = (max + min) >> 1;
+		if(comp.Compare(key, *(begin + mid)) > 0)
+			min = mid + 1;
+		else
+			max = mid;
+	}
+	return min;
+}
+
+template <class C, class K, class X>
+inline int BinFindCompIndex(const C& container, const K& key, const X& comp)
+{
+	return BinFindCompIndex(container.Begin(), container.End(), key, comp);
+}
+
+template <class I, class K, class X>
+inline I BinFindComp(I begin, I end, const K& key, const X& comp)
+{
+	return begin + BinFindCompIndex(begin, end, key, comp);
+}
+
+template <class C, class K, class X>
+inline typename C::ConstIterator BinFindComp(const C& container, const K& key, const X& comp)
+{
+	return BinFindComp(container.Begin(), container.End(), key, comp);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Append
+
+template <class T, class V>
+void Append(T& dst, V ptr, V end)
+{
+	for(; ptr != end; ++ptr)
+		dst.Add(*ptr);
+}
+
+template <class T, class V>
+void Append(T& dst, V ptr, int n)
+{
+	for(; n--; ++ptr)
+		dst.Add(*ptr);
+}
+
+template <class T, class V>
+void Append(T& dst, const V& src)
+{
+	Append(dst, src.Begin(), src.End());
+}
+
+//////////////////////////////////////////////////////////////////////
+// FindAppend::
+
+template <class C, class I>
+C& FindAppend(C& dest, I begin, I end)
+{
+	for(; begin != end; ++begin)
+		dest.FindAdd(*begin);
+	return dest;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class S>
+inline C& FindAppend(C& dest, const S& source)
+{
+	return FindAppend(dest, source.Begin(), source.End());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class L>
+C& AppendSorted(C& dest, const C& src, const L& less)
+{
+	if(src.IsEmpty())
+		return dest;
+	if(dest.IsEmpty())
+	{
+		dest <<= src;
+		return dest;
+	}
+	if(!less(*src, dest.Top()))
+	{
+		dest.Append(src);
+		return dest;
+	}
+	if(!less(*dest, src.Top()))
+	{
+		dest.Insert(0, src);
+		return dest;
+	}
+	int dc = dest.GetCount();
+	int sc = src.GetCount();
+	dest.SetCount(dc + sc);
+	typename C::Iterator de = dest.End();
+	typename C::ConstIterator se = src.End(), pe = dest.GetIter(dc);
+	--se;
+	--pe;
+	for(;;)
+	{
+		if(less(*se, *pe))
+		{
+			*--de = *pe;
+			if(pe == dest.Begin())
+			{ // dest items are finished
+				*--de = *se;
+				while(se != src.Begin())
+					*--de = *--se;
+				return dest;
+			}
+			--pe;
+		}
+		else
+		{
+			*--de = *se;
+			if(se == src.Begin())
+				return dest; // src items are finished, dest items are in place
+			--se;
+		}
+	}
+	return dest;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C>
+C& AppendSorted(C& dest, const C& src)
+{
+	typedef typename C::ValueType VT;
+	return AppendSorted(dest, src, StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class L>
+C& UnionSorted(C& dest, const C& src, const L& less)
+{
+	if(src.IsEmpty())
+		return dest;
+	if(dest.IsEmpty())
+	{
+		dest <<= src;
+		return dest;
+	}
+	if(less(dest.Top(), *src))
+	{
+		dest.Append(src);
+		return dest;
+	}
+	if(less(src.Top(), *dest))
+	{
+		dest.Insert(0, src);
+		return dest;
+	}
+	int dc = dest.GetCount();
+	int sc = src.GetCount();
+	dest.SetCount(dc + sc);
+	typename C::Iterator de = dest.End();
+	typename C::ConstIterator se = src.End(), pe = dest.GetIter(dc);
+	--se;
+	--pe;
+	for(;;)
+	{
+		if(less(*se, *pe))
+		{
+			*--de = *pe;
+			if(pe == dest.Begin())
+			{ // dest items are finished
+				*--de = *se;
+				while(se != src.Begin())
+					*--de = *--se;
+				dest.Remove(0, dest.GetIndex(*de));
+				return dest;
+			}
+			--pe;
+		}
+		else
+		{
+			*--de = *se;
+			if(!less(*pe, *se))
+			{
+				if(pe == dest.Begin())
+				{
+					while(se != src.Begin())
+						*--de = *--se;
+					dest.Remove(0, dest.GetIndex(*de));
+					return dest;
+				}
+				--pe;
+			}
+			if(se == src.Begin())
+			{
+				int pi = (pe - dest.Begin()) + 1;
+				dest.Remove(pi, (de - dest.Begin()) - pi);
+				return dest; // src items are finished, dest items are in place
+			}
+			--se;
+		}
+	}
+	return dest;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C>
+C& UnionSorted(C& dest, const C& src)
+{
+	typedef typename C::ValueType VT;
+	return UnionSorted(dest, src, StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class L>
+C& RemoveSorted(C& from, const C& what, const L& less)
+{
+	if(from.IsEmpty() || what.IsEmpty() ||
+	   less(from.Top(), *what.Begin()) || less(what.Top(), *from.Begin()))
+		return from;
+	typename C::ConstIterator we = what.End(), wp = BinFind(what, from[0], less);
+	if(wp == we)
+		return from;
+	typename C::Iterator fp = from.Begin() + BinFindIndex(from, *wp), fe = from.End(), fd = fp;
+	if(fp == fe)
+	{
+		from.Clear();
+		return from;
+	}
+	for(;;)
+	{
+		while(less(*fp, *wp))
+		{
+			*fd = *fp;
+			++fd;
+			if(++fp == fe)
+			{
+				from.SetCount(fd - from.Begin());
+				return from;
+			}
+		}
+		if(less(*wp, *fp))
+		{
+			do
+				if(++wp == we)
+				{
+					Copy(fd, fp, fe);
+					fd += (fe - fp);
+					from.SetCount(fd - from.Begin());
+					return from;
+				}
+			while(less(*wp, *fp));
+		}
+		else
+		{
+			const typename C::ValueType& value = *fp;
+			while(!less(value, *fp))
+				if(++fp == fe)
+				{
+					from.SetCount(fd - from.Begin());
+					return from;
+				}
+			do
+				if(++wp == we)
+				{
+					Copy(fd, fp, fe);
+					fd += (fe - fp);
+					from.SetCount(fd - from.Begin());
+					return from;
+				}
+			while(!less(value, *wp));
+		}
+	}
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C>
+C& RemoveSorted(C& from, const C& what)
+{
+	typedef typename C::ValueType VT;
+	return RemoveSorted(from, what, StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class D, class S, class L>
+D& IntersectSorted(D& dest, const S& src, const L& less)
+{
+	if(dest.IsEmpty())
+		return dest;
+	if(src.IsEmpty() || less(dest.Top(), src[0]) || less(src.Top(), dest[0]))
+	{ // empty source set or disjunct intervals
+		dest.Clear();
+		return dest;
+	}
+	typename S::ConstIterator ss = BinFind(src, dest[0], less), se = src.End();
+	if(ss == se)
+	{
+		dest.Clear();
+		return dest;
+	}
+	typename D::ConstIterator ds = BinFind(dest, src[0], less), de = dest.End();
+	if(ds == de)
+	{
+		dest.Clear();
+		return dest;
+	}
+	typename D::Iterator d = dest.Begin();
+	int count = 0;
+	for(;;)
+	{
+		if(less(*ss, *ds))
+		{
+			if(++ss == se)
+				break;
+		}
+		else
+		{
+			if(!less(*ds, *ss))
+			{
+				*d = *ds;
+				++d;
+				count++;
+			}
+			if(++ds == de)
+				break;
+		}
+	}
+	dest.SetCount(count);
+	return dest;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class D, class S>
+D& IntersectSorted(D& dest, const S& src)
+{
+	typedef typename D::ValueType VT;
+	return IntersectSorted(dest, src, StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+// StreamContainer
+
+#ifdef UPP
+template <class T>
+void StreamContainer(Stream& s, T& cont)
+{
+	int n = cont.GetCount();
+	s / n;
+	if(s.IsLoading())
+	{
+		cont.Clear();
+		while(n--)
+			s % cont.Add();
+	}
+	else
+	{
+		for(typename T::Iterator ptr = cont.Begin(); n--; ++ptr)
+			s % *ptr;
+	}
+}
+#endif
+//////////////////////////////////////////////////////////////////////
+// ForwardSort
+
+template <class I, class Less>
+void ForwardSort(I begin, I end, const Less& less)
+{
+	if(begin == end)
+		return;
+	I limit = end;
+	--limit;
+	while(!(begin == limit))
+	{
+		for(I best = limit, next = limit, ptr = limit;; best = ptr)
+			if(!less(*best, *--ptr))
+			{
+				if(ptr == begin)
+				{
+					begin = next;
+					break;
+				}
+			}
+			else
+			{
+				do
+				{
+					if(ptr == begin)
+					{
+						IterSwap(begin, best);
+						++begin;
+						goto NEXT_ITEM;
+					}
+				}
+				while(less(*best, *--ptr));
+				if(ptr == begin)
+				{
+					IterSwap(++begin, best);
+					++begin;
+					break;
+				}
+				next = ptr;
+				++next;
+			}
+	NEXT_ITEM:
+		;
+	}
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class T, class Less>
+void ForwardSort(T& c, const Less& less)
+{
+	ForwardSort(c.Begin(), c.End(), less);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class T>
+void ForwardSort(T& c)
+{
+	typedef typename T::ValueType VT;
+	ForwardSort(c.Begin(), c.End(), StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+enum
+{
+	__SORT_THRESHOLD = 16
+};
+
+//////////////////////////////////////////////////////////////////////
+// Sort
+
+template <class I, class Less>
+inline I IterMedian(I x, I y, I z, const Less& less)
+{
+	return less(*x, *y)
+		? less(*y, *z) ? y : less(*x, *z) ? z : x
+		: less(*x, *z) ? x : less(*y, *z) ? z : y;
+}
+
+template <class I, class Less>
+void Sort(I begin, I end, const Less& less)
+{
+	int count;
+	while((count = end - begin) > __SORT_THRESHOLD)
+	{
+		I b = begin, e = end, m = IterMedian(b, b + (count >> 1), e - 1, less);
+		for(;; ++b)
+		{
+			while(less(*m, *--e))
+				;
+			while(less(*b, *m))
+				++b;
+			if(!(b < e))
+				break;
+			if(m == b) m = e;
+			else if(m == e) m = b;
+			IterSwap(b, e);
+		}
+		if(b - begin < end - e)
+		{
+			Sort(begin, b, less);
+			begin = b;
+		}
+		else
+		{
+			Sort(b, end, less);
+			end = b;
+		}
+	}
+	if(count >= 1)
+		ForwardSort(begin, end, less);
+}
+
+template <class T, class Less>
+void Sort(T& c, int l, int h, const Less& less)
+{
+	Sort(c.GetIter(l), c.GetIter(h), less);
+}
+
+template <class T, class Less>
+void Sort(T& c, const Less& less)
+{
+	Sort(c.Begin(), c.End(), less);
+}
+
+template <class T>
+void Sort(T& c)
+{
+	typedef typename T::ValueType VT;
+	Sort(c.Begin(), c.End(), StdLess<VT>());
+}
+
+//////////////////////////////////////////////////////////////////////
+// IndexSort
+
+template <class II, class VI, class K>
+struct IndexSortIterator
+{
+	typedef IndexSortIterator<II, VI, K> Iter;
+
+	IndexSortIterator(II ii, VI vi) : ii(ii), vi(vi) {}
+
+	Iter&       operator ++ ()               { ++ii; ++vi; return *this; }
+	Iter&       operator -- ()               { --ii; --vi; return *this; }
+	const K&    operator *  () /*const*/     { return *ii; } //!! Fidler's bug in Array::Iterator
+	Iter        operator +  (int i) const    { return Iter(ii + i, vi + i); }
+	Iter        operator -  (int i) const    { return Iter(ii - i, vi - i); }
+	int         operator -  (Iter b) const   { return (int)(ii - b.ii); }
+	bool        operator == (Iter b) const   { return ii == b.ii; }
+	bool        operator <  (Iter b) const   { return ii <  b.ii; }
+	friend void IterSwap    (Iter a, Iter b) { IterSwap(a.ii, b.ii); IterSwap(a.vi, b.vi); }
+
+	II          ii;
+	VI          vi;
+};
+
+template <class II, class VI, class K, class Less>
+inline void __IndexSort(II begin, II end, VI pair, const Less& less, const K *)
+{
+	Sort(IndexSortIterator<II, VI, K>(begin, pair),
+		IndexSortIterator<II, VI, K>(end, pair + (end - begin)),
+		less);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class II, class VI, class Less>
+inline void IndexSort(II begin, II end, VI pair, const Less& less)
+{
+	if(begin != end)
+		__IndexSort(begin, end, pair, less, &*begin);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class KC, class VC, class Less>
+inline void IndexSort(KC& keys, VC& values, const Less& less)
+{
+	typedef typename KC::ValueType KT;
+	ASSERT(keys.GetCount() == values.GetCount());
+	if(keys.GetCount() >= 2)
+		__IndexSort(keys.Begin(), keys.End(), values.Begin(), less, (KT *)0);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class KC, class VC>
+inline void IndexSort(KC& keys, VC& values)
+{
+	typedef typename KC::ValueType KT;
+	if(keys.GetCount() >= 2)
+		__IndexSort(keys.Begin(), keys.End(), values.Begin(), StdLess<KT>(), (KT *)0);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class I, class V>
+struct SortOrderIterator
+{
+	typedef SortOrderIterator<I, V> Iter;
+
+	SortOrderIterator(int *ii, I vi) : ii(ii), vi(vi) {}
+
+	Iter&       operator ++ ()               { ++ii; return *this; }
+	Iter&       operator -- ()               { --ii; return *this; }
+	const V&    operator *  () const         { return *(vi + *ii); }
+	Iter        operator +  (int i) const    { return Iter(ii + i, vi); }
+	Iter        operator -  (int i) const    { return Iter(ii - i, vi); }
+	int         operator -  (Iter b) const   { return int(ii - b.ii); }
+	bool        operator == (Iter b) const   { return ii == b.ii; }
+	bool        operator <  (Iter b) const   { return ii < b.ii; }
+	friend void IterSwap    (Iter a, Iter b) { IterSwap(a.ii, b.ii); }
+
+	int        *ii;
+	I           vi;
+};
+
+template <class I, class V, class Less>
+inline void __SortOrder(int *begin, int *end, I data, const Less& less, const V *)
+{
+	Sort(SortOrderIterator<I, V>(begin, data), SortOrderIterator<I, V>(end, data), less);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class I, class Less>
+inline Vector<int> GetSortOrder(I begin, I end, const Less& less)
+{
+	Vector<int> index;
+	index.SetCount((int)(end - begin));
+	for(int i = index.GetCount(); --i >= 0; index[i] = i)
+		;
+	__SortOrder(index.Begin(), index.End(), begin, less, &*begin);
+	return index;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class Less>
+inline Vector<int> GetSortOrder(const C& container, const Less& less)
+{
+	return GetSortOrder(container.Begin(), container.End(), less);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C>
+inline Vector<int> GetSortOrder(const C& container)
+{
+	typedef typename C::ValueType V;
+	return GetSortOrder(container.Begin(), container.End(), StdLess<V>());
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class DC, class I, class F>
+void GetFieldContainer(DC& dest, I begin, I end, F field)
+{
+	for(; begin != end; ++begin)
+		dest.Add((*begin).*field);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class DC, class SC, class F>
+void GetFieldContainer(DC& dest, const SC& src, F field)
+{ GetFieldContainer<DC, TYPENAME SC::ConstIterator, F>(dest, src.Begin(), src.End(), field); }
+
+//////////////////////////////////////////////////////////////////////
+
+template <class I, class F, class O, class E>
+I FindField(I begin, I end, F field, const O& object, const E& equal)
+{
+	for(; begin != end && !equal((*begin).*field, object); ++begin)
+		;
+	return begin;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class I, class F, class O>
+I FindField(I begin, I end, F field, const O& object)
+{ return FindField(begin, end, field, object, StdEqual<O>()); }
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class F, class O, class E>
+int FindFieldIndex(const C& container, F field, const O& object, const E& equal)
+{
+	int i = 0;
+	for(typename C::ConstIterator b = container.Begin(), e = container.End(); b != e; ++b, ++i)
+		if(equal((*b).*field, object))
+			return i;
+	return -1;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+template <class C, class F, class O>
+int FindFieldIndex(const C& container, F field, const O& object)
+{ return FindFieldIndex(container, field, object, StdEqual<O>()); }
+
+//////////////////////////////////////////////////////////////////////
+
+template <class O, class T, class R>
+class FieldRelationCls {
+	O        T::*member;
+	const R& relation;
+
+public:
+	FieldRelationCls(O (T::*member), const R& relation) : member(member), relation(relation) {}
+	bool operator () (const T& t1, const T& t2) const { return relation(t1.*member, t2.*member); }
+};
+
+template <class O, class T, class R>
+inline FieldRelationCls<O, T, R> FieldRelation(O (T::*member), const R& relation)
+{ return FieldRelationCls<O, T, R>(member, relation); }
+
+//////////////////////////////////////////////////////////////////////
+
+template <class M, class T, class R>
+class MethodRelationCls {
+	M        method;
+	const R& relation;
+
+public:
+	MethodRelationCls(M method, const R& relation) : method(method), relation(relation) {}
+	bool operator () (const T& t1, const T& t2) const {
+		return relation((t1.*method)(), (t2.*method)());
+	}
+};
+
+template <class O, class T, class R>
+inline MethodRelationCls<O (T::*)(), T, R>
+	MethodRelation(O (T::*method)(), const R& relation)
+{ return MethodRelationCls<O (T::*)(), T, R>(method, relation); }
+
+template <class O, class T, class R>
+inline MethodRelationCls<O (T::*)() const, T, R>
+	MethodRelation(O (T::*method)() const, const R& relation)
+{ return MethodRelationCls<O (T::*)() const, T, R>(method, relation); }
+
+///////////////////////////////////////////////////////////////////////
+
+template <class C, class T>
+void LruAdd(C& lru, T value, int limit = 10) {
+	int q = FindIndex(lru, value);
+	if(q >= 0)
+		lru.Remove(q);
+	lru.Insert(0, value);
+	if(lru.GetCount() > limit)
+		lru.SetCount(limit);
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Topt.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Topt.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Topt.h	(revision 1526)
@@ -0,0 +1,422 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+inline void Swap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
+
+template <class I>
+inline void IterSwap(I a, I b) { if(a != b) Swap(*a, *b); }
+
+template <class T>
+class RelOps
+{
+	friend bool operator >  (const T& a, const T& b)  { return b < a; }
+	friend bool operator != (const T& a, const T& b)  { return !(a == b); }
+	friend bool operator <= (const T& a, const T& b)  { return !(b < a); }
+	friend bool operator >= (const T& a, const T& b)  { return !(a < b); }
+	
+	void operator=(const RelOps&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class U, class V>
+class AddOps
+{
+	friend U& operator -= (U& a, const V& b)          { a += -b; return a; }
+	friend U  operator +  (const U& a, const V& b)    { U x(a); x += b; return x; }
+	friend U  operator -  (const U& a, const V& b)    { U x(a); x += -b; return x; }
+
+	void operator=(const AddOps&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class T>
+class PostfixOps
+{
+	friend T operator ++ (T& i, int)                  { T x = i; ++i; return x; }
+	friend T operator -- (T& i, int)                  { T x = i; --i; return x; }
+
+	void operator=(const PostfixOps&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class T, int (*compare)(T a, T b)>
+class CompareRelOps
+{
+	friend bool operator <  (T a, T b)                { return (*compare)(a, b) <  0; }
+	friend bool operator >  (T a, T b)                { return (*compare)(a, b) >  0; }
+	friend bool operator == (T a, T b)                { return (*compare)(a, b) == 0; }
+	friend bool operator != (T a, T b)                { return (*compare)(a, b) != 0; }
+	friend bool operator <= (T a, T b)                { return (*compare)(a, b) <= 0; }
+	friend bool operator >= (T a, T b)                { return (*compare)(a, b) >= 0; }
+
+	void operator=(const CompareRelOps&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class T>
+inline void Fill(T *dst, const T *lim, const T& x) {
+	while(dst < lim)
+		*dst++ = x;
+}
+
+template <class T>
+inline void Copy(T *dst, const T *src, const T *lim) {
+	while(src < lim)
+		*dst++ = *src++;
+}
+
+template <class T>
+inline void Copy(T *dst, const T *src, int n) {
+	Copy(dst, src, src + n);
+}
+
+inline void Fill(char *t, const char *lim, const char& x)
+{ memset(t, x, size_t(lim - t)); }
+inline void Copy(char *dst, const char *src, const char *lim)
+{ memcpy(dst, src, size_t((byte *)lim - (byte *)src)); }
+
+inline void Fill(signed char *t, const signed char *lim, const signed char& x)
+{ memset(t, x, size_t(lim - t)); }
+inline void Copy(signed char *dst, const signed char *src, const signed char *lim)
+{ memcpy(dst, src, size_t((byte *)lim - (byte *)src)); }
+
+inline void Fill(unsigned char *t, const unsigned char *lim, const unsigned char& x)
+{ memset(t, x, size_t(lim - t)); }
+inline void Copy(unsigned char *dst, const unsigned char *src, const unsigned char *lim)
+{ memcpy(dst, src, size_t((byte *)lim - (byte *)src)); }
+
+template <class T>
+inline void DeepCopyConstruct(void *p, const T& x) {
+	::new(p) T(x);
+}
+
+template <class T>
+inline T *DeepCopyNew(const T& x) {
+	return new T(x);
+}
+
+template <class T>
+inline void ConstructArray(T *t, const T *lim) {
+	while(t < lim)
+		::new(t++) T;
+}
+
+template <class T>
+inline void DestroyArray(T *t, const T *lim) {
+	while(t < lim) {
+		t->T::~T();
+		t++;
+	}
+}
+
+template <class T>
+inline void DeepCopyConstructArray(T *t, const T *s, const T *lim) {
+	while(s < lim)
+		DeepCopyConstruct(t++, *s++);
+}
+
+template <class T>
+inline void DeepCopyConstructFill(T *t, const T *lim, const T& x) {
+	while(t < lim)
+		DeepCopyConstruct(t++, x);
+}
+
+#ifdef NO_MOVEABLE_CHECK
+
+template <class T>
+inline void AssertMoveable() {}
+
+#define MoveableTemplate(T)
+
+template <class T>
+class Moveable
+{
+	void operator=(const Moveable&) {} // MSC 6.0 empty base class bug fix
+};
+
+#define NTL_MOVEABLE(T)
+
+#else
+
+template <class T>
+inline void AssertMoveablePtr(T, T) {}
+
+template <class T>
+inline void AssertMoveable0(T *t) { AssertMoveablePtr(&**t, *t); }
+
+template <class T>
+inline void AssertMoveable(T *t = 0) { if(t) AssertMoveable0(t); }
+
+template <class T>
+struct Moveable {
+	friend void AssertMoveable0(T *) {}
+	void operator=(const Moveable&) {} // MSC 6.0 empty base class bug fix
+};
+
+#if defined(COMPILER_MSC) || defined(COMPILER_GNU)
+	#define NTL_MOVEABLE(T) inline void AssertMoveable0(T *) {}
+#else
+	#define NTL_MOVEABLE(T) template<> inline void AssertMoveable<T>(T *) {}
+#endif
+
+#endif
+
+NTL_MOVEABLE(bool);
+NTL_MOVEABLE(char);
+NTL_MOVEABLE(signed char);
+NTL_MOVEABLE(unsigned char);
+NTL_MOVEABLE(short);
+NTL_MOVEABLE(unsigned short);
+NTL_MOVEABLE(int);
+NTL_MOVEABLE(unsigned int);
+NTL_MOVEABLE(long);
+NTL_MOVEABLE(unsigned long);
+NTL_MOVEABLE(float);
+NTL_MOVEABLE(double);
+NTL_MOVEABLE(void *);
+NTL_MOVEABLE(const void *);
+
+template <class T>
+class DeepCopyOption {
+public:
+	friend T& operator<<=(T& dest, const T& src)
+	{ (&dest)->T::~T(); ::new(&dest) T(src, 1); return dest; }
+	friend void DeepCopyConstruct(void *dest, const T& src)
+	{ ::new (dest) T(src, 0); }
+	friend T *DeepCopyNew(const T& src)
+	{ return ::new T(src, 0); }
+	void operator=(const DeepCopyOption&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class T>
+class PolyDeepCopyNew
+{
+public:
+	friend T *DeepCopyNew(const T& t)              { return t.Copy(); }
+	void operator=(const PolyDeepCopyNew&) {} // MSC 6.0 empty base class bug fix
+};
+
+template <class T>
+class WithDeepCopy : public T {
+public:
+	WithDeepCopy(const T& a) : T(a, 1)             {}
+	WithDeepCopy(const WithDeepCopy& a) : T(a, 1)  {}
+	WithDeepCopy& operator=(const WithDeepCopy& a) { (T&)*this <<= a; return *this; }
+	WithDeepCopy(int, pick_ T& a) : T(a)           {}
+	WithDeepCopy& operator^=(pick_ T& a)           { (T&)*this = a; return *this; }
+	WithDeepCopy()                                 {}
+};
+
+template <class V>
+class ConstIIterator {
+protected:
+	const V       *cont;
+	int            ii;
+	typedef        TYPENAME V::ValueType T;
+	struct NP { int dummy; };
+
+public:
+	const T&       operator*() const       { return (*cont)[ii]; }
+	const T       *operator->() const      { return &(*cont)[ii]; }
+	const T&       operator[](int i) const { return (*cont)[ii + i]; }
+
+	ConstIIterator& operator++()           { ++ii; return *this; }
+	ConstIIterator& operator--()           { --ii; return *this; }
+	ConstIIterator  operator++(int)        { ConstIIterator t = *this; ++ii; return t; }
+	ConstIIterator  operator--(int)        { ConstIIterator t = *this; --ii; return t; }
+
+	ConstIIterator& operator+=(int d)      { ii += d; return *this; }
+	ConstIIterator& operator-=(int d)      { ii -= d; return *this; }
+
+	ConstIIterator  operator+(int d) const { return ConstIIterator(cont, ii + d); }
+	ConstIIterator  operator-(int d) const { return ConstIIterator(cont, ii - d); }
+
+	int  operator-(const ConstIIterator& b) const   { return ii - b.ii; }
+
+	bool operator==(const ConstIIterator& b) const  { return ii == b.ii; }
+	bool operator!=(const ConstIIterator& b) const  { return ii != b.ii; }
+	bool operator<(const ConstIIterator& b) const   { return ii < b.ii; }
+	bool operator>(const ConstIIterator& b) const   { return ii > b.ii; }
+	bool operator<=(const ConstIIterator& b) const  { return ii <= b.ii; }
+	bool operator>=(const ConstIIterator& b) const  { return ii >= b.ii; }
+
+	operator bool() const     { return ii < 0; }
+
+	ConstIIterator()          {}
+	ConstIIterator(NP *null)  { ASSERT(null == NULL); ii = -1; }
+	ConstIIterator(const V& _cont, int ii) : cont(&_cont), ii(ii) {}
+};
+
+template <class V>
+class IIterator {
+protected:
+	V             *cont;
+	int            ii;
+	typedef        TYPENAME V::ValueType T;
+	struct NP { int dummy; };
+
+public:
+	T&       operator*()              { return (*cont)[ii]; }
+	T       *operator->()             { return &(*cont)[ii]; }
+	T&       operator[](int i)        { return (*cont)[ii + i]; }
+
+	const T& operator*() const        { return (*cont)[ii]; }
+	const T *operator->() const       { return &(*cont)[ii]; }
+	const T& operator[](int i) const  { return (*cont)[ii + i]; }
+
+	IIterator& operator++()           { ++ii; return *this; }
+	IIterator& operator--()           { --ii; return *this; }
+	IIterator  operator++(int)        { IIterator t = *this; ++ii; return t; }
+	IIterator  operator--(int)        { IIterator t = *this; --ii; return t; }
+
+	IIterator& operator+=(int d)      { ii += d; return *this; }
+	IIterator& operator-=(int d)      { ii -= d; return *this; }
+
+	IIterator  operator+(int d) const { return IIterator(*cont, ii + d); }
+	IIterator  operator-(int d) const { return IIterator(*cont, ii - d); }
+
+	int  operator-(const IIterator& b) const   { return ii - b.ii; }
+
+	bool operator==(const IIterator& b) const  { return ii == b.ii; }
+	bool operator!=(const IIterator& b) const  { return ii != b.ii; }
+	bool operator<(const IIterator& b) const   { return ii < b.ii; }
+	bool operator>(const IIterator& b) const   { return ii > b.ii; }
+	bool operator<=(const IIterator& b) const  { return ii <= b.ii; }
+	bool operator>=(const IIterator& b) const  { return ii >= b.ii; }
+
+	operator bool() const                      { return ii < 0; }
+
+	IIterator()          {}
+	IIterator(NP *null)  { ASSERT(null == NULL); ii = -1; }
+	IIterator(V& _cont, int ii) : cont(&_cont), ii(ii) {}
+};
+
+int Pow2Bound(int i);
+
+unsigned memhash(const void *ptr, size_t size);
+
+inline unsigned GetHashValue0(const void *ptr)  { return (unsigned)(size_t) ptr; }
+inline unsigned GetHashValue0(char a)           { return (unsigned)a; }
+inline unsigned GetHashValue0(signed char a)    { return (unsigned)a; }
+inline unsigned GetHashValue0(unsigned char a)  { return (unsigned)a; }
+inline unsigned GetHashValue0(short a)          { return (unsigned)a; }
+inline unsigned GetHashValue0(unsigned short a) { return (unsigned)a; }
+inline unsigned GetHashValue0(int a)            { return (unsigned)a; }
+inline unsigned GetHashValue0(unsigned int a)   { return (unsigned)a; }
+inline unsigned GetHashValue0(long a)           { return (unsigned)a; }
+inline unsigned GetHashValue0(unsigned long a)  { return (unsigned)a; }
+inline unsigned GetHashValue0(bool a)           { return (unsigned)a; }
+
+unsigned GetHashValue0(const double& a);
+
+template <class T>
+inline unsigned GetHashValue(const T& ptr) { return GetHashValue0(ptr); }
+
+struct CombineHash {
+	unsigned hash;
+
+public:
+	CombineHash& Put(unsigned h) { hash = ((hash << 4) + hash) ^ h; return *this; }
+
+	operator unsigned() const    { return hash; }
+
+	CombineHash()                              { hash = 1234567890U; }
+	CombineHash(unsigned h1)                   { hash = 1234567890U; Put(h1); }
+	CombineHash(unsigned h1, unsigned h2)      { hash = 1234567890U; Put(h1); Put(h2); }
+	CombineHash(unsigned h1, unsigned h2, unsigned h3)
+	{ hash = 1234567890U; Put(h1); Put(h2); Put(h3); }
+	CombineHash(unsigned h1, unsigned h2, unsigned h3, unsigned h4)
+	{ hash = 1234567890U; Put(h1); Put(h2); Put(h3); Put(h4); }
+};
+
+// Allocation hack. In UPP, there is no need for this, but using NTL outside might benefit
+// warning - currently there is a bug that results in invalid count/size parameters
+// dont use them before fixed
+
+#ifndef NTL_RAW_ALLOC
+
+#define NTL_RAW_ALLOC(size)               new byte[(size)]
+#define NTL_RAW_FREE(ptr, count, size)    delete[] (byte *)(ptr)
+
+#endif
+
+// workaround for broken standard libraries...
+
+template <class T> inline const T& ntl_max(const T& a, const T& b) { return a > b ? a : b; }
+
+// STL compatibility hacks
+
+#define STL_INDEX_COMPATIBILITY(C) \
+	typedef T             value_type; \
+	typedef ConstIterator const_iterator; \
+	typedef const T&      const_reference; \
+	typedef const T&      const_reference; \
+	typedef int           size_type; \
+	typedef int           difference_type; \
+	const_iterator        begin() const          { return B::Begin(); } \
+	const_iterator        end() const            { return B::End(); } \
+	void                  clear()                { B::Clear(); } \
+	size_type             size()                 { return B::GetCount(); } \
+
+#define STL_BI_COMPATIBILITY(C) \
+	typedef T             value_type; \
+	typedef ConstIterator const_iterator; \
+	typedef const T&      const_reference; \
+	typedef const T&      const_reference; \
+	typedef int           size_type; \
+	typedef int           difference_type; \
+	const_iterator        begin() const          { return Begin(); } \
+	const_iterator        end() const            { return End(); } \
+	void                  clear()                { Clear(); } \
+	size_type             size()                 { return GetCount(); } \
+	typedef Iterator      iterator; \
+	typedef T&            reference; \
+	iterator              begin()                { return Begin(); } \
+	iterator              end()                  { return End(); } \
+
+#define STL_MAP_COMPATIBILITY(C) \
+	typedef T             value_type; \
+	typedef ConstIterator const_iterator; \
+	typedef const T&      const_reference; \
+	typedef const T&      const_reference; \
+	typedef int           size_type; \
+	typedef int           difference_type; \
+	const_iterator        begin() const          { return B::Begin(); } \
+	const_iterator        end() const            { return B::End(); } \
+	void                  clear()                { B::Clear(); } \
+	size_type             size()                 { return B::GetCount(); } \
+	typedef Iterator      iterator; \
+	typedef T&            reference; \
+	iterator              begin()                { return B::Begin(); } \
+	iterator              end()                  { return B::End(); } \
+
+#define STL_VECTOR_COMPATIBILITY(C) \
+	typedef T             value_type; \
+	typedef ConstIterator const_iterator; \
+	typedef const T&      const_reference; \
+	typedef const T&      const_reference; \
+	typedef int           size_type; \
+	typedef int           difference_type; \
+	const_iterator        begin() const          { return Begin(); } \
+	const_iterator        end() const            { return End(); } \
+	void                  clear()                { Clear(); } \
+	size_type             size()                 { return GetCount(); } \
+	typedef Iterator      iterator; \
+	typedef T&            reference; \
+	iterator              begin()                { return Begin(); } \
+	iterator              end()                  { return End(); } \
+	reference             front()                { return (*this)[0]; } \
+	const_reference       front() const          { return (*this)[0]; } \
+	reference             back()                 { return Top(); } \
+	const_reference       back() const           { return Top(); } \
+	void                  push_back(const T& x)  { Add(x); } \
+	void                  pop_back()             { Drop(); }
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.h	(revision 1526)
@@ -0,0 +1,249 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+enum { UNSIGNED_HIBIT = 0x80000000 };
+
+class HashBase : Moveable<HashBase> {
+	struct Link : Moveable<Link> {
+		int   next;
+		int   prev;
+	};
+	Vector<unsigned>      hash;
+	mutable Vector<Link>  link;
+	mutable int          *map;
+	mutable int           mask;
+	mutable int           unlinked;
+
+	void  LinkBefore(int i, Link& l, int bi) const;
+	void  LinkTo(int i, Link& l, int& m) const;
+	void  Unlink(int i, Link& l, int& mi);
+	void  Unlink(int i, Link& l);
+	int&  Maph(unsigned _hash) const;
+	int&  Mapi(int i) const;
+	void  FinishIndex() const;
+	void  DoIndex() const;
+	void  Free() const;
+
+public:
+	void  ClearIndex() const;
+	void  Reindex(int n) const;
+	void  Reindex() const;
+
+	void  Add(unsigned hash);
+	void  Set(int i, unsigned hash);
+	void  SetUn(int i, unsigned hash);
+	unsigned operator [] (int i) const      { return hash[i]; }
+	int   Find(unsigned hash) const;
+	int   FindNext(int i) const;
+	int   FindLast(unsigned hash) const;
+	int   FindPrev(int i) const;
+	int   Put(unsigned hash);
+
+	bool  IsUnlinked(int i) const           { return hash[i] & UNSIGNED_HIBIT; }
+	void  Unlink(int i);
+	Vector<int> GetUnlinked() const;
+
+	void  Remove(int i);
+	void  Remove(const int *sorted_list, int count);
+	void  Insert(int i, unsigned hash);
+
+	int   GetCount() const                  { return hash.GetCount(); }
+	void  Trim(int count);
+	void  Drop(int n);
+	void  Clear()                           { hash.Clear(); ClearIndex(); }
+
+	void  Reserve(int n);
+	void  Shrink();
+
+#ifdef UPP
+	void  Serialize(Stream& s);
+#endif
+
+	HashBase();
+	~HashBase();
+
+	HashBase(pick_ HashBase& b);
+	void operator=(pick_ HashBase& b);
+	HashBase(const HashBase& b, int);
+	void operator<<=(const HashBase& b);
+
+	bool  IsPicked() const                  { return hash.IsPicked(); }
+
+	const unsigned *Begin() const           { return hash.Begin(); }
+	const unsigned *End() const             { return hash.End(); }
+	
+	void Swap(HashBase& b);
+};
+
+template <class T>
+struct StdHash {
+	unsigned operator()(const T& x) const { return GetHashValue(x); }
+};
+
+template <class T, class V, class HashFn>
+class AIndex {
+public: // GCC bug ?
+	HashFn    hashfn;
+
+protected:
+	V         key;
+	HashBase  hash;
+
+	int      Find0(const T& x, int i) const {
+		while(i >= 0 && !(x == key[i])) i = hash.FindNext(i);
+		return i;
+	}
+	int      FindB(const T& x, int i) const {
+		while(i >= 0 && !(x == key[i])) i = hash.FindPrev(i);
+		return i;
+	}
+	void     Hash();
+
+public:
+	void     Add(const T& x, unsigned _hash);
+	void     Add(const T& x);
+	int      FindAdd(const T& key, unsigned _hash);
+	int      FindAdd(const T& key);
+	AIndex&  operator<<(const T& x)          { Add(x); return *this; }
+
+	int      Put(const T& x, unsigned _hash);
+	int      Put(const T& x);
+	int      FindPut(const T& key, unsigned _hash);
+	int      FindPut(const T& key);
+
+	int      Find(const T& x, unsigned _hash) const;
+	int      Find(const T& x) const;
+	int      FindNext(int i) const;
+	int      FindLast(const T& x, unsigned _hash) const;
+	int      FindLast(const T& x) const;
+	int      FindPrev(int i) const;
+
+	void     Set(int i, const T& x, unsigned _hash);
+	void     Set(int i, const T& x);
+
+	const T& operator[](int i) const         { return key[i]; }
+	int      GetCount() const                { return key.GetCount(); }
+	bool     IsEmpty() const                 { return key.IsEmpty(); }
+
+	void     Clear()                         { hash.Clear(); key.Clear(); }
+
+	void     ClearIndex() const              { hash.ClearIndex(); }
+	void     Reindex(int n) const            { hash.Reindex(n); }
+	void     Reindex() const                 { hash.Reindex(); }
+
+	void     Unlink(int i)                   { hash.Unlink(i); }
+	int      UnlinkKey(const T& k, unsigned h);
+	int      UnlinkKey(const T& k);
+	bool     IsUnlinked(int i) const         { return hash.IsUnlinked(i); }
+	void     Sweep();
+
+	void     Insert(int i, const T& k, unsigned h);
+	void     Insert(int i, const T& k);
+	void     Remove(int i);
+	void     Remove(const int *sorted_list, int count);
+	void     Remove(const Vector<int>& sorted_list);
+	int      RemoveKey(const T& k, unsigned h);
+	int      RemoveKey(const T& k);
+
+	void     Trim(int n)                     { key.SetCount(n); hash.Trim(n); }
+	void     Drop(int n = 1)                 { key.Drop(n); hash.Drop(n); }
+	const T& Top() const                     { return key.Top(); }
+
+	void     Reserve(int n)                  { key.Reserve(n); hash.Reserve(n); }
+	void     Shrink()                        { key.Shrink(); hash.Shrink(); }
+	int      GetAlloc() const                { return key.GetAlloc(); }
+
+#ifdef UPP
+	void     Serialize(Stream& s);
+#endif
+
+	V        PickKeys()                       { return key; }
+	const V& GetKeys() const                  { return key; }
+
+// Pick assignment & copy. Picked source can only Clear(), ~AIndex(), operator=, operator<<=
+
+	AIndex& operator=(pick_ V& s);
+	AIndex& operator<<=(const V& s);
+
+// Standard container interface
+	typedef T                ValueType;
+	typedef typename V::ConstIterator ConstIterator;
+	ConstIterator  Begin() const                          { return key.Begin(); }
+	ConstIterator  End() const                            { return key.End(); }
+	ConstIterator  GetIter(int pos) const                 { return key.GetIter(pos); }
+	
+	void Swap(AIndex& b)                                  { ::Swap(hash, b.hash);
+	                                                        ::Swap(key, b.key); }
+// Optimalizations
+	friend int  GetCount(const AIndex& v)                 { return v.GetCount(); }
+
+protected:
+	AIndex(pick_ V& s);
+	AIndex(const V& s, int);
+	AIndex() {}
+	AIndex(const AIndex& s, int);
+};
+
+template <class T, class HashFn = StdHash<T> >
+class Index : public AIndex<T, Vector<T>, HashFn>,
+              Moveable< Index<T, HashFn> >,
+              DeepCopyOption< Index<T, HashFn > > {
+	typedef AIndex< T, Vector<T>, HashFn > B;
+public:
+	T        Pop()                           { T x = B::Top(); B::Drop(); return x; }
+
+	Index() {}
+	Index(pick_ Index& s) : B(s)             {}
+	Index(const Index& s, int) : B(s, 1)     {}
+	Index(pick_ Vector<T>& s) : B(s)         {}
+	Index(const Vector<T>& s, int) : B(s, 1) {}
+
+	Index& operator=(pick_ Vector<T>& x)     { B::operator=(x); return *this; }
+	
+	friend void Swap(Index& a, Index& b)     { a.B::Swap(b); }
+
+	typedef typename B::ConstIterator ConstIterator; // GCC bug (?)
+	STL_INDEX_COMPATIBILITY(Index<T _cm_ HashFn>)
+};
+
+template <class T, class HashFn = StdHash<T> >
+class ArrayIndex : public AIndex<T, Array<T>, HashFn>,
+                   Moveable< ArrayIndex<T, HashFn> >,
+                   DeepCopyOption< ArrayIndex<T, HashFn > > {
+	typedef AIndex< T, Array<T>, HashFn > B;
+public:
+	void     Add(const T& x, unsigned _hash)        { B::Add(x, _hash); }
+	void     Add(const T& x)                        { B::Add(x); }
+	void     Set(int i, const T& x, unsigned _hash) { B::Set(i, x, _hash); }
+	void     Set(int i, const T& x)                 { B::Set(i, x); }
+
+	void     Add(T *newt, unsigned _hash);
+	void     Add(T *newt);
+	void     Set(int i, T *newt, unsigned _hash);
+	void     Set(int i, T *newt);
+
+	ArrayIndex() {}
+	ArrayIndex(pick_ ArrayIndex& s) : B(s)          {}
+	ArrayIndex(const ArrayIndex& s, int) : B(s, 1)  {}
+	ArrayIndex(pick_ Array<T>& s) : B(s)            {}
+	ArrayIndex(const Array<T>& s, int) : B(s, 1)    {}
+
+	ArrayIndex& operator=(pick_ Array<T>& x)        { B::operator=(x); return *this; }
+
+	friend void Swap(ArrayIndex& a, ArrayIndex& b)  { a.B::Swap(b); }
+
+	typedef typename B::ConstIterator ConstIterator; // GCC bug (?)
+	STL_INDEX_COMPATIBILITY(ArrayIndex<T _cm_ HashFn>)
+};
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.hpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.hpp	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/detail/Index.hpp	(revision 1526)
@@ -0,0 +1,534 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+inline void HashBase::LinkTo(int i, Link& l, int& m) const
+{
+	if(m >= 0) {
+		Link& bl = link[m];
+		l.next = m;
+		l.prev = bl.prev;
+		bl.prev = i;
+		link[l.prev].next = i;
+	}
+	else
+		m = l.prev = l.next = i;
+}
+
+inline void HashBase::Unlink(int i, Link& l, int& m)
+{
+	if(i == m) {
+		if(l.next == i) {
+			m = -1;
+			return;
+		}
+		m = l.next;
+	}
+	link[l.next].prev = l.prev;
+	link[l.prev].next = l.next;
+}
+
+inline void HashBase::Unlink(int i, Link& l)
+{
+	Unlink(i, l, hash[i] & UNSIGNED_HIBIT ? unlinked : Mapi(i));
+}
+
+inline int& HashBase::Mapi(int i) const
+{
+	return Maph(hash[i]);
+}
+
+inline int& HashBase::Maph(unsigned _hash) const
+{
+	unsigned h = _hash & ~UNSIGNED_HIBIT;
+	return map[int(((h >> 7) ^ (h >> 22) ^ (h >> 15) ^ h) & mask)];
+}
+
+inline void HashBase::DoIndex() const
+{
+	if(hash.GetCount() <= mask)
+		FinishIndex();
+	else
+		Reindex();
+}
+
+inline int HashBase::Find(unsigned _hash) const
+{
+	if(hash.GetCount() == 0) return -1;
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	return Maph(_hash & ~UNSIGNED_HIBIT);
+}
+
+inline int HashBase::FindNext(int i) const
+{
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	int q = link[i].next;
+	return q == Mapi(i) ? -1 : q;
+}
+
+inline int HashBase::FindLast(unsigned _hash) const
+{
+	if(hash.GetCount() == 0) return - 1;
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	int i = Find(_hash & ~UNSIGNED_HIBIT);
+	return i >= 0 ? link[i].prev : -1;
+}
+
+inline int HashBase::FindPrev(int i) const
+{
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	int q = link[i].prev;
+	return q == link[Mapi(i)].prev ? -1 : q;
+}
+
+inline void HashBase::Unlink(int i)
+{
+	ASSERT(!IsUnlinked(i));
+	hash[i] |= UNSIGNED_HIBIT;
+	if(i < link.GetCount()) {
+		Link& lnk = link[i];
+		Unlink(i, lnk, Mapi(i));
+		LinkTo(i, lnk, unlinked);
+	}
+}
+
+template <class T, class V, class HashFn>
+AIndex<T, V, HashFn>::AIndex(const AIndex& s, int)
+:	key(s.key, 0),
+	hash(s.hash, 0) {}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Hash() {
+	for(int i = 0; i < key.GetCount(); i++)
+		hash.Add(hashfn(key[i]));
+}
+
+template <class T, class V, class HashFn>
+AIndex<T, V, HashFn>& AIndex<T, V, HashFn>::operator=(pick_ V& s) {
+	key = s;
+	hash.Clear();
+	Hash();
+	return *this;
+}
+
+template <class T, class V, class HashFn>
+AIndex<T, V, HashFn>& AIndex<T, V, HashFn>::operator<<=(const V& s) {
+	key <<= s;
+	hash.Clear();
+	Hash();
+	return *this;
+}
+
+template <class T, class V, class HashFn>
+AIndex<T, V, HashFn>::AIndex(pick_ V& s) : key(s) {
+	Hash();
+}
+
+template <class T, class V, class HashFn>
+AIndex<T, V, HashFn>::AIndex(const V& s, int) : key(s, 1) {
+	Hash();
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Add(const T& x, unsigned _hash) {
+	key.Add(x);
+	hash.Add(_hash);
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Add(const T& x) {
+	Add(x, hashfn(x));
+}
+
+template <class T, class V, class HashFn>
+int  AIndex<T, V, HashFn>::FindAdd(const T& _key, unsigned _hash) {
+	int i = Find(_key, _hash);
+	if(i >= 0) return i;
+	i = key.GetCount();
+	Add(_key, _hash);
+	return i;
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::Put(const T& x, unsigned _hash)
+{
+	int q = hash.Put(_hash);
+	if(q < 0) {
+		q = key.GetCount();
+		Add(x, _hash);
+	}
+	else
+		key[q] = x;
+	return q;
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::Put(const T& x)
+{
+	return Put(x, hashfn(x));
+}
+
+template <class T, class V, class HashFn>
+int  AIndex<T, V, HashFn>::FindPut(const T& _key, unsigned _hash)
+{
+	int i = Find(_key, _hash);
+	if(i >= 0) return i;
+	return Put(_key, _hash);
+}
+
+template <class T, class V, class HashFn>
+int  AIndex<T, V, HashFn>::FindPut(const T& key)
+{
+	return FindPut(key, hashfn(key));
+}
+
+template <class T, class V, class HashFn>
+inline int AIndex<T, V, HashFn>::Find(const T& x, unsigned _hash) const {
+	return Find0(x, hash.Find(_hash));
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::Find(const T& x) const {
+	return Find(x, hashfn(x));
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::FindNext(int i) const {
+	return Find0(key[i], hash.FindNext(i));
+}
+
+template <class T, class V, class HashFn>
+inline int AIndex<T, V, HashFn>::FindLast(const T& x, unsigned _hash) const {
+	return FindB(x, hash.FindLast(_hash));
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::FindLast(const T& x) const {
+	return FindLast(x, hashfn(x));
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::FindPrev(int i) const {
+	return FindB(key[i], hash.FindPrev(i));
+}
+
+template <class T, class V, class HashFn>
+int  AIndex<T, V, HashFn>::FindAdd(const T& key) {
+	return FindAdd(key, hashfn(key));
+}
+
+template <class T, class V, class HashFn>
+void  AIndex<T, V, HashFn>::Set(int i, const T& x, unsigned _hash) {
+	key[i] = x;
+	hash.Set(i, _hash);
+}
+
+template <class T, class V, class HashFn>
+void  AIndex<T, V, HashFn>::Set(int i, const T& x) {
+	Set(i, x, hashfn(x));
+}
+
+#ifdef UPP
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Serialize(Stream& s) {
+	if(s.IsLoading()) ClearIndex();
+	key.Serialize(s);
+	hash.Serialize(s);
+}
+#endif
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::UnlinkKey(const T& k, unsigned h)
+{
+	int n = 0;
+	int q = hash.Find(h);
+	while(q >= 0) {
+		int w = q;
+		q = hash.FindNext(q);
+		if(k == key[w]) {
+			hash.Unlink(w);
+			n++;
+		}
+	}
+	return n;
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::UnlinkKey(const T& k)
+{
+	return UnlinkKey(k, hashfn(k));
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Sweep()
+{
+	Vector<int> b = hash.GetUnlinked();
+	Sort(b);
+	Remove(b);
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Insert(int i, const T& k, unsigned h) {
+	key.Insert(i, k);
+	hash.Insert(i, h);
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Insert(int i, const T& k) {
+	key.Insert(i, k);
+	hash.Insert(i, hashfn(k));
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Remove(int i)
+{
+	key.Remove(i);
+	hash.Remove(i);
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Remove(const int *sorted_list, int count)
+{
+	key.Remove(sorted_list, count);
+	hash.Remove(sorted_list, count);
+}
+
+template <class T, class V, class HashFn>
+void AIndex<T, V, HashFn>::Remove(const Vector<int>& sl)
+{
+	Remove(sl, sl.GetCount());
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::RemoveKey(const T& k, unsigned h)
+{
+	Vector<int> rk;
+	int q = Find(k, h);
+	while(q >= 0) {
+		rk.Add(q);
+		q = FindNext(q);
+	}
+	Remove(rk);
+	return rk.GetCount();
+}
+
+template <class T, class V, class HashFn>
+int AIndex<T, V, HashFn>::RemoveKey(const T& k)
+{
+	return RemoveKey(k, hashfn(k));
+}
+
+// ------------------
+
+template <class T, class HashFn>
+void ArrayIndex<T, HashFn>::Add(T *newt, unsigned _hash) {
+	B::key.Add(newt);
+	B::hash.Add(_hash);
+}
+
+template <class T, class HashFn>
+void ArrayIndex<T, HashFn>::Add(T *newt) {
+	Add(newt, B::hashfn(*newt));
+}
+
+template <class T, class HashFn>
+void ArrayIndex<T, HashFn>::Set(int i, T *newt, unsigned _hash) {
+	B::key.Set(i, newt);
+	B::hash.Set(i, _hash);
+}
+
+template <class T, class HashFn>
+void ArrayIndex<T, HashFn>::Set(int i, T *newt) {
+	Set(i, newt, B::hashfn(*newt));
+}
+
+// --------------------
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindAdd(const K& k) {
+	int i = Find(k);
+	if(i < 0) {
+		i = GetCount();
+		Add(k);
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindAdd(const K& k, const T& x) {
+	int i = Find(k);
+	if(i < 0) {
+		i = GetCount();
+		Add(k, x);
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindAddPick(const K& k, pick_ T& x) {
+	int i = Find(k);
+	if(i < 0) {
+		i = GetCount();
+		AddPick(k, x);
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+void AMap<K, T, V, HashFn>::Put(const K& k, const T& x)
+{
+	int i = key.Put(k);
+	if(i < value.GetCount())
+		value[i] = x;
+	else {
+		ASSERT(i == value.GetCount());
+		value.Add(x);
+	}
+}
+
+template <class K, class T, class V, class HashFn>
+void AMap<K, T, V, HashFn>::PutPick(const K& k, pick_ T& x)
+{
+	int i = key.Put(k);
+	if(i < value.GetCount())
+		value[i] = x;
+	else {
+		ASSERT(i == value.GetCount());
+		value.AddPick(x);
+	}
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::Put(const K& k)
+{
+	int i = key.Put(k);
+	if(i < value.GetCount())
+		return value[i];
+	else {
+		ASSERT(i == value.GetCount());
+		return value.Add();
+	}
+}
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindPut(const K& k)
+{
+	int i = Find(k);
+	if(i < 0) {
+		i = key.Put(k);
+		if(i >= value.GetCount()) {
+			ASSERT(i == value.GetCount());
+			i = value.GetCount();
+			value.Add();
+		}
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindPut(const K& k, const T& init)
+{
+	int i = Find(k);
+	if(i < 0) {
+		i = key.Put(k);
+		if(i >= value.GetCount()) {
+			ASSERT(i == value.GetCount());
+			i = value.GetCount();
+			value.Add(init);
+		}
+		else
+			value[i] = init;
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::FindPutPick(const K& k, pick_ T& init)
+{
+	int i = Find(k);
+	if(i < 0) {
+		i = key.Put(k);
+		if(i >= value.GetCount()) {
+			ASSERT(i == value.GetCount());
+			i = value.GetCount();
+			value.Add(init);
+		}
+		else
+			value[i] = init;
+	}
+	return i;
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetAdd(const K& k) {
+	int i = Find(k);
+	if(i >= 0) return value[i];
+	return Add(k);
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetAdd(const K& k, const T& x) {
+	int i = Find(k);
+	if(i >= 0) return value[i];
+	Add(k, x);
+	return value.Top();
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetAddPick(const K& k, pick_ T& x) {
+	int i = Find(k);
+	if(i >= 0) return value[i];
+	AddPick(k, x);
+	return value.Top();
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetPut(const K& k) {
+	return value[FindAdd(k)];
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetPut(const K& k, const T& x) {
+	return value[FindAdd(k, x)];
+}
+
+template <class K, class T, class V, class HashFn>
+T&  AMap<K, T, V, HashFn>::GetPutPick(const K& k, pick_ T& x) {
+	return value[FindAddPick(k, x)];
+}
+
+#ifdef UPP
+template <class K, class T, class V, class HashFn>
+void AMap<K, T, V, HashFn>::Serialize(Stream& s) {
+	int version = 0;
+	s / version % key % value;
+}
+#endif
+
+template <class K, class T, class V, class HashFn>
+int AMap<K, T, V, HashFn>::RemoveKey(const K& k)
+{
+	Vector<int> rk;
+	int q = Find(k);
+	while(q >= 0) {
+		rk.Add(q);
+		q = FindNext(q);
+	}
+	Remove(rk);
+	return rk.GetCount();
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntl.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntl.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntl.h	(revision 1526)
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef NTL_H
+#define NTL_H
+
+#include <assert.h>
+#include <string.h>
+
+#include <new>
+
+#ifndef ASSERT
+#define ASSERT assert
+#endif
+
+#define pick_  const   // Do not beat us for this. Imagine it is #define pick_ &&
+#define _cm_   ,
+
+typedef unsigned char byte;
+
+#ifdef _MSC_VER // Solve some MSC problems...
+
+	#ifdef TYPENAME
+    	//use predefined value
+	#elif _MSC_VER < 1300
+		#define TYPENAME
+	#else
+		#define TYPENAME typename
+	#endif
+
+	// Later we might consider #pragma warning(push/pop)
+	#pragma warning(disable : 4800) //'type' : forcing value to bool 'true' or 'false'
+	#pragma warning(disable : 4786) // identifier was truncated
+	#pragma warning(disable : 4345) // POD type constructed will be default-initialized
+	#pragma warning(disable : 4675) //'function' : resolved overload was found by Koenig lookup
+
+	#define COMPILER_MSC
+
+#else
+
+	#define TYPENAME typename
+
+#endif
+
+
+#ifdef __GNUC__
+#define COMPILER_GNU
+#endif
+
+#if defined(_M_IX86) || defined(__i386__)
+	#define CPU_IA32
+#endif
+
+#include <detail/Topt.h>
+#include <detail/Vcont.h>
+#include <detail/BiCont.h>
+#include <detail/Index.h>
+#include <detail/Map.h>
+#include <detail/Algo.h>
+#include <detail/Other.h>
+#include <detail/Vcont.hpp>
+#include <detail/Index.hpp>
+
+#endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/Cont.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/Cont.cpp	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/Cont.cpp	(revision 1526)
@@ -0,0 +1,325 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <ntl.h>
+
+#ifdef _MSC_VER
+#pragma inline_depth(255)
+#pragma optimize("t", on)
+#endif
+
+int Pow2Bound(int i)
+{
+	int n = 1;
+	while(n < i) {
+		n <<= 1;
+		ASSERT(n);
+	}
+	return n;
+}
+
+void HashBase::Free() const
+{
+	if(map)
+		NTL_RAW_FREE(map, mask + 1, sizeof(int));
+	map = NULL;
+	mask = 0;
+}
+
+void HashBase::ClearIndex() const
+{
+	link.Clear();
+	unlinked = -1;
+	Free();
+}
+
+HashBase::HashBase()
+{
+	unlinked = -1;
+	map = NULL;
+	mask = 0;
+}
+
+HashBase::HashBase(pick_ HashBase& b)
+: hash(b.hash),
+  link(b.link)
+{
+	map = b.map;
+	mask = b.mask;
+	unlinked = b.unlinked;
+	b.map = NULL;
+}
+
+void HashBase::operator=(pick_ HashBase& b)
+{
+	hash = b.hash;
+	link = b.link;
+	Free();
+	map = b.map;
+	mask = b.mask;
+	unlinked = b.unlinked;
+	b.map = NULL;
+}
+
+HashBase::HashBase(const HashBase& b, int)
+: hash(b.hash, 0)
+{
+	unlinked = -1;
+	map = NULL;
+	mask = 0;
+}
+
+void HashBase::operator<<=(const HashBase& b)
+{
+	ClearIndex();
+	hash <<= b.hash;
+}
+
+HashBase::~HashBase()
+{
+	Free();
+}
+
+inline void HashBase::LinkBefore(int i, Link& l, int bi) const
+{
+	Link& bl = link[bi];
+	l.next = bi;
+	l.prev = bl.prev;
+	bl.prev = i;
+	link[l.prev].next = i;
+}
+
+void HashBase::Trim(int count)
+{
+	ASSERT(count <= hash.GetCount() && count >= 0);
+	if(map) {
+		for(int i = count; i < link.GetCount(); i++)
+			Unlink(i, link[i]);
+		link.SetCount(count);
+	}
+	hash.SetCount(count);
+}
+
+void HashBase::Drop(int n)
+{
+	Trim(hash.GetCount() - n);
+}
+
+//inline //!! Fidler: either inline or .cpp
+void HashBase::FinishIndex() const
+{
+	int q = link.GetCount();
+	link.Reserve(hash.GetAlloc());
+	link.AddN(hash.GetCount() - q);
+	for(int i = q; i < hash.GetCount(); i++)
+		LinkTo(i, link[i], hash[i] & UNSIGNED_HIBIT ? unlinked : Mapi(i));
+}
+
+void HashBase::Reindex(int n) const
+{
+	ClearIndex();
+	Free();
+	n = ntl_max(16, Pow2Bound(n));
+	map = (int *)NTL_RAW_ALLOC(n * sizeof(int));
+	Fill(map, map + n, -1);
+	mask = n - 1;
+	FinishIndex();
+}
+
+void HashBase::Reindex() const
+{
+	Reindex(hash.GetCount());
+}
+
+void HashBase::Add(unsigned _hash)
+{
+	hash.Add(_hash & ~UNSIGNED_HIBIT);
+}
+
+void  HashBase::SetUn(int i, unsigned _hash)
+{
+	if(map) {
+		if(link.GetCount() < hash.GetCount())
+			DoIndex();
+		Link& lnk = link[i];
+		Unlink(i, lnk);
+		LinkTo(i, lnk, Maph(_hash & ~UNSIGNED_HIBIT));
+	}
+	hash[i] = _hash & ~UNSIGNED_HIBIT;
+}
+
+Vector<int> HashBase::GetUnlinked() const
+{
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	Vector<int> r;
+	int q = unlinked;
+	if(q >= 0) {
+		do {
+			r.Add(q);
+			q = link[q].next;
+		}
+		while(q != unlinked);
+	}
+	return r;
+}
+
+int HashBase::Put(unsigned _hash)
+{
+	if(unlinked < 0) return -1;
+	if(link.GetCount() < hash.GetCount())
+		DoIndex();
+	Link& l = link[unlinked];
+	int i = unlinked;
+	unlinked = link[unlinked].next;
+	if(i == unlinked)
+		unlinked = -1;
+	else {
+		link[l.next].prev = l.prev;
+		link[l.prev].next = l.next;
+	}
+	LinkTo(i, l, Maph(_hash & ~UNSIGNED_HIBIT));
+	hash[i] = _hash & ~UNSIGNED_HIBIT;
+	return i;
+}
+
+void HashBase::Set(int i, unsigned _hash) {
+	if(map) {
+		if(link.GetCount() < hash.GetCount())
+			DoIndex();
+		Link& lnk = link[i];
+		Unlink(i, lnk);
+		int& mi = Maph(_hash & ~UNSIGNED_HIBIT);
+		int ii = mi;
+		if(ii < 0)
+			mi = lnk.prev = lnk.next = i;
+		else
+		if(i < ii) {
+			LinkBefore(i, lnk, ii);
+			mi = i;
+		}
+		else {
+			int l = ii;
+			int h = link[ii].prev;
+			if(h - i < i - l) {
+				while(i < h) {
+					h = link[h].prev;
+				}
+				LinkBefore(i, lnk, link[h].next);
+			}
+			else {
+				l = link[l].next;
+				while(i > l && l != ii) {
+					l = link[l].next;
+				}
+				LinkBefore(i, lnk, l);
+			}
+		}
+	}
+	hash[i] = _hash & ~UNSIGNED_HIBIT;
+}
+
+void HashBase::Shrink() {
+	hash.Shrink();
+	if(Pow2Bound(hash.GetCount()) != mask + 1)
+		ClearIndex();
+	else
+		link.Shrink();
+}
+
+void HashBase::Reserve(int n)
+{
+	hash.Reserve(n);
+	link.Reserve(n);
+	n = Pow2Bound(n);
+	if(n > mask + 1)
+		Reindex(n);
+}
+
+void HashBase::Remove(int i)
+{
+	hash.Remove(i);
+	ClearIndex();
+}
+
+void HashBase::Remove(const int *sorted_list, int count)
+{
+	hash.Remove(sorted_list, count);
+	ClearIndex();
+}
+
+void HashBase::Insert(int i, unsigned _hash) {
+	hash.Insert(i, _hash & ~UNSIGNED_HIBIT);
+	ClearIndex();
+}
+
+#ifdef UPP
+void HashBase::Serialize(Stream& s) {
+	int version = 0;
+	s / version;
+	if(s.IsLoading())
+		ClearIndex();
+	hash.Serialize(s);
+}
+#endif
+
+void HashBase::Swap(HashBase& b) {
+	::Swap(hash, b.hash);
+	::Swap(link, b.link);
+	::Swap(map, b.map);
+	::Swap(mask, b.mask);
+	::Swap(unlinked, b.unlinked);
+}
+
+
+#ifdef CPU_IA32
+
+unsigned memhash(const void *ptr, size_t count)
+{
+	unsigned hash = 1234567890U;
+
+	const unsigned *ds = (unsigned *)ptr;
+	const unsigned *de = ds + (count >> 2);
+	while(ds < de)
+		hash = ((hash << 5) - hash) ^ *ds++;
+
+	const byte *s = (byte *)ds;
+	const byte *e = s + (count & 3);
+	while(s < e)
+		hash = ((hash << 5) - hash) ^ *s++;
+
+	return hash;
+}
+
+#else
+
+unsigned memhash(const void *ptr, size_t count)
+{
+	unsigned hash = 1234567890U;
+
+	const byte *s = (byte *)ptr;
+	const byte *e = s + count;
+	while(s < e)
+		hash = ((hash << 5) - hash) ^ *s++;
+
+	return hash;
+}
+
+#endif
+
+unsigned GetHashValue0(const double& d)
+{
+	return memhash(&d, sizeof(double));
+}
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntls.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntls.h	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/ntl/ntls.h	(revision 1526)
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+// NTL Nonstandard Template Library for C++
+// Copyright (c) 2003 by Miroslav Fidler, Tomas Rylek
+//
+// Created by Miroslav Fidler, Tomas Rylek, cxl@volny.cz
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the suitability of this software 
+//     for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef NTLS_H
+#define NTLS_H
+
+#include <string>
+#include <ntl.h>
+
+NTL_MOVEABLE(std::string)
+
+template<>
+inline unsigned GetHashValue(const std::string& x)
+{
+	return memhash(x.c_str(), x.size());
+}
+
+#ifndef NOWSTRING
+
+NTL_MOVEABLE(std::wstring)
+
+template<>
+inline unsigned GetHashValue(const std::wstring& x)
+{
+	CombineHash hash;
+	for(size_t i = 0; i != x.size(); ++i)
+		hash = hash.Put(x[i]);
+	return hash;
+}
+
+#endif
+
+#endif
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.h	(revision 1526)
@@ -27,5 +27,4 @@
 	class Face;
 
-
 	typedef buffer<Vertex *> vert_buffer;
 	typedef buffer<Edge *> edge_buffer;
@@ -37,13 +36,13 @@
 	extern void collectFaceLoop(Vertex *v, face_buffer& faces);
 
-	#define EDGE_BOGUS 0
-	#define EDGE_BORDER 1
-	#define EDGE_MANIFOLD 2
-	#define EDGE_NONMANIFOLD 3
+#define EDGE_BOGUS 0
+#define EDGE_BORDER 1
+#define EDGE_MANIFOLD 2
+#define EDGE_NONMANIFOLD 3
 	extern int classifyEdge(Edge *);
 
-	#define VERTEX_INTERIOR 0
-	#define VERTEX_BORDER 1
-	#define VERTEX_BORDER_ONLY 2
+#define VERTEX_INTERIOR 0
+#define VERTEX_BORDER 1
+#define VERTEX_BORDER_ONLY 2
 	extern int classifyVertex(Vertex *);
 
@@ -52,15 +51,16 @@
 	// The actual class definitions
 	//
+	////////////////////////////////////////////////////////////////////////
 
 	class VProp
 	{
-	public:
-		Vec3 color;
+		public:
+			Vec3 color;
 	};
 
 	class FProp
 	{
-	public:
-		Vec3 color;
+		public:
+			Vec3 color;
 	};
 
@@ -68,14 +68,14 @@
 	{
 		edge_buffer edge_uses;
-    
-	public:
-	#ifdef SUPPORT_VCOLOR
+
+		public:
+#ifdef SUPPORT_VCOLOR
 		VProp *props;
-	#endif
+#endif
 
 		Vertex(real x, real y, real z) : Vec3(x, y, z), edge_uses(6) {
-	#ifdef SUPPORT_VCOLOR
-		props = NULL;
-	#endif
+#ifdef SUPPORT_VCOLOR
+			props = NULL;
+#endif			
 		}
 		//
@@ -92,43 +92,44 @@
 		void remapTo(Vertex *v);
 
-		unsigned int vID;
+		// SUS
+		int vID; // this can be -1 when the vertex becomes non-valid
 	};
-
 
 	class Edge : public NPrim
 	{
-	private:
+		private:
 
-		Vertex *v1;
+			Vertex *v1;
 
-		face_buffer *face_uses;
-		Edge *twin;
+			face_buffer *face_uses;
+			Edge *twin;
 
-		Edge(Edge *twin, Vertex *org); // the twin constructor
+			Edge(Edge *twin, Vertex *org); // the twin constructor
 
-	public:
-		Edge(Vertex *, Vertex *);
-		~Edge();
+		public:
 
-		//
-		// Fundamental Edge accessors
-		//
-		Vertex *org()  { return v1;       }
-		Vertex *dest() { return twin->v1; }
-		Edge *sym()    { return twin;     }
+			Edge(Vertex *, Vertex *);
+			~Edge();
 
-		//
-		// Standard methods for all objects
-		//
-		void kill();
-		face_buffer& faceUses() { return *face_uses; }
+			//
+			// Fundamental Edge accessors
+			//
+			Vertex *org()  { return v1;       }
+			Vertex *dest() { return twin->v1; }
+			Edge *sym()    { return twin;     }
 
-		//
-		// Basic primitives for manipulating model topology
-		//
-		void linkFace(Face *);
-		void unlinkFace(Face *);
-		void remapEndpoint(Vertex *from, Vertex *to);
-		void remapTo(Edge *);
+			//
+			// Standard methods for all objects
+			//
+			void kill();
+			face_buffer& faceUses() { return *face_uses; }
+
+			//
+			// Basic primitives for manipulating model topology
+			//
+			void linkFace(Face *);
+			void unlinkFace(Face *);
+			void remapEndpoint(Vertex *from, Vertex *to);
+			void remapTo(Edge *);
 	};
 
@@ -137,9 +138,8 @@
 		Edge *edges[3];
 
-
-	public:
-	#ifdef SUPPORT_FCOLOR
+		public:
+#ifdef SUPPORT_FCOLOR
 		FProp *props;
-	#endif
+#endif
 
 		Face(Edge *, Edge *, Edge *);
@@ -148,13 +148,14 @@
 		// Basic Face accessors
 		//
-		const Vec3& vertexPos(int i) const { return *edges[i]->org(); }
-		void vertexPos(int, const Vec3&) {
+		const Vec3& vertexPos(int i) const{return *edges[i]->org();}
+
+		void vertexPos(int, const Vec3&)
+		{
 			fatal_error("Face: can't directly set vertex position.");
 		}
 
-		Vertex *vertex(int i) { return edges[i]->org(); }
-		const Vertex *vertex(int i) const { return edges[i]->org(); }
-		Edge *edge(int i)               { return edges[i];        }
-
+		Vertex *vertex(int i){return edges[i]->org();}
+		const Vertex *vertex(int i) const{return edges[i]->org();}
+		Edge *edge(int i){return edges[i];}
 
 		//
@@ -173,5 +174,5 @@
 }
 
-
 // NAUTILUS_ADJPRIMS_INCLUDED
 #endif
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.h	(revision 1526)
@@ -9,106 +9,130 @@
 #include <GeoMeshSimplifier.h>
 
+using	namespace	Geometry;
+
 class SimplificationMethod
 {
-private:
-	Geometry::Mesh	*mGeoMesh;
-	void compute_pair_info(simplif::pair_info*);
-	simplif::Model M0;
-	simplif::array<simplif::vert_info> vinfo;
-	simplif::Heap *heap;
-	simplif::real proximity_limit;    // distance threshold squared
-	int initialVertCount;
-	int initialEdgeCount;
-	int initialFaceCount;
+	private:
 
-	inline simplif::vert_info& vertex_info(simplif::Vertex *v)
-	{
-		return vinfo(v->validID());
-	}
-	
-	simplif::real pair_mesh_penalty(simplif::Model& M,
-																simplif::Vertex *v1,
-																simplif::Vertex *v2,
-																simplif::Vec3& vnew);
-	
-	int predict_face(simplif::Face& F,
-									simplif::Vertex *v1,
-									simplif::Vertex *v2,
-									simplif::Vec3& vnew,
-									simplif::Vec3& f1,
-									simplif::Vec3& f2,
-									simplif::Vec3& f3);
-	
-	bool check_for_pair(simplif::Vertex *v0, simplif::Vertex *v1);
-	
-	simplif::pair_info *new_pair(simplif::Vertex *v0, simplif::Vertex *v1);
-	
-	void delete_pair(simplif::pair_info *pair);
-	
-	void do_contract(simplif::Model& m, simplif::pair_info *pair);
-	
-	bool decimate_quadric(simplif::Vertex *v, simplif::Mat4& Q);
-	
-	void decimate_contract(simplif::Model& m);
-	
-	simplif::real decimate_error(simplif::Vertex *v);
-	
-	simplif::real decimate_min_error();
-	
-	simplif::real decimate_max_error(simplif::Model& m);
-	
-	void decimate_init(simplif::Model& m, simplif::real limit);
-	
-	bool pair_is_valid(simplif::Vertex *u, simplif::Vertex *v);
-	
-	void simplifmethod_run(int,	Geometry::TIPOFUNC	upb=0);
-	
-	void simplifmethod_runv(int,	Geometry::TIPOFUNC	upb=0);
-	
-	void simplifmethod_init(void);
+		Geometry::Mesh	*mGeoMesh;
 
-	//	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; 
+		void compute_pair_info(simplif::pair_info*);
 
-	//	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<simplif::pair_info *> pointers_to_remove;
+		simplif::Model M0;
 
-	int indexMeshLeaves;
-	
-public:
-	
-	const Geometry::Mesh *objmesh;
-	
-	//	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);
-	
-	void setMeshLeaves(int meshLeaves);
+		simplif::array<simplif::vert_info> vinfo;
 
-	///	Gets mesh simplified.
-	Geometry::Mesh	*	GetMesh();
-	
-	///Destructor
-	~SimplificationMethod();
+		simplif::Heap *heap;
+		simplif::real proximity_limit;    // distance threshold squared
+
+		int initialVertCount;
+		int initialEdgeCount;
+		int initialFaceCount;
+
+		//	Simplification sequence.
+		MeshSimplificationSequence	*msimpseq;
+
+		//	Stores the simplification step.
+		MeshSimplificationSequence::Step simplifstep;
+
+		inline simplif::vert_info& vertex_info(simplif::Vertex *v)
+		{
+			return vinfo(v->validID());
+		}
+
+		simplif::real pair_mesh_penalty(simplif::Model& M,
+				simplif::Vertex *v1,
+				simplif::Vertex *v2,
+				simplif::Vec3& vnew);
+
+		int predict_face(simplif::Face& F,
+				simplif::Vertex *v1,
+				simplif::Vertex *v2,
+				simplif::Vec3& vnew,
+				simplif::Vec3& f1,
+				simplif::Vec3& f2,
+				simplif::Vec3& f3);
+
+		bool check_for_pair(simplif::Vertex *v0, simplif::Vertex *v1);
+
+		simplif::pair_info *new_pair(simplif::Vertex *v0, simplif::Vertex *v1);
+
+		void delete_pair(simplif::pair_info *pair);
+
+		void do_contract(simplif::Model& m, simplif::pair_info *pair);
+
+		bool decimate_quadric(simplif::Vertex *v, simplif::Mat4& Q);
+
+		void decimate_contract(simplif::Model& m);
+
+		simplif::real decimate_error(simplif::Vertex *v);
+
+		simplif::real decimate_min_error();
+
+		simplif::real decimate_max_error(simplif::Model& m);
+
+		void decimate_init(simplif::Model& m, simplif::real limit);
+
+		bool pair_is_valid(simplif::Vertex *u, simplif::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.
+		//	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.
+		std::vector<Geometry::MeshSimplificationSequence::Step> decim_data;
+
+		std::string meshName;
+
+		unsigned int *first_index_submesh;
+
+		//std::vector<simplif::pair_info *> pointers_to_remove;
+
+		int indexMeshLeaves;
+
+		//	Contract lonely vertices that have same coords than the contracted one.
+		void	contractLonelyVertices(	simplif::Model	&m,
+																	simplif::Vertex	*v0,
+																	simplif::Vertex *v1,
+																	simplif::Vec3		candidate);
+
+		//	Remove twin edges.
+		void	removeTwinEdges(simplif::Model	&m,
+													simplif::Vertex	*v0,
+													simplif::Vertex	*v1,
+													simplif::Vec3		candidate);
+
+	public:
+
+		const Geometry::Mesh *objmesh;
+
+		//	Total number of triangles of all the submeshes.
+		int number_of_triangles;
+
+		SimplificationMethod(const Geometry::Mesh *m);
+
+		void	generateSimplifModel(void);
+
+		Geometry::MeshSimplificationSequence *Decimate(	float lod,
+				int simpliftype,
+				Geometry::TIPOFUNC	upb=0);
+
+		void setMeshLeaves(int meshLeaves);
+
+		///	Gets mesh simplified.
+		Geometry::Mesh	*	GetMesh();
+
+		///	Destructor.
+		~SimplificationMethod();
 };
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.h	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjModel.h	(revision 1526)
@@ -22,113 +22,128 @@
 	class Model : public SMF_Model
 	{
-	protected:
-		vert_buffer vertices;
-		edge_buffer edges;
-		face_buffer faces;
-		vec3_buffer normals; // SUS
-		vec2_buffer texcoords;
+		protected:
+			
+			vert_buffer vertices;
+			edge_buffer edges;
+			face_buffer faces;
+			vec3_buffer normals; // SUS
+			vec2_buffer texcoords;
 
-	private:
+		private:
 
-		void maybeFixFace(Face *);
+			void maybeFixFace(Face *);
 
-	public:
-		Model() {
-			validVertCount = 0;
-			validEdgeCount = 0;
-			validFaceCount = 0;
-		}
+		public:
+			
+			Model()
+			{
+				validVertCount = 0;
+				validEdgeCount = 0;
+				validFaceCount = 0;
+			}
 
-		~Model(){
-			for (int i=0; i<vertices.length(); i++)
-				delete vertices[i];
-			for (int i=0; i<edges.length(); i++)
-				delete edges[i];
-			for (int i=0; i<faces.length(); i++)
-				delete faces[i];
-		}
+			~Model()
+			{
+				for (int i=0; i<vertices.length(); i++)
+				{
+					delete vertices[i];
+				}
 
-		Bounds bounds;
+				for (int i=0; i<edges.length(); i++)
+				{
+					delete edges[i];
+				}
 
-		int validVertCount;
-		int validEdgeCount;
-		int validFaceCount;
+				for (int i=0; i<faces.length(); i++)
+				{
+					delete faces[i];
+				}
+			}
 
-		//
-		// Basic model accessor functions
-		//
-		simplif::Vertex *vertex(int i) { return vertices(i); }
-		simplif::Vec3 & normal(int i){ return normals(i); }
-		simplif::Vec2 & texcoord(int i){ return texcoords(i); }
-		simplif::Edge *edge(int i) { return edges(i); }
-		simplif::Face *face(int i) { return faces(i); }
+			Bounds bounds;
 
-		int vertCount() { return vertices.length(); }
-		int normCount() { return normals.length();  }
-		int texcoordCount() { return texcoords.length();  }
-		int edgeCount() { return edges.length();    }
-		int faceCount() { return faces.length();    }
+			int validVertCount;
+			int validEdgeCount;
+			int validFaceCount;
 
-		vert_buffer& allVertices() { return vertices; }
-		edge_buffer& allEdges()    { return edges;    }
-		face_buffer& allFaces()    { return faces;    }
+			//
+			// Basic model accessor functions
+			//
+			simplif::Vertex *vertex(int i) { return vertices(i); }
+			simplif::Vec3 & normal(int i){ return normals(i); }
+			simplif::Vec2 & texcoord(int i){ return texcoords(i); }
+			simplif::Edge *edge(int i) { return edges(i); }
+			simplif::Face *face(int i) { return faces(i); }
 
-		//
-		// Simplification primitives
-		//
-		Vertex   *newVertex(real x=0.0, real y=0.0, real z=0.0);
-		Edge     *newEdge(Vertex *,Vertex *);
-		Face *newFace(Vertex *, Vertex *, Vertex *);
+			int vertCount() { return vertices.length(); }
+			int normCount() { return normals.length();  }
+			int texcoordCount() { return texcoords.length();  }
+			int edgeCount() { return edges.length();    }
+			int faceCount() { return faces.length();    }
 
-		void killVertex(Vertex *);
-		void killEdge(Edge *);
-		void killFace(Face *);
+			vert_buffer& allVertices() { return vertices; }
+			edge_buffer& allEdges()    { return edges;    }
+			face_buffer& allFaces()    { return faces;    }
 
-		void reshapeVertex(Vertex *, real, real, real);
-		void remapVertex(Vertex *from, Vertex *to);
+			//
+			// Simplification primitives
+			//
+			Vertex   *newVertex(real x=0.0, real y=0.0, real z=0.0);
+			Edge     *newEdge(Vertex *,Vertex *);
+			Face *newFace(Vertex *, Vertex *, Vertex *);
 
-		void contract(Vertex *v1, Vertex *v2, const Vec3& to,
-			  face_buffer& changed);
+			void killVertex(Vertex *);
+			void killEdge(Edge *);
+			void killFace(Face *);
 
-		void contract(Vertex *v1, 
-			  const vert_buffer& others,
-			  const Vec3& to,
-			  face_buffer& changed);
+			void reshapeVertex(Vertex *, real, real, real);
+			void remapVertex(Vertex *from, Vertex *to);
 
+			void contract(Vertex *v1, Vertex *v2, const Vec3& to,
+					face_buffer& changed);
 
-		//
-		// Simplification convenience procedures
-		//
-		void removeDegeneracy(face_buffer& changed);
-		void contractionRegion(Vertex *v1, Vertex *v2, face_buffer& changed);
-		void contractionRegion(Vertex *v1,
-				   const vert_buffer& vertices,
-				   face_buffer& changed);
+			void contract(Vertex *v1, 
+					const vert_buffer& others,
+					const Vec3& to,
+					face_buffer& changed);
 
-		//
-		// SMF reader functions
-		//
-		int in_Vertex(const Vec3&);
-		int in_Normal(const Vec3&);
-		int in_TexCoord(const Vec2&);
-		int in_Face(int v1, int v2, int v3, int n1, int n2, int n3, int t1, int t2, int t3);
-		int miin_Face(int v1, int v2, int v3);
+			//
+			// Simplification convenience procedures
+			//
+			void removeDegeneracy(face_buffer& changed);
+			void contractionRegion(Vertex *v1, Vertex *v2, face_buffer& changed);
+			void contractionRegion(Vertex *v1,
+					const vert_buffer& vertices,
+					face_buffer& changed);
 
-/*	#ifdef SUPPORT_VCOLOR
-		int in_VColor(const Vec3&);
-	#endif
-	#ifdef SUPPORT_FCOLOR
-		int in_FColor(const Vec3&);
-	#endif
+			//
+			// SMF reader functions
+			//
+			int in_Vertex(const Vec3&);
+			int in_Normal(const Vec3&);
+			int in_TexCoord(const Vec2&);
+
+			int in_Face(int v1, int v2, int v3, 
+									int n1, int n2, int n3,
+									int t1, int t2, int t3);
+
+			int miin_Face(int v1, int v2, int v3);
+
+			/*	#ifdef SUPPORT_VCOLOR
+					int in_VColor(const Vec3&);
+#endif
+#ifdef SUPPORT_FCOLOR
+int in_FColor(const Vec3&);
+#endif
 */
-		//
-		// Some random functions that are mostly temporary
-		//
+			//
+			// Some random functions that are mostly temporary
+			//
 
-		Vec3 synthesizeNormal(Vertex *);
+			Vec3 synthesizeNormal(Vertex *);
 	};
 }
 
-
 // NAUTILUS_ADJMODEL_INCLUDED
 #endif
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.cxx
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.cxx	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/AdjPrims.cxx	(revision 1526)
@@ -18,25 +18,25 @@
 {
 #ifdef SAFETY
-    assert( edge_uses.length() == 0 );
-#endif
-    markInvalid();
-    edge_uses.reset();
+	assert( edge_uses.length() == 0 );
+#endif
+	markInvalid();
+	edge_uses.reset();
 }
 
 void Vertex::linkEdge(Edge *e)
 {
-    edge_uses.add(e);
+	edge_uses.add(e);
 }
 
 void Vertex::unlinkEdge(Edge *e)
 {
-    int index = edge_uses.find(e);
-
-#ifdef SAFETY
-    assert( index >= 0 );
-#endif
-    edge_uses.remove(index);
-    if( edge_uses.length() <= 0 )
-	kill();
+	int index = edge_uses.find(e);
+
+#ifdef SAFETY
+	assert( index >= 0 );
+#endif
+	edge_uses.remove(index);
+	if( edge_uses.length() <= 0 )
+		kill();
 }
 
@@ -45,7 +45,7 @@
 void Vertex::remapTo(Vertex *v)
 {
-    if( v != this )
-    {
-		for(int i=0; i<edge_uses.length(); i++)
+	if ( v != this )
+	{
+		for (int i=0; i<edge_uses.length(); i++)
 		{
 			assert( edge_uses(i)->org() == this );
@@ -54,37 +54,36 @@
 
 		kill();
-    }
-}
-
+	}
+}
 
 Edge::Edge(Vertex *a, Vertex *b)
 {
-    v1 = a;
-    v1->linkEdge(this);
-
-    face_uses = new buffer<Face *>(2);
-
-    twin = new Edge(this, b);
+	v1 = a;
+	v1->linkEdge(this);
+
+	face_uses = new buffer<Face *>(2);
+
+	twin = new Edge(this, b);
 }
 
 Edge::Edge(Edge *sibling, Vertex *org)
 {
-    v1 = org;
-    v1->linkEdge(this);
-
-    face_uses = sibling->face_uses;
-    twin = sibling;
+	v1 = org;
+	v1->linkEdge(this);
+
+	face_uses = sibling->face_uses;
+	twin = sibling;
 }
 
 Edge::~Edge()
 {
-    if( twin )
-    {
-	face_uses->f_r_e_e();
-	delete face_uses;
-
-	twin->twin = NULL;
-	delete twin;
-    }
+	if ( twin )
+	{
+		face_uses->f_r_e_e();
+		delete face_uses;
+
+		twin->twin = NULL;
+		delete twin;
+	}
 }
 
@@ -92,87 +91,86 @@
 {
 #ifdef SAFETY
-    assert( face_uses->length() == 0 );
-#endif
-    if( isValid() )
-    {
-	org()->unlinkEdge(this);
-	dest()->unlinkEdge(sym());
-	markInvalid();
-	twin->markInvalid();
-	face_uses->reset();
-    }
+	assert( face_uses->length() == 0 );
+#endif
+	if ( isValid() )
+	{
+		org()->unlinkEdge(this);
+		dest()->unlinkEdge(sym());
+		markInvalid();
+		twin->markInvalid();
+		face_uses->reset();
+	}
 }
 
 void Edge::linkFace(Face *face)
 {
-    face_uses->add(face);
+	face_uses->add(face);
 }
 
 void Edge::unlinkFace(Face *face)
 {
-    int index = face_uses->find(face);
-
-#ifdef SAFETY
-    assert( index>=0 );
-#endif
-    face_uses->remove(index);
-    if( face_uses->length() == 0 )
-	kill();
+	int index = face_uses->find(face);
+
+#ifdef SAFETY
+	assert( index>=0 );
+#endif
+	face_uses->remove(index);
+	if( face_uses->length() == 0 )
+		kill();
 }
 
 void Edge::remapTo(Edge *e)
 {
-    if( e != this )
-    {
-	for(int i=0; i<face_uses->length(); i++)
-	{
-	    (*face_uses)(i)->remapEdge(this, e);
-	}
-    
-	// Disconnect from all faces and vertices
-	kill();
-    }
+	if ( e != this )
+	{
+		for (int i=0; i<face_uses->length(); i++)
+		{
+			(*face_uses)(i)->remapEdge(this, e);
+		}
+
+		// Disconnect from all faces and vertices
+		kill();
+	}
 }
 
 void Edge::remapEndpoint(Vertex *from, Vertex *to)
 {
-    if( org()==from )
-    {
+	if ( org() == from )
+	{
 		v1 = to;
 		to->linkEdge(this);
-    }
-    else if( dest()==from )
-    {
+	}
+	else if ( dest() == from )
+	{
 		twin->v1 = to;
 		to->linkEdge(twin);
-    }
-    else
-    {
+	}
+	else
+	{
 		std::cerr << "WARNING remapEndpoint: Illegal endpoint." << std::endl;
-    }
-
-    //
-    // The cached Plane equations for the faces attached to us may
-    // no longer be valid (in general, chances are pretty slim that they're OK)
-    for(int i=0; i<face_uses->length(); i++)
-    {
+	}
+
+	//
+	// The cached Plane equations for the faces attached to us may
+	// no longer be valid (in general, chances are pretty slim that they're OK)
+	for (int i	=	0; i < face_uses->length(); i++)
+	{
 		face_uses->ref(i)->invalidatePlane();
-    }
-}
-
+	}
+}
 
 Face::Face(Edge *e0, Edge *e1, Edge *e2)
     : Face3(*e0->org(), *e1->org(), *e2->org())
 {
-    edges[0] = e0;
-    edges[1] = e1;
-    edges[2] = e2;
-
-    edges[0]->linkFace(this);
-    edges[1]->linkFace(this);
-    edges[2]->linkFace(this);
+	edges[0] = e0;
+	edges[1] = e1;
+	edges[2] = e2;
+
+	edges[0]->linkFace(this);
+	edges[1]->linkFace(this);
+	edges[2]->linkFace(this);
 
 #ifdef SUPPORT_FCOLOR
-    props = NULL;
+	props = NULL;
 #endif
 }
@@ -180,88 +178,91 @@
 void Face::kill()
 {
-    if( isValid() )
-    {
-	if( edge(0)->isValid() )
-	    edge(0)->unlinkFace(this);
-
-	if( edge(1)->isValid() )
-	    edge(1)->unlinkFace(this);
-
-	if( edge(2)->isValid() )
-	    edge(2)->unlinkFace(this);
-
-	markInvalid();
-    }
+	if( isValid() )
+	{
+		if( edge(0)->isValid() )
+			edge(0)->unlinkFace(this);
+
+		if( edge(1)->isValid() )
+			edge(1)->unlinkFace(this);
+
+		if( edge(2)->isValid() )
+			edge(2)->unlinkFace(this);
+
+		markInvalid();
+	}
 }
 
 void Face::remapEdge(Edge *from, Edge *to)
 {
-    for(int i=0; i<3; i++)
-    {
-	if( edges[i] == from )
-	{
-	    edges[i] = to;
-	    to->linkFace(this);
-	}
-	else if( edges[i] == from->sym() )
-	{
-	    edges[i] = to->sym();
-	    to->sym()->linkFace(this);
-	}
-    }
-
-    invalidatePlane();
-}
-
+	for (int i=0; i<3; i++)
+	{
+		if ( edges[i] == from )
+		{
+			edges[i] = to;
+			to->linkFace(this);
+		}
+		else if ( edges[i] == from->sym() )
+		{
+			edges[i] = to->sym();
+			to->sym()->linkFace(this);
+		}
+	}
+
+	invalidatePlane();
+}
 
 void simplif::untagFaceLoop(Vertex *v)
 {
-    edge_buffer& edges = v->edgeUses();
-
-    for(int j=0; j<edges.length(); j++)
-    {	    
-	face_buffer& faces = edges(j)->faceUses();
-	for(int k=0; k<faces.length(); k++)
-	    faces(k)->untag();
-    }
+	edge_buffer& edges = v->edgeUses();
+
+	for (int j	=	0; j < edges.length(); j++)
+	{	    
+		face_buffer& faces = edges(j)->faceUses();
+
+		for (int k	=	0; k < faces.length(); k++)
+		{
+			faces(k)->untag();
+		}
+	}
 }
 
 void simplif::collectFaceLoop(Vertex *v, face_buffer& loop)
 {
-    edge_buffer& edges = v->edgeUses();
-
-    for(int j=0; j<edges.length(); j++)
-    {	    
-	face_buffer& faces = edges(j)->faceUses();
-	for(int k=0; k<faces.length(); k++)
-	    if( !faces(k)->isTagged() )
-	    {
-		loop.add(faces(k));
-		faces(k)->tag();
-	    }
-    }
+	edge_buffer& edges = v->edgeUses();
+
+	for(int j=0; j<edges.length(); j++)
+	{	    
+		face_buffer& faces = edges(j)->faceUses();
+		for(int k=0; k<faces.length(); k++)
+			if( !faces(k)->isTagged() )
+			{
+				loop.add(faces(k));
+				faces(k)->tag();
+			}
+	}
 }
 
 int simplif::classifyEdge(Edge *e)
 {
-    int cls = e->faceUses().length();
-
-    if( cls>3 ) cls=3;
-
-    return cls;
+	int cls = e->faceUses().length();
+
+	if( cls>3 ) cls=3;
+
+	return cls;
 }
 
 int simplif::classifyVertex(Vertex *v)
 {
-    int border_count = 0;
-    const edge_buffer& edges = v->edgeUses();
-
-    for(int i=0; i<edges.length(); i++)
-	if( classifyEdge(edges(i)) == 1 )
-	    border_count++;
-
-    if( border_count == edges.length() )
-	return VERTEX_BORDER_ONLY;
-    else 
-	return (border_count > 0);
-}
+	int border_count = 0;
+	const edge_buffer& edges = v->edgeUses();
+
+	for(int i=0; i<edges.length(); i++)
+		if( classifyEdge(edges(i)) == 1 )
+			border_count++;
+
+	if( border_count == edges.length() )
+		return VERTEX_BORDER_ONLY;
+	else 
+		return (border_count > 0);
+}
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/avars.cxx
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/avars.cxx	(revision 1025)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/avars.cxx	(revision 1526)
@@ -19,5 +19,5 @@
 bool simplif::will_preserve_mesh_quality = true;
 bool simplif::will_constrain_boundaries = true;
-simplif::real simplif::boundary_constraint_weight = 1.0;
+simplif::real simplif::boundary_constraint_weight = 10.0;
 
 bool simplif::will_weight_by_area = false;
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp	(revision 1009)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimpSequence.cpp	(revision 1526)
@@ -4,94 +4,135 @@
 using namespace std;
 
-MeshSimplificationSequence::MeshSimplificationSequence() 
+//---------------------------------------------------------------------------
+//	Constructor.
+//---------------------------------------------------------------------------
+MeshSimplificationSequence::MeshSimplificationSequence()
 {
-	meshName="";
+	meshName	=	"";
 }
 
-MeshSimplificationSequence::~MeshSimplificationSequence() 
+MeshSimplificationSequence::~MeshSimplificationSequence()
 {
 }
 
-void MeshSimplificationSequence::Load(Serializer &s) 
+//---------------------------------------------------------------------------
+//	Loads mesh simplification sequence.
+//---------------------------------------------------------------------------
+void MeshSimplificationSequence::Load(Serializer &s)
 {
-	//Loads a simplification sequence from a file
-	char buffer[256];
-	unsigned int modVertex;
-	char name[256];
+	//	Loads a simplification sequence from a file.
+	char 					buffer[256];
+	unsigned int	modVertex;
+	char					name[256];
 
+	//	Read mesh name.
 	if (s.ReadData(buffer,256) != NULL)
 	{
 		sscanf(buffer,"%s",&name);
-		meshName=new char[strlen(name)];
+
+		meshName	=	new char[strlen(name)];
+
 		strcpy(meshName,name);
 	}
 
+	//	Read steps data.
 	while (s.ReadData(buffer,256) != NULL)
 	{
 		Geometry::MeshSimplificationSequence::Step simplifstep;
-		//new step
-		sscanf(buffer,"%u %u %u %u %u %f %f %f &",&simplifstep.mV1,&simplifstep.mV0, &simplifstep.mT0,&simplifstep.mT1, &simplifstep.obligatorio,&simplifstep.x, &simplifstep.y, &simplifstep.z);
-		//sscanf(buffer,"%u %u %u %u %u &",&simplifstep.mV1,&simplifstep.mV0, &simplifstep.mT0,&simplifstep.mT1, &simplifstep.obligatorio);
-		//sscanf(buffer + 3,"%u %u %f %f %f %u %u &",&simplifstep.mV0,&simplifstep.mV1,&simplifstep.x, &simplifstep.y, &simplifstep.z, &simplifstep.mT0,&simplifstep.mT1);
-		//sscanf(buffer,"%u %u %u %u %u &",&simplifstep.mV0,&simplifstep.mV1,&simplifstep.mT0,&simplifstep.mT1, &simplifstep.obligatorio);
 
-		buffer[strlen(buffer)-1]='\0';
+		//	New step.
+		sscanf(	buffer,
+						"%u %u %u %u %u %f %f %f &",
+						&simplifstep.mV1,
+						&simplifstep.mV0,
+						&simplifstep.mT0,
+						&simplifstep.mT1,
+						&simplifstep.obligatory,
+						&simplifstep.x,
+						&simplifstep.y,
+						&simplifstep.z);
 
-		//if(!simplifstep.obligatorio)
-		//{
+		buffer[strlen(buffer)-1]	=	'\0';
+
 		char *ptr1;
-		ptr1=strtok(buffer,"&");
-		ptr1=strtok(NULL,"&");
 
-		if (ptr1!=NULL)
+		ptr1	=	strtok(buffer,"&");
+		ptr1	=	strtok(NULL,"&");
+
+		if (ptr1 != NULL)
 		{
 			char *ptr;
-			ptr=strtok(ptr1," ");
+
+			ptr	=	strtok(ptr1," ");
 			
-			while(ptr != NULL )
+			while (ptr != NULL )
 			{
-				modVertex = (unsigned int)atoi(ptr);
+				modVertex	=	(unsigned int)atoi(ptr);
+
 				simplifstep.mModfaces.push_back(modVertex);
-				ptr=strtok(NULL," ");
+
+				ptr	=	strtok(NULL," ");
 			}
 		}
+
 		mSteps.push_back(simplifstep);
-		//}
-
 	}
-
 }
 
+//---------------------------------------------------------------------------
+//	Saves simplification sequence.
+//---------------------------------------------------------------------------
 void MeshSimplificationSequence::Save(Serializer &s)
 {
-	//Stores the simplification sequence in a file
+	//	Stores the simplification sequence in a file.
 	char simp[256];
 
-	//Name of the mesh
+	//	Name of the mesh.
 	sprintf(simp,"%s\n",meshName);
 	s.WriteData(simp,sizeof(char),strlen(simp));
 
-	for(unsigned int i=0; i<mSteps.size(); i++)
+	//	For each step.
+	for (unsigned int i	=	0; i < mSteps.size(); i++)
 	{
 		Geometry::MeshSimplificationSequence::Step paso = mSteps.operator [](i);
-		//sprintf(simp,"%u %u %u %u %u &", paso.mV0, paso.mV1, paso.mT0, paso.mT1,paso.obligatorio);
-		sprintf(simp,"%u %u %u %u %u %f &", paso.mV0, paso.mV1, paso.mT0, paso.mT1,paso.obligatorio,paso.x);
+		
+		sprintf(simp,
+						"%u %u %u %u %u %f &",
+						paso.mV0,
+						paso.mV1,
+						paso.mT0,
+						paso.mT1,
+						paso.obligatory,
+						paso.x);
+
+		//	Write step.
 		s.WriteData(simp,sizeof(char),strlen(simp));
-		for (unsigned int j=0; j<paso.mModfaces.size(); j++)
+		
+		//	Triangles modified.
+		for (unsigned int j	=	0; j < paso.mModfaces.size(); j++)
 		{
 			sprintf(simp," %u",paso.mModfaces.operator [](j));
 			s.WriteData(simp,sizeof(char),strlen(simp));
 		}
+		
+		//	New line.
 		s.WriteData("\n",sizeof(char),1);
 	}
 }
 
-void MeshSimplificationSequence::putMeshName(char *name) 
+//---------------------------------------------------------------------------
+//	Puts mesh name.
+//---------------------------------------------------------------------------
+void MeshSimplificationSequence::putMeshName(char *name)
 {
-	meshName=name;
+	meshName	=	name;
 }
 
-char *MeshSimplificationSequence::getMeshName(void) 
+//---------------------------------------------------------------------------
+//	Gets mesh name.
+//---------------------------------------------------------------------------
+char *MeshSimplificationSequence::getMeshName(void)
 {
 	return meshName;
 }
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1070)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp	(revision 1526)
@@ -413,5 +413,5 @@
 		current_step.z	=	VMI::mVMISteps[i].z;
 
-		current_step.obligatorio	=	VMI::mVMISteps[i].obligatory;
+		current_step.obligatory	=	VMI::mVMISteps[i].obligatory;
 
 		//	For each face modificated.
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp	(revision 1136)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp	(revision 1526)
@@ -7,12 +7,9 @@
 Geometry::LodTreeLibrary::LodTreeLibrary(const LodStripsLibraryData *lodstripsdata,
 										 const TreeSimplificationSequence *simpseq,
-										 Geometry::Mesh *treeGeoMesh/*,
-										 uint32 leafSubMeshID,
-							   CREATEVERTEXDATAFUNC vdfun,
-							   CREATEINDEXDATAFUNC idfun,
-							   CREATEMULTIINDEXDATAFUNC midfun*/)
+										 Geometry::Mesh *treeGeoMesh,
+										 Geometry::IndexData *userindexdata)
 {
 	// Cargar el tronco
-	trunk = new LodStripsLibrary(lodstripsdata,treeGeoMesh);
+	trunk = new LodStripsLibrary(lodstripsdata,treeGeoMesh,userindexdata);
 
 	// select the first triangle-list submesh as leaves submesh
@@ -28,7 +25,10 @@
 	}
 
+	delete_indexdata=false;
+	dataRetrievalInterface=userindexdata;
+
 	// Cargar la copa del árbol
 	Geometry::SubMesh * leafsSubMesh = &(treeGeoMesh->mSubMesh[mLeavesSubMesh]);
-	foliage = new Foliage(leafsSubMesh,simpseq);
+	foliage = new Foliage(mLeavesSubMesh,leafsSubMesh,simpseq);
 	GoToFoliageLod(1.0f);
 }
@@ -56,7 +56,5 @@
 	if (trunk) delete trunk;
 	if (foliage) delete foliage;
-/*	if (trunk_all_indices) delete trunk_all_indices;
-	if (indices_offsets) delete[] indices_offsets;
-//	if (current_foliage_indices) delete[] current_foliage_indices;*/
+	if (delete_indexdata) delete dataRetrievalInterface;
 }
 /*
@@ -101,19 +99,10 @@
 void LodTreeLibrary::GoToFoliageLod(float newlod)
 {
-	uint32 targetLeaves = (uint32)
-												(
-													(1.0f - newlod)
-													*
-													foliage->minLeaves
+	uint32 targetLeaves = (uint32)	(	(1.0f - newlod) * foliage->minLeaves
 													+
-													newlod
-													*
-													foliage->leafCount
-												);
+										newlod * foliage->leafCount 	);
 
 	foliage->CalculateLOD(targetLeaves);
 
-	foliage->indexdata->Begin();
-	foliage->vertexdata->Begin();
 	int i = foliage->begin;
 	int auxnumleaves = 0;
@@ -124,6 +113,8 @@
 	}
 
-	assert(auxnumleaves*6<=int(foliage->indexdata->GetNumMaxIndices()));
-	foliage->indexdata->SetNumValidIndices(auxnumleaves*6);
+//	foliage->indexdata->Begin(GetLeavesSubMesh(),auxnumleaves*6);
+	dataRetrievalInterface->Begin(GetLeavesSubMesh(),auxnumleaves*6);
+//	foliage->vertexdata->Begin();
+
 	i = foliage->begin;
 	int index=0;
@@ -136,21 +127,22 @@
 		v3 = foliage->Leaves[i].vertsLeaf[3];
 
-		foliage->indexdata->SetIndex(index+0,v0);
-		foliage->indexdata->SetIndex(index+1,v1);
-		foliage->indexdata->SetIndex(index+2,v2);
-		foliage->indexdata->SetIndex(index+3,v2);
-		foliage->indexdata->SetIndex(index+4,v1);
-		foliage->indexdata->SetIndex(index+5,v3);
-
-		foliage->vertexdata->SetVertexTexCoord(v0,0,0);
+		dataRetrievalInterface->SetIndex(index+0,v0);
+		dataRetrievalInterface->SetIndex(index+1,v1);
+		dataRetrievalInterface->SetIndex(index+2,v2);
+		dataRetrievalInterface->SetIndex(index+3,v2);
+		dataRetrievalInterface->SetIndex(index+4,v1);
+		dataRetrievalInterface->SetIndex(index+5,v3);
+
+/*		foliage->vertexdata->SetVertexTexCoord(v0,0,0);
 		foliage->vertexdata->SetVertexTexCoord(v1,0,1);
 		foliage->vertexdata->SetVertexTexCoord(v2,1,0);
-		foliage->vertexdata->SetVertexTexCoord(v3,1,1); 
+		foliage->vertexdata->SetVertexTexCoord(v3,1,1); */
 
 		index+=6;
 		i=foliage->Acth[i].next;
 	}
-	foliage->indexdata->End();
-	foliage->vertexdata->End();
+	dataRetrievalInterface->End();
+//	foliage->vertexdata->End();
+	currentFoliageLodFactor = newlod;
 }
 /*
@@ -170,8 +162,8 @@
 const IndexData* LodTreeLibrary::CurrentLOD_Trunk_Indices(void) const 
 { 
-	return trunk->dataRetrievalInterface;
-}
-
-
+	return trunk->GetIndexDataInterface();
+}
+
+/*
 const VertexData* LodTreeLibrary::Get_Foliage_VertexData(void) const
 {
@@ -181,9 +173,9 @@
 const IndexData* LodTreeLibrary::CurrentLOD_Foliage_Indices(void) const
 {
-	return foliage->indexdata;
-}
-
-
-/*void ThrowFileNotFoundError(const char *text)
+	return currentLOD_foliageIndexCount;
+}
+
+
+void ThrowFileNotFoundError(const char *text)
 {
 	throw Geometry::FileNotFound(text);
@@ -193,5 +185,6 @@
 {
 //	return current_foliage_indexcount;
-	return foliage->indexdata->GetNumValidIndices();
+//	return foliage->indexdata->GetNumValidIndices();
+	return foliage->active_leaf_count*6;
 }
 /*
@@ -213,5 +206,5 @@
 uint32 LodTreeLibrary::Get_Foliage_MaxIndexCount(void) const
 {
-	return foliage->indexdata->GetNumMaxIndices();
+	return foliage->leafTotal*6;
 }
 
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp	(revision 1136)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp	(revision 1526)
@@ -681,15 +681,20 @@
 			{
 				case 0xabcd:
+					
+					//	Debug.
 					cout << "LODSTRIPS_Chunk" << endl;
+					
 					lodstripsdata = new Geometry::LodStripsLibraryData;
 
-					int				aux,v,c;
+					int							aux,v,c;
 					LODRegisterType	lod_register;
-					LODData			dataaux;
-					int				tam;
+					LODData					dataaux;
+					int							tam;
 
 					fread(&tam, sizeof(int), 1, f);
+					
 					lodstripsdata->mFileVertices.clear();
-					for (v=0; v<tam; v++)
+					
+					for (v	=	0; v < tam; v++)
 					{
 						fread(&aux, sizeof(int), 1, f);
@@ -698,6 +703,8 @@
 
 					lodstripsdata->mFileChangesLOD.clear();
+					
 					fread(&tam, sizeof(int), 1, f);
-					for (c=0; c<tam; c++)
+					
+					for (c	=	0; c < tam; c++)
 					{
 						fread(&dataaux, sizeof(LODData), 1, f);
@@ -706,6 +713,5 @@
 						lod_register.vertexRepetition= dataaux.nL1;
 						lod_register.edgeRepetition= dataaux.nL2;
-						//lod_register.obligatory=false;
-						//lod_register.obligatory= dataaux.obligatory;
+						lod_register.obligatory=dataaux.obligatory;
 
 						lodstripsdata->mFileChangesLOD.push_back(lod_register);
@@ -713,6 +719,8 @@
 					
 					lodstripsdata->mData.clear();
+					
 					fread(&tam, sizeof(int), 1, f);
-					for (int b=0; b<tam; b++)
+					
+					for (int	b	=	0; b < tam; b++)
 					{
 						fread(&aux, sizeof(int), 1, f);
@@ -721,10 +729,12 @@
 
 					lodstripsdata->p_changes.clear();
+					
 					fread(&tam, sizeof(int), 1, f);
-					for (int p=0; p<tam; p++)
+					
+					for (int	p	=	0; p < tam; p++)
 					{
 						fread(&aux, sizeof(int), 1, f);
 						lodstripsdata->p_changes.push_back(aux);
-					}					
+					}
 
 					break;
@@ -1146,5 +1156,5 @@
 				cout	<<	version	<<	endl;
 
-				if (strcmp(version,"[MeshSerializer_v1.30]\n"))
+				/*if (strcmp(version,"[MeshSerializer_v1.30]\n"))
 				{
 					//	Debug.
@@ -1156,5 +1166,5 @@
 					//	Error.
 					mError	=	true;
-				}
+				}*/
 
 				while(!feof(pFile))
@@ -1423,7 +1433,7 @@
 //	Read bones of the submesh.
 //---------------------------------------------------------------------------
-void GeoMeshLoader::readSubMeshBoneAssignment(FILE* f,
-																							SubMesh* geoSubMesh,
-																							int option)
+void GeoMeshLoader::readSubMeshBoneAssignment(FILE		*f,
+																							SubMesh	*geoSubMesh,
+																							int			option)
 {
 	if (option == GEOMESH_BUILD)
@@ -1445,5 +1455,5 @@
 //	Read bones of the main mesh.
 //---------------------------------------------------------------------------
-void GeoMeshLoader::readMeshBoneAssignment(FILE* f, Mesh* geoMesh,int option)
+void GeoMeshLoader::readMeshBoneAssignment(FILE	*f, Mesh	*geoMesh,	int option)
 {
 	if (option == GEOMESH_BUILD)
@@ -1465,5 +1475,5 @@
 //	Read skeleton link.
 //---------------------------------------------------------------------------
-void GeoMeshLoader::readSkeletonLink(FILE* f, Mesh* geoMesh,int option)
+void GeoMeshLoader::readSkeletonLink(FILE	*f, Mesh	*geoMesh,	int option)
 {
 	if (option == GEOMESH_BUILD)
@@ -1829,4 +1839,5 @@
 		const std::vector<face_t> & vecfaces = faces[i];
 		std::vector<Geometry::Index> aux_indices;
+		
 		submesh->mSharedVertexBuffer = true;
 		submesh->mIndexCount = vecfaces.size()*3;
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsConstructor.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsConstructor.cpp	(revision 1136)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsConstructor.cpp	(revision 1526)
@@ -27,24 +27,21 @@
 void LodStripsConstructor::CalcularCambiosLODsVNuevaED(TIPOFUNC upb)
 {
-//	LODPosition						pos;
-//	vector	<LODPosition>	listaPos;
-	long 		int							k;
-	long 		int							i;
-	unsigned long 		int		t;
-	long 		int							r;
-	unsigned long 		int		v;
-	long 		int							p0;
-	long 		int							lod	=	0;
-	long 		int							sigue;
-	long 		int							ac[3]	=	{0,0,0};
-	long 		int							totalRegs	=	0;
-	long 		int							RegsCambios;
-	std::vector<std::vector<int> >			TiraOriginal;
-	LODData 								regLOD;
-	//LODChanges							listaCambios;
-	std::vector<LODData>						listaCambios;
-	float										percent;
-	float										increment;
-	long		int							update;
+	long 		int					k;
+	long 		int					i;
+	unsigned long 		int			t;
+	long 		int					r;
+	unsigned long 		int			v;
+	long 		int					p0;
+	long 		int					lod	=	0;
+	long 		int					sigue;
+	long 		int					ac[3]	=	{0,0,0};
+	long 		int					totalRegs	=	0;
+	long 		int					RegsCambios;
+	std::vector<std::vector<int> >	TiraOriginal;
+	LODData 						regLOD;
+	std::vector<LODData>			listaCambios;
+	float							percent;
+	float							increment;
+	long		int					update;
 
 	//	Saves original copy.
@@ -68,23 +65,16 @@
 	
 	this->LodsDisp	=	this->TOTALCAMBIOS	=	lod;
-	pCambios				=	new uint32[this->TOTALCAMBIOS];
-	pCambios[0]			=	0;
+	pCambios		=	new uint32[this->TOTALCAMBIOS];
+	pCambios[0]		=	0;
 	
 	for	(lod = 0; ((this->cVerts[lod].Next) != -1); lod++)
 	{
-/*		if (update	!= (int)(increment * lod))
-		{
-			update	=	(int)(increment * lod);
-			upb(percent);
-		}*/
-
 		tipoVertice & cVertsLOD = this->cVerts[lod];
 		
 		RegsCambios				=	0;
-		regLOD.obligatory	=	this->Ordenacion[lod].obligatorio;
+		regLOD.obligatory	=	this->Ordenacion[lod].obligatory;
 		
 		for(t = 0; t < this->cStrips.size(); t++)
 		{
-
 			std::vector<int> & cStripsT = this->cStrips[t];
 
@@ -101,7 +91,5 @@
 					//	Strips.
 					if (regLOD.strip == this->MARCAVACIO)
-					{
-						regLOD.strip	=	t;
-					}
+						regLOD.strip = t;
 					
 					++totalRegs;
@@ -118,8 +106,8 @@
 			//	Changes for simplification of level 1 to greater than 2.
 			totalRegs	=	0;
-			i					=	0;
-			r					=	0;
-			sigue			=	0;
-			k					=	long(cStripsT.size()-3);
+			i			=	0;
+			r			=	0;
+			sigue		=	0;
+			k			=	long(cStripsT.size()-3);
 			
 			while (i < k)
@@ -305,16 +293,13 @@
 	long int vSig;
 	long int k;
-	VECTORVERTEX				Vertices;
+	VECTORVERTEX			Vertices;
 	std::vector<tipoVertice>		NuevosVerts;
-	//vector	<VECTORINT>	NuevasTiras;
-	std::vector<std::vector<int> > NuevasTiras;
-//	VECTORINT						tira;
-	std::vector<int> tira;
-	vector	<Index>			mV1Aux;
-	tipoOrden						Orden;
-	tipoOrden						*Ord;
-	bool								bEncontrado;
-	long	int						c1;
-	long	int						c2;
+	std::vector<std::vector<int> >	NuevasTiras;
+	std::vector<int> 		tira;
+	tipoOrden				Orden;
+	tipoOrden				*Ord;
+	bool					bEncontrado;
+
+
 	//	Progress bar
 	float			percent;
@@ -326,7 +311,4 @@
 	size_t	mStepsSize = mGeoMeshSQ->mSteps.size();
 
-	c1					=	0;
-	c2					=	0;
-	
 	update			=	-1;
 	percent			=	1.0;
@@ -341,21 +323,18 @@
 		}
 		
-		const Geometry::MeshSimplificationSequence::Step & theStep = this->mGeoMeshSQ->mSteps[i];
-
-		mV1Aux.push_back(theStep.mV1);
+		const MeshSimplificationSequence::Step & theStep = this->mGeoMeshSQ->mSteps[i];
 
 		Orden.vQslimNext	=	theStep.mV0;
-		Orden.vQslim			=	theStep.mV1;
-		Orden.obligatorio	=	theStep.obligatorio;
-		Orden.vLS					=	i;
-
-		Orden.x						=	theStep.x;
-		Orden.vLSNext			=	-1;
-		Orden.cambio			=	"n";
+		Orden.vQslim		=	theStep.mV1;
+		Orden.obligatory	=	theStep.obligatory;
+		Orden.vLS			=	i;
+
+		Orden.x				=	theStep.x;
+		Orden.vLSNext		=	-1;
+		Orden.cambio		=	"n";
 
 		Ordenacion.push_back(Orden);
 	}
 	
-	this->NumVertsRepetidos = c2;
 
 	update		=	-1;
@@ -363,39 +342,4 @@
 	percent		=	1.0;
 
-	//	Change all vertices that have x != 0.
-	for(i	=	0;	i < Ordenacion.size();	i++)
-	{
-		if (update	!= (int)(i * increment))
-		{
-			update	= (int)(i * increment);
-			upb(percent);
-		}
-		
-		Ord	=	&(Ordenacion[i]);
-
-		if (Ord->x!=0)
-		{
-			//	Change the simplification order.
-			v								=	Ord->vQslim;
-			Ord->vQslim			=	Ord->vQslimNext;
-			Ord->vQslimNext	=	v;
-
-			for (j = i+1; j < Ordenacion.size(); j++)
-			{
-				tipoOrden & ordJ = Ordenacion[j];
-				if (ordJ.vQslim == Ord->vQslim)
-				{
-					ordJ.vQslim	=	Ord->vQslimNext;
-					ordJ.cambio	=	"y";
-				}
-				else if (ordJ.vQslimNext == Ord->vQslim)
-				{
-					ordJ.vQslimNext	=	Ord->vQslimNext;	
-					ordJ.cambio			=	"y";
-				}
-			}
-		}
-	}
-
 	update		=	-1;
 	increment	=	(float)(10.0) / (float)(Ordenacion.size());
@@ -412,8 +356,10 @@
 		}
 
-		c1++;
-		NuevosVerts.push_back(this->cVerts[Ordenacion[i].vQslim]);
-
-		cVerts[Ordenacion[i].vQslim].Next	=	-1;
+		int OrdvQslim = Ordenacion[i].vQslim;
+		int OrdvQslimNext = Ordenacion[i].vQslimNext;
+
+		NuevosVerts.push_back(this->cVerts[OrdvQslim]);
+
+		cVerts[OrdvQslim].Next	=	-1;
 
 	}
@@ -421,5 +367,5 @@
 	//	Añadir aquellos vertices que no estaban en NuevosVerts 
 	//	y no se simplificaban.
-	int cont				=	0;
+	int cont		=	0;
 	int contestaban	=	0;
 
@@ -431,8 +377,8 @@
 			cont++;
 			NuevosVerts.push_back(this->cVerts[i]);
-			Orden.vLS					=	int(Ordenacion.size());
-			Orden.obligatorio	= 0;
-			Orden.vLSNext			=	-1;
-			Orden.vQslim			=	i;
+			Orden.vLS			=	int(Ordenacion.size());
+			Orden.obligatory	= 0;
+			Orden.vLSNext		=	-1;
+			Orden.vQslim		=	i;
 			Orden.vQslimNext	=	-1;
 
@@ -466,11 +412,11 @@
 		for (t = 0; t < Ordenacion.size() && !vSig;t++)
 		{
-			if (Ordenacion[t].vQslim==v)
-			{
-				vSig=Ordenacion[t].vLS;
-			}
-		}
-
-		if (vSig!=0)
+			if (Ordenacion[t].vQslim == v)
+			{
+				vSig	=	Ordenacion[t].vLS;
+			}
+		}
+
+		if (vSig != 0)
 		{
 			Ordenacion[i].vLSNext	=	vSig;
@@ -485,6 +431,9 @@
 
 		size_t	cStripsSizeT = this->cStrips[t].size();
+
 		for(i = 0; i < cStripsSizeT; i++)
+		{
 			tira.push_back(0);
+		}
 
 		NuevasTiras.push_back(tira);
@@ -499,5 +448,6 @@
 	//	2 min.
 	//Cambiar los vertices de las tiras
-	size_t	NuevosVertsSize = NuevosVerts.size();	
+	size_t	NuevosVertsSize = NuevosVerts.size();
+
 	for(v = 0; v < NuevosVertsSize; v++)
 	{
@@ -515,4 +465,5 @@
 			std::vector<int> & NuevasTirasT = NuevasTiras[t];
 			size_t	cStripsSizeT = thisStrip.size();
+
 			for(i = 0; i < cStripsSizeT; i++)
 			{
@@ -531,4 +482,5 @@
 	//NuevosVerts y Ordenacion = tamaño.
 	NuevosVertsSize = NuevosVerts.size();
+
 	for(i = 0; i < NuevosVertsSize; i++)
 	{
@@ -563,4 +515,7 @@
 	
 	this->mGeoMeshSQ	=	const_cast<MeshSimplificationSequence*>(ms);
+
+	//	Add new vertices to mesh.
+	AddNewVertices();
 
 	//	Set the leaves submesh.
@@ -612,13 +567,9 @@
 void LodStripsConstructor::Save(std::string filename)
 {
-	//size_t	i, j;
-	int			k	=	0;
-	char		simp[256];
-
 	int vertexCount		=	(int)this->cVerts.size();
 	int changesCount	=	(int)this->cCambios.size();
-	int dataCount			=	(int)this->cDatos.size();
+	int dataCount		=	(int)this->cDatos.size();
 	int cambiosCount	=	this->TOTALCAMBIOS;
-	int size					=	changesCount*sizeof(LODData) + 
+	int size			=	changesCount*sizeof(LODData) + 
 				(vertexCount + dataCount + cambiosCount + 4)*sizeof(int) +
 				CHUNK_OVERHEAD_SIZE;
@@ -630,4 +581,5 @@
 	fwrite(&size,sizeof(unsigned long),1,f);
 
+	// VERTICES
 	fwrite(&vertexCount, sizeof(int), 1, f);
 	for(size_t	i = 0; i < this->cVerts.size(); i++)
@@ -636,12 +588,4 @@
 		fwrite(&auxv, sizeof(int), 1, f);
 	}
-
-	//	VERTICES.
-/*	for(i = 0; i < this->cVerts.size(); i++)
-	{
-		sprintf(simp,"v %d\n",cVerts[i].Next);
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-*/
 	
 	//	CSTRIPS.
@@ -649,7 +593,5 @@
 	
 	for(size_t	i = 0; i < this->cStrips.size(); i++)
-	{
 		this->TOTALINDICES += int(this->cStrips[i].size());
-	}
 
 	//	lines starting with a d.
@@ -662,25 +604,6 @@
 	}
 
-
-/*	for(i = 0; i < this->cCambios.size(); i++)
-	{
-		sprintf(simp,"c\n");
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-		
-		sprintf(simp,
-						"d %u %u %u %u %u\n",
-						cCambios[i].strip,
-						cCambios[i].nP,
-						cCambios[i].nL1,
-						cCambios[i].nL2,
-						cCambios[i].obligatory);
-		
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-*/	//	Lines starting with a b.
 	//	Data.
-
 	fwrite(&dataCount, sizeof(int), 1, f);
-
 	for(size_t	i = 0; i < this->cDatos.size(); i++)
 	{
@@ -688,15 +611,4 @@
 		fwrite(&data, sizeof(int), 1, f);
 	}
-
-	sprintf(simp,"a\n");
-/*	oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	
-	for(i = 0; i < this->cDatos.size(); i++)
-	{
-		sprintf(simp,"b %d\n",cDatos[i]);
-
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-*/
 
 	//	lines starting with a p.
@@ -711,60 +623,4 @@
 
 	fclose(f);
-
-/*
-	//	VERTICES.
-	for(i = 0; i < this->cVerts.size(); i++)
-	{
-		sprintf(simp,"v %d\n",cVerts[i].Next);
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-
-	//	CSTRIPS.
-	this->TOTALINDICES	=	0;
-	
-	for(i = 0; i < this->cStrips.size(); i++)
-	{
-		this->TOTALINDICES += int(this->cStrips[i].size());
-	}
-
-	//	lines starting with a d.
-	//	Changes
-	for(i = 0; i < this->cCambios.size(); i++)
-	{
-		sprintf(simp,"c\n");
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-		
-		sprintf(simp,
-						"d %u %u %u %u %u\n",
-						cCambios[i].strip,
-						cCambios[i].nP,
-						cCambios[i].nL1,
-						cCambios[i].nL2,
-						cCambios[i].obligatory);
-		
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-	//	Lines starting with a b.
-	//	Data.
-	sprintf(simp,"a\n");
-	oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	
-	for(i = 0; i < this->cDatos.size(); i++)
-	{
-		sprintf(simp,"b %d\n",cDatos[i]);
-
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-
-	//	lines starting with a p.
-	//	Chages made in a LOD.
-	for(i = 0; i < this->TOTALCAMBIOS; i++)
-	{
-		sprintf(simp,"p %d\n",this->pCambios[i]);
-
-		oSerializer.WriteData(simp,sizeof(char),strlen(simp));
-	}
-
-	oSerializer.WriteData("\n",sizeof(char),1);	*/
 }
 
@@ -815,10 +671,8 @@
 	for(i = 0; i < this->TOTALTIRAS; i++)
 	{
-		t	=	long(this->cStrips[i].size());
+		t = long(this->cStrips[i].size());
 		
 		if (t > max)
-		{
-			max	=	t;
-		}
+			max	= t;
 	}
 
@@ -970,8 +824,7 @@
 				}
 
-				vAux.Next			=	-10;
-				vAux.numMesh	=	0;
-			
-				vAux.obligatorio	=	0;
+				vAux.Next		=	-10;
+				vAux.numMesh	=	0;			
+				vAux.obligatory	=	0;
 				
 				this->cVerts.push_back(vAux);
@@ -1170,12 +1023,11 @@
 		{
 			assign.boneIndex	=	0;
-			assign.weight			=	1;
-
-			for (	size_t	m = copy_vb->mVertexCount;
+			assign.weight		=	1;
+
+			for (size_t	m = copy_vb->mVertexCount;
 						m < mesh_vb->mVertexCount;
 						m++)
 			{
 				assign.vertexIndex	=	(unsigned int)m;
-				
 				mesh_bones->push_back(assign);
 			}
@@ -1185,12 +1037,9 @@
 			{
 				n	=	(*mesh_bones)[m].vertexIndex;
-
 				o	=	0;
 				
-				while (!(	(mesh_vb->mPosition[n].x == copy_vb->mPosition[o].x)
-									&&
-									(mesh_vb->mPosition[n].y == copy_vb->mPosition[o].y)
-									&&
-									(mesh_vb->mPosition[n].z == copy_vb->mPosition[o].z)))
+				while (!(	(mesh_vb->mPosition[n].x == copy_vb->mPosition[o].x)	&&
+							(mesh_vb->mPosition[n].y == copy_vb->mPosition[o].y)	&&
+							(mesh_vb->mPosition[n].z == copy_vb->mPosition[o].z)))
 				{
 					o++;
@@ -1200,7 +1049,5 @@
 				
 				while ((*copy_bones)[p].vertexIndex != o)
-				{
 					p++;
-				}
 
 				//	Same bone for 'm' and 'p'.
@@ -1244,5 +1091,5 @@
 }
 
-void Geometry::LodStripsConstructor::UpdateMesh(void)
+void LodStripsConstructor::UpdateMesh(void)
 {
 	int num_no	=	0;
@@ -1303,5 +1150,4 @@
 
 			indice++;
-
 		}
 
@@ -1436,2 +1282,78 @@
 	}
 }
+
+//---------------------------------------------------------------------------
+//	Add new vertices to mesh.
+//---------------------------------------------------------------------------
+void LodStripsConstructor::AddNewVertices()
+{
+	int				num_vertices;
+	SubMesh			*geosubmesh;
+	VertexBuffer	*vertex_buffer;
+	VertexBuffer	*new_vertex_buffer;
+
+	//	Gets old vertex buffer.
+	vertex_buffer	=	mGeoMesh->mVertexBuffer;
+	
+	num_vertices	=	vertex_buffer->mVertexCount
+									+
+						mGeoMeshSQ->mNewVertices.size();
+
+	//	Initialize auxiliar vertex buffer.
+	new_vertex_buffer	=	new	VertexBuffer();
+
+	new_vertex_buffer->mVertexCount	=	num_vertices;
+	
+	new_vertex_buffer->mPosition		=	new	Vector3[num_vertices];
+	new_vertex_buffer->mNormal			=	new	Vector3[num_vertices];
+	new_vertex_buffer->mTexCoords		=	new	Vector2[num_vertices];
+
+	new_vertex_buffer->mVertexInfo	=	vertex_buffer->mVertexInfo;
+
+	//	Num old vertices.
+	num_vertices	=	vertex_buffer->mVertexCount;
+
+	//	Copy the old vertex buffer.
+	for	(unsigned	int	i	=	0;	i < num_vertices;	i++)
+	{
+		new_vertex_buffer->mPosition[i]	=	vertex_buffer->mPosition[i];
+		new_vertex_buffer->mNormal[i]	=	vertex_buffer->mNormal[i];
+		new_vertex_buffer->mTexCoords[i]=	vertex_buffer->mTexCoords[i];
+	}
+
+
+	//	Copy new vertices.
+	for (unsigned	int	i	=	0;	i < mGeoMeshSQ->mNewVertices.size();	i++)
+	{
+		new_vertex_buffer->mPosition[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].position;
+		new_vertex_buffer->mTexCoords[num_vertices + i]	= mGeoMeshSQ->mNewVertices[i].texcoord;
+		new_vertex_buffer->mNormal[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].normal;
+
+		// check if my twin-vertex-bone has a bone assignment
+		// we check only the GeoMesh bones because the lodstrips only works for sharedvertex bones
+		for (std::vector<VertexBoneAssignment>::iterator it = mGeoMesh->mBones.begin(); it != mGeoMesh->mBones.end(); it ++)
+		{
+			if (it->vertexIndex == mGeoMeshSQ->mNewVertices[i].bonefrom)
+			{
+				VertexBoneAssignment vba;
+				vba.boneIndex = it->boneIndex;
+				vba.vertexIndex = mGeoMeshSQ->mNewVertices[i].id;
+				vba.weight = it->weight;
+				mGeoMesh->mBones.push_back(vba);
+			}
+		}
+	}
+
+	//	For each submesh.
+	for (unsigned int submesh	=	0; submesh < mGeoMesh->mSubMeshCount; submesh++)
+	{
+		geosubmesh	=	&mGeoMesh->mSubMesh[submesh];
+
+		geosubmesh->mVertexBuffer	=	new_vertex_buffer;
+	}
+
+	delete	vertex_buffer;
+	
+	mGeoMesh->mVertexBuffer	=	new_vertex_buffer;
+}
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp	(revision 1136)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp	(revision 1526)
@@ -878,2 +878,3 @@
 	}
 }
+
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1090)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1526)
@@ -20,5 +20,5 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories=".\src\libs;.\include;.\src\libs\vmi\include"
+				AdditionalIncludeDirectories=".\src\libs;.\include;.\src\libs\vmi\include;.\src\libs\ntl"
 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;GLEW_STATIC"
 				MinimalRebuild="TRUE"
@@ -63,5 +63,5 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
-				AdditionalIncludeDirectories=".\src\libs;.\include;.\src\libs\vmi\include"
+				AdditionalIncludeDirectories=".\src\libs;.\include;.\src\libs\vmi\include;.\src\libs\ntl"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;GLEW_STATIC"
 				MinimalRebuild="TRUE"
@@ -324,4 +324,11 @@
 				<File
 					RelativePath=".\src\libs\vmi\src\simplify.cpp">
+				</File>
+			</Filter>
+			<Filter
+				Name="ntl"
+				Filter="">
+				<File
+					RelativePath=".\src\libs\ntl\Cont.cpp">
 				</File>
 			</Filter>
Index: GTP/trunk/Lib/Geom/shared/GTGeometry/README.txt
===================================================================
--- GTP/trunk/Lib/Geom/shared/GTGeometry/README.txt	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GTGeometry/README.txt	(revision 1526)
@@ -0,0 +1,55 @@
+Overview
+--------
+
+The GTGeometry project is a library that contains a set of features to work
+with geometry. The library is mainly focused to the generation of LOD models. 
+However it also supplies some extra features such as mesh simplification and
+stripification.
+
+This project compiles into a static library into:
+	build/Debug/GTGeometry_d.lib
+	build/Release/GTGeometry.lib
+
+
+Features
+--------
+The features the GTGeometry include are:
+
+- LodStrips: supplies a triangle strips-based LOD model for generic meshes.
+
+--- LodStrips generation: used to generate a LOD model from a plain mesh.
+
+--- LodStrips visualization: runtime module used to include LOD objects 
+	into external applications.
+
+- LodTree: supplies a LOD model developed to handle level of detail trees.
+
+--- LodTree generation: used to generate a LOD tree model from a mesh repre- 
+	sentation of the tree.
+
+--- LodTree visualization: runtime module used to include LOD tree objects
+	into external applications.
+
+- Mesh Simplification: include two simplification algorithms to be used in external 
+	applications. They are also used to generate the LOD models.
+
+--- Geometry-based simplification: supplies a simplification algorithm designed 
+	for game meshes: it can handle sub-meshes and vertex repetitions in the	mesh.
+
+--- Viewpoint-driven simplification: provides a simplification algorithm which uses
+	a visual error metric. This is slower than the geometry-based one, but offers
+	more accurate results.
+	
+- Foliage simplification: offers a foliage simplification algorithm based on leaf
+	collapse operations. This is used internally by the LodTree generation module.
+
+- Stripification: offers a stripification utility. This is used internally by the 
+	LodStrips generation module.
+
+
+Usage
+-----
+
+To compile the GTGeometry library into an application, the needed files in 
+	GTGeometry/include
+must be included, and the library GTGeometry{_d}.lib must be statically linked.
Index: GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h	(revision 1090)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h	(revision 1526)
@@ -87,4 +87,46 @@
 using	namespace	Geometry;
 
+class GeoToolIndexData : public Geometry::IndexData
+{
+public:
+	GeoToolIndexData(unsigned int submeshes):Geometry::IndexData(){
+		submeshcount = submeshes;
+		indices=new unsigned int*[submeshcount];
+		indexCount=new unsigned int[submeshcount];
+		for (int i=0; i<submeshcount; i++)
+		{
+			indices[i]=NULL;
+			indexCount[i]=0;
+		}
+	}
+	virtual ~GeoToolIndexData(void){
+		for (int i=0; i<submeshcount; i++)
+			if (indices[i])
+				delete[] indices[i];
+		delete[] indices;
+		delete[] indexCount;
+	}
+
+	virtual void Begin(unsigned int submesh, unsigned int numinds){
+		if (indices[submesh])		
+			delete[] indices[submesh];
+		indices[submesh] = new unsigned int[numinds];     
+		indexCount[submesh] = numinds;
+		modifySubmesh=submesh;
+	}
+
+	virtual void SetIndex(unsigned int i, unsigned int index){
+		indices[modifySubmesh][i] = index;
+	}
+
+	virtual void End(void){}
+	virtual void BorrowIndexData(const IndexData *){}
+
+	unsigned int submeshcount;
+	unsigned int **indices;
+	unsigned int *indexCount;
+	unsigned int modifySubmesh;
+};
+
 class GeoMeshViewUI
 {
@@ -109,5 +151,5 @@
 	//	Lod tree object.
 	LodTreeLibrary	*lodTreeLib;
-	
+
 	MeshSimplifier 			*mMeshSimplifier;
 	TreeSimplifier			*mTreeSimplifier;
@@ -117,6 +159,6 @@
 
 	MeshSimplificationSequence	*oMeshSimpSequence;
-	LodStripsConstructor		*oLodStrip;
-	GeoMeshLoader				*geoMeshLoader;
+	LodStripsConstructor				*oLodStrip;
+	GeoMeshLoader								*geoMeshLoader;
 
 	inline void cb_menuFileOpen_i(fltk::Item*, void*);
@@ -288,4 +330,7 @@
 
 	public:
+
+	// the indexdata for the LOD models
+	GeoToolIndexData *lod_index_data;
 
 	GeoMeshView					*geoMeshView;
Index: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 1098)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 1526)
@@ -1075,5 +1075,5 @@
 					{
 						//	Create the simplification sequence.
-						createSimplificationSequence();
+						//createSimplificationSequence();
 
 						//	Show build process.
@@ -1120,7 +1120,7 @@
 					{
 						//	Create the simplification sequence.
-						createSimplificationSequence();
+						//createSimplificationSequence();
 						
-						delete	mMeshSimplifier;
+						//delete	mMeshSimplifier;
 						geoMeshView->restoreContext();
 
@@ -1211,8 +1211,11 @@
 
 				//	Simplification sequence.
-				oMeshSimpSequence = new MeshSimplificationSequence();
+				//oMeshSimpSequence = new MeshSimplificationSequence();
 
 				//	Loads a simplification sequence file.
-				oMeshSimpSequence->Load(Serializer("SimplifSequence.txt",Serializer::READ));
+				//oMeshSimpSequence->Load(Serializer("SimplifSequence.txt",Serializer::READ));
+
+				//	Simplification sequence.
+				oMeshSimpSequence =	mMeshSimplifier->GetSimplificationSequence();
 
 				//	If the simplification sequence and the mesh exist.
@@ -1224,7 +1227,5 @@
 							progress_function);
 
-//						oSerializer	= new Serializer(file_name,Serializer::Mode::WRITE);
-
-                    oLodStrip->UpdateMesh();
+					oLodStrip->UpdateMesh();
 
 					//	Deletes the previous mesh.
@@ -1243,6 +1244,6 @@
 
 					mesh_saver	=	new	GeoMeshSaver();
-//					file_name[strlen(file_name) - 4]	=	'\0';
-					
+					//					file_name[strlen(file_name) - 4]	=	'\0';
+
 					mesh_saver->leavesSubMesh=idMeshLeaves;
 					mesh_saver->leavesVB=origSubMeshVB;
@@ -1252,6 +1253,9 @@
 					delete	mesh_saver;
 					oLodStrip->Save(file_name);
+
+					//	Delete simplified mesh.
+					delete	mMeshSimplifier;
 					//	Close file.
-//						delete	oSerializer;				
+					//						delete	oSerializer;				
 				}
 				else
@@ -1262,5 +1266,5 @@
 
 				//	Deletes the siplification sequence object.
-				delete	oMeshSimpSequence;
+				//delete	oMeshSimpSequence;
 
 				if (mApplicationState==LODTREES_AUTO)
@@ -2145,9 +2149,8 @@
 	
 	secsimpl	=	mMeshSimplifier->GetSimplificationSequence();
-	
-	secsimpl->putMeshName(nombremesh); // 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));
-
-	//delete	secsimpl;
 }
 
@@ -2325,8 +2328,10 @@
 	{
 		delete	lodStripsLib;
+		delete	lod_index_data;
 	}
 
 	//	New lod strips object.
-	lodStripsLib	=	new	LodStripsLibrary(loddata, geomesh);
+	lod_index_data	=	new GeoToolIndexData(geomesh->mSubMeshCount);
+	lodStripsLib	=	new	LodStripsLibrary(loddata, geomesh, lod_index_data);
 
 	//	Sets the slider range.
@@ -2348,9 +2353,13 @@
 	//	If there is no lod strips object.
 	if (lodTreeLib)
+	{
 		delete	lodTreeLib;
+		delete	lod_index_data;
+	}
 
 	//	New lod strips object.
 
-	lodTreeLib = new Geometry::LodTreeLibrary(lodstripsdata,treesimpseq,geomesh/*,ileafSubMesh*/);
+	lod_index_data	=	new GeoToolIndexData(geomesh->mSubMeshCount);
+	lodTreeLib = new Geometry::LodTreeLibrary(lodstripsdata,treesimpseq,geomesh,lod_index_data);
 
 	//	Sets the slider range.
@@ -2669,5 +2678,5 @@
 
 				{
-					mMetricLabel	= new fltk::Output(26, 28, 5, 25, "Metric");
+					mMetricLabel	= new fltk::Output(26, 28, 0, 25, "Metric");
 					fltk::Output* o	=	mMetricLabel;
 					o->set_vertical();
@@ -2715,5 +2724,5 @@
 
 				{
-					mMeshReductionLabel	= new fltk::Output(26, 124, 5, 25, "Mesh Reduction");
+					mMeshReductionLabel	= new fltk::Output(26, 124, 0, 25, "Mesh Reduction");
 					fltk::Output* o	=	mMeshReductionLabel;
 					o->set_vertical();
Index: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp	(revision 1090)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp	(revision 1526)
@@ -594,13 +594,10 @@
 	//	For each strip.
 //	MultiIndexData *dataInterface = lodStripsLib->dataRetrievalInterface;
-	IndexData *dataInterface = lodStripsLib->dataRetrievalInterface;
+/*	IndexData *dataInterface = lodStripsLib->dataRetrievalInterface;
 	size_t triangle_count = dataInterface->GetNumValidIndices() - 2;
-/*	for (int strip	=	0; strip < dataInterface->GetNumPrims(); strip++)
-	{
-//		triangle_count	+=	lodStripsLib->mStrips[strip].size() - 2;
-		triangle_count	+=	dataInterface->GetNumValidIndices(strip) - 2;
-	}*/
-
-	return	triangle_count;
+
+	return	triangle_count;*/
+
+	return lodStripsLib->GetCurrentTriangleCount();
 }
 
@@ -716,5 +713,5 @@
 		i	= 0;
 
-/*		if (getColorStrips())
+		if (getColorStrips())
 		{
 			//	Gets the color of the strip.
@@ -728,5 +725,7 @@
 			//	Paint a new color.
 			glColor3f(r,g,b);
-		}*/
+			GLfloat color[]	=	{r,g,b,1.0f};
+			glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color);
+		}
 
 
@@ -904,74 +903,13 @@
 
 		//	For each one of the strips.
-/*		for (int strip = 0; strip < geosubmesh->mStripCount; strip++)
-		{
-			//	Paint the current strip.
-			glBegin(GL_TRIANGLE_STRIP);
-
-			if (getColorStrips())
-			{
-				//	Gets the color of the strip.
-				r	=	mStripColors[submesh][color_index].r;
-				g	=	mStripColors[submesh][color_index].g;
-				b	=	mStripColors[submesh][color_index].b;
-
-				//	Change to the next color.
-				color_index++;
-
-				//	Paint a new color.
-				glColor3f(r,g,b);
-			}
-
-			//	For each index of the strip.
-			for (int index = 0; index < lodStripsLib->dataRetrievalInterface->GetNumValidIndices(current_strip); index++)
-			{
-				position	=	lodStripsLib->dataRetrievalInterface->GetIndex(current_strip,index);
-
-				//	Gets the vertex normal.
-				vector3	=	geosubmesh->mVertexBuffer->mNormal[position];
-
-				x				=	vector3[0];
-				y				=	vector3[1];
-				z				=	vector3[2];
-
-				//	Sets the vertex normal.
-				glNormal3f(x,y,z);
-
-				// set the texture coordinates if needed
-				if (usetex)
-				{
-					vector2 = geosubmesh->mVertexBuffer->mTexCoords[position];
-					x				=	vector2[0];
-					y				=	vector2[1];
-					glTexCoord2f(x,y);
-				}
-
-				//	Gets the vertex coordinates.
-				vector3	=	geosubmesh->mVertexBuffer->mPosition[position];
-
-				x				=	vector3[0];
-				y				=	vector3[1];
-				z				=	vector3[2];
-
-				//	Sets the vertex position.
-				glVertex3f(x,y,z);
-			}
-
-			//	Increments current strip.
-			current_strip++;
-
-			//	A strip is generated.
-			glEnd();
-
-		}*/
-
 		int indices_to_render = lodStripsLib->GetValidIndexCount(submesh);
 		int offset = lodStripsLib->GetValidOffset(submesh);
 
 		glBegin(GL_TRIANGLE_STRIP);
-		//for (int index = 0; index < lodStripsLib->dataRetrievalInterface->GetNumValidIndices(); index ++)
-		for (int index = offset; index < indices_to_render+offset; index ++)
-		{
-			position = lodStripsLib->dataRetrievalInterface->GetIndex(index);
+//		for (int index = offset; index < indices_to_render+offset; index ++)
+		for (int index = 0; index < mGeoMeshViewUI->lod_index_data->indexCount[submesh]; index ++)
+		{
+//			position = lodStripsLib->dataRetrievalInterface->GetIndex(index);
+			position = mGeoMeshViewUI->lod_index_data->indices[submesh][index];
 
 			//	Gets the vertex normal.
@@ -1045,74 +983,13 @@
 
 		//	For each one of the strips.
-/*		for (int strip = 0; strip < geosubmesh->mStripCount; strip++)
-		{
-			//	Paint the current strip.
-			glBegin(GL_TRIANGLE_STRIP);
-
-			if (getColorStrips())
-			{
-				//	Gets the color of the strip.
-				r	=	mStripColors[submesh][color_index].r;
-				g	=	mStripColors[submesh][color_index].g;
-				b	=	mStripColors[submesh][color_index].b;
-
-				//	Change to the next color.
-				color_index++;
-
-				//	Paint a new color.
-				glColor3f(r,g,b);
-			}
-
-			//	For each index of the strip.
-			for (int index = 0; index < lodTreeLib->CurrentLOD_Trunk_IndexCountByStrip(current_strip); index++)
-			{
-				position = lodTreeLib->CurrentLOD_Trunk_Indices()->GetIndex(current_strip,index);
-
-				//	Gets the vertex normal.
-				vector3	=	geosubmesh->mVertexBuffer->mNormal[position];
-
-				x				=	vector3[0];
-				y				=	vector3[1];
-				z				=	vector3[2];
-
-				//	Sets the vertex normal.
-				glNormal3f(x,y,z);
-
-				// set the texture coordinates if needed
-				if (usetex)
-				{
-					vector2 = geosubmesh->mVertexBuffer->mTexCoords[position];
-					x				=	vector2[0];
-					y				=	vector2[1];
-					glTexCoord2f(x,y);
-				}
-
-				//	Gets the vertex coordinates.
-				vector3	=	geosubmesh->mVertexBuffer->mPosition[position];
-
-				x				=	vector3[0];
-				y				=	vector3[1];
-				z				=	vector3[2];
-
-				//	Sets the vertex position.
-				glVertex3f(x,y,z);
-			}
-
-			//	Increments current strip.
-			current_strip++;
-
-			//	A strip is generated.
-			glEnd();
-
-		}*/
-	
-//		int indices_to_render = lodTreeLib->trunk->GetValidIndexCount(submesh);
 		int indices_to_render = lodTreeLib->GetValidTrunkIndexCount(submesh);
 		int begin_index = lodTreeLib->GetValidTrunkOffset(submesh);
         		
 		glBegin(GL_TRIANGLE_STRIP);
-		for (int index = begin_index; index < indices_to_render+begin_index; index ++)
-		{
-			position = lodTreeLib->CurrentLOD_Trunk_Indices()->GetIndex(index);
+//		for (int index = begin_index; index < indices_to_render+begin_index; index ++)
+		for (int index = 0; index < mGeoMeshViewUI->lod_index_data->indexCount[submesh]; index ++)
+		{
+//			position = lodTreeLib->CurrentLOD_Trunk_Indices()->GetIndex(index);
+			position = mGeoMeshViewUI->lod_index_data->indices[submesh][index];
 
 			//	Gets the vertex normal.
@@ -1157,18 +1034,18 @@
 
 	glBegin(GL_TRIANGLES);
-	const Geometry::VertexData *foliage_verts = lodTreeLib->Get_Foliage_VertexData();
-	const Geometry::IndexData *foliage_inds = lodTreeLib->CurrentLOD_Foliage_Indices();
-	for (int j=0; j<lodTreeLib->CurrentLOD_Foliage_IndexCount(); j++)
-	{
-		float vx,vy,vz;
+	Geometry::SubMesh & foliageSubMesh = geoMesh->mSubMesh[lodTreeLib->GetLeavesSubMesh()];
+	Geometry::Vector3 auxv;
+	for (int j=0; j<mGeoMeshViewUI->lod_index_data->indexCount[lodTreeLib->GetLeavesSubMesh()]; j++)
+	{		
+		int k = mGeoMeshViewUI->lod_index_data->indices[lodTreeLib->GetLeavesSubMesh()][j];
 		if (usetex)
 		{
-			foliage_verts->GetVertexTexCoord(foliage_inds->GetIndex(j),vx,vy);
-			glTexCoord2f(vx,vy);
-		}
-		foliage_verts->GetVertexNormal(foliage_inds->GetIndex(j),vx,vy,vz);
-		glNormal3f(vx,vy,vz);
-		foliage_verts->GetVertexCoord(foliage_inds->GetIndex(j),vx,vy,vz);
-		glVertex3f(vx,vy,vz);
+			Geometry::Vector2 tc = foliageSubMesh.mVertexBuffer->mTexCoords[k];
+			glTexCoord2f(tc.x,tc.y);
+		}
+		auxv = foliageSubMesh.mVertexBuffer->mNormal[k];
+		glNormal3f(auxv.x,auxv.y,auxv.z);
+		auxv = foliageSubMesh.mVertexBuffer->mPosition[k];
+		glVertex3f(auxv.x,auxv.y,auxv.z);
 	}
 	glEnd();
@@ -1253,5 +1130,5 @@
 
 	glEnable (GL_POLYGON_OFFSET_LINE);
-	glPolygonOffset(-1,-1);
+	glPolygonOffset(-0.5,1);
 	glEnable(GL_DEPTH_TEST);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -1269,5 +1146,5 @@
 	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color_blanco);
 
-	glClearColor(0,0,0,0);
+	glClearColor(0.3,0.3,0.3,0);
 	
 	if (mCW)
@@ -1292,5 +1169,5 @@
 	{
 		enableColorStrips();
-		glDisable(GL_LIGHTING);
+		//glDisable(GL_LIGHTING);
 		glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
 		drawGeoMesh(false);
@@ -1304,6 +1181,9 @@
 	{
 		disableColorStrips();
-		glDisable(GL_LIGHTING);
-		glColor3d(0.0, 0.0, 1.0);
+		//glDisable(GL_LIGHTING);
+		glColor3d(0.0, 0.0, 0.0);
+		GLfloat color[]	=	{0.0f,0.0f,0.0f,1.0f};
+		glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color);
+
 		glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
 		drawGeoMesh(true);
@@ -1313,6 +1193,6 @@
 		if (!mSolid)
 		{
-			enableColorStrips();
-			glEnable(GL_LIGHTING);
+			disableColorStrips();
+			//glEnable(GL_LIGHTING);
 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 			drawGeoMesh(false);
Index: GTP/trunk/Lib/Geom/shared/GeoTool/README.txt
===================================================================
--- GTP/trunk/Lib/Geom/shared/GeoTool/README.txt	(revision 1526)
+++ GTP/trunk/Lib/Geom/shared/GeoTool/README.txt	(revision 1526)
@@ -0,0 +1,43 @@
+Overview
+--------
+
+The GeoTool application exposes all the funcionality of the GTGeometry library to
+make it directly usable by the user. The features are: LodStrips generation and 
+visualization, LodTree model generation and visualization, mesh simplification and
+stripification.
+These features are described in more detail in the Gametools Geometry User Manual 
+and in the README.txt file of the GTGeometry project.
+
+The following sections will explain howto build a LodStrips and a LodTree object.
+This information is also available in the GameTools Geometry User Manual.
+
+HowTo construct a LodStrips model
+---------------------------------
+
+First step is open a mesh object. We can do this by the 'Open' option of the 'File' 
+menu. The next step is to select option 'Generate' of the 'LODStrip' menu to begin 
+the generation process. At right appears the 'Generate LODStrips' panel, in which 
+we can choose the simplification methon between 'Geometry base' and 'Viewpoint Driven'. 
+In addition, we must specify mesh reduction by percent or by the number of triangles 
+to obtain. Pushing the 'Process' button the simplification is performed and its result 
+can be viewed at screen. At this point, if the result of simplification don't like us, 
+we can undo this step and change simplification options. In the other hand, if the 
+results of the simplification are OK, we can build the LOD object pushing the 'Build' 
+button and filling the name of this one. If we can view the result of build process 
+can do this by selecting the option 'Visualize' of the menu 'LODStrips' that makes a
+slidebar appear in the right panel. By moving the slidebar we can change the Level 
+Of Detail of the object.
+
+
+HowTo construct a LodTree model
+-------------------------------
+
+After having a tree mesh opened in the application, we must select the 'Select Leaves'
+option of the 'Edit' menu. This makes that the 'Select Leaves' panel appears. In this 
+panel there is a mesh info browser that shows the submeshes in which is divided the 
+object and relevant geometric information. Clicking a submesh in the browser paint this 
+in red at the view window. We must choose the treetop submesh and push the button 'Process'
+to make the selection of leaves. Next we can go to do the LODStrip procress as described 
+before. Finaly the result of the LODStrip process is used as inpunt of the LODTree one. 
+Using the 'LODTree' menu we can perform the LODTree building following the same steps 
+than a LODStrip process.
