← Back to team overview

yade-dev team mailing list archive

[svn] r1612 - in trunk/extra: . SpherePadder mgpost/doc mgpost/src

 

Author: richefeu
Date: 2009-01-06 17:38:10 +0100 (Tue, 06 Jan 2009)
New Revision: 1612

Added:
   trunk/extra/SpherePadder/
   trunk/extra/SpherePadder/Makefile
   trunk/extra/SpherePadder/SpherePadder.cpp
   trunk/extra/SpherePadder/SpherePadder.hpp
   trunk/extra/SpherePadder/TetraMesh.cpp
   trunk/extra/SpherePadder/TetraMesh.hpp
   trunk/extra/SpherePadder/main.cpp
Modified:
   trunk/extra/mgpost/doc/mgpost-doc-en.tex
   trunk/extra/mgpost/src/display_funcs.c
   trunk/extra/mgpost/src/display_funcs.h
   trunk/extra/mgpost/src/ihm.c
Log:
- add a new tool for sphere packing (still in dev)
- some enhancement in mgpost interface



Added: trunk/extra/SpherePadder/Makefile
===================================================================
--- trunk/extra/SpherePadder/Makefile	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/Makefile	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,25 @@
+CC      = g++
+CFLAGS  = -O3 -Wall
+
+SRC = main.cpp \
+      SpherePadder.cpp TetraMesh.cpp
+
+OBJS = $(subst .cpp,.o,$(SRC))
+
+.SUFFIXES: .cpp
+.cpp.o:
+	$(CC) -c $(CFLAGS) $<
+
+all: $(OBJS)
+	$(CC) -o pad $(OBJS)
+
+clean:
+	rm -f *~ \#*\#
+	rm -f *.o
+
+depend:
+	makedepend -- $(CFLAGS) -- *.cpp
+
+# DO NOT DELETE
+
+

