diff --git a/Fltk/GUI_Projection.cpp b/Fltk/GUI_Projection.cpp
index 4676356b3c6b8d7646fbca271bfb51e91ebb5ae5..60ee12aca424281f36167c8252a5380c4837813a 100644
--- a/Fltk/GUI_Projection.cpp
+++ b/Fltk/GUI_Projection.cpp
@@ -3,12 +3,15 @@
 #include "Context.h"
 #include "SelectBuffer.h"
 #include "GUI_Projection.h"
+#include "FFace.h"
 
 extern GModel *GMODEL;
 extern Context_T CTX;
 
 #if defined(HAVE_FOURIER_MODEL)
 
+#include "FPatch.h"
+
 #define HARDCODED
 
 uvPlot::uvPlot(int x, int y, int w, int h, const char *l)
@@ -257,11 +260,14 @@ projectionEditor::projectionEditor(std::vector<FProjectionFace*> &faces)
   {
     int bb = (int)(0.37 * BB);
     new Fl_Box(WB, height - 3 * WB - 3 * BH, BB / 2, BH, "Delete:");
-    Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 3 * WB - 3 * BH, bb, BH, "last");
+    Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 3 * WB - 3 * BH, 
+				  bb, BH, "last");
     b1->callback(action_cb, (void*)"delete_last");
-    Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 3 * WB - 3 * BH, bb, BH, "all");
+    Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 3 * WB - 3 * BH,
+				  bb, BH, "all");
     b2->callback(action_cb, (void*)"delete_all");
-    Fl_Button *b3 = new Fl_Button(WB + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, bb, BH, "sel.");
+    Fl_Button *b3 = new Fl_Button(WB + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH,
+				  bb, BH, "sel.");
     b3->callback(action_cb, (void*)"delete_select");
   }
 
@@ -269,17 +275,22 @@ projectionEditor::projectionEditor(std::vector<FProjectionFace*> &faces)
     int bb = (int)(0.37 * BB);
     int s = width - WB - BB / 2 - 3 * bb;
     new Fl_Box(s, height - 3 * WB - 3 * BH, BB / 2, BH, "Save:");
-    Fl_Button *b1 = new Fl_Button(s + BB / 2, height - 3 * WB - 3 * BH, bb, BH, "last");
+    Fl_Button *b1 = new Fl_Button(s + BB / 2, height - 3 * WB - 3 * BH,
+				  bb, BH, "last");
     b1->callback(action_cb, (void*)"save_last");
-    Fl_Button *b2 = new Fl_Button(s + BB / 2 + bb, height - 3 * WB - 3 * BH, bb, BH, "all");
+    Fl_Button *b2 = new Fl_Button(s + BB / 2 + bb, height - 3 * WB - 3 * BH,
+				  bb, BH, "all");
     b2->callback(action_cb, (void*)"save_all");
-    Fl_Button *b3 = new Fl_Button(s + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH, bb, BH, "sel.");
+    Fl_Button *b3 = new Fl_Button(s + BB / 2 + 2 * bb, height - 3 * WB - 3 * BH,
+				  bb, BH, "sel.");
     b3->callback(action_cb, (void*)"save_select");
   }
 
   {
-    Fl_Button *b1 = new Fl_Button(WB, height - 2 * WB - 2 * BH, BB, BH, "Blend");
-    Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - 2 * WB - 2 * BH, BB, BH, "Intersect");
+    Fl_Button *b1 = new Fl_Button(WB, height - 2 * WB - 2 * BH, 
+				  BB, BH, "Blend");
+    Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - 2 * WB - 2 * BH, 
+				  BB, BH, "Intersect");
   }
 
   Fl_Button *b = new Fl_Button(width - WB - BB, height - WB - BH, BB, BH, "Cancel");
@@ -551,92 +562,54 @@ void compute_cb(Fl_Widget *w, void *data)
     e->uv()->get(u, v, dist, f);
     if(f.empty()) return;
 
