From 3b5957d61dfe8de458cf28db6b7a4724330a50a3 Mon Sep 17 00:00:00 2001
From: Akash Anand <akasha@iitk.ac.in>
Date: Wed, 14 May 2008 21:16:49 +0000
Subject: [PATCH] changes for FM

---
 Fltk/GUI_Projection.cpp  | 131 ++++++++++++++++++++++++---------------
 Geo/GModel.h             |   8 +++
 Geo/GModelIO_Fourier.cpp | 100 ++++++++++++++++++++++--------
 Geo/GModelIO_Fourier.h   |  25 +++++++-
 4 files changed, 185 insertions(+), 79 deletions(-)

diff --git a/Fltk/GUI_Projection.cpp b/Fltk/GUI_Projection.cpp
index 4d61d7a370..5228c966ad 100644
--- a/Fltk/GUI_Projection.cpp
+++ b/Fltk/GUI_Projection.cpp
@@ -17,6 +17,7 @@ extern Context_T CTX;
 #include "FM_BlendedPatch.h"
 #include "FM_BlendOperator.h"
 #include "FM_PlaneProjectionSurface.h"
+#include "FM_TrapezoidProjectionSurface.h"
 #include "FM_SphericalProjectionSurface.h"
 #include "FM_ParaboloidProjectionSurface.h"
 #include "FM_CylindricalProjectionSurface.h"
@@ -30,6 +31,8 @@ static fourierProjectionFace *createProjectionFaceFromName(const char *name)
   fourierProjectionFace *f = 0;
   if(!strcmp(name, "plane"))
     f = new fourierProjectionFace(m, tag, new FM::PlaneProjectionSurface(tag));
+  else if(!strcmp(name, "trapezoid"))
+    f = new fourierProjectionFace(m, tag, new FM::TrapezoidProjectionSurface(tag));
   else if(!strcmp(name, "sphere"))
     f = new fourierProjectionFace(m, tag, new FM::SphericalProjectionSurface(tag));
   else if(!strcmp(name, "paraboloid"))
@@ -226,6 +229,13 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
 
 projectionEditor::projectionEditor() 
 {
+  GModel *m = GModel::current();
+
+  // construct FM_Internals 
+  m->readFourier();
+  printf("readerSize = %d\n",m->getFMInternals()->getSize());
+  printf("currentSize = %d\n",m->getFMInternals()->current()->GetNumGroups());
+
   // construct GUI in terms of standard sizes
   const int BH = 2 * GetFontSize() + 1, BB = 7 * GetFontSize(), WB = 7;
   const int width = (int)(3.75 * BB), height = 25 * BH;
@@ -238,7 +248,7 @@ projectionEditor::projectionEditor()
   Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH);
   _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points");
   _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements");
-  if(GModel::current()->getNumMeshElements())
+  if(m->getNumMeshElements())
     _select[1]->value(1);
   else
     _select[0]->value(1);
@@ -389,6 +399,8 @@ projectionEditor::projectionEditor()
   _window->hotspot(_window);
   _window->resizable(_uvPlot);
   _window->size_range(width, (int)(0.85 * height));
+
+  // create
 }
 
 void projectionEditor::load(fourierProjectionFace *face, std::string tag)
