diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 306ff4787600a9cd28896daa0b35c7ccfc1882e5..63f4924cd99a28636ec6c8767617322d203e300e 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -2668,6 +2668,20 @@ GRegion* GModel::addVolume (std::vector<std::vector<GFace *> > faces){
   return 0;
 }
 
+GFace *GModel::add2Drect(double x0, double y0, double dx, double dy)
+{
+  if(_factory) 
+	return _factory->add2Drect(this, x0, y0, dx, dy);
+  return 0;
+}
+
+GFace *GModel::add2Dellips(double xc, double yc, double rx, double ry)
+{
+  if(_factory) 
+	return _factory->add2Dellips(this, xc, yc, rx, ry);
+  return 0;
+}
+
 GEntity *GModel::revolve(GEntity *e, std::vector<double> p1, std::vector<double> p2,
                          double angle)
 {
@@ -2724,6 +2738,13 @@ GEntity *GModel::addBlock(std::vector<double> p1, std::vector<double> p2)
   return 0;
 }
 
+GEntity *GModel::add3DBlock(std::vector<double> p1, double dx, double dy, double dz )
+{
+  if(_factory) 
+	return _factory->add3DBlock(this, p1, dx, dy, dz);
+  return 0;
+}
+
 GEntity *GModel::addCone(std::vector<double> p1, std::vector<double> p2,
                          double radius1, double radius2)
 {
@@ -2752,6 +2773,36 @@ GModel *GModel::computeBooleanDifference(GModel *tool, int createNewModel)
   return 0;
 }
 