+    int uModes = (int)e->modes[0]->value();
+    int vModes = (int)e->modes[1]->value();
+
+    if(f.size() < uModes * vModes){
+      Msg(GERROR, "Number of points < uModes * vModes");
+      return;
+    }
+
+    int uM = (int)e->modes[2]->value();
+    int vM = (int)e->modes[3]->value();
+    int h0 = e->hardEdges[0]->value();
+    int h1 = e->hardEdges[1]->value();
+    int h2 = e->hardEdges[2]->value();
+    int h3 = e->hardEdges[3]->value();
+
     // create the Fourier faces (with boundaries)
     ProjectionSurface *ps = p->face->GetProjectionSurface();
     if(ps->IsUPeriodic()) {
-      Patch* patchL = 
-	new FPatch(0,ps->clone(),u,v,f,3,(int)(e->modes[0]->value()),
-		   (int)(e->modes[1]->value()),(int)(e->modes[2]->value()), 
-		   (int)(e->modes[3]->value()), e->hardEdges[0]->value(), 
-		   e->hardEdges[1]->value(), e->hardEdges[2]->value(), 
-		   e->hardEdges[3]->value());
+      Patch* patchL = new FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
+				 uM, vM, h0, h1, h2, h3);
       patchL->SetMinU(-0.35);
       patchL->SetMaxU(0.35);
       makeGFace(patchL);
-
-      Patch* patchR = 
-	new FPatch(0,ps->clone(),u,v,f,3,(int)(e->modes[0]->value()),
-		   (int)(e->modes[1]->value()),(int)(e->modes[2]->value()), 
-		   (int)(e->modes[3]->value()), e->hardEdges[0]->value(), 
-		   e->hardEdges[1]->value(), e->hardEdges[2]->value(), 
-		   e->hardEdges[3]->value());
+      Patch* patchR = new FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
+				 uM, vM, h0, h1, h2, h3);
       patchR->SetMinU(0.15);
       patchR->SetMaxU(0.85);
       makeGFace(patchR);
     }
     else if (ps->IsVPeriodic()) {
-      Patch* patchL = 
-	new FPatch(0,ps->clone(),u,v,f,3,(int)(e->modes[0]->value()),
-		   (int)(e->modes[1]->value()),(int)(e->modes[2]->value()), 
-		   (int)(e->modes[3]->value()), e->hardEdges[0]->value(),
-		   e->hardEdges[1]->value(), e->hardEdges[2]->value(), 
-		   e->hardEdges[3]->value());
+      Patch* patchL = new FPatch(0,ps->clone(), u, v, f, 3, uModes, vModes, 
+				 uM, vM, h0, h1, h2, h3);
       patchL->SetMinV(-0.35);
       patchL->SetMaxV(0.35);
       makeGFace(patchL);
-
-      Patch* patchR = 
-	new FPatch(0,ps->clone(),u,v,f,3,(int)(e->modes[0]->value()),
-		   (int)(e->modes[1]->value()),(int)(e->modes[2]->value()), 
-		   (int)(e->modes[3]->value()), e->hardEdges[0]->value(),
-		   e->hardEdges[1]->value(), e->hardEdges[2]->value(), 
-		   e->hardEdges[3]->value());
+      Patch* patchR = new FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
+				 uM, vM, h0, h1, h2, h3);
       patchR->SetMinV(0.15);
       patchR->SetMaxV(0.85);
       makeGFace(patchR);
     }
     else {
-      Patch* patch = 
-	new FPatch(0,ps->clone(),u,v,f,3,(int)(e->modes[0]->value()),
-		   (int)(e->modes[1]->value()),(int)(e->modes[2]->value()), 
-		   (int)(e->modes[3]->value()), e->hardEdges[0]->value(), 
-		   e->hardEdges[1]->value(), e->hardEdges[2]->value(), 
-		   e->hardEdges[3]->value());
+      Patch* patch = new FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+				uM, vM, h0, h1, h2, h3);
       makeGFace(patch);
     }
   }
 
-  // IO Test Code
-  char *filename = "patches.fm";
-
-  FILE *fp = fopen(filename, "w+");
-  if(!fp){
-    printf("Unable to open file '%s'\n", filename);
-    return;
-  }
-
-  std::set<GFace*, GEntityLessThan>::iterator fiter;
-  int numFourierPatches = 0;
-  for (fiter = GMODEL->firstFace(); fiter != GMODEL->lastFace(); fiter++) {
-    if ((*fiter)->getNativeType() == GEntity::FourierModel) {
-      numFourierPatches++;
-    }
-  }
-  fprintf(fp, "%d\n", numFourierPatches);
-  for (fiter = GMODEL->firstFace(); fiter != GMODEL->lastFace(); fiter++) {
-    if ((*fiter)->getNativeType() == GEntity::FourierModel) {
-      FFace* ff = (FFace*) (*fiter);
-      ff->GetFMFace()->GetPatch()->Export(fp);
-    }
-  }
-  fclose(fp);
-
-  FM_Reader* reader = new FM_Reader(filename);
-  for (int i = 0; i < reader->GetNumPatches(); i++)
-    makeGFace(reader->GetPatch(i));
-
-  // End Test
-
   Draw();
 }
 
