diff --git a/CMakeLists.txt b/CMakeLists.txt
index b4b01bdf2af890a977bafc39a94399f84ae38b93..cb478406c11f61f9d6a1cb0d78591d908c9da4a9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -125,6 +125,7 @@ set(GMSH_API
     Geo/SPoint2.h Geo/SPoint3.h Geo/SVector3.h Geo/STensor3.h Geo/SBoundingBox3d.h 
     Geo/Pair.h Geo/Range.h Geo/SOrientedBoundingBox.h 
     Geo/CellComplex.h Geo/ChainComplex.h Geo/Cell.h Geo/Homology.h Geo/Chain.h 
+    Geo/GenericVertex.h Geo/GenericEdge.h Geo/GenericFace.h Geo/GenericRegion.h
     Geo/partitionEdge.h Geo/CGNSOptions.h Geo/gmshLevelset.h Geo/boundaryLayersData.h
   Mesh/meshGEdge.h Mesh/meshGFace.h Mesh/meshGFaceOptimize.h 
     Mesh/meshGFaceElliptic.h Mesh/meshPartition.h Mesh/meshGFaceDelaunayInsertion.h 
diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt
index ed90152c76c7a16f9211fc93c3f62f4a3ae822ed..78bae5b48cf5cbde67f700cbff8a66fc419726dc 100644
--- a/Geo/CMakeLists.txt
+++ b/Geo/CMakeLists.txt
@@ -14,6 +14,7 @@ set(SRC
     gmshVertex.cpp gmshEdge.cpp gmshFace.cpp gmshRegion.cpp
    gmshSurface.cpp
    OCCVertex.cpp OCCEdge.cpp OCCFace.cpp OCCRegion.cpp
+   GenericVertex.cpp GenericEdge.cpp GenericFace.cpp GenericRegion.cpp
     discreteEdge.cpp discreteFace.cpp discreteRegion.cpp
     fourierEdge.cpp fourierFace.cpp fourierProjectionFace.cpp
   ACISVertex.cpp
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index b120b83799c8864166b947ece032e4780409649d..4ec679f7605cad11efef20b3592b9ed75f5f26fa 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -65,6 +65,7 @@ class GEntity {
     GmshModel,
     FourierModel,
     OpenCascadeModel,
+    GenericModel,
     AcisModel
   };
 
@@ -239,6 +240,9 @@ class GEntity {
 
   // get the native pointer of the particular representation
   virtual void *getNativePtr() const { return 0; }
+  
+  // get the native id (int) of the particular representation
+  virtual int getNativeInt() const { return 0; }
 
   // the model owning this entity
   GModel *model() const { return _model; }
diff --git a/Geo/GenericEdge.cpp b/Geo/GenericEdge.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53af6e71a781ede4985fd67e755f695b9fad1d8f
--- /dev/null
+++ b/Geo/GenericEdge.cpp
@@ -0,0 +1,162 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#include <limits>
+#include "GmshConfig.h"
+#include "GmshMessage.h"
+#include "GModel.h"
+#include "GenericEdge.h"
+#include "GenericFace.h"
+#include "Context.h"
+
+//------------------------------------------------------------------------
+
+GenericEdge::ptrfunction_int_double_refvector GenericEdge::EdgeEvalXYZFromT = NULL;
+GenericEdge::ptrfunction_int_refdouble_refdouble GenericEdge::EdgeEvalParBounds = NULL;
+GenericEdge::ptrfunction_int_refstring GenericEdge::EdgeGeomType = NULL;
+GenericEdge::ptrfunction_int_refbool GenericEdge::EdgeDegenerated = NULL;
+GenericEdge::ptrfunction_int_double_refvector GenericEdge::EdgeEvalFirstDer = NULL;
+GenericEdge::ptrfunction_int_double_refdouble GenericEdge::EdgeEvalCurvature = NULL;
+GenericEdge::ptrfunction_int_refvector_refdouble_refvector_refbool GenericEdge::EdgeClosestPoint = NULL;
+GenericEdge::ptrfunction_int_refbool GenericEdge::EdgeIs3D = NULL;
+GenericEdge::ptrfunction_int_int_double_int_refvector GenericEdge::EdgeReparamOnFace = NULL;
+
+//------------------------------------------------------------------------
+
+GenericEdge::GenericEdge(GModel *m, int num, int _native_id, GVertex *v1, GVertex *v2):GEdge(m, num, v1, v2), id(_native_id){
+  if ((!EdgeEvalParBounds)||(!EdgeEvalXYZFromT)) Msg::Error("GenericEdge::ERROR: Callback not set");
+  bool ok = EdgeEvalParBounds(id,s0,s1);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalParBounds ! " );
+}
+
+//------------------------------------------------------------------------
+
+GenericEdge::~GenericEdge(){
+}
+
+//------------------------------------------------------------------------
+
+Range<double> GenericEdge::parBounds(int i) const{
+  return Range<double>(s0, s1);
+}
+
+//------------------------------------------------------------------------
+
+SPoint2 GenericEdge::reparamOnFace(const GFace *face, double par, int dir) const{
+  vector<double> res(2,0.);
+  if (!EdgeReparamOnFace) Msg::Error("GenericEdge::ERROR: Callback EdgeReparamOnFace not set");
+  bool ok = EdgeReparamOnFace(id,face->getNativeInt(),par, dir,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeReparamOnFace ! " );
+  return SPoint2(res[0],res[1]);;
+}
+
+//------------------------------------------------------------------------
+
+GPoint GenericEdge::closestPoint(const SPoint3 &qp, double &param) const{
+  vector<double> queryPoint(3,0.);
+  for (int i=0;i<3;i++) queryPoint[i] = qp[i];
+  vector<double> res(3,0.);
+  bool is_on_edge;
+  if (!EdgeClosestPoint) Msg::Error("GenericEdge::ERROR: Callback EdgeClosestPoint not set");
+  bool ok = EdgeClosestPoint(id,queryPoint,param,res,is_on_edge);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeClosestPoint ! " );
+  if (!is_on_edge) Msg::Warning("WARNING:GenericEdge::closestPoint closest point NOT on edge, out of bounds ! " );
+  return GPoint(res[0], res[1], res[2], this, param);
+}
+
+//------------------------------------------------------------------------
+
+// True if the edge is a seam for the given face
+bool GenericEdge::isSeam(const GFace *face) const{
+  Msg::Error("GenericEdge::isSeam: not implemented yet ! ");
+  return false;
+}
+
+//------------------------------------------------------------------------
+
+GPoint GenericEdge::point(double par) const{
+  vector<double> res(3,0.);
+  if (!EdgeEvalXYZFromT) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalXYZFromT not set");
+  bool ok = EdgeEvalXYZFromT(id,par,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalXYZFromT ! " );
+  return GPoint(res[0], res[1], res[2], this, par);
+}
+
+//------------------------------------------------------------------------
+
+SVector3 GenericEdge::firstDer(double par) const{
+  vector<double> res(3,0.);
+  if (!EdgeEvalFirstDer) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalFirstDer not set");
+  bool ok = EdgeEvalFirstDer(id,par,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalFirstDer ! " );
+  return SVector3(res[0],res[1],res[2]);
+}
+
+//------------------------------------------------------------------------
+
+GEntity::GeomType GenericEdge::geomType() const{
+  string s;
+  if (!EdgeGeomType) Msg::Error("GenericEdge::ERROR: Callback EdgeGeomType not set");
+  bool ok = EdgeGeomType(id,s);
+  if (!ok){
+    Msg::Error("GenericEdge::ERROR from EdgeGeomType ! " );
+    return Unknown;
+  }
+
+  if(s.compare("Line")==0)
+    return Line;
+  else if(s.compare("Circle")==0)
+    return Circle;
+  else if(s.compare("Ellipse")==0)
+    return Ellipse;
+  else if(s.compare("Parabola")==0)
+    return Parabola;
+  else if(s.compare("Hyperbola")==0)
+    return Hyperbola;
+  else if(s.compare("Bezier")==0)
+    return Bezier;
+  else if(s.compare("BSpline")==0)
+    return BSpline;
+  else if(s.compare("TrimmedCurve")==0)
+    return TrimmedCurve;
+
+  Msg::Warning("GenericEdge::geomType:: unknown type from callback: ", s.c_str());
+
+  return Unknown;
+}
+
+//------------------------------------------------------------------------
+
+double GenericEdge::curvature(double par) const{
+  double res;
+  if (!EdgeEvalCurvature) Msg::Error("GenericEdge::ERROR: Callback EdgeEvalCurvature not set");
+  bool ok = EdgeEvalCurvature(id,par,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeEvalCurvature ! " );
+  return res;
+}
+
+//------------------------------------------------------------------------
+
+bool GenericEdge::is3D() const{
+  bool res;
+  if (!EdgeIs3D) Msg::Error("GenericEdge::ERROR: Callback EdgeIs3D not set");
+  bool ok = EdgeIs3D(id,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeIs3D ! " );
+  return res;
+}
+
+//------------------------------------------------------------------------
+
+bool GenericEdge::degenerate(int) const{
+  bool res;
+  if (!EdgeDegenerated) Msg::Error("GenericEdge::ERROR: Callback EdgeDegenerated not set");
+  bool ok = EdgeDegenerated(id,res);
+  if (!ok) Msg::Error("GenericEdge::ERROR from EdgeDegenerated ! " );
+  return res;
+}
+
+//------------------------------------------------------------------------
+
+
diff --git a/Geo/GenericEdge.h b/Geo/GenericEdge.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd29aadadb2ce4e99e7d298bc3d496c72aa96a30
--- /dev/null
+++ b/Geo/GenericEdge.h
@@ -0,0 +1,85 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _GENERIC_EDGE_H
+#define _GENERIC_EDGE_H
+
+#include "GmshConfig.h"
+#include "GEdge.h"
+#include "GModel.h"
+#include "GenericVertex.h"
+#include "Range.h"
+#include <vector>
+
+using namespace std;
+
+class GenericFace;
+
+/*The set of Generic Entities is a generic interface to any other modeler.
+  Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */
+
+class GenericEdge : public GEdge {
+  protected:
+    double s0, s1;
+    int id;
+  public:
+    // callbacks typedef
+    typedef bool (*ptrfunction_int_double_refvector)(int, double, vector<double>&);
+    typedef bool (*ptrfunction_int_refdouble_refdouble)(int, double&, double&);
+    typedef bool (*ptrfunction_int_double_refdouble)(int, double, double&);
+    typedef bool (*ptrfunction_int_refstring)(int, string&);
+    typedef bool (*ptrfunction_int_refbool)(int, bool&);
+    typedef bool (*ptrfunction_int_refvector_refdouble_refvector_refbool)(int, const vector<double> &, double &, vector<double>&, bool &);
+    typedef bool (*ptrfunction_int_int_double_int_refvector)(int, int, double, int, vector<double> &);
+
+    GenericEdge(GModel *model, int num,int _native_id, GVertex *v1, GVertex *v2);
+    virtual ~GenericEdge();
+
+    virtual Range<double> parBounds(int i) const;
+    virtual GeomType geomType() const;
+    virtual bool degenerate(int) const;
+    virtual GPoint point(double p) const;
+    virtual SVector3 firstDer(double par) const;
+    virtual double curvature (double par) const;
+    virtual SPoint2 reparamOnFace(const GFace *face, double epar, int dir) const;
+    virtual GPoint closestPoint(const SPoint3 &queryPoint, double &param) const;
+
+    ModelType getNativeType() const { return GenericModel; }
+    virtual int getNativeInt()const{return id;};
+
+    bool is3D() const;
+    bool isSeam(const GFace *) const;
+
+    // sets the callbacks, to be given by the user
+    static void setEdgeEvalXYZFromT(ptrfunction_int_double_refvector fct){EdgeEvalXYZFromT = fct;};
+    static void setEdgeEvalParBounds(ptrfunction_int_refdouble_refdouble fct){EdgeEvalParBounds = fct;};
+    static void setEdgeGeomType(ptrfunction_int_refstring fct){EdgeGeomType = fct;};
+    static void setEdgeDegenerated(ptrfunction_int_refbool fct){EdgeDegenerated = fct;};
+    static void setEdgeEvalFirstDer(ptrfunction_int_double_refvector fct){EdgeEvalFirstDer = fct;};
+    static void setEdgeEvalCurvature(ptrfunction_int_double_refdouble fct){EdgeEvalCurvature = fct;};
+    static void setEdgeClosestPoint(ptrfunction_int_refvector_refdouble_refvector_refbool fct){EdgeClosestPoint = fct;};
+    static void setEdgeIs3D(ptrfunction_int_refbool fct){EdgeIs3D = fct;};
+    static void setEdgeReparamOnFace(ptrfunction_int_int_double_int_refvector fct){EdgeReparamOnFace = fct;};
+
+  private:
+    // the callbacks:
+    // --------------
+    static ptrfunction_int_double_refvector EdgeEvalXYZFromT;
+    static ptrfunction_int_refdouble_refdouble EdgeEvalParBounds;
+    static ptrfunction_int_refstring EdgeGeomType;
+    static ptrfunction_int_refbool EdgeDegenerated;
+    static ptrfunction_int_double_refvector EdgeEvalFirstDer;
+    static ptrfunction_int_double_refdouble EdgeEvalCurvature;
+    // the first vector is a query point xyz, fills the second vector with closest point 
+    // on edge using orthogonal projection.  Fills double param with parametric coordinate of end point projection.
+    static ptrfunction_int_refvector_refdouble_refvector_refbool EdgeClosestPoint;
+    static ptrfunction_int_refbool EdgeIs3D;
+    static ptrfunction_int_int_double_int_refvector EdgeReparamOnFace;
+
+
+};
+
+
+#endif
diff --git a/Geo/GenericFace.cpp b/Geo/GenericFace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3046436973158c188c6fea287e1e076e63347f51
--- /dev/null
+++ b/Geo/GenericFace.cpp
@@ -0,0 +1,244 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#include "GmshConfig.h"
+#include "GmshMessage.h"
+#include "GModel.h"
+#include "GEdgeLoop.h"
+#include "GenericVertex.h"
+#include "GenericEdge.h"
+#include "GenericFace.h"
+#include "Numeric.h"
+#include "Context.h"
+#include <math.h>
+
+
+//------------------------------------------------------------------------
+
+GenericFace::ptrfunction_int_refstring GenericFace::FaceGeomType = NULL;
+GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceUVFromXYZ = NULL;
+GenericFace::ptrfunction_int_refvector_refvector_refvector GenericFace::FaceClosestPoint = NULL;
+GenericFace::ptrfunction_int_refvector_refbool GenericFace::FaceContainsPointFromXYZ = NULL;
+GenericFace::ptrfunction_int_refvector_refbool GenericFace::FaceContainsPointFromUV = NULL;
+GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceXYZFromUV = NULL;
+GenericFace::ptrfunction_int_int_refdouble_refdouble GenericFace::FaceParBounds = NULL;
+GenericFace::ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble GenericFace::FaceCurvatures = NULL;
+GenericFace::ptrfunction_int_refvector_refvector GenericFace::FaceEvalNormal = NULL;
+GenericFace::ptrfunction_int_refvector_refvector_refvector GenericFace::FaceFirstDer = NULL;
+GenericFace::ptrfunction_int_refvector_refvector_refvector_refvector GenericFace::FaceSecondDer = NULL;
+
+//------------------------------------------------------------------------
+
+GenericFace::GenericFace(GModel *m, int num, int _native_id):GFace(m, num), id(_native_id){
+  if (!FaceParBounds) Msg::Fatal("Genericface::ERROR: Callback FaceParBounds not set");
+  Range<double> rangeu = parBounds(0);
+  Range<double> rangev = parBounds(1);
+  umin = rangeu.low();
+  umax = rangeu.high();
+  vmin = rangev.low();
+  vmax = rangev.high();
+  
+  // TODO: set periodic or not !!!
+  //bool _periodic[2];// is periodic in u, v
+//  throw;
+}
+
+//------------------------------------------------------------------------
+
+GenericFace::~GenericFace(){
+}
+
+//------------------------------------------------------------------------
+
+Range<double> GenericFace::parBounds(int i) const{
+  if(i == 0) return Range<double>(umin, umax);
+  return Range<double>(vmin, vmax);
+}
+
+//------------------------------------------------------------------------
+
+SVector3 GenericFace::normal(const SPoint2 &param) const{
+  vector<double> res(3,0.);
+  vector<double> par(2,0.);
+  for (int i=0;i<3;i++) par[i] = param[i];
+  if (!FaceEvalNormal) Msg::Fatal("Genericface::ERROR: Callback FaceEvalNormal not set");
+  bool ok = FaceEvalNormal(id,par,res);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceEvalNormal ! " );
+  return SVector3(res[0],res[1],res[2]);
+}
+
+//------------------------------------------------------------------------
+
+Pair<SVector3,SVector3> GenericFace::firstDer(const SPoint2 &param) const{
+  if (!FaceFirstDer) Msg::Fatal("Genericface::ERROR: Callback FaceFirstDer not set");
+  vector<double> deru(3,0.);
+  vector<double> derv(3,0.);
+  vector<double> par(2,0.);
+  for (int i=0;i<3;i++) par[i] = param[i];
+  bool ok = FaceFirstDer(id,par,deru,derv);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceFirstDer ! " );
+  return Pair<SVector3,SVector3>(SVector3(deru[0],deru[1],deru[2]),
+                                 SVector3(derv[0],derv[1],derv[2]));
+}
+
+//------------------------------------------------------------------------
+
+void GenericFace::secondDer(const SPoint2 &param,SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const{
+  vector<double> deruu(3,0.);
+  vector<double> dervv(3,0.);
+  vector<double> deruv(3,0.);
+  vector<double> par(2,0.);
+  for (int i=0;i<3;i++) par[i] = param[i];
+  if (!FaceSecondDer) Msg::Fatal("Genericface::ERROR: Callback FaceSecondDer not set");
+  bool ok = FaceSecondDer(id,par,deruu,dervv,deruv);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceSecondDer ! " );
+  *dudu = SVector3(deruu[0],deruu[1],deruu[2]);
+  *dvdv = SVector3(dervv[0],dervv[1],dervv[2]);
+  *dudv = SVector3(deruv[0],deruv[1],deruv[2]);
+  return;
+}
+
+//------------------------------------------------------------------------
+
+GPoint GenericFace::point(double par1, double par2) const{
+  vector<double> uv(2,0.);
+  uv[0] = par1;
+  uv[1] = par2;
+  vector<double> xyz(3,0.);
+  if (!FaceXYZFromUV) Msg::Fatal("Genericface::ERROR: Callback FaceXYZFromUV not set");
+  bool ok = FaceXYZFromUV(id,uv,xyz);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceXYZFromUV ! " );
+  double pp[2] = {par1, par2};
+  return GPoint(xyz[0], xyz[1], xyz[2], this, pp);
+}
+
+//------------------------------------------------------------------------
+
+GPoint GenericFace::closestPoint(const SPoint3 &qp, const double initialGuess[2]) const{
+  vector<double> uvres(2,0.);
+  vector<double> xyzres(3,0.);
+  vector<double> queryPoint(3,0.);
+  for (int i=0;i<3;i++) queryPoint[i] = qp[i];
+  if (!FaceClosestPoint) Msg::Fatal("Genericface::ERROR: Callback FaceClosestPoint not set");
+  bool ok = FaceClosestPoint(id,queryPoint,xyzres,uvres);// orthogonal projection
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceClosestPoint ! " );
+
+  // check if the projected point lies on the face...
+  bool on_the_face;
+
+  //  ok = FaceContainsPointFromXYZ(id,xyzres,on_the_face);// check if the projected point lies on the face...
+  //  if (!ok) cout << "ERROR from FaceContainsPointFromXYZ ! " << endl;
+  //  if (!on_the_face) cout << "GenericFace::closestPoint::WARNING (using XYZ) !!!! The returned point does not lies on the face ! " << endl;
+
+  if (!FaceContainsPointFromUV) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromUV not set");
+  ok = FaceContainsPointFromUV(id,uvres,on_the_face);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromUV ! " );
+  if (!on_the_face) Msg::Warning("GenericFace::closestPoint::Warning (using UV)  !!!! The returned point does not lies on the face ! " );
+  double pp[2] = {uvres[0], uvres[1]};
+  return GPoint(xyzres[0], xyzres[1], xyzres[2], this, pp);
+}
+
+//------------------------------------------------------------------------
+
+SPoint2 GenericFace::parFromPoint(const SPoint3 &qp, bool onSurface) const{
+  vector<double> uvres(2,0.);
+  vector<double> xyzres(3,0.);
+  vector<double> queryPoint(3,0.);
+  for (int i=0;i<3;i++) queryPoint[i] = qp[i];
+  bool ok=true;
+  if (onSurface){
+    if (!FaceUVFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceUVFromXYZ not set");
+    ok = FaceUVFromXYZ(id,queryPoint,uvres);// assuming point is on surface 
+    if (!ok) Msg::Error("GenericFace::ERROR from FaceUVFromXYZ ! " );
+  }
+  if ((!onSurface)||(!ok)){// if not on surface
+    if (!FaceClosestPoint) Msg::Fatal("Genericface::ERROR: Callback FaceClosestPoint not set");
+    ok = FaceClosestPoint(id,queryPoint,xyzres,uvres);// orthogonal projection
+    if (!ok) Msg::Error("GenericFace::ERROR from FaceClosestPoint ! " );
+    bool on_the_face;
+    if (!FaceContainsPointFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromXYZ not set");
+    ok = FaceContainsPointFromXYZ(id,xyzres,on_the_face);// check if the projected point lies on the face...
+    if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromXYZ ! " );
+    if (!on_the_face) Msg::Warning("GenericFace::parFromPoint::Warning !!!! The returned point does not lies on the face ! " );
+  }
+  return SPoint2(uvres[0],uvres[1]);
+}
+
+//------------------------------------------------------------------------
+
+GEntity::GeomType GenericFace::geomType() const{
+  string s;
+  if (!FaceGeomType) Msg::Fatal("Genericface::ERROR: Callback FaceGeomType not set");
+  bool ok = FaceGeomType(id,s);
+  if (!ok){
+    Msg::Error("GenericFace::ERROR from FaceGeomType ! " );
+    return Unknown;
+  }
+
+  if(s.compare("Plane")==0)
+    return Plane;
+  else if(s.compare("Cylinder")==0)
+    return Cylinder;
+  else if(s.compare("Cone")==0)
+    return Cone;
+  else if(s.compare("Sphere")==0)
+    return Sphere;
+  else if(s.compare("Torus")==0)
+    return Torus;
+  else if(s.compare("BezierSurface")==0)
+    return BezierSurface;
+  else if(s.compare("BSplineSurface")==0)
+    return BSplineSurface;
+  else if(s.compare("SurfaceOfRevolution")==0)
+    return SurfaceOfRevolution;
+
+  return Unknown;
+}
+
+//------------------------------------------------------------------------
+
+double GenericFace::curvatureMax(const SPoint2 &param) const{
+  vector<double> dirMax(3,0.);
+  vector<double> dirMin(3,0.);
+  double curvMax,curvMin;
+  vector<double> par(2,0.);
+  for (int i=0;i<3;i++) par[i] = param[i];
+  if (!FaceCurvatures) Msg::Fatal("Genericface::ERROR: Callback FaceCurvatures not set");
+  bool ok = FaceCurvatures(id,par,dirMax,dirMin,curvMax,curvMin);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceCurvatures ! " );
+  return std::max(fabs(curvMax), fabs(curvMin));
+}
+
+//------------------------------------------------------------------------
+
+double GenericFace::curvatures(const SPoint2 &_param,SVector3 *_dirMax,SVector3 *_dirMin,double *curvMax,double *curvMin) const{
+  vector<double> param(2,0.);
+  for (int i=0;i<3;i++) param[i] = _param[i];
+  vector<double> dirMax(3,0.);
+  vector<double> dirMin(3,0.);
+
+  if (!FaceCurvatures) Msg::Fatal("Genericface::ERROR: Callback FaceCurvatures not set");
+  bool ok = FaceCurvatures(id,param,dirMax,dirMin,*curvMax,*curvMin);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceCurvatures ! " );
+  
+  *_dirMax = SVector3(dirMax[0],dirMax[1],dirMax[2]);
+  *_dirMin = SVector3(dirMin[0],dirMin[1],dirMin[2]);
+  return *curvMax;
+}
+
+//------------------------------------------------------------------------
+
+bool GenericFace::containsPoint(const SPoint3 &pt) const{
+  bool res;
+  vector<double> queryPoint(3,0.);
+  for (int i=0;i<3;i++) queryPoint[i] = pt[i];
+  if (!FaceContainsPointFromXYZ) Msg::Fatal("Genericface::ERROR: Callback FaceContainsPointFromXYZ not set");
+  bool ok = FaceContainsPointFromXYZ(id,queryPoint,res);
+  if (!ok) Msg::Error("GenericFace::ERROR from FaceContainsPointFromXYZ ! " );
+  return res;
+}
+
+//------------------------------------------------------------------------
+
diff --git a/Geo/GenericFace.h b/Geo/GenericFace.h
new file mode 100644
index 0000000000000000000000000000000000000000..76c5e55de9c997c209c1b3764812ffb0f0f1db04
--- /dev/null
+++ b/Geo/GenericFace.h
@@ -0,0 +1,92 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _GENERIC_FACE_H_
+#define _GENERIC_FACE_H_
+
+#include "GmshConfig.h"
+#include "GFace.h"
+#include "GModel.h"
+#include "GenericVertex.h"
+#include "GenericEdge.h"
+#include "Range.h"
+#include <vector>
+
+using namespace std;
+
+/*The set of Generic Entities is a generic interface to any other modeler.
+  Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */
+
+class GenericFace : public GFace {
+  protected:
+    int id;
+    double umin, umax, vmin, vmax;// face uv bounds
+    bool _periodic[2];// is periodic in u, v
+
+  public:
+    // callbacks typedef
+    typedef bool (*ptrfunction_int_refstring)(int, string&);
+    typedef bool (*ptrfunction_int_refvector_refvector)(const int , const vector<double> &, vector<double> &);
+    typedef bool (*ptrfunction_int_refvector_refvector_refvector)(const int , const vector<double> &, vector<double> &, vector<double> &);
+    typedef bool (*ptrfunction_int_refvector_refbool)(const int , const vector<double> &, bool &);
+    typedef bool (*ptrfunction_int_int_refdouble_refdouble)(const int, const int, double &, double &);
+    typedef bool (*ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble)(const int, const vector<double> &, vector<double> &, vector<double> &, double &, double &);
+    typedef bool (*ptrfunction_int_refvector_refvector_refvector_refvector)(const int , const vector<double> &, vector<double> &, vector<double> &, vector<double> &);
+
+    GenericFace(GModel *m, int num, int _native_id);
+    virtual ~GenericFace();
+
+    Range<double> parBounds(int i) const;
+    virtual GPoint point(double par1, double par2) const;
+    virtual GPoint closestPoint(const SPoint3 & queryPoint,
+        const double initialGuess[2]) const;
+    virtual bool containsPoint(const SPoint3 &pt) const;
+    virtual SVector3 normal(const SPoint2 &param) const;
+    virtual Pair<SVector3,SVector3> firstDer(const SPoint2 &param) const;
+    virtual void secondDer(const SPoint2 &, SVector3 *, SVector3 *, SVector3 *) const;
+    virtual GEntity::GeomType geomType() const;
+    virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface=true) const;
+    virtual double curvatureMax(const SPoint2 &param) const;
+    virtual double curvatures(const SPoint2 &param, SVector3 *dirMax, SVector3 *dirMin,
+        double *curvMax, double *curvMin) const;
+
+    ModelType getNativeType() const { return GenericModel; }
+    virtual int getNativeInt()const{return id;};
+    
+    void addBndInfo(int loop, GEdge *ptr, int sign){
+      bnd.insert(make_pair(loop, make_pair(ptr,sign)));
+      l_dirs.push_back(sign);
+      l_edges.push_back(ptr);
+      ptr->addFace(this);
+    };
+    
+    // sets callbacks
+    static void setFaceGeomType(ptrfunction_int_refstring fct){FaceGeomType = fct;};
+    static void setFaceUVFromXYZ(ptrfunction_int_refvector_refvector fct){FaceUVFromXYZ = fct;};
+    static void setFaceClosestPoint(ptrfunction_int_refvector_refvector_refvector fct){FaceClosestPoint = fct;};
+    static void setFaceContainsPointFromXYZ(ptrfunction_int_refvector_refbool fct){FaceContainsPointFromXYZ = fct;};
+    static void setFaceContainsPointFromUV(ptrfunction_int_refvector_refbool fct){FaceContainsPointFromUV = fct;};
+    static void setFaceXYZFromUV(ptrfunction_int_refvector_refvector fct){FaceXYZFromUV = fct;};
+    static void setFaceParBounds(ptrfunction_int_int_refdouble_refdouble fct){FaceParBounds = fct;};
+    static void setFaceCurvatures(ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble fct){FaceCurvatures = fct;};
+    static void setFaceEvalNormal(ptrfunction_int_refvector_refvector fct){FaceEvalNormal = fct;};
+    static void setFaceFirstDer(ptrfunction_int_refvector_refvector_refvector fct){FaceFirstDer = fct;};
+    static void setFaceSecondDer(ptrfunction_int_refvector_refvector_refvector_refvector fct){FaceSecondDer = fct;};
+  
+  private:
+    multimap<int, pair<GEdge*,int> > bnd;
+
+    // the callbacks:
+    static ptrfunction_int_refstring FaceGeomType;
+    static ptrfunction_int_refvector_refvector FaceUVFromXYZ,FaceXYZFromUV,FaceEvalNormal;
+    static ptrfunction_int_refvector_refvector_refvector FaceClosestPoint,FaceFirstDer;
+    static ptrfunction_int_refvector_refbool FaceContainsPointFromXYZ,FaceContainsPointFromUV;
+    static ptrfunction_int_int_refdouble_refdouble FaceParBounds;
+    static ptrfunction_int_refvector_refvector_refvector_refdouble_refdouble FaceCurvatures;
+    static ptrfunction_int_refvector_refvector_refvector_refvector FaceSecondDer;
+
+};
+
+#endif
diff --git a/Geo/GenericRegion.cpp b/Geo/GenericRegion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6b8f1a408777c553d70eddad8ebeb541a48d391
--- /dev/null
+++ b/Geo/GenericRegion.cpp
@@ -0,0 +1,34 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#include "GmshConfig.h"
+#include "GmshMessage.h"
+#include "GModel.h"
+#include "GenericVertex.h"
+#include "GenericEdge.h"
+#include "GenericFace.h"
+#include "GenericRegion.h"
+
+//------------------------------------------------------------------------
+
+GenericRegion::GenericRegion(GModel *m, int num, int _native_id):GRegion(m, num), id(_native_id)
+{
+}
+
+//------------------------------------------------------------------------
+
+GenericRegion::~GenericRegion()
+{
+}
+
+//------------------------------------------------------------------------
+
+GEntity::GeomType GenericRegion::geomType() const
+{
+  return Unknown;
+}
+
+//------------------------------------------------------------------------
+
diff --git a/Geo/GenericRegion.h b/Geo/GenericRegion.h
new file mode 100644
index 0000000000000000000000000000000000000000..74850cc8b2e7cb3535f48a167b283391adc97e48
--- /dev/null
+++ b/Geo/GenericRegion.h
@@ -0,0 +1,37 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _GENERIC_REGION_H_
+#define _GENERIC_REGION_H_
+
+#include "GmshConfig.h"
+#include "GRegion.h"
+
+/*The set of Generic Entities is a generic interface to any other modeler.
+  Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */
+
+class GenericRegion : public GRegion {
+  public:
+    GenericRegion(GModel *m, int num, int _native_id);
+    virtual ~GenericRegion();
+
+    virtual GeomType geomType() const;
+
+    ModelType getNativeType() const { return GenericModel; }
+    virtual int getNativeInt()const{return id;};
+
+    // TODO: When using GRegion->l_dirs and l_faces, what is the convention for l_dirs ? For now, assuming positive value for normals pointing inside the region.
+    void addFace(GenericFace *ptr, int sign){
+      l_dirs.push_back(sign);
+      l_faces.push_back(ptr);
+      ptr->addRegion(this);
+    };
+
+
+  private:
+    int id;
+};
+
+#endif
diff --git a/Geo/GenericVertex.cpp b/Geo/GenericVertex.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a80e787cf8c51a8eb43d9c8e14ae6b87b1d546de
--- /dev/null
+++ b/Geo/GenericVertex.cpp
@@ -0,0 +1,92 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#include "GmshConfig.h"
+#include "GModel.h"
+#include "MVertex.h"
+#include "MPoint.h"
+#include "GenericVertex.h"
+#include "GenericEdge.h"
+#include "GenericFace.h"
+#include<algorithm>
+
+//------------------------------------------------------------------------
+
+GenericVertex::ptrfunction_int_vector GenericVertex::VertexXYZ = NULL;
+
+//------------------------------------------------------------------------
+
+GenericVertex::GenericVertex(GModel *m, int num, int _native_id):GVertex(m, num), id(_native_id){
+  if (!VertexXYZ)
+    Msg::Fatal("GenericVertex::ERROR: Callback not set");
+
+  vector<double> vec(3,0.);
+  bool ok = VertexXYZ(id,vec);
+  if (!ok) Msg::Error("GenericVertex::ERROR from callback VertexXYZ ");
+  _x=vec[0];
+  _y=vec[1];
+  _z=vec[2];
+}
+
+//------------------------------------------------------------------------
+
+GenericVertex::~GenericVertex(){
+}
+
+//------------------------------------------------------------------------
+
+SPoint2 GenericVertex::reparamOnFace(const GFace *gf, int dir) const
+{
+  std::list<GEdge*>::const_iterator it = l_edges.begin();
+  //      // TODO: isSeam not ready yet !!!
+  //  while(it != l_edges.end()){
+  //    std::list<GEdge*> l = gf->edges();
+  //    if(std::find(l.begin(), l.end(), *it) != l.end()){
+  //      if((*it)->isSeam(gf)){
+  //        const TopoDS_Face *s = (TopoDS_Face*)gf->getNativePtr();
+  //        const TopoDS_Edge *c = (TopoDS_Edge*)(*it)->getNativePtr();
+  //        double s1,s0;
+  //        Handle(Geom2d_Curve) curve2d = BRep_Tool::CurveOnSurface(*c, *s, s0, s1);
+  //        if((*it)->getBeginVertex() == this)
+  //          return (*it)->reparamOnFace(gf, s0, dir);
+  //        else if((*it)->getEndVertex() == this)
+  //          return (*it)->reparamOnFace(gf, s1, dir);
+  //      }
+  //    }
+  //    ++it;
+  //  }
+  it = l_edges.begin();
+  while(it != l_edges.end()){
+    std::list<GEdge*> l = gf->edges();
+    if(std::find(l.begin(), l.end(), *it) != l.end()){
+      // the vertex belongs to an edge, which belongs to a face -> just find if begin or end vertex and edge->reparamOnFace(begin or end param)
+      Range<double> vec = (*it)->parBounds(0);
+      if((*it)->getBeginVertex() == this)
+        return (*it)->reparamOnFace(gf, vec.low(), dir);
+      else if((*it)->getEndVertex() == this)
+        return (*it)->reparamOnFace(gf, vec.high(), dir);
+    }
+    ++it;
+  }
+
+  // normally never here
+  return GVertex::reparamOnFace(gf, dir);
+}
+
+//------------------------------------------------------------------------
+
+void GenericVertex::setPosition(GPoint &p)
+{
+  _x = p.x();
+  _y = p.y();
+  _z = p.z();
+  if(mesh_vertices.size()){
+    mesh_vertices[0]->x() = p.x();
+    mesh_vertices[0]->y() = p.y();
+    mesh_vertices[0]->z() = p.z();
+  }
+}
+
+//------------------------------------------------------------------------
diff --git a/Geo/GenericVertex.h b/Geo/GenericVertex.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb34abceb81105f35f8a38d9512952738044547c
--- /dev/null
+++ b/Geo/GenericVertex.h
@@ -0,0 +1,51 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
+#ifndef _GENERIC_VERTEX_H_
+#define _GENERIC_VERTEX_H_
+
+#include "GmshConfig.h"
+#include "GModel.h"
+#include "GVertex.h"
+#include <vector>
+
+using namespace std;
+
+/*The set of Generic Entities is a generic interface to any other modeler.
+  Callbacks (function pointers) are given, sending requests, enquiries, to the native modeler. */
+
+class GenericVertex : public GVertex {
+  protected:
+    int id;
+    double _x, _y, _z;
+  public:
+    // callbacks typedef
+    typedef bool (*ptrfunction_int_vector)(int, vector<double>&);
+
+    GenericVertex(GModel *m, int num, int _native_id);
+    virtual ~GenericVertex();
+
+    virtual GPoint point() const { return GPoint(x(), y(), z()); }
+    virtual double x() const { return _x; }
+    virtual double y() const { return _y; }
+    virtual double z() const { return _z; }
+
+    virtual void setPosition(GPoint &p);
+    virtual SPoint2 reparamOnFace(const GFace *gf, int) const;
+
+    ModelType getNativeType() const { return GenericModel; }
+    virtual int getNativeInt()const{return id;};
+
+    // sets the callbacks
+    static void setVertexXYZ(ptrfunction_int_vector fct){VertexXYZ = fct;};
+    
+  private:
+    // the callbacks:
+    // --------------
+    // fills vector xyz for vertex of int id
+    static ptrfunction_int_vector VertexXYZ;
+};
+
+#endif