Added: trunk/extra/SpherePadder/SpherePadder.cpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.cpp	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/SpherePadder.cpp	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,292 @@
+/*************************************************************************
+*  Copyright (C) 2009 by Jean Francois Jerier                            *
+*  jerier@xxxxxxxxxxxxxxx                                                *
+*  Copyright (C) 2009 by Vincent Richefeu                                *
+*  vincent.richefeu@xxxxxxxxxxx                                          *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#include "SpherePadder.hpp"
+
+double rand01()
+{
+	return (double)rand()/(double)RAND_MAX;
+}
+
+void SpherePadder::read_data (const char* filename)
+{
+	//FIXME : 
+	// si on utilise la class dans un autre programme c'est peu etre pas util
+		
+	//rmin = 1e-2;
+	//rmax = 2e-2;
+	//rmoy = 0.5 * (rmin + rmax);
+	ratio = 3.0; rmoy = 0.0;
+
+/* FIXME
+pour le moment, l'utilisateur ne peut entre qu'un ratio.
+Le rayon des sphere depend du maillage (des longueurs des segments)
+*/
+
+
+}
+	
+void SpherePadder::plugTetraMesh (TetraMesh * pluggedMesh)
+{
+	mesh = pluggedMesh;
+	
+	// Si l'utilisateur n'a choisi qu'une valeur de ratio, 
+    // on cree les valeur de rmin et rmax:
+	if (rmoy == 0 && ratio > 0)
+	{
+		rmoy = 0.125 * mesh->mean_segment_length; // 1/8
+	    rmin = (2.0 * rmoy) / (ratio + 1.0);
+	    //rmax = (2.0 * ratio * rmoy) / (ratio + 1.0); // FIXME ask jf
+		rmax = 2.0 * rmoy - rmin;
+	    //dr	 = 0.5 * (rmax - rmin); // FIXME : voir avec jf ce qu'il fait vraiment (sa version (rmax+rmin)/2)
+		dr = rmax - rmoy;
+	}
+}
+
+void SpherePadder::pad_5 ()
+{
+	// TODO check if all si ok (mesh exist...)
+	place_at_nodes();
+	place_at_segment_middle();
+	place_at_faces_barycentre(); // TODO tester avec barycentres
+	cancel_overlap();
+	// ...
+}
+
+void SpherePadder::save_mgpost (const char* name)
+{
+  ofstream fmgpost(name);
+
+  fmgpost << "<?xml version=\"1.0\"?>" << endl
+	      << " <mgpost mode=\"3D\">" << endl
+	      << "  <newcolor name=\"nodes\"/>" << endl
+	      << "  <newcolor name=\"middle nodes\"/>" << endl	
+	      << "  <newcolor name=\"fixme\"/>" << endl
+	      << "  <state id=\"" << 1 
+	      << "\" time=\"" << 0.0 << "\">" << endl;
+
+  for (unsigned int i = 0 ; i < sphere.size() ; ++i)
+    {
+    fmgpost << "   <body>" << endl;
+    fmgpost << "    <SPHER id=\"" << i+1 << "\" col=\"" << sphere[i].type << "\" r=\"" << sphere[i].R << "\">" << endl
+		    << "     <position x=\"" << sphere[i].x << "\" y=\"" << sphere[i].y << "\" z=\"" << sphere[i].z << "\"/>" << endl	 
+            << "    </SPHER>" << endl << flush;
+
+// tmp (bricolage)
+if (i < mesh->node.size())
+		for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
+		{
+			if (mesh->segment[s].nodeId[0] == i)
+			{
+				fmgpost << "    <SPSPx antac=\"" << mesh->segment[s].nodeId[1] + 1 << "\"/>" << endl;
+			}
+		}
+
+
+    fmgpost << "   </body>" << endl;
+    }
+
+  fmgpost << "  </state>" << endl
+	      << " </mgpost>" << endl;
+		
+}
+	
+void SpherePadder::place_at_nodes ()
+{
+	unsigned int segId;
+	Sphere S;
+	S.type = 0;
+	S.owner.push_back(0);
+	
+	cerr << "place at nodes... ";
+	
+	for (unsigned int n = 0 ; n < mesh->node.size() ; ++n)
+	{
+		S.x = mesh->node[n].x;
+		S.y = mesh->node[n].y;
+		S.z = mesh->node[n].z;
+		S.R = mesh->segment[ mesh->node[n].segmentOwner[0] ].length;
+		for (unsigned int i = 1 ; i < mesh->node[n].segmentOwner.size() ; ++i)
+		{
+			segId = mesh->node[n].segmentOwner[i];
+			S.R = (S.R < mesh->segment[segId].length) ? S.R : mesh->segment[segId].length;
+		}	
+		S.R /= 4.0;
+		S.owner[0] = n;// FIXME utile ???
+		
+		S.tetraOwner = mesh->node[n].tetraOwner[0];
+		mesh->tetraedre[S.tetraOwner].sphereId.push_back(n);
+		
+		sphere.push_back(S);	
+	}
+	cerr << "done" << endl;
+}
+
+void SpherePadder::place_at_segment_middle ()
+{	
+	cerr << "place at segment middle... ";
+	Sphere S;
+	S.type = 1;
+	S.owner.push_back(0);
+	double x1,y1,z1;
+	double x2,y2,z2;
+	unsigned int id1,id2;
+	unsigned int n0 = sphere.size();
+	
+	for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
+	{
+		id1 = mesh->segment[s].nodeId[0];
+		id2 = mesh->segment[s].nodeId[1];
+		
+		x1  = mesh->node[id1].x;
+		y1  = mesh->node[id1].y;
+		z1  = mesh->node[id1].z;
+		
+		x2  = mesh->node[id2].x;
+		y2  = mesh->node[id2].y;
+		z2  = mesh->node[id2].z;
+		
+		S.x = 0.5 * (x1 + x2);
+		S.y = 0.5 * (y1 + y2);
+		S.z = 0.5 * (z1 + z2);
+		S.R = 0.125 * mesh->segment[s].length;
+		if (S.R < rmin) S.R = rmin;
+		else if (S.R > rmax) S.R = rmoy + dr * rand01();
+		S.owner[0] = s;
+		sphere.push_back(S);	
+		
+		S.tetraOwner = mesh->node[id1].tetraOwner[0];
+		mesh->tetraedre[S.tetraOwner].sphereId.push_back(n0 + s);
+		
+		mesh->segment[s].sphereId = n0 + s;
+		
+	}	
+	cerr << "done" << endl;	
+}
+
+
+
+
+void SpherePadder::place_at_faces_barycentre ()
+{
+	cerr << "place at faces_barycentre... ";
+
+	unsigned int sphereId,faceId;
+	for (unsigned int s = 0 ; s < mesh->segment.size() ; ++s)
+	{
+		sphereId = mesh->segment[s].sphereId;
+		for (unsigned int f = 0 ; f < mesh->segment[s].faceOwner.size() ; ++f)
+		{
+			faceId = mesh->segment[s].faceOwner[f];
+			mesh->face[ faceId ].sphereId.push_back( sphereId );
+		}
+	}
+	
+	Sphere S;
+	S.type = 2;
+	// todo S.owner ...
+	unsigned int ns = sphere.size();
+        const double untiers = 0.3333333333333;
+	double R1,R2,R3;
+
+	for (unsigned int f = 0 ; f < mesh->face.size() ; ++f)
+	{
+
+		Sphere S1 = sphere[ mesh->face[f].sphereId[0] ];
+		Sphere S2 = sphere[ mesh->face[f].sphereId[1] ];
+		Sphere S3 = sphere[ mesh->face[f].sphereId[2] ];
+
+		S.x = untiers * (S1.x + S2.x + S3.x); 
+		S.y = untiers * (S1.y + S2.y + S3.y); 
+		S.z = untiers * (S1.z + S2.z + S3.z); 
+		
+		R1 = distance_centre_spheres(S1,S) - S1.R;
+		R2 = distance_centre_spheres(S2,S) - S2.R;
+		R3 = distance_centre_spheres(S3,S) - S3.R;
+		S.R = (R1>R2)    ? R2 : R1;
+		S.R = (S.R > R3) ? R3 : S.R;
+		
+		sphere.push_back(S);
+
+		S.tetraOwner = mesh->node[ mesh->face[f].nodeId[0] ].tetraOwner[0];
+		mesh->tetraedre[S.tetraOwner].sphereId.push_back(ns++);
+	}
+	cerr << "done" << endl;
+}
+
+
+
+
+
+
+
+
+double SpherePadder::distance_spheres(unsigned int i, unsigned int j)
+{
+	double lx,ly,lz;
+	lx  = sphere[j].x - sphere[i].x;
+	ly  = sphere[j].y - sphere[i].y;
+	lz  = sphere[j].z - sphere[i].z;
+	return (sqrt(lx*lx + ly*ly + lz*lz) - sphere[i].R - sphere[j].R);
+}
+
+double SpherePadder::distance_centre_spheres(Sphere& S1, Sphere& S2)
+{
+	double lx,ly,lz;
+	lx  = S2.x - S1.x;
+	ly  = S2.y - S1.y;
+	lz  = S2.z - S1.z;
+	return (sqrt(lx*lx + ly*ly + lz*lz));
+}
+
+
+void SpherePadder::cancel_overlap()
+{
+	
+	cerr << "cancel_overlap... ";
+	unsigned int current_tetra_id,tetra_neighbor_id,j;
+	Tetraedre current_tetra, tetra_neighbor;
+	double distance,k;
+	
+	for(unsigned int i = 0 ; i <  sphere.size(); ++i)
+	{
+		if (sphere[i].R < 0.0) continue;
+		current_tetra_id = sphere[i].tetraOwner;
+		current_tetra = mesh->tetraedre[current_tetra_id];
+		
+		for (unsigned int t = 0 ; t < current_tetra.tetraNeighbor.size() ; ++t)
+		{
+			tetra_neighbor_id = current_tetra.tetraNeighbor[t];
+			tetra_neighbor = mesh->tetraedre[tetra_neighbor_id];
+			for (unsigned int n = 0 ; n < tetra_neighbor.sphereId.size() ; ++n)
+			{
+				j = tetra_neighbor.sphereId[n];
+
+				if (sphere[j].R < 0.0) continue;
+				if (i < j)
+				{
+					while ( (distance = distance_spheres(i,j)) < -0.001)
+					{						
+						k = 1.0 + distance / (sphere[i].R+ sphere[j].R);
+						sphere[i].R *= k;
+						sphere[j].R *= k;
+					}
+				}
+			}
+		}
+	}
+	cerr << "done" << endl;
+}
+
+
+void SpherePadder::place_at_tetra_centers ()
+{
+// TODO	
+}