@@ -692,7 +665,18 @@ void action_cb(Fl_Widget *w, void *data)
     for(unsigned int i = 0; i < faces.size(); i++) delete_fourier(faces[i]);
   }
   else{
-    // call IO code
+    char *filename = "patches.fm";
+    FILE *fp = fopen(filename, "w+");
+    if(!fp){
+      printf("Unable to open file '%s'\n", filename);
+      return;
+    }
+    fprintf(fp, "%d\n", (int)faces.size());
+    for(unsigned int i = 0; i < faces.size(); i++){
+      FFace* ff = (FFace*)faces[i];
+      ff->GetFMFace()->GetPatch()->Export(fp);
+    }
+    fclose(fp);
   }
 
   Draw();
@@ -727,69 +711,6 @@ void mesh_parameterize_cb(Fl_Widget* w, void* data)
   editor->show();
 }
 
-void makeGFace(Patch* patch)
-{
-  double LL[2], LR[2], UL[2], UR[2];
-  LL[0] = 0.0; LL[1] = 0.0;
-  LR[0] = 1.0; LR[1] = 0.0;
-  UL[0] = 0.0; UL[1] = 1.0;
-  UR[0] = 1.0; UR[1] = 1.0;
-  
-  int i1, i2;
-  double xx,yy,zz;
-  
-  int tagVertex = GMODEL->numVertex();
-  patch->F(LL[0],LL[1],xx,yy,zz);
-  FM_Vertex* vLL = new FM_Vertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vLL->GetTag(),vLL));
-  patch->F(LR[0],LR[1],xx,yy,zz);
-  FM_Vertex* vLR = new FM_Vertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vLR->GetTag(),vLR));
-  patch->F(UL[0],UL[1],xx,yy,zz);
-  FM_Vertex* vUL = new FM_Vertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vUL->GetTag(),vUL));
-  patch->F(UR[0],UR[1],xx,yy,zz);
-  FM_Vertex* vUR = new FM_Vertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vUR->GetTag(),vUR));
-  
-  Curve* curveB = new FCurve(0,patch,LL,LR);
-  Curve* curveR = new FCurve(0,patch,LR,UR);
-  Curve* curveT = new FCurve(0,patch,UR,UL);
-  Curve* curveL = new FCurve(0,patch,UL,LL);
-  
-  int tagEdge = GMODEL->numEdge();
-  FM_Edge* eB = new FM_Edge(++tagEdge,curveB,vLL,vLR);
-  i1 = eB->GetStartPoint()->GetTag();
-  i2 = eB->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eB,eB->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
-  FM_Edge* eR = new FM_Edge(++tagEdge,curveR,vLR,vUR); 
-  i1 = eR->GetStartPoint()->GetTag();
-  i2 = eR->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eR,eR->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2))); 
-  FM_Edge* eT = new FM_Edge(++tagEdge,curveT,vUR,vUL);
-  i1 = eT->GetStartPoint()->GetTag();
-  i2 = eT->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eT,eT->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
-  FM_Edge* eL = new FM_Edge(++tagEdge,curveL,vUL,vLL); 
-  i1 = eL->GetStartPoint()->GetTag();
-  i2 = eL->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eL,eL->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
-  
-  FM_Face* face = new FM_Face(GMODEL->numFace() + 1,patch);
-  face->AddEdge(eB); face->AddEdge(eR); 
-  face->AddEdge(eT); face->AddEdge(eL);
-  std::list<GEdge*> l_edges;
-  for (int j=0;j<face->GetNumEdges();j++) {
-    int tag = face->GetEdge(j)->GetTag(); 
-    l_edges.push_back(GMODEL->edgeByTag(tag));
-  }
-  GMODEL->add(new FFace(GMODEL,face,face->GetTag(),l_edges));
-}
-
 #else
 
 void mesh_parameterize_cb(Fl_Widget* w, void* data)
diff --git a/Fltk/GUI_Projection.h b/Fltk/GUI_Projection.h
index 908845b98a87f6178899c0288dcb2b5120d576c2..a40acd895f238e18d70e5b1b93333bdf816151dd 100644
--- a/Fltk/GUI_Projection.h
+++ b/Fltk/GUI_Projection.h
@@ -4,6 +4,7 @@
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "GModel.h"
+#include "GModelIO_F.h"
 #include "GUI.h"
 #include "Shortcut_Window.h"
 #include "ColorTable.h"
