diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f857f7c32812078e8ff9ba368b9d222007ba5387
--- /dev/null
+++ b/Geo/GModelFactory.cpp
@@ -0,0 +1,420 @@
+#include "GModelFactory.h"
+
+#if defined(HAVE_OCC)
+#include "OCCIncludes.h"
+#include "GModelIO_OCC.h"
+#include "OCCVertex.h"
+#include "OCCEdge.h"
+#include "OCCRegion.h"
+#include "BRepBuilderAPI_MakeVertex.hxx"
+#include "BRepBuilderAPI_MakeEdge.hxx"
+#include "BRepPrimAPI_MakeRevol.hxx"
+#include "BRepPrimAPI_MakePrism.hxx"
+#include <GC_MakeArcOfCircle.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gce_MakeCirc.hxx>
+#include <gce_MakePln.hxx>
+#include <ElCLib.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom_BezierCurve.hxx>
+
+OCCFactory::OCCFactory() : GModelFactory()
+{
+}
+
+
+GVertex * OCCFactory::createVertex (GModel *_gm, double x, double y, double z, double lc){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Pnt aPnt;
+  aPnt = gp_Pnt(x, y, z);
+  BRepBuilderAPI_MakeVertex mkVertex (aPnt);
+  TopoDS_Vertex occv =  mkVertex.Vertex();
+  
+  return _gm->_occ_internals->addVertexToModel(_gm,occv);
+}
+
+
+GEdge * OCCFactory::createLine (GModel *_gm, GVertex *start, GVertex *end){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  OCCVertex *occv1 = dynamic_cast<OCCVertex*>(start);
+  OCCVertex *occv2 = dynamic_cast<OCCVertex*>(end);
+  TopoDS_Edge occEdge;
+  if (occv1 && occv2){
+     occEdge = BRepBuilderAPI_MakeEdge(occv1->getShape(), 
+				       occv2->getShape()).Edge();
+  }
+  else{
+    gp_Pnt p1(start->x(),start->y(),start->z());
+    gp_Pnt p2(end->x(),end->y(),end->z());
+    TopoDS_Edge occEdge = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
+  }  
+  return _gm->_occ_internals->addEdgeToModel(_gm,occEdge,start,end);
+}
+
+
+GEdge *OCCFactory::createCircleArc (GModel *_gm, const arcCreationMethod &method,
+			       GVertex *start, 
+			       GVertex *end, 
+			       const SPoint3 &aPoint) {
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Pnt aP1 (start->x(),start->y(),start->z());
+  gp_Pnt aP2 (aPoint.x(),aPoint.y(),aPoint.z());
+  gp_Pnt aP3 (end->x(),end->y(),end->z());
+
+  if (method == GModelFactory::THREE_POINTS){
+    GC_MakeArcOfCircle arc(aP1, aP2, aP3);
+    TopoDS_Edge occEdge = BRepBuilderAPI_MakeEdge(arc).Edge();
+    return _gm->_occ_internals->addEdgeToModel(_gm,occEdge,start,end);
+  }
+  else if (method == GModelFactory::CENTER_START_END){
+    Standard_Real Radius = aP1.Distance(aP2);
+    gce_MakeCirc MC(aP1,gce_MakePln(aP1, aP2, aP3).Value(),Radius);
+    const gp_Circ& Circ = MC.Value();
+    Standard_Real Alpha1 = ElCLib::Parameter(Circ,aP1);
+    Standard_Real Alpha2 = ElCLib::Parameter(Circ,aP3);
+    Handle(Geom_Circle) C = new Geom_Circle(Circ);
+    Handle(Geom_TrimmedCurve) arc = new Geom_TrimmedCurve(C,Alpha1,Alpha2,false);
+    TopoDS_Edge occEdge = BRepBuilderAPI_MakeEdge(arc).Edge();
+    return _gm->_occ_internals->addEdgeToModel(_gm,occEdge,start,end);
+  }
+  return 0;
+}
+
+GEdge *OCCFactory::createSpline (GModel *_gm, const splineType &type,
+				 GVertex *start, 
+				 GVertex *end, 
+				 fullMatrix<double> *points){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  OCCEdge *occEd = 0;
+  int nbControlPoints = points->size1();
+  TColgp_Array1OfPnt ctrlPoints (1, nbControlPoints+2);
+  int index = 1;
+  ctrlPoints.SetValue(index++,gp_Pnt(start->x(),start->y(),start->z()));  
+  for (int i = 0; i < nbControlPoints; i++) {
+    gp_Pnt aP((*points)(i,0),(*points)(i,1),(*points)(i,2));
+    ctrlPoints.SetValue(index++, aP);
+  }
+  ctrlPoints.SetValue(index++,gp_Pnt(end->x(),end->y(),end->z()));  
+  if (type == BEZIER) {
+    Handle(Geom_BezierCurve) Bez = new Geom_BezierCurve(ctrlPoints);
+    TopoDS_Edge bez = BRepBuilderAPI_MakeEdge(Bez).Edge();
+    return _gm->_occ_internals->addEdgeToModel(_gm,bez,start,end);
+  } 
+  else {
+    throw;
+  }
+  return 0;
+}
+
+GEntity *OCCFactory::revolve (GModel *_gm, GEntity* base, 
+			      double x1, double y1, double z1, 
+			      double x2, double y2, double z2,
+			      double angle ){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Dir direction (x2-x1,y2-y1,z2-z1);
+  gp_Ax1 axisOfRevolution (gp_Pnt (x1,y1,z1),direction);
+  BRepPrimAPI_MakeRevol MR (*(TopoDS_Shape*)base->getNativePtr(), 
+			    axisOfRevolution, angle, Standard_False);
+  GEntity *ret;
+  if (base->Cast2Vertex()){
+    TopoDS_Edge result =  TopoDS::Edge(MR.Shape());
+    ret  = _gm->_occ_internals->addEdgeToModel(_gm,result);
+  }
+  if (base->Cast2Edge()){
+    TopoDS_Face result =  TopoDS::Face(MR.Shape());
+    ret =  _gm->_occ_internals->addFaceToModel(_gm,result);    
+  }
+  if (base->Cast2Face()){
+    TopoDS_Solid result =  TopoDS::Solid(MR.Shape());
+    ret =  _gm->_occ_internals->addRegionToModel(_gm,result);    
+  }
+  _gm->glue(Precision::Confusion());
+  return ret;
+}
+
+GEntity *OCCFactory::extrude (GModel *_gm, GEntity* base, 
+			      double x1, double y1, double z1, 
+			      double x2, double y2, double z2){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Vec direction (gp_Pnt (x1,y1,z1),gp_Pnt (x2,y2,z2));
+  gp_Ax1 axisOfRevolution (gp_Pnt (x1,y1,z1),direction);
+
+  BRepPrimAPI_MakePrism MP(*(TopoDS_Shape*)base->getNativePtr(), direction, Standard_False);
+
+  GEntity *ret;
+  
+  if (base->Cast2Vertex()){
+    TopoDS_Edge result =  TopoDS::Edge(MP.Shape());
+    ret =  _gm->_occ_internals->addEdgeToModel(_gm,result);
+  }
+  if (base->Cast2Edge()){
+    TopoDS_Face result =  TopoDS::Face(MP.Shape());
+    ret = _gm->_occ_internals->addFaceToModel(_gm,result);    
+  }
+  if (base->Cast2Face()){
+    TopoDS_Solid result =  TopoDS::Solid(MP.Shape());
+    ret = _gm->_occ_internals->addRegionToModel(_gm,result);    
+  }
+  _gm->glue(Precision::Confusion());
+  return ret;
+}
+
+
+GEntity *OCCFactory::sphere (GModel *_gm,  double xc, double yc, double zc, double radius){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Pnt aP(xc,yc,zc);  
+  _gm->_occ_internals->buildShapeFromLists(BRepPrimAPI_MakeSphere(aP, radius).Shape());
+  _gm->destroy();
+  _gm->_occ_internals->buildLists();
+  _gm->_occ_internals->buildGModel(_gm);  
+}
+
+GEntity *OCCFactory::cylinder (GModel *_gm,  std::vector<double> p1, std::vector<double> p2, double radius){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  const double x1 =p1[0]; 
+  const double y1 =p1[1]; 
+  const double z1 =p1[2]; 
+  const double x2 =p2[0]; 
+  const double y2 =p2[1]; 
+  const double z2 =p2[2]; 
+
+  gp_Pnt aP(x1,y1,z1);
+  const double H = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)); 
+  gp_Vec aV((x2-x1)/H,(y2-y1)/H,(z2-z1)/H);
+  gp_Ax2 anAxes(aP, aV);
+  BRepPrimAPI_MakeCylinder MC (anAxes, radius, H);
+  MC.Build();
+  if (!MC.IsDone()) {
+    Msg::Error("Cylinder can't be computed from the given parameters");
+    return 0;
+  }
+  _gm->_occ_internals->buildShapeFromLists(MC.Shape());
+  _gm->destroy();
+  _gm->_occ_internals->buildLists();
+  _gm->_occ_internals->buildGModel(_gm);  
+  return 0;
+}
+
+GEntity *OCCFactory::torus (GModel *_gm,  std::vector<double> p1, std::vector<double> p2, double radius1, double radius2){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  const double x1 =p1[0]; 
+  const double y1 =p1[1]; 
+  const double z1 =p1[2]; 
+  const double x2 =p2[0]; 
+  const double y2 =p2[1]; 
+  const double z2 =p2[2]; 
+  gp_Pnt aP(x1,y1,z1);
+  const double H = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)); 
+  gp_Vec aV((x2-x1)/H,(y2-y1)/H,(z2-z1)/H);
+  gp_Ax2 anAxes(aP, aV);
+  BRepPrimAPI_MakeTorus MC (anAxes, radius1, radius2);
+  MC.Build();
+  if (!MC.IsDone()) {
+    Msg::Error("Cylinder can't be computed from the given parameters");
+    return 0;
+  }
+  _gm->_occ_internals->buildShapeFromLists(MC.Shape());
+  _gm->destroy();
+  _gm->_occ_internals->buildLists();
+  _gm->_occ_internals->buildGModel(_gm);  
+  return 0;
+}
+
+GEntity *OCCFactory::cone (GModel *_gm,  std::vector<double> p1, std::vector<double> p2, double radius1, double radius2){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  const double x1 =p1[0]; 
+  const double y1 =p1[1]; 
+  const double z1 =p1[2]; 
+  const double x2 =p2[0]; 
+  const double y2 =p2[1]; 
+  const double z2 =p2[2]; 
+
+  gp_Pnt aP(x1,y1,z1);
+  const double H = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)); 
+  gp_Vec aV((x2-x1)/H,(y2-y1)/H,(z2-z1)/H);
+  gp_Ax2 anAxes(aP, aV);
+  BRepPrimAPI_MakeCone MC (anAxes, radius1, radius2, H);
+  MC.Build();
+  if (!MC.IsDone()) {
+    Msg::Error("Cylinder can't be computed from the given parameters");
+    return 0;
+  }
+  _gm->_occ_internals->buildShapeFromLists(MC.Shape());
+  _gm->destroy();
+  _gm->_occ_internals->buildLists();
+  _gm->_occ_internals->buildGModel(_gm);  
+  return 0;
+}
+
+GEntity *OCCFactory::block  (GModel *_gm, std::vector<double> p1, std::vector<double> p2){
+  if (!_gm->_occ_internals)
+    _gm->_occ_internals = new OCC_Internals;
+
+  gp_Pnt P1(p1[0],p1[1],p1[2]);
+  gp_Pnt P2(p2[0],p2[1],p2[2]);
+  BRepPrimAPI_MakeBox MB(P1, P2);
+  MB.Build();
+  if (!MB.IsDone()) {
+    Msg::Error("Box can not be computed from the given point");
+    return 0;
+  }
+  _gm->_occ_internals->buildShapeFromLists(MB.Shape());
+  _gm->destroy();
+  _gm->_occ_internals->buildLists();
+  _gm->_occ_internals->buildGModel(_gm);  
+}
+
+GModel *OCCFactory::booleanUnion (GModel* obj, GModel* tool, int createNewModel){
+
+  OCC_Internals *occ_obj  = obj->getOCCInternals();
+  OCC_Internals *occ_tool = tool->getOCCInternals();
+
+  if (!occ_obj || !occ_tool)return NULL;
+
+  if (createNewModel){
+    GModel *temp = new GModel;
+    temp->_occ_internals = new OCC_Internals;
+    temp->_occ_internals->addShapeToLists(occ_obj->getShape());
+    obj = temp;
+  }
+  obj->_occ_internals->applyBooleanOperator(occ_tool->getShape(),OCC_Internals::Fuse);
+  obj->destroy();
+  obj->_occ_internals->buildLists();
+  obj->_occ_internals->buildGModel(obj);
+  
+  return obj;
+}
+
+GModel *OCCFactory::booleanDifference (GModel* obj, GModel* tool, int createNewModel){
+
+  OCC_Internals *occ_obj  = obj->getOCCInternals();
+  OCC_Internals *occ_tool = tool->getOCCInternals();
+
+  if (!occ_obj || !occ_tool)return NULL;
+
+  if (createNewModel){
+    GModel *temp = new GModel;
+    temp->_occ_internals = new OCC_Internals;
+    temp->_occ_internals->addShapeToLists(occ_obj->getShape());
+    obj = temp;
+  }
+  obj->getOCCInternals()->applyBooleanOperator(occ_tool->getShape(),OCC_Internals::Cut);
+  obj->destroy();
+  obj->_occ_internals->buildLists();
+  obj->_occ_internals->buildGModel(obj);
+  return obj;
+}
+
+GModel *OCCFactory::booleanIntersection (GModel* obj, GModel* tool, int createNewModel){
+
+  OCC_Internals *occ_obj  = obj->getOCCInternals();
+  OCC_Internals *occ_tool = tool->getOCCInternals();
+
+
+  if (!occ_obj || !occ_tool)return NULL;
+
+  if (createNewModel){
+    GModel *temp = new GModel;
+    temp->_occ_internals = new OCC_Internals;
+    temp->_occ_internals->addShapeToLists(occ_obj->getShape());
+    obj = temp;
+  }
+  obj->getOCCInternals()->applyBooleanOperator(occ_tool->getShape(),OCC_Internals::Intersection);
+  obj->destroy();
+  obj->_occ_internals->buildLists();
+  obj->_occ_internals->buildGModel(obj);
+  return obj;
+}
+
+#endif
+
+#include "Bindings.h"
+void GModelFactory::registerBindings (binding *b)
+{
+  classBinding *cb = b->addClass<GModelFactory>("GModelFactory");
+  cb->setDescription("an interface to Gentity Construction");
+  methodBinding *mb;
+  mb = cb->addMethod("createVertex", &GModelFactory::createVertex);
+  mb->setDescription("creates a GVertex");
+  mb->setArgNames("model", "x", "y","z","lc",NULL);
+  mb = cb->addMethod("createLine", &GModelFactory::createLine);
+  mb->setDescription("creates a Line going from v1 to v2");
+  mb->setArgNames("model","v1", "v2",NULL);
+  mb = cb->addMethod("createBezierLine", &GModelFactory::createBezier);
+  mb->setDescription("creates a Spline going from v1 to v2 and with some control points listed in a fullMatrix(N,3)");
+  mb->setArgNames("model","v1", "v2", "controlPoints", NULL);
+  mb = cb->addMethod("createCircleArcCenter", &GModelFactory::createCircleArcCenter);
+  mb->setDescription("creates a circle arc going from v1 to v2 with its center Xc(x,y,z)");
+  mb->setArgNames("model","x","y","z","v1", "v2", NULL);
+  mb = cb->addMethod("createCircleArc3Points", &GModelFactory::createCircleArc3Points);
+  mb->setDescription("creates a circle arc going from v1 to v2 with an intermediary point Xi(x,y,z)");
+  mb->setArgNames("model","x","y","z","v1", "v2", NULL);
+  mb = cb->addMethod("revolve", &GModelFactory::revolve_);
+  mb->setDescription("revolves an entity of an angle. Axis is defined by 2 points in a full Matrix(2,3)");
+  mb->setArgNames("model","entity", "angle", "axis",NULL);
+  mb = cb->addMethod("extrude", &GModelFactory::extrude_);
+  mb->setDescription("extrudes an entity. Axis is defined by 2 points in a full Matrix(2,3)");
+  mb->setArgNames("model","entity", "axis",NULL);
+
+  mb = cb->addMethod("sphere", &GModelFactory::sphere);
+  mb->setDescription("builds a sphere");
+  mb->setArgNames("model","xc","yc","zc","radius",NULL);
+
+  mb = cb->addMethod("block", &GModelFactory::block);
+  mb->setDescription("builds a block");
+  mb->setArgNames("model","{x1,y1,z1}","{x2,y2,z2}",NULL);
+
+  mb = cb->addMethod("cone", &GModelFactory::cone);
+  mb->setDescription("builds a cone");
+  mb->setArgNames("model","{x1,y1,z1}","{x2,y2,z2}","R1","R2",NULL);
+
+  mb = cb->addMethod("cylinder", &GModelFactory::cylinder);
+  mb->setDescription("builds a cylinder");
+  mb->setArgNames("model","{x1,y1,z1}","{x2,y2,z2}", "R",NULL);
+
+  mb = cb->addMethod("torus", &GModelFactory::torus);
+  mb->setDescription("builds a torus");
+  mb->setArgNames("model","{x1,y1,z1}","{x2,y2,z2}","R1","R2",NULL);
+
+  mb = cb->addMethod("union", &GModelFactory::booleanUnion);
+  mb->setDescription("returns a GModel that is the boolean union of 2 GModels. Third parameter tells if a new model has to be created");
+  mb->setArgNames("g1","g2","createNewGModel",NULL);
+
+  mb = cb->addMethod("intersection", &GModelFactory::booleanIntersection);
+  mb->setDescription("returns a GModel that is the boolean intersection of 2 GModels. Third parameter tells if a new model has to be created");
+  mb->setArgNames("g1","g2","createNewGModel",NULL);
+
+  mb = cb->addMethod("difference", &GModelFactory::booleanDifference);
+  mb->setDescription("returns a GModel that is the boolean difference of 2 GModels. Third parameter tells if a new model has to be created");
+  mb->setArgNames("g1","g2","createNewGModel",NULL);
+#if defined(HAVE_OCC)
+  cb = b->addClass<OCCFactory>("OCCFactory");
+  cb->setDescription("a GEntity Factory for OpenCascade");
+  mb = cb->setConstructor<OCCFactory>();
+  mb->setDescription("a GEntity Factory for OpenCascade");
+  cb->setParentClass<GModelFactory>();
+#endif
+}
+
diff --git a/Geo/GModelFactory.h b/Geo/GModelFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e3b7ce6a39c7b7188a2acd054ac5314754a7c75
--- /dev/null
+++ b/Geo/GModelFactory.h
@@ -0,0 +1,131 @@
+#ifndef _GMODEL_FACTORY_H_
+#define _GMODEL_FACTORY_H_
+#include <vector>
+
+#include "GmshConfig.h"
+#include "fullMatrix.h"
+#include "SPoint3.h"
+#include "GEntity.h"
+
+class GVertex;
+class GEdge;
+class GModel;
+class binding;
+
+class GModelFactory {
+ protected :
+ public:
+  // constructor takes the GModel as input
+  GModelFactory (){}
+  // creation methods
+  enum arcCreationMethod {THREE_POINTS=1, CENTER_START_END=2};
+  enum splineType {BEZIER=1, CATMULL_ROM=2};
+
+  virtual GVertex* createVertex (GModel *gm, double x, double y, double z, double lc) = 0;
+
+  virtual GEdge *createLine (GModel *, GVertex *v1, GVertex *v2) = 0;
+
+
+  virtual GEdge *createCircleArc (GModel *gm, const arcCreationMethod &method,
+				  GVertex *start, 
+				  GVertex *end, 
+				  const SPoint3 &aPoint)= 0;
+  inline GEdge *createCircleArcCenter (GModel *gm, double x, double y, double z,
+				       GVertex *start, 
+				       GVertex *end){
+    return createCircleArc (gm, CENTER_START_END,start,end,SPoint3(x,y,z));
+  }
+
+  inline GEdge *createCircleArc3Points (GModel *gm, double x, double y, double z,
+					GVertex *start, 
+					GVertex *end){
+    return createCircleArc (gm, THREE_POINTS,start,end,SPoint3(x,y,z));
+  }
+  virtual GEdge *createSpline (GModel *gm,const splineType &type,
+			       GVertex *start, 
+			       GVertex *end, 
+			       fullMatrix<double> *controlPoints)= 0;
+  inline GEdge *createBezier ( GModel *gm, GVertex *start, 
+			       GVertex *end, 
+			       fullMatrix<double> *controlPoints){
+    return createSpline(gm, BEZIER,start, end, controlPoints);
+  }
+
+  virtual GEntity* revolve (GModel *gm, GEntity*, 
+			    double x1, double y1, double z1, 
+			    double x2, double y2, double z2,
+			    double angle ) = 0;
+  virtual GEntity* extrude (GModel *gm, GEntity*, 
+			    double x1, double y1, double z1, 
+			    double x2, double y2, double z2) = 0;
+
+  inline GEntity* revolve_ (GModel *gm, GEntity* e, 
+			    double angle,
+			    fullMatrix<double> *axis){
+    revolve (gm, e, (*axis)(0,0),(*axis)(0,1),(*axis)(0,2),
+	     (*axis)(1,0),(*axis)(1,1),(*axis)(1,2),angle);
+  }
+  inline GEntity* extrude_ (GModel *gm, GEntity* e, 
+			    fullMatrix<double> *axis){
+    extrude (gm, e, (*axis)(0,0),(*axis)(0,1),(*axis)(0,2),
+	     (*axis)(1,0),(*axis)(1,1),(*axis)(1,2));
+  }
+  // primitives
+  virtual GEntity * sphere   (GModel *gm, double cx, double cy, double cz, double radius) = 0; 
+  virtual GEntity * cylinder (GModel *gm, std::vector<double> p1, std::vector<double> p2, 
+			      double radius) = 0; 
+  virtual GEntity * torus   (GModel *gm, std::vector<double> p1, std::vector<double> p2, 
+			     double radius1, double radius2) = 0; 
+  virtual GEntity * block  (GModel *gm, std::vector<double> p1, std::vector<double> p2) = 0;
+  virtual GEntity * cone   (GModel *gm, std::vector<double> p1, std::vector<double> p2,
+			    double radius1, double radius2) = 0; 
+
+  // boolean operators acting on 2 GEntities
+  virtual GModel * booleanUnion (GModel *obj, GModel*tool, int createNewModel) = 0;
+  virtual GModel * booleanIntersection (GModel *obj, GModel*tool, int createNewModel) = 0;
+  virtual GModel * booleanDifference (GModel *obj, GModel*tool, int createNewModel) = 0;
+  
+
+  // bindings
+  static void registerBindings(binding *b);
+};
+
+#if defined(HAVE_OCC)
+class OCCFactory : public GModelFactory {
+ public:
+  OCCFactory ();
+  GVertex *createVertex (GModel *gm,double x, double y, double z, double lc);
+  virtual GEdge *createLine (GModel *gm,GVertex *v1, GVertex *v2);
+  GEdge *createCircleArc (GModel *gm,const arcCreationMethod &method,				  
+			  GVertex *start, 
+			  GVertex *end, 
+			  const SPoint3 &aPoint);
+  GEdge *createSpline (GModel *gm,const splineType &type,
+		       GVertex *start, 
+		       GVertex *end, 
+		       fullMatrix<double> *controlPoints);
+
+  GEntity* revolve (GModel *gm,GEntity*, 
+		    double x1, double y1, double z1, 
+		    double x2, double y2, double z2,
+		    double angle );
+
+  GEntity* extrude (GModel *gm,GEntity*, 
+		    double x1, double y1, double z1, 
+		    double x2, double y2, double z2);
+
+  GEntity * sphere   (GModel *gm,double cx, double cy, double cz, double radius); 
+  GEntity * cylinder (GModel *gm,std::vector<double> p1, std::vector<double> p2, 
+		      double radius); 
+  GEntity * torus   (GModel *gm,std::vector<double> p1, std::vector<double> p2, 
+		     double radius1, double radius2); 
+  GEntity * block  (GModel *gm,std::vector<double> p1, std::vector<double> p2); 
+  GEntity * cone   (GModel *gm,std::vector<double> p1, std::vector<double> p2, double radius1, double radius2); 
+  // booleans
+  GModel * booleanUnion (GModel *obj, GModel*tool, int createNewModel);
+  GModel * booleanIntersection (GModel *obj, GModel*tool, int createNewModel);
+  GModel * booleanDifference (GModel *obj, GModel*tool, int createNewModel);
+};
+#endif
+
+#endif