Added: trunk/extra/SpherePadder/SpherePadder.hpp
===================================================================
--- trunk/extra/SpherePadder/SpherePadder.hpp	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/SpherePadder.hpp	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,59 @@
+/*************************************************************************
+*  Copyright (C) 2009 by Jean Francois Jerier                            *
+*  jerier@xxxxxxxxxxxxxxx                                                *
+*  Copyright (C) 2009 by Vincent Richefeu                                *
+*  vincent.richefeu@xxxxxxxxxxx                                          *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#ifndef SPHERE_PADDER_HPP
+#define SPHERE_PADDER_HPP
+
+#include "TetraMesh.hpp"
+
+struct Sphere
+{
+	double                x,y,z,R;
+	unsigned int          type; // FIXME utiliser un enum ??
+	unsigned int          tetraOwner;
+	vector<unsigned int>  owner; // a documenter... FIXME necessaire ?
+	// type = 0 => owner = nodeId
+	// type = 1 => owner = segId
+};
+
+struct Neighbor
+{
+	unsigned int i,j;	
+};
+
+class SpherePadder
+{
+protected:
+	
+	double distance_spheres (unsigned int i, unsigned int j);
+        double distance_centre_spheres(Sphere& S1, Sphere& S2);
+	void place_at_nodes ();
+	void place_at_segment_middle ();
+	void place_at_faces_barycentre ();
+	void cancel_overlap ();
+	void place_at_tetra_centers ();
+	
+public:
+	double rmin,rmax,rmoy,dr;
+	double ratio;
+	double max_overlap; // ATTENTION negatif 
+	
+	TetraMesh * mesh;
+	vector<Sphere> sphere;
+
+	void read_data (const char* filename);
+	void plugTetraMesh (TetraMesh * mesh);
+	void save_mgpost (const char* name);
+	//void save_Rxyz (const char* name);
+	
+	void pad_5 ();		
+};
+
+#endif // SPHERE_PADDER_HPP

Added: trunk/extra/SpherePadder/TetraMesh.cpp
===================================================================
--- trunk/extra/SpherePadder/TetraMesh.cpp	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/TetraMesh.cpp	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,284 @@
+/*************************************************************************
+*  Copyright (C) 2009 by Jean Francois Jerier                            *
+*  jerier@xxxxxxxxxxxxxxx                                                *
+*  Copyright (C) 2009 by Vincent Richefeu                                *
+*  vincent.richefeu@xxxxxxxxxxx                                          *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#include "TetraMesh.hpp"
+
+void TetraMesh::read_data (const char* name)
+{
+	ifstream meshFile(name);
+	if(!meshFile)
+	{
+		cerr << "TetraMesh::read_data, cannot open file " << name << endl;
+		return;
+	}  
+
+    cout << "Read data... " << flush;
+	string token;
+	meshFile >> token;
+
+	while(meshFile)
+	{
+		if (token == "NODES") 
+		{
+			unsigned int nbnodes;
+			Node N;
+
+			meshFile >> nbnodes; 
+			for (unsigned int n = 0 ; n < nbnodes ; ++n)
+			{
+				meshFile >> N.x >> N.y >> N.z;
+				node.push_back(N);	
+			}
+		}
+
+		if (token == "TETRA") 
+		{
+			unsigned int nbTetra;
+			Tetraedre T;
+			
+			meshFile >> nbTetra;
+			for (unsigned int t = 0 ; t < nbTetra ; ++t)
+			{
+				meshFile >> T.nodeId[0] >> T.nodeId[1] >> T.nodeId[2] >> T.nodeId[3];
+				
+				// numbers begin at 0 instead of 1
+				// (0 in C corresponds to 1 in the file)
+				T.nodeId[0] -= 1;
+				T.nodeId[1] -= 1;
+				T.nodeId[2] -= 1;
+				T.nodeId[3] -= 1;
+				
+				node[T.nodeId[0]].tetraOwner.push_back(t);
+				node[T.nodeId[1]].tetraOwner.push_back(t);
+				node[T.nodeId[2]].tetraOwner.push_back(t);
+				node[T.nodeId[3]].tetraOwner.push_back(t);
+				
+				tetraedre.push_back(T);	
+			}			
+		}
+		
+		if (token == "EOF") break;
+		
+		meshFile >> token;
+	}
+	cout << "Done" << endl;
+	
+	organize ();
+}
+
+int compareInt (const void * a, const void * b)
+{
+	return ( *(int*)a > *(int*)b ) ? 1 :-1;
+}
+
+void TetraMesh::organize ()
+{
+	cout << "Organize data... " << flush;
+	
+	// Translate all nodes in such a manner that all coordinates are > 0
+	xtrans = node[0].x;
+	ytrans = node[0].y;
+	ztrans = node[0].z;
+	for (unsigned int i = 1 ; i < node.size() ; ++i)
+	{
+		xtrans = (xtrans < node[i].x) ? xtrans : node[i].x;
+		ytrans = (ytrans < node[i].y) ? ytrans : node[i].y;
+		ztrans = (ztrans < node[i].z) ? ztrans : node[i].z;
+	}
+	xtrans = (xtrans<0.0) ? -xtrans : 0.0;
+	ytrans = (ytrans<0.0) ? -ytrans : 0.0;
+	ztrans = (ztrans<0.0) ? -ztrans : 0.0;
+	for (unsigned int i = 0 ; i < node.size() ; ++i)
+	{
+		node[i].x += xtrans;
+		node[i].y += ytrans;
+		node[i].z += ztrans;
+	}	
+	
+	// Organize tetraedre nodes in ascending order
+	for (unsigned int i = 0 ; i < tetraedre.size() ; ++i)
+	{
+		qsort (&(tetraedre[i].nodeId[0]), 4, sizeof(int), compareInt);
+	}
+	
+	// Face creation
+	vector <Face> tmpFace; // This will contain all faces more than one time
+	Face F;
+	F.tetraOwner.push_back(0);
+	F.belongBoundary = true;
+	for (unsigned int i = 0 ; i < tetraedre.size() ; ++i)
+	{
+		F.tetraOwner[0] = i;
+		
+		// Note that nodes are still organized in ascending order
+		F.nodeId[0] = tetraedre[i].nodeId[0];
+		F.nodeId[1] = tetraedre[i].nodeId[1];
+		F.nodeId[2] = tetraedre[i].nodeId[2];
+		tmpFace.push_back(F);
+		
+		F.nodeId[0] = tetraedre[i].nodeId[1];
+		F.nodeId[1] = tetraedre[i].nodeId[2];
+		F.nodeId[2] = tetraedre[i].nodeId[3];
+		tmpFace.push_back(F);
+		
+		F.nodeId[0] = tetraedre[i].nodeId[0];
+		F.nodeId[1] = tetraedre[i].nodeId[2];
+		F.nodeId[2] = tetraedre[i].nodeId[3];
+		tmpFace.push_back(F);
+		
+		F.nodeId[0] = tetraedre[i].nodeId[0];
+		F.nodeId[1] = tetraedre[i].nodeId[1];
+		F.nodeId[2] = tetraedre[i].nodeId[3];
+		tmpFace.push_back(F);		
+	}
+	
+	face.push_back(tmpFace[0]);
+	bool duplicated;
+	for (unsigned int i = 1 ; i < tmpFace.size() ; ++i)
+	{
+		duplicated = false;
+		for (unsigned int n = 0 ; n < face.size() ; ++n)
+		{
+			if (   tmpFace[i].nodeId[0] == face[n].nodeId[0]
+			    && tmpFace[i].nodeId[1] == face[n].nodeId[1]
+			    && tmpFace[i].nodeId[2] == face[n].nodeId[2])
+			{
+				duplicated = true;
+				face[n].tetraOwner.push_back(tmpFace[i].tetraOwner[0]);
+				face[n].belongBoundary = false;
+				break;
+			}				
+		}
+		
+		if (!duplicated) 
+		{
+			face.push_back(tmpFace[i]);
+		}
+	}
+	tmpFace.clear(); // It should be usefull to free memory before the end of the function
+	
+	for (unsigned int f = 0 ; f < face.size() ; ++f)
+	{
+		node[face[f].nodeId[0]].faceOwner.push_back(f);
+		node[face[f].nodeId[1]].faceOwner.push_back(f);
+		node[face[f].nodeId[2]].faceOwner.push_back(f);
+	}
+	
+	// Segment creation
+	vector <Segment> tmpSegment;
+	Segment S;
+	S.faceOwner.push_back(0);
+	//S.belongBoundary = true; // a voir
+	for (unsigned int i = 0 ; i < face.size() ; ++i)
+	{
+		S.faceOwner[0] = i;
+		S.nodeId[0] = face[i].nodeId[0];
+		S.nodeId[1] = face[i].nodeId[1];
+		tmpSegment.push_back(S);
+		
+		S.nodeId[0] = face[i].nodeId[1];
+		S.nodeId[1] = face[i].nodeId[2];
+		tmpSegment.push_back(S);
+		
+		S.nodeId[0] = face[i].nodeId[0];
+		S.nodeId[1] = face[i].nodeId[2];
+		tmpSegment.push_back(S);
+				
+	}
+	
+	segment.push_back(tmpSegment[0]);
+	for (unsigned int i = 1 ; i < tmpSegment.size() ; ++i)
+	{
+		duplicated = false;
+		for (unsigned int n = 0 ; n < segment.size() ; ++n)
+		{
+			if (   tmpSegment[i].nodeId[0] == segment[n].nodeId[0]
+			    && tmpSegment[i].nodeId[1] == segment[n].nodeId[1])
+			{
+				duplicated = true;
+				segment[n].faceOwner.push_back(tmpSegment[i].faceOwner[0]);
+				break;
+			}
+				
+		}
+		
+		if (!duplicated) 
+		{
+			segment.push_back(tmpSegment[i]);
+		}
+	}
+	
+	for (unsigned int s = 0 ; s < segment.size() ; ++s)
+	{
+		node[segment[s].nodeId[0]].segmentOwner.push_back(s);
+		node[segment[s].nodeId[1]].segmentOwner.push_back(s);
+	}
+		
+	// Compute length of segments
+	double lx,ly,lz;
+	unsigned int id1,id2;
+	mean_segment_length = 0.0;
+	min_segment_length = 0.0;
+	max_segment_length = 0.0;
+	for (unsigned int s = 0 ; s < segment.size() ; ++s)
+	{
+		id1 = segment[s].nodeId[0];
+		id2 = segment[s].nodeId[1];
+		
+		lx  = node[id2].x - node[id1].x;
+	    ly  = node[id2].y - node[id1].y;
+	    lz  = node[id2].z - node[id1].z;
+		
+		mean_segment_length += (segment[s].length = sqrt(lx*lx + ly*ly + lz*lz));
+		min_segment_length = (segment[s].length < min_segment_length) ? segment[s].length : min_segment_length;
+		max_segment_length = (segment[s].length > max_segment_length) ? segment[s].length : max_segment_length;
+	}
+	mean_segment_length /= (double)(segment.size());
+	
+	
+	// Define tetraedre neighbors
+	for (unsigned int t1 = 0 ; t1 < tetraedre.size() ; ++t1)
+	{
+		for (unsigned int t2 = t1 ; t2 < tetraedre.size() ; ++t2)
+		{
+			if (   (tetraedre[t1].nodeId[0] > tetraedre[t2].nodeId[3]) 
+				|| (tetraedre[t1].nodeId[3] < tetraedre[t2].nodeId[0]) ) continue;
+                        
+                        // TODO mettre du while...
+			for (unsigned int i = 0 ; i < 4 ; i++)
+                        {
+			        for (unsigned int j = 0 ; j < 4 ; j++)
+				{
+				    if (tetraedre[t1].nodeId[i] == tetraedre[t2].nodeId[j])
+				    {
+				      tetraedre[t1].tetraNeighbor.push_back(t2);
+				      tetraedre[t2].tetraNeighbor.push_back(t1);
+				      break;
+				    }
+				}
+                        }	  
+		}
+	}
+	
+	// Define Owners FIXME :  a voir plus tard
+	/*
+	for (unsigned int t = 0 ; t < tetraedre.size() ; ++t)
+	{
+		node[tetraedre[t].nodeId[0]].tetraOwner.push_back(t);
+		node[tetraedre[t].nodeId[1]].tetraOwner.push_back(t);
+		node[tetraedre[t].nodeId[2]].tetraOwner.push_back(t);
+		node[tetraedre[t].nodeId[3]].tetraOwner.push_back(t);
+	}
+	*/
+	cout << "Done" << endl;
+}
+
+
+