@@ -901,6 +913,10 @@ void save_projection_cb(Fl_Widget *w, void *data)
 
 void compute_cb(Fl_Widget *w, void *data)
 {
+  GModel* m = GModel::current();
+
+  printf("ngroups = %d\n",m->getFMInternals()->current()->GetNumGroups());
+
   projectionEditor *e = (projectionEditor*)data;
 
   projection *p = e->getCurrentProjection();
@@ -930,48 +946,67 @@ void compute_cb(Fl_Widget *w, void *data)
     if (e->getPatchType()) {
       // create the US-FFT/Windowing faces (with boundaries)
       FM::Patch* patch =
-        new FM::WFPatch(0, ps->clone(), u, v, f, 3, uModes, vModes);
-      makeGFace(GModel::current(), patch);
+	new FM::WFPatch(0, ps->clone(), u, v, f, 3, uModes, vModes);
+      m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	AddPatch(patch);
+      m->getFMInternals()->makeGFace(patch,m);
+      //makeGFace(patch);
     }
     else {
       // create the Fourier faces (with boundaries)
       if(ps->IsUPeriodic()) {
-        FM::Patch* patchL = 
-          new FM::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(GModel::current(), patchL);
-        FM::Patch* patchR = 
-          new FM::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(GModel::current(), patchR);
+	FM::Patch* patchL = 
+	  new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+			 uM, vM, h0, h1, h2, h3);
+	patchL->SetMinU(-0.35);
+	patchL->SetMaxU(0.35);
+	m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	  AddPatch(patchL);
+	m->getFMInternals()->makeGFace(patchL,m);
+	//makeGFace(patchL);
+	FM::Patch* patchR = 
+	  new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
+			 uM, vM, h0, h1, h2, h3);
+	patchR->SetMinU(0.15);
+	patchR->SetMaxU(0.85);
+	m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	  AddPatch(patchR);
+	m->getFMInternals()->makeGFace(patchR,m);
+	//makeGFace(patchR);
       }
       else if (ps->IsVPeriodic()) {
-        FM::Patch* patchL = 
-          new FM::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(GModel::current(), patchL);
-        FM::Patch* patchR = 
-          new FM::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(GModel::current(), patchR);
+	FM::Patch* patchL = 
+	  new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+			 uM, vM, h0, h1, h2, h3);
+	patchL->SetMinV(-0.35);
+	patchL->SetMaxV(0.35);
+	m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	  AddPatch(patchL);
+	m->getFMInternals()->makeGFace(patchL,m);
+	//makeGFace(patchL);
+	FM::Patch* patchR = 
+	  new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
+			 uM, vM, h0, h1, h2, h3);
+	patchR->SetMinV(0.15);
+	patchR->SetMaxV(0.85);
+	m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	  AddPatch(patchR);
+	m->getFMInternals()->makeGFace(patchR,m);
+	//makeGFace(patchR);
       }
       else {
-        FM::Patch* patch = 
-          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
-                         uM, vM, h0, h1, h2, h3);
-        makeGFace(GModel::current(), patch);
+	FM::Patch* patch = 
+	  new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+			 uM, vM, h0, h1, h2, h3);
+	m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
+	  AddPatch(patch);
+	m->getFMInternals()->makeGFace(patch,m);
+	//makeGFace(patch);
       }
     }
   }
-
+  printf("nPatches = %d\n",m->getFMInternals()->current()->GetGroup(0)->
+	 GetBlendGroup()->GetNumPatches());
   Draw();
 }
 