+void GModel::salomeconnect()
+{
+  if(_factory) 
+	_factory->salomeconnect(this);
+}
+
+void GModel::occconnect()
+{
+  if(_factory)
+	_factory->occconnect(this);
+}
+
+void GModel::setPeriodicAllFaces(std::vector<double> FaceTranslationVector)
+{
+  if(_factory) 
+	_factory->setPeriodicAllFaces(this, FaceTranslationVector);
+}
+
+void GModel::setPeriodicPairOfFaces(int numFaceMaster, std::vector<int> EdgeListMaster, int numFaceSlave, std::vector<int> EdgeListSlave)
+{
+  if(_factory) 
+	_factory->setPeriodicPairOfFaces(this, numFaceMaster, EdgeListMaster, numFaceSlave, EdgeListSlave);
+}
+
+void GModel::setPhysicalNumToEntitiesInBox(int EntityType, int PhysicalGroupNumber, std::vector<double> p1, std::vector<double> p2)
+{
+  if(_factory) 
+	_factory->setPhysicalNumToEntitiesInBox(this,EntityType,PhysicalGroupNumber,p1,p2);
+}
+
 static void computeDuplicates(GModel *model,
                               std::multimap<GVertex*, GVertex*> &Unique2Duplicates,
                               std::map<GVertex*, GVertex*> &Duplicates2Unique,
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 57898970f7eeb751a09985e4682a5cb02aa14815..f72da346edb64a5d4053be0332228c7ca899eaf4 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -512,6 +512,9 @@ class GModel
   void addRuledFaces(std::vector<std::vector<GEdge *> > edges);
   GFace *addFace(std::vector<GEdge *> edges, std::vector< std::vector<double > > points);
   GFace *addPlanarFace(std::vector<std::vector<GEdge *> > edges);
+  GFace *add2Drect(double x0, double y0, double dx, double dy);
+  GFace *add2Dellips(double xc, double yc, double rx, double ry);
+
   GEdge *addCompoundEdge(std::vector<GEdge*> edges, int num=-1);
   GFace *addCompoundFace(std::vector<GFace*> faces, int type, int split, int num=-1);
   GRegion *addVolume(std::vector<std::vector<GFace*> > faces);
@@ -522,6 +525,7 @@ class GModel
   GEntity *addTorus(std::vector<double> p1, std::vector<double> p2, double radius1,
                     double radius2);
   GEntity *addBlock(std::vector<double> p1, std::vector<double> p2);
+  GEntity *add3DBlock(std::vector<double> p1, double dx, double dy , double dz);
   GEntity *addCone(std::vector<double> p1, std::vector<double> p2, double radius1,
                    double radius2);
 
@@ -529,6 +533,16 @@ class GModel
   GModel *computeBooleanUnion(GModel *tool, int createNewModel=0);
   GModel *computeBooleanIntersection(GModel *tool, int createNewModel=0);
   GModel *computeBooleanDifference(GModel *tool, int createNewModel=0);
+  void    salomeconnect(); 
+  void    occconnect();
+	
+	// do stuff for all entities inside a bounding box
+  void    setPeriodicAllFaces(std::vector<double> FaceTranslationVector);
+  void    setPeriodicPairOfFaces(int numFaceMaster, std::vector<int> EdgeListMaster, 
+																 int numFaceSlave, std::vector<int> EdgeListSlave);
+  void    setPhysicalNumToEntitiesInBox(int EntityType, int PhysicalGroupNumber, 
+																				std::vector<double> p1,std::vector<double> p2);
+	
 
   // build a new GModel by cutting the elements crossed by the levelset ls
   // if cutElem is set to false, split the model without cutting the elements
diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp
index 3a4a2a8b7cfb5b19bc7f4d1c77dbe23ae67c536e..34d114f459c79e5a065bf0c18d35df25e35ef60f 100644
--- a/Geo/GModelFactory.cpp
+++ b/Geo/GModelFactory.cpp
@@ -453,6 +453,38 @@ std::vector<GEntity*> GeoFactory::extrudeBoundaryLayer(GModel *gm, GEntity *e,
 #include <TColgp_HArray1OfPnt.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepPrimAPI_MakeBox.hxx>
+#include <BRepPrimAPI_MakeTorus.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <BRepPrimAPI_MakeCylinder.hxx>
+#include <GeomLProp_SLProps.hxx>
+
+#include <BRepAlgoAPI_Section.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx> 
+#include <TopoDS_Shape.hxx>
+#include <BRepTools.hxx>
+#include <BRepBndLib.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax2d.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Dir2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Trsf.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include "OCC_Connect.h"
+#if defined(HAVE_SALOME)
+	#include "Partition_Spliter.hxx"
+#endif
 
 GVertex *OCCFactory::addVertex(GModel *gm, double x, double y, double z, double lc)
 {
@@ -618,6 +650,52 @@ GEdge *OCCFactory::addNURBS(GModel *gm, GVertex *start, GVertex *end,
   return 0;
 }
 
+/* add2Drect: rectangluar face, given lower left point and width/height (in X-Y plane)*/
+GFace *OCCFactory::add2Drect(GModel *gm,double x0, double y0, double dx, double dy)
+{
+	Msg::Info("Default working plane is XY in add2D* functions...");
+	
+	if (!gm->_occ_internals)
+		gm->_occ_internals = new OCC_Internals;
+
+	TopoDS_Vertex occv1 = BRepBuilderAPI_MakeVertex( gp_Pnt(x0   , y0   , 0.) );
+	TopoDS_Vertex occv2 = BRepBuilderAPI_MakeVertex( gp_Pnt(x0+dx, y0   , 0.) );
+	TopoDS_Vertex occv3 = BRepBuilderAPI_MakeVertex( gp_Pnt(x0+dx, y0+dy, 0.) );
+	TopoDS_Vertex occv4 = BRepBuilderAPI_MakeVertex( gp_Pnt(x0   , y0+dy, 0.) );
+
+	TopoDS_Edge occEdge1 = BRepBuilderAPI_MakeEdge(occv1,occv2);
+	TopoDS_Edge occEdge2 = BRepBuilderAPI_MakeEdge(occv2,occv3);
+	TopoDS_Edge occEdge3 = BRepBuilderAPI_MakeEdge(occv3,occv4);
+	TopoDS_Edge occEdge4 = BRepBuilderAPI_MakeEdge(occv4,occv1);
+
+	TopoDS_Wire rectWire = BRepBuilderAPI_MakeWire(occEdge1 , occEdge2 , occEdge3, occEdge4);
+	TopoDS_Face rectFace = BRepBuilderAPI_MakeFace(rectWire);
+
+	return gm->_occ_internals->addFaceToModel(gm, TopoDS::Face(rectFace));
+}
+
+/* add2Dellips: ellips face, given lower left point and width/height (in X-Y plane)*/
+GFace *OCCFactory::add2Dellips(GModel *gm, double xc, double yc, double rx, double ry)
+{
+	Msg::Info("Default working plane is XY in add2D* functions...");
+	
+	if (!gm->_occ_internals)
+		gm->_occ_internals = new OCC_Internals;
+ 	
+	gp_Dir N_dir(0., 0., 1.); 
+	gp_Dir x_dir(1., 0., 0.); 
+	gp_Pnt center(xc, yc, 0.); 
+	gp_Ax2 axis(center, N_dir, x_dir);  
+	gp_Elips ellipse = gp_Elips(axis, rx, ry);  
+	// gp_Ax2(gp_Pnt(xc,yc;0),gp_Dir(0.,0.,1.)),rx,ry
+	TopoDS_Edge ellipsEdge = BRepBuilderAPI_MakeEdge(ellipse);
+	TopoDS_Wire ellipsWire = BRepBuilderAPI_MakeWire(ellipsEdge);
+	TopoDS_Face ellipsFace = BRepBuilderAPI_MakeFace(ellipsWire);
+	// TopoDS_Edge ellipsEdge = BRepBuilderAPI_MakeEdge( gp_Elips2d(gp_Ax22d(gp_Pnt2d(xc,yc),gp_Dir2d(1.,0.), gp_Dir2d(0.,1.)),rx,ry) );
+	
+	return gm->_occ_internals->addFaceToModel(gm, TopoDS::Face(ellipsFace));
+}
+
 /*
 GEdge *OCCFactory::addBezierSurface(GModel *gm,
 				    std::vector<GEdge *> & wires, // four edges indeed
@@ -854,6 +932,27 @@ GEntity *OCCFactory::addBlock(GModel *gm, std::vector<double> p1,
   return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
 }
 
+GEntity *OCCFactory::add3DBlock(GModel *gm,std::vector<double> p1, 
+																					 double dx, double dy, double dz)
+{
+	if (!gm->_occ_internals)
+		gm->_occ_internals = new OCC_Internals;
+    
+	gp_Pnt P1(p1[0], p1[1], p1[2]);
+	BRepPrimAPI_MakeBox MB(P1, dx, dy, dz);
+	MB.Build();
+	if (!MB.IsDone()) {
+		Msg::Error("Box can not be computed from the given point");
+		return 0;
+	}
+	TopoDS_Shape shape = MB.Shape();
+	gm->_occ_internals->buildShapeFromLists(shape);
+	gm->destroy();
+	gm->_occ_internals->buildLists();
+	gm->_occ_internals->buildGModel(gm);
+	return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
+}
+
 GModel *OCCFactory::computeBooleanUnion(GModel* obj, GModel* tool,
                                         int createNewModel)
 {
@@ -936,6 +1035,329 @@ GModel *OCCFactory::computeBooleanIntersection(GModel* obj, GModel* tool,
   return obj;
 }
 
+/* same as checkbox GUI - works a bit better than occconnect... */
+void OCCFactory::salomeconnect(GModel *gm)
+{
+#if defined(HAVE_SALOME)
+	Msg::Info("- cutting and connecting faces with Salome's Partition_Spliter");
+	TopExp_Explorer e2;
+	Partition_Spliter ps;
+	TopoDS_Shape shape = gm->_occ_internals->getShape();
+	for (e2.Init(shape, TopAbs_SOLID); e2.More(); e2.Next())
+		ps.AddShape(e2.Current());
+	try{
+		ps.Compute();
+		shape = ps.Shape();
+		gm->destroy();
+		gm->_occ_internals->loadShape(&shape);
+		gm->_occ_internals->buildLists();
+		gm->_occ_internals->buildGModel(gm);
+	}
+	catch(Standard_Failure &err){
+		Msg::Error("%s", err.GetMessageString());
+	}
+#else
+	Msg::Info("You need to recompile with Salome support to use Salome's Partition_Spliter");
+#endif
+}
+
+/* same as checkbox GUI - does not work at all, though!*/
+void OCCFactory::occconnect(GModel *gm)
+{
+	Msg::Info("- cutting and connecting faces with OCC_Connect");
+	OCC_Connect connect(1);
+	TopoDS_Shape shape = gm->_occ_internals->getShape();
+	for(TopExp_Explorer p(shape, TopAbs_SOLID); p.More(); p.Next())
+		connect.Add(p.Current());
+	connect.Connect();
+	shape = connect;
+	gm->destroy();
+	gm->_occ_internals->loadShape(&shape);
+	gm->_occ_internals->buildLists();
+	gm->_occ_internals->buildGModel(gm);
+}
+
+
+/* IsEqualG : a tolerance function for setPeriodicAllFaces */
+bool IsEqualG(double x, double y);
+bool IsEqualG(double x, double y)
+{
+	const double epsilon = 0.00000000001;
+	return fabs(x - y) <= epsilon * (std::max(fabs(x),fabs(y)));
+}
+
+/* setPeriodicAllFaces: detects T-periodic pair of faces and 
+uses setPeriodicPairOfFaces to make them all periodic */
+void OCCFactory::setPeriodicAllFaces(GModel *gm, std::vector<double> FaceTranslationVector) 
+{	
+	Msg::Info("Experimental: search for 'translated' faces and calls setPeriodicPairOfFaces automatically");
+	TopoDS_Shape shape = gm->_occ_internals->getShape();
+	gp_Trsf theTransformation;
+	gp_Vec theVectorOfTranslation(FaceTranslationVector[0], FaceTranslationVector[1], FaceTranslationVector[2]);	
+	int               numFaceMaster   , numFaceSlave;
+	std::list<GEdge*> ListOfEdgeMaster, ListOfEdgeSlave;
+	for(TopExp_Explorer aFaceExplorer(shape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
+	{
+		TopoDS_Face aFace1 = TopoDS::Face(aFaceExplorer.Current());		
+		for(TopExp_Explorer aFaceExplorer2(shape, TopAbs_FACE); aFaceExplorer2.More(); aFaceExplorer2.Next())
+		{
+			TopoDS_Face aFace2 = TopoDS::Face(aFaceExplorer2.Current());
+			// Get number of Edges
+			int NumberOfEdgesInFace1=0;
+			int NumberOfEdgesInFace2=0;
+			for (TopExp_Explorer aEdgeExplorer1(aFace1,TopAbs_EDGE); aEdgeExplorer1.More(); aEdgeExplorer1.Next()) {NumberOfEdgesInFace1++;}
+			for (TopExp_Explorer aEdgeExplorer2(aFace2,TopAbs_EDGE); aEdgeExplorer2.More(); aEdgeExplorer2.Next()) {NumberOfEdgesInFace2++;}
+			// Get Surfaces of Faces (occtopo=>occgeom)
+			Handle(Geom_Surface) Surf1=BRep_Tool::Surface(aFace1);
+			Handle(Geom_Surface) Surf2=BRep_Tool::Surface(aFace2);
+			// Get barycenter and area
+			GProp_GProps FaceProps1;
+			GProp_GProps FaceProps2;
+			BRepGProp::SurfaceProperties(aFace1,FaceProps1);
+			BRepGProp::SurfaceProperties(aFace2,FaceProps2);
+			gp_Pnt BarycenterFace1 = FaceProps1.CentreOfMass ();
+			gp_Pnt BarycenterFace2 = FaceProps2.CentreOfMass ();
+			Standard_Real Area1 = FaceProps1.Mass();
+			Standard_Real Area2 = FaceProps2.Mass();		
+			// Get surface normal	
+			Standard_Real umin, vmin;//umax,vmax
+			GeomLProp_SLProps props1(Surf1, umin, vmin, 1, 0.01);
+			GeomLProp_SLProps props2(Surf2, umin, vmin, 1, 0.01);
+			gp_Dir norm1=props1.Normal();
+			gp_Dir norm2=props2.Normal();
+
+			if(  NumberOfEdgesInFace1==NumberOfEdgesInFace2 
+				&& IsEqualG(Area1,Area2)
+					&& IsEqualG(BarycenterFace1.X()+FaceTranslationVector[0],BarycenterFace2.X()) 
+						&& IsEqualG(BarycenterFace1.Y()+FaceTranslationVector[1],BarycenterFace2.Y()) 
+							&& IsEqualG(BarycenterFace1.Z()+FaceTranslationVector[2],BarycenterFace2.Z()) 
+			){
+				numFaceMaster = gm->getOCCInternals()->getGTagOfOCCFaceByNativePtr(gm,aFace1); 
+				numFaceSlave  = gm->getOCCInternals()->getGTagOfOCCFaceByNativePtr(gm,aFace2);
+				//Msg::Info("Face %d (slave) is most likely Face %d (master) translated by (%.2e,%.2e,%.2e)!", 
+				//           numFaceSlave,numFaceMaster,FaceTranslationVector[0],FaceTranslationVector[1],FaceTranslationVector[2]);
+
+				std::vector<int>  EdgeListMaster(NumberOfEdgesInFace1);
+				std::vector<int>  EdgeListSlave(NumberOfEdgesInFace2);
+				int i1=0,i2=0;
+				
+				// ici il faut imbriquer la seconde boucle pour fournir des edges qui match slave/master
+				for (TopExp_Explorer aEdgeExplorer1(aFace1,TopAbs_EDGE); aEdgeExplorer1.More(); aEdgeExplorer1.Next()) {
+					TopoDS_Edge aEdge1 = TopoDS::Edge(aEdgeExplorer1.Current());
+					int numEdgeMaster  = gm->getOCCInternals()->getGTagOfOCCEdgeByNativePtr(gm,aEdge1);
+					EdgeListMaster[i1] = numEdgeMaster;
+					i2=0;
+					for (TopExp_Explorer aEdgeExplorer2(aFace2,TopAbs_EDGE); aEdgeExplorer2.More(); aEdgeExplorer2.Next()) {
+						TopoDS_Edge aEdge2 = TopoDS::Edge(aEdgeExplorer2.Current());
+						GProp_GProps EdgeProps1;
+						GProp_GProps EdgeProps2;
+						BRepGProp::LinearProperties(aEdge1, EdgeProps1);
+						BRepGProp::LinearProperties(aEdge2, EdgeProps2);
+						gp_Pnt BarycenterEdge1 = EdgeProps1.CentreOfMass ();
+						gp_Pnt BarycenterEdge2 = EdgeProps2.CentreOfMass ();
+						Standard_Real Length1 = EdgeProps1.Mass();
+						Standard_Real Length2 = EdgeProps2.Mass();		
+						if(     IsEqualG(Length1,Length2)
+							&& IsEqualG(BarycenterEdge1.X()+FaceTranslationVector[0],BarycenterEdge2.X()) 
+								&& IsEqualG(BarycenterEdge1.Y()+FaceTranslationVector[1],BarycenterEdge2.Y()) 
+									&& IsEqualG(BarycenterEdge1.Z()+FaceTranslationVector[2],BarycenterEdge2.Z()) 
+						){
+							int numEdgeSlave   = gm->getOCCInternals()->getGTagOfOCCEdgeByNativePtr(gm,aEdge2);
+							EdgeListSlave[i1]  = numEdgeSlave;
+						}
+					}
+					i1++;											
+				}
+				if(NumberOfEdgesInFace1==4)
+					Msg::Info("Setting Periodic : Face %d  {%d,%d,%d,%d} (slave) and Face %d  {%d,%d,%d,%d} (master)",
+				numFaceSlave ,EdgeListSlave[0] ,EdgeListSlave[1] ,EdgeListSlave[2] ,EdgeListSlave[3] ,
+				numFaceMaster,EdgeListMaster[0],EdgeListMaster[1],EdgeListMaster[2],EdgeListMaster[3]);
+				setPeriodicPairOfFaces(gm, numFaceMaster, EdgeListMaster, numFaceSlave, EdgeListSlave);
+			}
+			else ;
+		}
+	}
+}
+
+/* setPeriodicPairOfFaces: set periodic given a 
+Slave/Master pair of numFace-Edgelist */
+void OCCFactory::setPeriodicPairOfFaces(GModel *gm, int numFaceMaster, std::vector<int> EdgeListMaster, int numFaceSlave, std::vector<int> EdgeListSlave)
+{
+	int NEdges=EdgeListMaster.size();
+	if (EdgeListMaster.size() != EdgeListSlave.size())
+	{
+		Msg::Error("Slave/Master faces don't have the same number of edges!");
+	}
+	else
+	{
+		Surface *s_slave = FindSurface(abs(numFaceSlave));
+		if(s_slave)
+		{	
+			GModel::current()->getGEOInternals()->periodicFaces[numFaceSlave] = numFaceMaster;
+			for (int i = 0; i < NEdges; i++)
+			{
+				GModel::current()->getGEOInternals()->periodicEdges[EdgeListSlave[i]] = EdgeListMaster[i];
+				s_slave->edgeCounterparts[EdgeListSlave[i]] = EdgeListMaster[i];
+			}
+		}
+		else
+		{
+			GFace *gf = GModel::current()->getFaceByTag(abs(numFaceSlave));
+			if(gf)
+			{
+				gf->setMeshMaster(numFaceMaster);
+				for (int i = 0; i < NEdges; i++)
+				{
+					gf->edgeCounterparts[EdgeListSlave[i]] = EdgeListMaster[i];
+					GEdge *ges = GModel::current()->getEdgeByTag(abs(EdgeListSlave[i]));
+					ges->setMeshMaster(EdgeListMaster[i]);
+				}
+			}
+			else Msg::Error("Slave surface %d not found", numFaceSlave);
+		}
+	}
+}
+
+/* setPhysicalNumToEntitiesInBox allows to set a physical number to all entities 
+of a given type (0:vertex, 1:edge, 2:face, 3:volume) lying inside a 3D box 
+defined by 2 points */
+void OCCFactory::setPhysicalNumToEntitiesInBox(GModel *gm, int EntityType, int PhysicalGroupNumber, std::vector<double> p1, std::vector<double> p2)
+{
+	std::vector<int> ListOfGVerticeTagsInbox;
+	std::vector<int> ListOfGEdgesTagsInbox;
+	std::vector<int> ListOfGFacesTagsInbox;
+	std::vector<int> ListOfGRegionsTagsInbox;
+
+	Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+	TopoDS_Shape shape = gm->_occ_internals->getShape();
+	switch (EntityType) {
+		case 0 :
+		for(TopExp_Explorer aVertexExplorer(shape, TopAbs_VERTEX); aVertexExplorer.More(); aVertexExplorer.Next())
+		{
+			TopoDS_Vertex aVertex = TopoDS::Vertex(aVertexExplorer.Current());
+			Bnd_Box VertexBB;
+			BRepBndLib::Add(aVertex,VertexBB);
+			VertexBB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+			if(     aXmin>p1[0]
+				&& aYmin>p1[1]
+					&& aZmin>p1[2]
+						&& aXmax<p2[0]
+							&& aYmax<p2[1]
+								&& aZmax<p2[2]
+			){
+				int GVertexTag = gm->getOCCInternals()->getGTagOfOCCVertexByNativePtr(gm,aVertex);
+				//Msg::Info("This volume %d (xmin,ymin,zmin)=(%lf,%lf,%lf)  (xmax,ymax,zmax)=(%lf,%lf,%lf)",GVertexTag);
+				ListOfGVerticeTagsInbox.push_back(GVertexTag);
+			}
+		}
+		Msg::Info("These edges have OCC bounding boxes inside the given box!");
+		for (std::vector<int>::iterator it = ListOfGVerticeTagsInbox.begin() ; it != ListOfGVerticeTagsInbox.end(); ++it)
+		{
+			Msg::Info("- %d",*it);
+			GVertex *gv = gm->getVertexByTag(*it);
+			if(gv)
+			{
+				gv->addPhysicalEntity(PhysicalGroupNumber);
+			}
+		}
+		break;
+		case 1 :
+		for(TopExp_Explorer aEdgeExplorer(shape, TopAbs_EDGE); aEdgeExplorer.More(); aEdgeExplorer.Next())
+		{
+			TopoDS_Edge aEdge = TopoDS::Edge(aEdgeExplorer.Current());
+			Bnd_Box EdgeBB;
+			BRepBndLib::Add(aEdge,EdgeBB);
+			EdgeBB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+		
+			if(     aXmin>p1[0]
+				&& aYmin>p1[1]
+					&& aZmin>p1[2]
+						&& aXmax<p2[0]
+							&& aYmax<p2[1]
+								&& aZmax<p2[2]
+			){
+				int GEdgeTag = gm->getOCCInternals()->getGTagOfOCCEdgeByNativePtr(gm,aEdge);
+				//Msg::Info("This edge %d (xmin,ymin,zmin)=(%lf,%lf,%lf)  (xmax,ymax,zmax)=(%lf,%lf,%lf)",GEdgeTag);
+				ListOfGEdgesTagsInbox.push_back(GEdgeTag);
+			}
+		}
+		Msg::Info("These edges have OCC bounding boxes inside the given box!");
+		for (std::vector<int>::iterator it = ListOfGEdgesTagsInbox.begin() ; it != ListOfGEdgesTagsInbox.end(); ++it)
+		{
+			Msg::Info("- %d",*it);
+			GEdge *ge = gm->getEdgeByTag(*it);
+			if(ge)
+			{
+				ge->addPhysicalEntity(PhysicalGroupNumber);
+			}
+		}
+		break;
+		case 2 :
+		for(TopExp_Explorer aFaceExplorer(shape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
+		{
+			TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());
+			Bnd_Box FaceBB;
+			BRepBndLib::Add(aFace,FaceBB);
+			FaceBB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+		
+			if(     aXmin>p1[0]
+				&& aYmin>p1[1]
+					&& aZmin>p1[2]
+						&& aXmax<p2[0]
+							&& aYmax<p2[1]
+								&& aZmax<p2[2]
+			){
+				int GFaceTag = gm->getOCCInternals()->getGTagOfOCCFaceByNativePtr(gm,aFace);
+				//Msg::Info("This face %d (xmin,ymin,zmin)=(%lf,%lf,%lf)  (xmax,ymax,zmax)=(%lf,%lf,%lf)",GFaceTag);
+				ListOfGFacesTagsInbox.push_back(GFaceTag);
+			}
+		}
+		Msg::Info("This faces have OCC bounding boxes inside the given box!");
+		for (std::vector<int>::iterator it = ListOfGFacesTagsInbox.begin() ; it != ListOfGFacesTagsInbox.end(); ++it)
+		{
+			Msg::Info("- %d",*it);
+			GFace *gf = gm->getFaceByTag(*it);
+			if(gf)
+			{
+				gf->addPhysicalEntity(PhysicalGroupNumber);
+			}
+		}
+		break;
+		case 3 :
+		for(TopExp_Explorer aSolidExplorer(shape, TopAbs_SOLID); aSolidExplorer.More(); aSolidExplorer.Next())
+		{
+			TopoDS_Solid aSolid = TopoDS::Solid(aSolidExplorer.Current());
+			Bnd_Box SolidBB;
+			BRepBndLib::Add(aSolid,SolidBB);
+			SolidBB.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+			if(     aXmin>p1[0]
+				&& aYmin>p1[1]
+					&& aZmin>p1[2]
+						&& aXmax<p2[0]
+							&& aYmax<p2[1]
+								&& aZmax<p2[2]
+			){
+				int GSolidTag = gm->getOCCInternals()->getGTagOfOCCSolidByNativePtr(gm,aSolid);
+				//Msg::Info("This volume %d (xmin,ymin,zmin)=(%lf,%lf,%lf)  (xmax,ymax,zmax)=(%lf,%lf,%lf)",GSolidTag);
+				ListOfGRegionsTagsInbox.push_back(GSolidTag);
+			}
+		}
+		Msg::Info("These edges have OCC bounding boxes inside the given box!");
+		for (std::vector<int>::iterator it = ListOfGRegionsTagsInbox.begin() ; it != ListOfGRegionsTagsInbox.end(); ++it)
+		{
+			Msg::Info("- %d",*it);
+			GRegion *gr = gm->getRegionByTag(*it);
+			if(gr)
+			{
+				gr->addPhysicalEntity(PhysicalGroupNumber);
+			}
+		}
+		break;
+		default: 
+		Msg::Error("First argument of setPhysicalNumToEntitiesInBox should be 0,1,2 or 3 (Vertice, Edge, Surface or Volume)");
+	}
+}
+
 void OCCFactory::fillet(GModel *gm, std::vector<int> edges, double radius)
 {
   try{
diff --git a/Geo/GModelFactory.h b/Geo/GModelFactory.h
index 57f2659742c904c44f6ede28147d2389f4e070cf..90433e8bd038e60aac55561b47e666dfc5b7dac1 100644
--- a/Geo/GModelFactory.h
+++ b/Geo/GModelFactory.h
@@ -76,6 +76,16 @@ class GModelFactory {
     Msg::Error("addFace not implemented yet");
     return 0;
   }
+  virtual GFace *add2Drect(GModel *gm,double x0, double y0, double dx, double dy)
+  {
+    Msg::Error("add2Drect not implemented yet");
+    return 0;
+  }  
+  virtual GFace *add2Dellips(GModel *gm,double xc, double yc, double rx, double ry)
+  {
+    Msg::Error("add2Dellips not implemented yet");
+    return 0;
+  }  
 
   // sweep stuff
   virtual GEntity *revolve(GModel *gm, GEntity*, std::vector<double> p1,
@@ -121,13 +131,19 @@ class GModelFactory {
   {
     Msg::Error("addTorus not implemented yet");
     return 0;
-  }
+  } 
   virtual GEntity *addBlock(GModel *gm, std::vector<double> p1,
                             std::vector<double> p2)
   {
     Msg::Error("addBlock not implemented yet");
     return 0;
   }
+  virtual GEntity *add3DBlock(GModel *gm, std::vector<double> p1,
+                            double dx, double dy, double dz)
+  {
+    Msg::Error("add3DBlock not implemented yet");
+    return 0;
+  }
   virtual GEntity *addCone(GModel *gm, std::vector<double> p1,
                            std::vector<double> p2, double radius1,
                            double radius2)
@@ -172,6 +188,29 @@ class GModelFactory {
     Msg::Error("computeBooleanDifference not implemented yet");
     return 0;
   }
+  
+	virtual void salomeconnect(GModel *gm)
+  {
+    Msg::Error("salomeconnect not implemented yet");
+  }
+  virtual void occconnect(GModel *gm)
+  {
+    Msg::Error("occconnect not implemented yet");
+  }
+  virtual void setPeriodicAllFaces(GModel *gm, std::vector<double> FaceTranslationVector)
+  {
+    Msg::Error("findperiodic not implemented yet");
+  }  
+  virtual void setPeriodicPairOfFaces(GModel *gm, int numFaceMaster, std::vector<int> EdgeListMaster, int numFaceSlave, std::vector<int> EdgeListSlave)
+  {
+    Msg::Error("setPeriodicPairOfFaces not implemented yet");
+  }  
+  ;
+  virtual void setPhysicalNumToEntitiesInBox(GModel *gm, int EntityType, int PhysicalGroupNumber, std::vector<double> p1,std::vector<double> p2)
+  {
+    Msg::Error("setPhysicalNumToEntitiesInBox not implemented yet");
+  }  
+
 };
 
 class GeoFactory : public GModelFactory {
@@ -218,10 +257,13 @@ class OCCFactory : public GModelFactory {
   GFace *addFace(GModel *gm, std::vector<GEdge *> edges,
                  std::vector< std::vector<double > > points);
   GFace *addPlanarFace(GModel *gm, std::vector<std::vector<GEdge *> > edges);
+  GFace *add2Drect(GModel *gm,double x0, double y0, double dx, double dy);
+  GFace *add2Dellips(GModel *gm,double xc, double yc, double rx, double ry);
   GRegion *addVolume(GModel *gm, std::vector<std::vector<GFace *> > faces);
   GEntity *addTorus(GModel *gm,std::vector<double> p1, std::vector<double> p2,
                     double radius1, double radius2);
   GEntity *addBlock(GModel *gm,std::vector<double> p1, std::vector<double> p2);
+  GEntity *add3DBlock(GModel *gm,std::vector<double> p1, double dx, double dy, double dz);
   GEntity *addCone(GModel *gm,std::vector<double> p1, std::vector<double> p2,
                    double radius1, double radius2);
   void translate(GModel *gm, std::vector<double> dx, int addToTheModel);
@@ -230,6 +272,13 @@ class OCCFactory : public GModelFactory {
   GModel *computeBooleanUnion(GModel *obj, GModel *tool, int createNewModel);
   GModel *computeBooleanIntersection(GModel *obj, GModel *tool, int createNewModel);
   GModel *computeBooleanDifference(GModel *obj, GModel *tool, int createNewModel);
+  void    salomeconnect(GModel *gm);
+  void    occconnect(GModel *gm);
+	
+  void setPeriodicAllFaces(GModel *gm, std::vector<double> FaceTranslationVector);
+  void setPeriodicPairOfFaces(GModel *gm, int numFaceMaster, std::vector<int> EdgeListMaster, int numFaceSlave, std::vector<int> EdgeListSlave);
+  void setPhysicalNumToEntitiesInBox(GModel *gm, int EntityType, int PhysicalGroupNumber, std::vector<double> p1, std::vector<double> p2);
+	
   void fillet(GModel *gm, std::vector<int> edges, double radius);
 };
 
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index fe8f3be13db0bb0342fcb87f26b595946401439a..0181a5ab05e0873a56023b66edd5f0ca45f94726 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -698,6 +698,35 @@ GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region)
   return getOCCRegionByNativePtr(model, region);
 }
 
+/* I needed getGTagOfOCC*ByNativePtr whithin setPhysicalNumToEntitiesInBox */
+int OCC_Internals::getGTagOfOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind)
+{
+	if(gvNumCache.IsBound(toFind))
+		return (int)gvNumCache.Find(toFind);
+	return 0;	
+}
+
+int OCC_Internals::getGTagOfOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind)
+{
+	if(gfNumCache.IsBound(toFind))
+		return (int)gfNumCache.Find(toFind);
+	return 0;
+}
+
+int OCC_Internals::getGTagOfOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind)
+{
+	if(geNumCache.IsBound(toFind))
+		return (int)geNumCache.Find(toFind);
+	return 0;
+}
+
+int OCC_Internals::getGTagOfOCCSolidByNativePtr(GModel *model, TopoDS_Solid toFind)
+{
+	if(grNumCache.IsBound(toFind))
+		return (int)grNumCache.Find(toFind);
+	return 0;	
+}
+
 void OCC_Internals::buildGModel(GModel *model)
 {
   // building geom vertices
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index ace5d5cea2925283cf4627600d10f838125f3175..d0d132cf18c06598da05553b618e300639e9806f 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -57,6 +57,11 @@ class OCC_Internals {
   GRegion *addRegionToModel(GModel *model, TopoDS_Solid r);
   void fillet(std::vector<TopoDS_Edge> &shapes, double radius);
   void applyBooleanOperator(TopoDS_Shape tool, const BooleanOperator &op);
+	
+  int getGTagOfOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind);
+  int getGTagOfOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind);
+  int getGTagOfOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind);
+  int getGTagOfOCCSolidByNativePtr(GModel *model, TopoDS_Solid toFind);
 };
 
 #endif