Added: trunk/extra/SpherePadder/TetraMesh.hpp
===================================================================
--- trunk/extra/SpherePadder/TetraMesh.hpp	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/TetraMesh.hpp	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,73 @@
+/*************************************************************************
+*  Copyright (C) 2009 by Jean Francois Jerier                            *
+*  jerier@xxxxxxxxxxxxxxx                                                *
+*  Copyright (C) 2009 by Vincent Richefeu                                *
+*  vincent.richefeu@xxxxxxxxxxx                                          *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#ifndef TETRA_MESH_HPP
+#define TETRA_MESH_HPP
+
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <stdlib.h> // for qsort
+#include <math.h>
+
+using namespace std;
+
+struct Node
+{
+	double x,y,z;
+	vector<unsigned int> tetraOwner;
+	vector<unsigned int> faceOwner;
+	vector<unsigned int> segmentOwner;
+};
+
+struct Segment
+{
+	unsigned int nodeId[2];
+	double length;
+	vector<unsigned int> faceOwner;
+	unsigned int sphereId;
+};
+
+struct Face
+{
+	unsigned int nodeId[3];
+	vector<unsigned int> tetraOwner; // FIXME utile ???
+	vector<unsigned int> sphereId;
+	bool belongBoundary;
+};
+
+struct Tetraedre
+{
+	unsigned int nodeId[4];
+	vector<unsigned int> sphereId;
+	vector<unsigned int> tetraNeighbor;
+};
+	
+class TetraMesh
+{
+
+	
+public:
+	vector<Node>       node;
+	vector<Segment>    segment;
+    vector<Face>       face;
+	vector<Tetraedre>  tetraedre;
+
+	double xtrans,ytrans,ztrans;
+	double mean_segment_length;
+	double min_segment_length;
+	double max_segment_length;
+		
+	//void read_data (string filename);
+	void read_data (const char* name);
+	void organize (); // FIXME protected ?
+};
+
+#endif // TETRA_MESH_HPP

Added: trunk/extra/SpherePadder/main.cpp
===================================================================
--- trunk/extra/SpherePadder/main.cpp	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/SpherePadder/main.cpp	2009-01-06 16:38:10 UTC (rev 1612)
@@ -0,0 +1,29 @@
+/*************************************************************************
+*  Copyright (C) 2009 by Jean Francois Jerier                            *
+*  jerier@xxxxxxxxxxxxxxx                                                *
+*  Copyright (C) 2009 by Vincent Richefeu                                *
+*  vincent.richefeu@xxxxxxxxxxx                                          *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#include "SpherePadder.hpp"
+
+int main()
+{
+	SpherePadder * padder = new SpherePadder();
+	padder->read_data("padding.dat");
+	TetraMesh * mesh = new TetraMesh();
+	mesh->read_data("test.msh");
+	padder->plugTetraMesh(mesh);
+	
+	padder->pad_5();
+	
+	padder->save_mgpost("mgp.out.001");
+	
+	return 0;
+}
+
+
+

Modified: trunk/extra/mgpost/doc/mgpost-doc-en.tex
===================================================================
--- trunk/extra/mgpost/doc/mgpost-doc-en.tex	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/mgpost/doc/mgpost-doc-en.tex	2009-01-06 16:38:10 UTC (rev 1612)
@@ -184,7 +184,7 @@
 \end{verbatim}
 
 \marginlabel{\texttt{-section \var{a} \var{b} \var{c} \var{d}}}
-Define the parameters  $a$ $b$ $c$ et $d$ of the plan given by:
+Define the parameters  $a$ $b$ $c$ and $d$ of the plan given by:
 
 \begin{equation}
 aX + bY + cZ + d = 0 

Modified: trunk/extra/mgpost/src/display_funcs.c
===================================================================
--- trunk/extra/mgpost/src/display_funcs.c	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/mgpost/src/display_funcs.c	2009-01-06 16:38:10 UTC (rev 1612)
@@ -89,7 +89,7 @@
   glEnable (GL_LIGHTING);
 }
 
-void disp_outline () /* ne fonctionne que pour les spheres */
+void disp_outline () /* Only for spheres */
 {
   int i;
   GLdouble Xcam = Xviewp * TRANS_CAM_FACTOR, Ycam = Yviewp * TRANS_CAM_FACTOR;
@@ -359,7 +359,7 @@
     if (pres_du_plan (i, dist_section))
       {
       
-      if (layer[i] % 2) /* a tester : if (layer[i] & 1) */
+      if (layer[i] % 2)
         glColor3f (0.7f, 1.0f, 0.7f);
       else
         glColor3f (0.0f, 0.5f, 0.25f);

Modified: trunk/extra/mgpost/src/display_funcs.h
===================================================================
--- trunk/extra/mgpost/src/display_funcs.h	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/mgpost/src/display_funcs.h	2009-01-06 16:38:10 UTC (rev 1612)
@@ -13,18 +13,15 @@
 
 int graph_xm, graph_xM, graph_ym, graph_yM;
 
-void (*rendu) (void);
-void (*disp_current) (void); 
-void (*rendu_sup) (void);
-void (*rendu_fluid) (void);
+void (*rendu)         (void);
+void (*disp_current)  (void); 
+void (*rendu_sup)     (void);
+void (*rendu_fluid)   (void);
 void (*affgraph_func) (void);
 
 int nb_section1 = 17;
 int nb_section2 = 7;
 
-
-/* ----- display functions */
-
 void disp_time ();
 void disp_text (char *text);
 void disp_grad_color ();

Modified: trunk/extra/mgpost/src/ihm.c
===================================================================
--- trunk/extra/mgpost/src/ihm.c	2009-01-05 19:54:39 UTC (rev 1611)
+++ trunk/extra/mgpost/src/ihm.c	2009-01-06 16:38:10 UTC (rev 1612)
@@ -6,8 +6,7 @@
 *  GNU General Public License v2 or later. See file LICENSE for details. *
 *************************************************************************/
 
-void 
-mgpost_init(int argc, char **argv)
+void mgpost_init(int argc, char **argv)
 {
   int             i, c;
   char            namebuf[256];
@@ -67,6 +66,7 @@
       
       multifiles = MG_TRUE;
     }
+
     strcpy(buf, &namebuf[strlen(namebuf) - 3]);
     buf[3] = 0;
     
@@ -74,6 +74,7 @@
       strcpy(datafilename, (const char *) namebuf);
       multifiles = MG_FALSE;
     }
+
     strcpy(buf, &namebuf[strlen(namebuf) - 6]);
     buf[6] = 0;
     
@@ -92,37 +93,45 @@
       
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-files")) {
       make_mgpalloc_file();
       make_mgconf_file();
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-mgpalloc")) {
       make_mgpalloc_file();
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-mgconf")) {
       make_mgconf_file();
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-nformat")) {
       strcpy(num_file_format, (const char *) argv[i + 1]);
     }