@@ -995,27 +1030,22 @@ void delete_fourier(GFace *gf)
 
 void blend_cb(Fl_Widget *w, void *data)
 {
-  std::vector<GFace*> faces;
-  std::vector<FM::Patch*> patches;
-
   GModel *m = GModel::current();
 
-  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
-    if((*it)->getNativeType() == GEntity::FourierModel)
+  std::vector<GFace*> faces;
+  for (GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
+    if ((*it)->getNativeType() == GEntity::FourierModel)
       faces.push_back(*it);
-  for(unsigned int i = 0; i < faces.size(); i++){
-    fourierFace* ff = (fourierFace*)faces[i];
-    FM::TopoFace* tf = (FM::TopoFace*)ff->getNativePtr();
-    patches.push_back(tf->GetPatch());
-  }
-  FM::BlendOperator* blendOp = new FM::BlendOperator(patches);
-  for (unsigned int i = 0; i < patches.size(); i++) {
-    FM::BlendedPatch* patch = new FM::BlendedPatch(i, blendOp);
-    makeGFace(GModel::current(), patch);
-  }
-  for(unsigned int i = 0; i < faces.size(); i++) {
-    delete_fourier(faces[i]);
-    //faces[i]->setVisibility(0, true);
+
+  m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->Blend();
+  for (int i = 0; i < m->getFMInternals()->current()->GetGroup(0)->
+	 GetBlendGroup()->GetNumPatches(); i++)
+    m->getFMInternals()->makeGFace(m->getFMInternals()->current()->
+				   GetGroup(0)->GetBlendGroup()->
+				   GetPatch(i),m);
+  for (int i = 0; i < faces.size(); i++) {
+    //delete_fourier(faces[i]);
+    faces[i]->setVisibility(0, true);
   }
 }
 
@@ -1083,6 +1113,7 @@ void mesh_parameterize_cb(Fl_Widget* w, void* data)
   if(!editor){
     editor = new projectionEditor();
     editor->load(createProjectionFaceFromName("plane"));
+    editor->load(createProjectionFaceFromName("trapezoid"));
     editor->load(createProjectionFaceFromName("sphere"));
     editor->load(createProjectionFaceFromName("paraboloid"));
     editor->load(createProjectionFaceFromName("cylinder"));
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 34f10031a4..5da79fd8bc 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -29,6 +29,7 @@
 #include "GRegion.h"
 #include "SBoundingBox3d.h"
 
+class FM_Internals;
 class GEO_Internals;
 class OCC_Internals;
 class smooth_normals;
@@ -68,6 +69,10 @@ class GModel
   // index of the current model
   static int _current;
 
+  FM_Internals *_fm_internals;
+  void createFMInternals();
+  void deleteFMInternals();
+ 
  protected:
   std::string modelName;
   std::set<GRegion*, GEntityLessThan> regions;
@@ -95,6 +100,7 @@ class GModel
   void destroy();
 
   // Access internal CAD representations
+  FM_Internals *getFMInternals() { return _fm_internals; }
   GEO_Internals *getGEOInternals(){ return _geo_internals; }
   OCC_Internals *getOCCInternals(){ return _occ_internals; }
 
@@ -224,7 +230,9 @@ class GModel
   int writeGEO(const std::string &name, bool printLabels=true);
 
   // Fourier model
+  int readFourier();
   int readFourier(const std::string &name);
+  int writeFourier(const std::string &name);
 
   // OCC model
   int readOCCBREP(const std::string &name);
diff --git a/Geo/GModelIO_Fourier.cpp b/Geo/GModelIO_Fourier.cpp
index 4c100a7ddc..0b581492bd 100644
--- a/Geo/GModelIO_Fourier.cpp
+++ b/Geo/GModelIO_Fourier.cpp
@@ -9,13 +9,12 @@
 #if defined(HAVE_FOURIER_MODEL)
 
 #include "FM_FPatch.h"
-#include "FM_FCurve.h"
+#include "FM_PCurve.h"
 #include "FM_TopoVertex.h"
 #include "FM_TopoEdge.h"
 #include "FM_TopoFace.h"
-#include "FM_Reader.h"
 
-void makeGFace(GModel *m, FM::Patch* patch)
+void FM_Internals::makeGFace(FM::Patch* patch, GModel* model)
 {
   double LL[2], LR[2], UL[2], UR[2];
   LL[0] = 0.0; LL[1] = 0.0;
@@ -26,66 +25,106 @@ void makeGFace(GModel *m, FM::Patch* patch)
   int i1, i2;
   double xx,yy,zz;
 
-  int tagVertex = m->getNumVertices();
+  int tagVertex = model->getNumVertices();
   patch->F(LL[0], LL[1], xx, yy, zz);
   FM::TopoVertex* vLL = new FM::TopoVertex(++tagVertex, xx, yy, zz);
-  m->add(new fourierVertex(m, vLL->GetTag(), vLL));
+  model->add(new fourierVertex(model, vLL->GetTag(), vLL));
   patch->F(LR[0], LR[1], xx, yy, zz);
   FM::TopoVertex* vLR = new FM::TopoVertex(++tagVertex, xx, yy, zz);
-  m->add(new fourierVertex(m, vLR->GetTag(), vLR));
+  model->add(new fourierVertex(model, vLR->GetTag(), vLR));
   patch->F(UL[0], UL[1], xx, yy, zz);
   FM::TopoVertex* vUL = new FM::TopoVertex(++tagVertex, xx, yy, zz);
-  m->add(new fourierVertex(m, vUL->GetTag(), vUL));
+  model->add(new fourierVertex(model, vUL->GetTag(), vUL));
   patch->F(UR[0], UR[1], xx, yy, zz);
   FM::TopoVertex* vUR = new FM::TopoVertex(++tagVertex, xx, yy, zz);
-  m->add(new fourierVertex(m, vUR->GetTag(), vUR));
+  model->add(new fourierVertex(model, vUR->GetTag(), vUR));
   
-  FM::Curve* curveB = new FM::FCurve(0, patch, LL, LR);
-  FM::Curve* curveR = new FM::FCurve(0, patch, LR, UR);
-  FM::Curve* curveT = new FM::FCurve(0, patch, UR, UL);
-  FM::Curve* curveL = new FM::FCurve(0, patch, UL, LL);
+  FM::Curve* curveB = new FM::PCurve(LL, LR, patch);
+  FM::Curve* curveR = new FM::PCurve(LR, UR, patch);
+  FM::Curve* curveT = new FM::PCurve(UR, UL, patch);
+  FM::Curve* curveL = new FM::PCurve(UL, LL, patch);
   
-  int tagEdge = m->getNumEdges();
+  int tagEdge = model->getNumEdges();
   FM::TopoEdge* eB = new FM::TopoEdge(++tagEdge, curveB, vLL, vLR);
   i1 = eB->GetStartPoint()->GetTag();
   i2 = eB->GetEndPoint()->GetTag();
-  m->add(new fourierEdge(m, eB, eB->GetTag(), m->getVertexByTag(i1),
-                         m->getVertexByTag(i2)));
+  model->add(new fourierEdge(model, eB, eB->GetTag(), model->getVertexByTag(i1),
+			 model->getVertexByTag(i2)));
   FM::TopoEdge* eR = new FM::TopoEdge(++tagEdge, curveR, vLR, vUR); 
   i1 = eR->GetStartPoint()->GetTag();
   i2 = eR->GetEndPoint()->GetTag();
-  m->add(new fourierEdge(m, eR, eR->GetTag(), m->getVertexByTag(i1),
-                         m->getVertexByTag(i2))); 
+  model->add(new fourierEdge(model, eR, eR->GetTag(), model->getVertexByTag(i1),
+			 model->getVertexByTag(i2))); 
   FM::TopoEdge* eT = new FM::TopoEdge(++tagEdge, curveT, vUR, vUL);
   i1 = eT->GetStartPoint()->GetTag();
   i2 = eT->GetEndPoint()->GetTag();
-  m->add(new fourierEdge(m, eT, eT->GetTag(), m->getVertexByTag(i1),
-                         m->getVertexByTag(i2)));
+  model->add(new fourierEdge(model, eT, eT->GetTag(), model->getVertexByTag(i1),
+			 model->getVertexByTag(i2)));
   FM::TopoEdge* eL = new FM::TopoEdge(++tagEdge, curveL, vUL, vLL); 
   i1 = eL->GetStartPoint()->GetTag();
   i2 = eL->GetEndPoint()->GetTag();
-  m->add(new fourierEdge(m, eL, eL->GetTag(), m->getVertexByTag(i1),
-                         m->getVertexByTag(i2)));
+  model->add(new fourierEdge(model, eL, eL->GetTag(), model->getVertexByTag(i1),
+			 model->getVertexByTag(i2)));
   
-  FM::TopoFace* face = new FM::TopoFace(m->getNumFaces() + 1, patch);
+  FM::TopoFace* face = new FM::TopoFace(model->getNumFaces() + 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(m->getEdgeByTag(tag));
+    l_edges.push_back(model->getEdgeByTag(tag));
   }
-  m->add(new fourierFace(m, face, face->GetTag(), l_edges));
+  model->add(new fourierFace(model, face, face->GetTag(), l_edges));
 }
 
-int GModel::readFourier(const std::string &filename)
+void FM_Internals::loadFM()
+{
+  reader.push_back(new FM::Reader());
+}
+
+void FM_Internals::loadFM(const char* filename)
+{
+  reader.push_back(new FM::Reader(filename));
+}
+
+void FM_Internals::buildGModel(FM::Reader* reader, GModel* model)
 {
-  FM::Reader *reader = new FM::Reader(filename.c_str());
   for (int i = 0; i < reader->GetNumPatches(); i++)
-    makeGFace(this, reader->GetPatch(i));
+    makeGFace(reader->GetPatch(i), model);
+}
+
+void GModel::createFMInternals()
+{
+  if (!_fm_internals)
+    _fm_internals = new FM_Internals;  
+}
+
+void GModel::deleteFMInternals()
+{
+  delete _fm_internals;
+  _fm_internals = 0;
+}
+
+int GModel::readFourier()
+{
+  createFMInternals();
+  getFMInternals()->loadFM();
+}
+
+int GModel::readFourier(const std::string &filename)
+{
+  createFMInternals();
+  getFMInternals()->loadFM(filename.c_str());
+  getFMInternals()->buildGModel(getFMInternals()->current(),this);
+
   return 1;
 }
 
+int GModel::writeFourier(const std::string &filename)
+{
+  FILE *fp = fopen(filename.c_str(), "w");
+}
+
 #else
 
 int GModel::readFourier(const std::string &fn)
@@ -95,4 +134,11 @@ int GModel::readFourier(const std::string &fn)
   return 0;
 }
 
+int GModel::writeFourier(const std::string &fn)
+{
+  Msg(GERROR, "Gmsh has to be compiled with Fourier Model support to load '%s'",
+      fn.c_str());
+  return 0;
+}
+
 #endif
diff --git a/Geo/GModelIO_Fourier.h b/Geo/GModelIO_Fourier.h
index 605a99d0f3..c28d98f43c 100644
--- a/Geo/GModelIO_Fourier.h
+++ b/Geo/GModelIO_Fourier.h
@@ -1,13 +1,34 @@
 #ifndef _GMODEL_IO_FOURIER_H_
 #define _GMODEL_IO_FOURIER_H_
 
+#include <vector>
 #include "GModel.h"
 
 #if defined(HAVE_FOURIER_MODEL)
 
-#include "FM_Patch.h"
+#include "FM_Reader.h"
 
-void makeGFace(GModel *m, FM::Patch* patch);
+class FM_Internals {
+ private:
+  std::vector<FM::Reader*> reader;
+
+ public:
+  FM_Internals() {}
+  ~FM_Internals() {}
+
+  void loadFM();
+  void loadFM(const char* filename);
+  void makeGFace(FM::Patch* patch, GModel* model);
+  void buildGModel(FM::Reader* reater, GModel* model);
+
+  FM::Reader* getReader(int tag) 
+    { 
+      if (tag < reader.size())
+	return reader[tag]; 
+    }
+  int getSize() { return reader.size(); }
+  FM::Reader* current() { return reader[reader.size() - 1]; }
+};
 
 #endif
 
-- 
GitLab