@@ -15,16 +16,7 @@
 #include "Utils.h"
 #include <vector>
 #include <complex>
-#include "FVertex.h"
-#include "FEdge.h"
-#include "FFace.h"
-#include "FPatch.h"
-#include "FCurve.h"
 #include "FProjectionFace.h"
-#include "FM_Vertex.h"
-#include "FM_Edge.h"
-#include "FM_Face.h"
-#include "FM_Reader.h"
 
 void select_cb(Fl_Widget *w, void *data);
 void filter_cb(Fl_Widget *w, void *data);
@@ -36,8 +28,6 @@ void save_cb(Fl_Widget *w, void *data);
 void compute_cb(Fl_Widget *w, void *data);
 void action_cb(Fl_Widget *w, void *data);
 
-void makeGFace(Patch* patch);
-
 class uvPlot : public Fl_Window {
  private:
   std::vector<double> _u, _v, _dist;
diff --git a/Geo/GModelIO_F.cpp b/Geo/GModelIO_F.cpp
index 574fa46b4c16b52b6a286941e5be791066c58953..778d5a94a04546e7007777bf0b086e2f7de6fbe9 100644
--- a/Geo/GModelIO_F.cpp
+++ b/Geo/GModelIO_F.cpp
@@ -1,62 +1,91 @@
 #include <string>
 #include "GModel.h"
 #include "Message.h"
-#include "Context.h"
-#include "Views.h"
 #include "FFace.h"
-#include "meshGFace.h" 
 #include "GModelIO_F.h"
 
 #if defined(HAVE_FOURIER_MODEL)
 
+#include "FVertex.h"
+#include "FEdge.h"
+#include "FFace.h"
+#include "FPatch.h"
+#include "FCurve.h"
+#include "FM_Vertex.h"
+#include "FM_Edge.h"
+#include "FM_Face.h"
+#include "FM_Reader.h"
 
-extern Context_T CTX;
-
-void F_Internals::loadF(const char *fn)
-{
-  _reader = new FM_Reader((char*)fn);
-}
+extern GModel *GMODEL;
 
-void F_Internals::buildGModel(GModel *model)
+void makeGFace(Patch* patch)
 {
-/*
-  // building geom vertices
-  int nVertices = _reader->GetNumVertices();
-  for (int i=0;i<nVertices;i++) {
-    FVertex* v = new FVertex(model,i,_reader->GetVertex(i));
-    model->add(v);
+  double LL[2], LR[2], UL[2], UR[2];
+  LL[0] = 0.0; LL[1] = 0.0;
+  LR[0] = 1.0; LR[1] = 0.0;
+  UL[0] = 0.0; UL[1] = 1.0;
+  UR[0] = 1.0; UR[1] = 1.0;
+  
+  int i1, i2;
+  double xx,yy,zz;
+  
+  int tagVertex = GMODEL->numVertex();
+  patch->F(LL[0],LL[1],xx,yy,zz);
+  FM_Vertex* vLL = new FM_Vertex(++tagVertex,xx,yy,zz);
+  GMODEL->add(new FVertex(GMODEL,vLL->GetTag(),vLL));
+  patch->F(LR[0],LR[1],xx,yy,zz);
+  FM_Vertex* vLR = new FM_Vertex(++tagVertex,xx,yy,zz);
+  GMODEL->add(new FVertex(GMODEL,vLR->GetTag(),vLR));
+  patch->F(UL[0],UL[1],xx,yy,zz);
+  FM_Vertex* vUL = new FM_Vertex(++tagVertex,xx,yy,zz);
+  GMODEL->add(new FVertex(GMODEL,vUL->GetTag(),vUL));
+  patch->F(UR[0],UR[1],xx,yy,zz);
+  FM_Vertex* vUR = new FM_Vertex(++tagVertex,xx,yy,zz);
+  GMODEL->add(new FVertex(GMODEL,vUR->GetTag(),vUR));
+  
+  Curve* curveB = new FCurve(0,patch,LL,LR);
+  Curve* curveR = new FCurve(0,patch,LR,UR);
+  Curve* curveT = new FCurve(0,patch,UR,UL);
+  Curve* curveL = new FCurve(0,patch,UL,LL);
+  
+  int tagEdge = GMODEL->numEdge();
+  FM_Edge* eB = new FM_Edge(++tagEdge,curveB,vLL,vLR);
+  i1 = eB->GetStartPoint()->GetTag();
+  i2 = eB->GetEndPoint()->GetTag();
+  GMODEL->add(new FEdge(GMODEL,eB,eB->GetTag(),GMODEL->vertexByTag(i1),
+			GMODEL->vertexByTag(i2)));
+  FM_Edge* eR = new FM_Edge(++tagEdge,curveR,vLR,vUR); 
+  i1 = eR->GetStartPoint()->GetTag();
+  i2 = eR->GetEndPoint()->GetTag();
+  GMODEL->add(new FEdge(GMODEL,eR,eR->GetTag(),GMODEL->vertexByTag(i1),
+			GMODEL->vertexByTag(i2))); 
+  FM_Edge* eT = new FM_Edge(++tagEdge,curveT,vUR,vUL);
+  i1 = eT->GetStartPoint()->GetTag();
+  i2 = eT->GetEndPoint()->GetTag();
+  GMODEL->add(new FEdge(GMODEL,eT,eT->GetTag(),GMODEL->vertexByTag(i1),
+			GMODEL->vertexByTag(i2)));
+  FM_Edge* eL = new FM_Edge(++tagEdge,curveL,vUL,vLL); 
+  i1 = eL->GetStartPoint()->GetTag();
+  i2 = eL->GetEndPoint()->GetTag();
+  GMODEL->add(new FEdge(GMODEL,eL,eL->GetTag(),GMODEL->vertexByTag(i1),
+			GMODEL->vertexByTag(i2)));
+  
+  FM_Face* face = new FM_Face(GMODEL->numFace() + 1,patch);
+  face->AddEdge(eB); face->AddEdge(eR); 
+  face->AddEdge(eT); face->AddEdge(eL);
+  std::list<GEdge*> l_edges;
+  for (int j=0;j<face->GetNumEdges();j++) {
+    int tag = face->GetEdge(j)->GetTag(); 
+    l_edges.push_back(GMODEL->edgeByTag(tag));
   }
-  // building geom edges
-  int nEdges = _reader->GetNumEdges();
-  for (int i=0;i<nEdges;i++) {
-    FM_Edge* edge = _reader->GetEdge(i);
-    int i1 = edge->GetStartPoint()->GetTag();
-    int i2 = edge->GetEndPoint()->GetTag();
-    GVertex *v1 = model->vertexByTag(i1);
-    GVertex *v2 = model->vertexByTag(i2);
-    FEdge *e = new FEdge(model, edge, i, v1, v2);
-    model->add(e);
-  }
-  // building geom faces
-  int nFaces = _reader->GetNumFaces();
-  for(int i=0;i<nFaces;i++){
-    FM_Face* face = _reader->GetFace(i);
-    std::list<GEdge*> l_edges;
-    for (int j=0;j<face->GetNumEdges();j++) {
-      int tag = face->GetEdge(j)->GetTag(); 
-     l_edges.push_back(model->edgeByTag(tag));
-    }
-    FFace *f = new FFace(model, face, i, l_edges);
-    model->add(f);
-  }
-*/
+  GMODEL->add(new FFace(GMODEL,face,face->GetTag(),l_edges));
 }
 
-int GModel::readF(const std::string &fn)
+int GModel::readF(const std::string &filename)
 {
-  f_internals = new F_Internals;
-  f_internals->loadF(fn.c_str());
-  f_internals->buildGModel(this);
+  FM_Reader* reader = new FM_Reader(filename.c_str());
+  for (int i = 0; i < reader->GetNumPatches(); i++)
+    makeGFace(reader->GetPatch(i));
 
   return 1;
 }
diff --git a/Geo/GModelIO_F.h b/Geo/GModelIO_F.h
index d32867b2f58bb2eac534d5a50805b6fc11882abf..584e492afe6929c52ea06bac1a4d4cfebad310d6 100644
--- a/Geo/GModelIO_F.h
+++ b/Geo/GModelIO_F.h
@@ -5,16 +5,10 @@
 
 #if defined(HAVE_FOURIER_MODEL)
 
-#include "FM_Reader.h"
+#include "Patch.h"
 
-class F_Internals {
- protected:
-  FM_Reader* _reader;
- public:
-  F_Internals() : _reader(0) {}
-  void loadF(const char *);
-  void buildGModel(GModel *gm);
-};
+void makeGFace(Patch* patch);
 
 #endif
+
 #endif