+
     if (!strcmp(argv[i], "-num")) {
        if      (atoi(argv[i + 1]) == 3) strcpy(num_file_format,"%03d");
        else if (atoi(argv[i + 1]) == 4) strcpy(num_file_format,"%04d");
        else                             strcpy(num_file_format,"%d");
     }
+
     if (!strcmp(argv[i], "-i")) {
       strcpy(datafilename, (const char *) argv[i + 1]);
       cin_mode = MG_FALSE;
       multifiles = MG_FALSE;
     }
+
     if (!strcmp(argv[i], "-cin")) {
       strcpy(datafilename, (const char *) argv[i + 1]);
       cin_mode = MG_TRUE;
       multifiles = MG_FALSE;
     }
+
     if (!strcmp(argv[i], "-his")) {
       if (argv[i + 1] != NULL)
         nfile = atoi(argv[i + 1]);
@@ -137,12 +146,15 @@
       his_mode = MG_TRUE;
       multifiles = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-polye")) {
       more_forces = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-fluid")) {
       with_fluid = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-layer")) {
       with_layers = MG_TRUE;
       
@@ -152,6 +164,7 @@
         nbLayers = 5;
       
     }
+
     if (!strcmp(argv[i], "-p")) {
       strcpy(pstfilename, (const char *) argv[i + 1]);
       
@@ -170,6 +183,7 @@
       
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-pz")) {
       strcpy(pstfilename, (const char *) argv[i + 1]);
       
@@ -188,6 +202,7 @@
       
       exit(EXIT_SUCCESS);
     }
