diff --git a/Mesh/Voronoi3D.cpp b/Mesh/Voronoi3D.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..e607294a34bcfd44f92072e2c11a50e0fb32274b
--- /dev/null
+++ b/Mesh/Voronoi3D.cpp
@@ -0,0 +1,299 @@
+// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include "voro++.hh"
+#include "Voronoi3D.h"
+#include "GModel.h"
+#include "MElement.h"
+#include "meshGRegion.h"
+#include <fstream>
+#include "Levy3D.h"
+
+using namespace voro;
+
+/*********class clip*********/
+
+clip::clip(){}
+
+clip::~clip(){}
+
+void clip::execute(){
+  GRegion* gr;
+  GModel* model = GModel::current();
+  GModel::riter it;
+
+  for(it=model->firstRegion();it!=model->lastRegion();it++)
+  {
+    gr = *it;
+	if(gr->getNumMeshElements()>0){
+	  execute(gr);
+	}
+  }
+}
+
+void clip::execute(GRegion* gr){
+  int i;
+  int j;
+  MElement* element;
+  MVertex* vertex;
+  std::vector<SPoint3> vertices2;
+  std::set<MVertex*> vertices;
+  std::set<MVertex*>::iterator it;
+  std::vector<VoronoiElement> clipped;
+	
+  for(i=0;i<gr->getNumMeshElements();i++){
+    element = gr->getMeshElement(i);
+	for(j=0;j<element->getNumVertices();j++){
+	  vertex = element->getVertex(j);
+	  vertices.insert(vertex);
+	}
+  }
+	
+  for(it=vertices.begin();it!=vertices.end();it++){
+    vertices2.push_back(SPoint3((*it)->x(),(*it)->y(),(*it)->z()));
+  }
+	
+  execute(vertices2,clipped);
+  printf("%d\n",clipped.size());	
+	
+  std::ofstream file("cells.pos");
+  file << "View \"test\" {\n";
+  for(i=0;i<clipped.size();i++){
+    print_segment(clipped[i].get_v1().get_point(),clipped[i].get_v2().get_point(),file);
+	print_segment(clipped[i].get_v1().get_point(),clipped[i].get_v3().get_point(),file);
+	print_segment(clipped[i].get_v1().get_point(),clipped[i].get_v4().get_point(),file);
+	print_segment(clipped[i].get_v2().get_point(),clipped[i].get_v3().get_point(),file);
+	print_segment(clipped[i].get_v3().get_point(),clipped[i].get_v4().get_point(),file);
+	print_segment(clipped[i].get_v4().get_point(),clipped[i].get_v2().get_point(),file);
+  }
+  file << "};\n";
+}
+
+void clip::execute(std::vector<SPoint3>& vertices,std::vector<VoronoiElement>& clipped){
+  int i;
+  int j;
+  int start;
+  int end;
+  int index;
+  int index1;
+  int index2;
+  int index3;
+  int count;
+  int pid;
+  double x,y,z;
+  double x1,y1,z1;
+  double x2,y2,z2;
+  double x3,y3,z3;
+  double delta;
+  double min_x,max_x;
+  double min_y,max_y;
+  double min_z,max_z;
+  double volume1;
+  double volume2;
+  double l1,l2,l3,l4,l5;
+  voronoicell_neighbor* pointer;
+  voronoicell_neighbor cell;
+  VoronoiVertex v1,v2,v3,v4;
+  VoronoiElement e;
+  std::vector<int> faces;
+  std::vector<double> voronoi_vertices;
+  std::vector<voronoicell_neighbor*> pointers;
+  std::vector<SPoint3> generators;
+  std::vector<int> IDs;
+  std::vector<int> IDs2;
+  std::vector<int> neighbors;
+  std::vector<std::vector<std::vector<int> > > bisectors;
+	
+  min_x = 1000000000.0;
+  max_x = -1000000000.0;
+  min_y = 1000000000.0;
+  max_y = -1000000000.0;
+  min_z = 1000000000.0;
+  max_z = -1000000000.0;
+  for(i=0;i<vertices.size();i++){
+    min_x = min(vertices[i].x(),min_x);
+	max_x = max(vertices[i].x(),max_x);
+	min_y = min(vertices[i].y(),min_y);
+	max_y = max(vertices[i].y(),max_y);
+	min_z = min(vertices[i].z(),min_z);
+	max_z = max(vertices[i].z(),max_z);
+  }
+
+  delta = 0.2*(max_x - min_x);
+  container cont(min_x-delta,max_x+delta,min_y-delta,max_y+delta,min_z-delta,max_z+delta,6,6,6,false,false,false,vertices.size());
+  volume1 = (max_x-min_x+2.0*delta)*(max_y-min_y+2.0*delta)*(max_z-min_z+2.0*delta);
+	
+  for(i=0;i<vertices.size();i++){
+    cont.put(i,vertices[i].x(),vertices[i].y(),vertices[i].z());
+  }
+
+  count = 0;
+  IDs.resize(vertices.size());
+  c_loop_all loop(cont);
+  loop.start();
+  do{
+    cont.compute_cell(cell,loop);
+	loop.pos(x,y,z);
+	pointer = new voronoicell_neighbor();
+	*pointer = cell;
+	pointers.push_back(pointer);
+	generators.push_back(SPoint3(x,y,z));
+	pid = loop.pid();
+	IDs[pid] = count;
+	IDs2.push_back(pid);
+	count++;
+  }while(loop.inc());	
+	
+  bisectors.resize(pointers.size());
+  for(i=0;i<pointers.size();i++){
+    faces.clear();
+	voronoi_vertices.clear();
+	pointers[i]->face_vertices(faces);
+	pointers[i]->neighbors(neighbors);
+	pointers[i]->vertices(generators[i].x(),generators[i].y(),generators[i].z(),voronoi_vertices);
+	bisectors[i].resize(voronoi_vertices.size()/3);
+	for(j=0;j<bisectors[i].size();j++){
+	  bisectors[i][j].push_back(IDs2[i]);
+	}
+	count = 0;
+	end = 0;
+	while(end<faces.size()){
+	  start = end + 1;
+	  end = start + faces[end];
+	  for(j=start;j<end;j++){
+	    index = faces[j];
+		bisectors[i][index].push_back(neighbors[count]);
+	  }
+	  count++;
+	}
+  }
+
+  for(i=0;i<bisectors.size();i++){
+    for(j=0;j<bisectors[i].size();j++){
+      //printf("%d %d %d %d %d %d\n",i,IDs2[i],bisectors[i][j][0],bisectors[i][j][1],bisectors[i][j][2],bisectors[i][j][3]);
+	}
+  }
+	
+  for(i=0;i<pointers.size();i++){
+	faces.clear();
+	voronoi_vertices.clear();
+	pointers[i]->face_vertices(faces);
+	pointers[i]->vertices(generators[i].x(),generators[i].y(),generators[i].z(),voronoi_vertices);
+	end = 0;
+    while(end<faces.size()){
+	  start = end + 1;
+	  end = start + faces[end];
+	  for(j=start+1;j<end-1;j++){
+	    index1 = faces[start];
+	    index2 = faces[j];
+		index3 = faces[j+1];
+		x1 = voronoi_vertices[3*index1];
+		y1 = voronoi_vertices[3*index1+1];
+		z1 = voronoi_vertices[3*index1+2];
+		x2 = voronoi_vertices[3*index2];
+		y2 = voronoi_vertices[3*index2+1];
+		z2 = voronoi_vertices[3*index2+2];
+		x3 = voronoi_vertices[3*index3];
+		y3 = voronoi_vertices[3*index3+1];
+		z3 = voronoi_vertices[3*index3+2];
+		v1 = VoronoiVertex();
+		v2 = VoronoiVertex();
+		v3 = VoronoiVertex();
+		v4 = VoronoiVertex();
+		v1.set_point(SPoint3(generators[i].x(),generators[i].y(),generators[i].z()));
+		v1.set_category(4);
+		v1.set_index1(IDs2[i]);
+		v2.set_point(SPoint3(x1,y1,z1));
+		v2.set_category(category(bisectors[i][index1][0],bisectors[i][index1][1],bisectors[i][index1][2],bisectors[i][index1][3]));
+		v2.set_index1(bisectors[i][index1][0]);
+		v2.set_index2(bisectors[i][index1][1]);
+		v2.set_index3(bisectors[i][index1][2]);
+		v2.set_index4(bisectors[i][index1][3]);
+		v3.set_point(SPoint3(x2,y2,z2));
+		v3.set_category(category(bisectors[i][index2][0],bisectors[i][index2][1],bisectors[i][index2][2],bisectors[i][index2][3]));
+		v3.set_index1(bisectors[i][index2][0]);
+		v3.set_index2(bisectors[i][index2][1]);
+		v3.set_index3(bisectors[i][index2][2]);
+		v3.set_index4(bisectors[i][index2][3]);
+		v4.set_point(SPoint3(x3,y3,z3));
+		v4.set_category(category(bisectors[i][index3][0],bisectors[i][index3][1],bisectors[i][index3][2],bisectors[i][index3][3]));
+		v4.set_index1(bisectors[i][index3][0]);
+		v4.set_index2(bisectors[i][index3][1]);
+		v4.set_index3(bisectors[i][index3][2]);
+		v4.set_index4(bisectors[i][index3][3]);
+		e = VoronoiElement();
+		e.set_v1(v1);
+		e.set_v2(v2);
+		e.set_v3(v3);
+		e.set_v4(v4);
+		clipped.push_back(e);
+	  }
+	}
+  }
+  
+  volume2 = 0.0;
+  for(i=0;i<clipped.size();i++){
+    if(clipped[i].get_v2().get_category()==1){
+	  l1 = (clipped[i].get_v2().get_point()).distance(clipped[i].get_v1().get_point());
+	  l2 = (clipped[i].get_v2().get_point()).distance(generators[IDs[clipped[i].get_v2().get_index1()]]);
+	  l3 = (clipped[i].get_v2().get_point()).distance(generators[IDs[clipped[i].get_v2().get_index2()]]);
+	  l4 = (clipped[i].get_v2().get_point()).distance(generators[IDs[clipped[i].get_v2().get_index3()]]);
+	  l5 = (clipped[i].get_v2().get_point()).distance(generators[IDs[clipped[i].get_v2().get_index4()]]);
+	  //printf("%f %f %f %f %f %f %f %f %f\n",l1,l2,l3,l4,l5,l1-l2,l1-l3,l1-l4,l1-l5);
+	}
+	if(clipped[i].get_v3().get_category()==1){
+	  l1 = (clipped[i].get_v3().get_point()).distance(clipped[i].get_v1().get_point());
+	  l2 = (clipped[i].get_v3().get_point()).distance(generators[IDs[clipped[i].get_v3().get_index1()]]);
+	  l3 = (clipped[i].get_v3().get_point()).distance(generators[IDs[clipped[i].get_v3().get_index2()]]);
+	  l4 = (clipped[i].get_v3().get_point()).distance(generators[IDs[clipped[i].get_v3().get_index3()]]);
+	  l5 = (clipped[i].get_v3().get_point()).distance(generators[IDs[clipped[i].get_v3().get_index4()]]);
+	  //printf("%f %f %f %f %f %f %f %f %f\n",l1,l2,l3,l4,l5,l1-l2,l1-l3,l1-l4,l1-l5);
+	}
+	if(clipped[i].get_v4().get_category()==1){
+	  l1 = (clipped[i].get_v4().get_point()).distance(clipped[i].get_v1().get_point());
+	  l2 = (clipped[i].get_v4().get_point()).distance(generators[IDs[clipped[i].get_v4().get_index1()]]);
+	  l3 = (clipped[i].get_v4().get_point()).distance(generators[IDs[clipped[i].get_v4().get_index2()]]);
+	  l4 = (clipped[i].get_v4().get_point()).distance(generators[IDs[clipped[i].get_v4().get_index3()]]);
+	  l5 = (clipped[i].get_v4().get_point()).distance(generators[IDs[clipped[i].get_v4().get_index4()]]);
+	  //printf("%f %f %f %f %f %f %f %f %f\n",l1,l2,l3,l4,l5,l1-l2,l1-l3,l1-l4,l1-l5);
+	}
+	clipped[i].compute_jacobian();
+	volume2 = volume2 + fabs(clipped[i].get_jacobian())/6.0;
+  }
+  //printf("%f %f\n",volume1,volume2);
+	
+  for(i=0;i<pointers.size();i++) delete pointers[i];
+}
+
+double clip::min(double a,double b){
+  if(a<b) return a;
+  else return b;
+}
+
+double clip::max(double a,double b){
+  if(a>b) return a;
+  else return b;
+}
+
+int clip::category(int a,int b,int c,int d)
+{
+  int count;
+  count = 0;
+  if(a<0) count++;
+  if(b<0) count++;
+  if(c<0) count++;
+  if(d<0) count++;
+  if(count==0) return 1;
+  else if(count==1) return 2;
+  else if(count==2) return 3;
+  else return 4;
+}
+
+void clip::print_segment(SPoint3 p1,SPoint3 p2,std::ofstream& file){
+  file << "SL (" 
+  << p1.x() << ", " << p1.y() << ", " << p1.z() << ", "
+  << p2.x() << ", " << p2.y() << ", " << p2.z() 
+  << "){10, 20};\n";	
+}
\ No newline at end of file
diff --git a/Mesh/Voronoi3D.h b/Mesh/Voronoi3D.h
new file mode 100755
index 0000000000000000000000000000000000000000..d8b28456a27018dc91a734857ec92d7c81ef22e2
--- /dev/null
+++ b/Mesh/Voronoi3D.h
@@ -0,0 +1,21 @@
+// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include "GRegion.h"
+
+class VoronoiElement;
+
+class clip{
+ public:
+  clip();
+  ~clip();
+  void execute();
+  void execute(GRegion*);
+  void execute(std::vector<SPoint3>&,std::vector<VoronoiElement>&);
+  double min(double,double);
+  double max(double,double);
+  int category(int,int,int,int);
+  void print_segment(SPoint3,SPoint3,std::ofstream&);
+};
\ No newline at end of file