+
     if (!strcmp(argv[i], "-mf")) {
       
       if (argv[i + 1] != NULL)
@@ -201,6 +216,7 @@
       fgziped = MG_FALSE;
       multifiles = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-mfz")) {
       
       if (argv[i + 1] != NULL)
@@ -215,22 +231,27 @@
       fgziped = MG_TRUE;
       multifiles = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-r0")) {
       middle_rep = MG_FALSE;
     }
+
     if (!strcmp(argv[i], "-dim")) {
       W = atoi(argv[i + 1]);
       H = atoi(argv[i + 2]);
     }
+
     if (!strcmp(argv[i], "-2d")) {
       phi = -90;
       theta = 0;
       mode2D = MG_TRUE;
     }
+
     if (!strcmp(argv[i], "-mono")) {
       for (c = 0; c <= nb_val_couleurs; c++)
         gradc[c] = gradmono[c];
     }
+
     if (!strcmp(argv[i], "-colormap")) {
       FILE * f;
       f = fopen ("colormap","r");
@@ -248,15 +269,18 @@
         fprintf(stderr,"File colormap not found\n");
         }
     }   
+
     if (!strcmp(argv[i], "-section")) {
       section.a = atof(argv[i + 1]);
       section.b = atof(argv[i + 2]);
       section.c = atof(argv[i + 3]);
       section.d = atof(argv[i + 4]);
     }
+
     if (!strcmp(argv[i], "-dsec")) {
       dist_section = atof(argv[i + 1]);
     }
+
     i++;
   }
 }
@@ -397,8 +421,7 @@
 }
 
 /* Convert a string in color */
-couleur 
-select_color(const char *col)
+couleur select_color(const char *col)
 {
   couleur         retcol = fg_color;
   
@@ -420,8 +443,7 @@
   return retcol;
 }
 
-void 
-processDialogF1()
+void processDialogF1()
 {
   if (!strcmp(dialArea[2].state, "SELECTED"))
     afficheRepere = MG_TRUE;
@@ -454,8 +476,7 @@
     dynamic_scale = MG_FALSE;  
 }
 
-void 
-processDialogF2()
+void processDialogF2()
 {
   double val;
   
@@ -501,8 +522,7 @@
 }
 
 
-void 
-processDialogF3()
+void processDialogF3()
 {
   int             val;
   
@@ -519,8 +539,7 @@
     modDirCon = val;
 }
 
-void 
-processDialogF4()
+void processDialogF4()
 {
   double val;
   
@@ -530,8 +549,7 @@
   
 }
 
-void 
-processDialogF5()
+void processDialogF5()
 {
   double val;
   int c;
@@ -555,8 +573,7 @@
     }
 }
 
-void 
-specialKey(int touche, int x, int y)
+void specialKey(int touche, int x, int y)
 {
   char            str[40];
   int             c;
@@ -567,14 +584,22 @@
       dialogMode();
       
       openDialog(20, 50, 300, 180);
-      
+
+#ifdef _FR      
       creatCheckBox(30, 55,  "Repere global", afficheRepere);
       creatCheckBox(30, 75,  "Affichage State et Time", afftime);
       creatCheckBox(30, 95,  "Orientation des grains", orient);
       creatCheckBox(30, 115, "Numero des corps", bodies_numbers);
       creatCheckBox(30, 135, "Affichage Noms fonctions", affFuncname);
       creatCheckBox(30, 155, "Echelle adaptable", dynamic_scale);    
-      
+#else
+      creatCheckBox(30, 55,  "Global Frame", afficheRepere);
+      creatCheckBox(30, 75,  "Display State and Time", afftime);
+      creatCheckBox(30, 95,  "Particle Orientation", orient);
+      creatCheckBox(30, 115, "Body Numbers", bodies_numbers);
+      creatCheckBox(30, 135, "Display Names of Functions", affFuncname);
+      creatCheckBox(30, 155, "Dynamic Color-Scale", dynamic_scale);
+#endif
       processDialog = processDialogF1;
       
       glutPostRedisplay();
@@ -751,8 +776,8 @@
   mgterminal = GL_TERMINAL;
 }
 
-void 
-clavier(unsigned char touche, int ix, int iy)
+/* keyboard */
+void clavier(unsigned char touche, int ix, int iy)
 {
   
   switch (touche) {
@@ -1096,22 +1121,21 @@
                 if (strcmp(mgpost_editor, "")) {
                   
 #ifdef _MACOSX
-                  strcpy(command, "open -a ");	/* MEMO a tester */
-                         strcat(command, (const char *) mgpost_editor);
-                         strcat(command, " mgconf");
+                  strcpy(command, "open -a ");	/* TODO test it */
+                  strcat(command, (const char *) mgpost_editor);
+                  strcat(command, " mgconf");
 #endif
                          
 #ifdef _WINDOWS
-                         strcpy(command, "$MGPOST_EDITOR mgconf");	/* MEMO a tester */
+                  strcpy(command, "$MGPOST_EDITOR mgconf"); /* TODO test it */
 #endif
                                 
 #ifdef _LINUX
-                                strcpy(command, "$MGPOST_EDITOR ./mgconf &");
+                  strcpy(command, "$MGPOST_EDITOR ./mgconf &");
 #endif
                                 
-                                system(command);
-                } else
-fprintf(stdout, "You must define the environment variable MGPOST_EDITOR !\n");
+                  system(command);
+                } else fprintf(stdout, "You must define the environment variable MGPOST_EDITOR !\n");
               }
 break;