From 178a07a384e6f5de092aa3295048df94dc444a71 Mon Sep 17 00:00:00 2001
From: Guillaume Demesy <demesy@MacBook-Pro-de-Guillaume.local>
Date: Thu, 23 Mar 2017 13:58:32 +0100
Subject: [PATCH] interface to OCC GTransform - prepare OCC dilate

---
 Geo/GModelFactory.cpp | 151 ++++++++++++++++++++++++------------------
 Geo/GModelFactory.h   |  21 +++---
 Geo/GModelIO_GEO.cpp  |   2 +-
 Geo/GModelIO_GEO.h    |   3 +-
 Geo/GModelIO_OCC.cpp  |  31 +++++++++
 Geo/GModelIO_OCC.h    |  11 ++-
 6 files changed, 142 insertions(+), 77 deletions(-)

diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp
index 6c8cc1f58a..cf07dea5f3 100644
--- a/Geo/GModelFactory.cpp
+++ b/Geo/GModelFactory.cpp
@@ -53,7 +53,7 @@ GEdge *GeoFactory::addLine(GModel *gm, GVertex *start, GVertex *end)
   List_Add(iList, &tagEnd);
 
   Curve *c = CreateCurve(num, MSH_SEGM_LINE, 1, iList, NULL,
-			  -1, -1, 0., 1.);
+        -1, -1, 0., 1.);
   Tree_Add(gm->getGEOInternals()->Curves, &c);
   CreateReversedCurve(c);
   List_Delete(iList);
@@ -146,7 +146,7 @@ GEdge* GeoFactory::addCircleArc(GModel *gm,GVertex *begin, GVertex *center, GVer
   List_Add(iList, &tagEnd);
 
   Curve *c = CreateCurve(num, MSH_SEGM_CIRC, 1, iList, NULL,
-			  -1, -1, 0., 1.);
+        -1, -1, 0., 1.);
   Tree_Add(gm->getGEOInternals()->Curves, &c);
   CreateReversedCurve(c);
   List_Delete(iList);
@@ -327,8 +327,8 @@ std::vector<GEntity*> GeoFactory::extrudeBoundaryLayer(GModel *gm, GEntity *e,
   //      ge->geomType() == GEntity::BoundaryLayerCurve){
   //     ExtrudeParams *ep = ge->meshAttributes.extrude;
   //     if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == COPIED_ENTITY &&
-  // 	std::abs(ep->geo.Source) ==e->tag() )
-  // 	  newEnt = ge;
+  //  std::abs(ep->geo.Source) ==e->tag() )
+  //    newEnt = ge;
   //     }
   //   }
   // }
@@ -336,11 +336,11 @@ std::vector<GEntity*> GeoFactory::extrudeBoundaryLayer(GModel *gm, GEntity *e,
   //   for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); it++){
   //     GFace *gf = *it;
   //     if(gf->getNativeType() == GEntity::GmshModel &&
-  // 	 gf->geomType() == GEntity::BoundaryLayerSurface){
-  // 	ExtrudeParams *ep = gf->meshAttributes.extrude;
-  // 	if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == COPIED_ENTITY
-  // 	   && std::abs(ep->geo.Source) == e->tag())
-  // 	  newEnt = gf;
+  //   gf->geomType() == GEntity::BoundaryLayerSurface){
+  //  ExtrudeParams *ep = gf->meshAttributes.extrude;
+  //  if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == COPIED_ENTITY
+  //     && std::abs(ep->geo.Source) == e->tag())
+  //    newEnt = gf;
   //     }
   //   }
   // }
@@ -375,50 +375,50 @@ GFace *GeoFactory::_addPlanarFace(GModel *gm, const std::vector<std::vector<GEdg
       //create curve if it does not exist
       Curve *c = FindCurve(numEdge);
       if(!c){
-	GVertex *gvb = ge->getBeginVertex();
-	GVertex *gve = ge->getEndVertex();
-	Vertex *vertb = FindPoint(abs(gvb->tag()));
-	Vertex *verte = FindPoint(abs(gve->tag()));
-	if (!vertb){
-	  vertb = CreateVertex(gvb->tag(), gvb->x(), gvb->y(), gvb->z(),
-				gvb->prescribedMeshSizeAtVertex(), 1.0);
-	  Tree_Add(gm->getGEOInternals()->Points, &vertb);
-	  vertb->Typ = MSH_POINT;
-	  vertb->Num = gvb->tag();
-	 }
-	if (!verte){
-	  verte = CreateVertex(gve->tag(), gve->x(), gve->y(), gve->z(),
-				gve->prescribedMeshSizeAtVertex(), 1.0);
-	  Tree_Add(gm->getGEOInternals()->Points, &verte);
-	  verte->Typ = MSH_POINT;
-	  verte->Num = gve->tag();
-	}
-
-	if (ge->geomType() == GEntity::Line){
-	  c = CreateCurve(numEdge, MSH_SEGM_LINE, 1, NULL, NULL, -1, -1, 0., 1.);
-	}
-	else if (ge->geomType() == GEntity::DiscreteCurve){
-	  c = CreateCurve(numEdge, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);
-	}
-	else if(ge->geomType() == GEntity::CompoundCurve){
-	  c = CreateCurve(numEdge, MSH_SEGM_COMPOUND, 1, NULL, NULL, -1, -1, 0., 1.);
-	  std::vector<GEdge*> gec = ((GEdgeCompound*)ge)->getCompounds();
-	  for(unsigned int i = 0; i < gec.size(); i++)
-	    c->compound.push_back(gec[i]->tag());
-	}
-	else{
-	  c = CreateCurve(numEdge, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);
-	}
-
-	c->Control_Points = List_Create(2, 1, sizeof(Vertex *));
-	List_Add(c->Control_Points, &vertb);
-	List_Add(c->Control_Points, &verte);
-	c->beg = vertb;
-	c->end = verte;
-	EndCurve(c);
-
-	Tree_Add(gm->getGEOInternals()->Curves, &c);
-	CreateReversedCurve(c);
+  GVertex *gvb = ge->getBeginVertex();
+  GVertex *gve = ge->getEndVertex();
+  Vertex *vertb = FindPoint(abs(gvb->tag()));
+  Vertex *verte = FindPoint(abs(gve->tag()));
+  if (!vertb){
+    vertb = CreateVertex(gvb->tag(), gvb->x(), gvb->y(), gvb->z(),
+        gvb->prescribedMeshSizeAtVertex(), 1.0);
+    Tree_Add(gm->getGEOInternals()->Points, &vertb);
+    vertb->Typ = MSH_POINT;
+    vertb->Num = gvb->tag();
+   }
+  if (!verte){
+    verte = CreateVertex(gve->tag(), gve->x(), gve->y(), gve->z(),
+        gve->prescribedMeshSizeAtVertex(), 1.0);
+    Tree_Add(gm->getGEOInternals()->Points, &verte);
+    verte->Typ = MSH_POINT;
+    verte->Num = gve->tag();
+  }
+
+  if (ge->geomType() == GEntity::Line){
+    c = CreateCurve(numEdge, MSH_SEGM_LINE, 1, NULL, NULL, -1, -1, 0., 1.);
+  }
+  else if (ge->geomType() == GEntity::DiscreteCurve){
+    c = CreateCurve(numEdge, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);
+  }
+  else if(ge->geomType() == GEntity::CompoundCurve){
+    c = CreateCurve(numEdge, MSH_SEGM_COMPOUND, 1, NULL, NULL, -1, -1, 0., 1.);
+    std::vector<GEdge*> gec = ((GEdgeCompound*)ge)->getCompounds();
+    for(unsigned int i = 0; i < gec.size(); i++)
+      c->compound.push_back(gec[i]->tag());
+  }
+  else{
+    c = CreateCurve(numEdge, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);
+  }
+
+  c->Control_Points = List_Create(2, 1, sizeof(Vertex *));
+  List_Add(c->Control_Points, &vertb);
+  List_Add(c->Control_Points, &verte);
+  c->beg = vertb;
+  c->end = verte;
+  EndCurve(c);
+
+  Tree_Add(gm->getGEOInternals()->Curves, &c);
+  CreateReversedCurve(c);
       }
       int signedNumEdge = numEdge*signedEdge.getSign();
       List_Add(temp, &signedNumEdge);
@@ -479,6 +479,7 @@ GFace *GeoFactory::_addPlanarFace(GModel *gm, const std::vector<std::vector<GEdg
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_GTransform.hxx>
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepFilletAPI_MakeFillet.hxx>
 #include <BRepGProp.hxx>
@@ -573,6 +574,7 @@ GFace *GeoFactory::_addPlanarFace(GModel *gm, const std::vector<std::vector<GEdg
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Trsf.hxx>
+#include <gp_GTrsf.hxx>
 #include <gp_Vec.hxx>
 
 GVertex *OCCFactory::addVertex(GModel *gm, double x, double y, double z, double lc)
@@ -604,7 +606,7 @@ GEdge *OCCFactory::addLine(GModel *gm, GVertex *start, GVertex *end)
   TopoDS_Edge occEdge;
   if (occv1 && occv2){
      occEdge = BRepBuilderAPI_MakeEdge(occv1->getShape(),
-				       occv2->getShape()).Edge();
+               occv2->getShape()).Edge();
   }
   else{
     gp_Pnt p1(start->x(),start->y(),start->z());
@@ -656,7 +658,7 @@ GEdge *OCCFactory::addCircleArc(GModel *gm, const arcCreationMethod &method,
 
 GEdge *OCCFactory::addSpline(GModel *gm, const splineType &type,
                              GVertex *start, GVertex *end,
-			     std::vector<std::vector<double> > points)
+           std::vector<std::vector<double> > points)
 {
   if (!gm->_occ_internals)
     gm->_occ_internals = new OCC_Internals;
@@ -702,10 +704,10 @@ GEdge *OCCFactory::addSpline(GModel *gm, const splineType &type,
 
 
 GEdge *OCCFactory::addNURBS(GModel *gm, GVertex *start, GVertex *end,
-			    std::vector<std::vector<double> > points,
-			    std::vector<double> knots,
-			    std::vector<double> weights,
-			    std::vector<int> mult)
+          std::vector<std::vector<double> > points,
+          std::vector<double> knots,
+          std::vector<double> weights,
+          std::vector<int> mult)
 {
   try{
   if (!gm->_occ_internals)
@@ -735,7 +737,7 @@ GEdge *OCCFactory::addNURBS(GModel *gm, GVertex *start, GVertex *end,
 
   const int degree = totKnots - nbControlPoints - 1;
   Msg::Debug("creation of a nurbs of degree %d with %d control points",
-	     degree,nbControlPoints);
+       degree,nbControlPoints);
 
   int index = 1;
   ctrlPoints.SetValue(index++, gp_Pnt(start->x(), start->y(), start->z()));
@@ -1265,8 +1267,8 @@ void OCCFactory::fillet(GModel *gm, std::vector<int> edges, double radius)
     for (unsigned i = 0; i < edges.size(); i++){
       GEdge *ed = gm->getEdgeByTag(edges[i]);
       if (ed){
-	OCCEdge *occed = dynamic_cast<OCCEdge*>(ed);
-	if (occed)edgesToFillet.push_back(occed->getTopoDS_Edge());
+  OCCEdge *occed = dynamic_cast<OCCEdge*>(ed);
+  if (occed)edgesToFillet.push_back(occed->getTopoDS_Edge());
       }
     }
     gm->_occ_internals->fillet(edgesToFillet, radius);
@@ -1324,6 +1326,27 @@ void OCCFactory::rotate(GModel *gm, std::vector<double> p1, std::vector<double>
   gm->_occ_internals->buildGModel(gm);
 }
 
+void OCCFactory::dilate(GModel *gm, std::vector<double> s, int addToTheModel)
+{
+  if (!gm->_occ_internals)
+    gm->_occ_internals = new OCC_Internals;
+
+  const double a = s[0];
+  const double b = s[1];
+  const double c = s[2];
+
+  gp_GTrsf transformation;  
+  transformation.SetVectorialPart(gp_Mat(a, 0, 0, 0, b, 0, 0, 0, c));
+  BRepBuilderAPI_GTransform aTransformation(gm->_occ_internals->getShape(),
+                                           transformation, Standard_False);
+  TopoDS_Shape temp = aTransformation.Shape();
+  if (!addToTheModel) gm->_occ_internals->loadShape(&temp);
+  else gm->_occ_internals->buildShapeFromLists(temp);
+  gm->destroy();
+  gm->_occ_internals->buildLists();
+  gm->_occ_internals->buildGModel(gm);
+}
+
 std::vector<GFace *> OCCFactory::addRuledFaces(GModel *gm,
                                                std::vector< std::vector<GEdge *> > wires)
 {
@@ -1341,7 +1364,7 @@ std::vector<GFace *> OCCFactory::addRuledFaces(GModel *gm,
       GEdge *ge = wires[i][j];
       OCCEdge *occe = dynamic_cast<OCCEdge*>(ge);
       if (occe){
-	wire_maker.Add(occe->getTopoDS_Edge());
+  wire_maker.Add(occe->getTopoDS_Edge());
       }
     }
     aGenerator.AddWire (wire_maker.Wire());
@@ -1419,7 +1442,7 @@ GFace *OCCFactory::addPlanarFace(GModel *gm, std::vector< std::vector<GEdge *> >
       GEdge *ge = wires[i][j];
       OCCEdge *occe = dynamic_cast<OCCEdge*>(ge);
       if (occe){
-	wire_maker.Add(occe->getTopoDS_Edge());
+  wire_maker.Add(occe->getTopoDS_Edge());
       }
     }
     TopoDS_Wire myWire = wire_maker.Wire();
diff --git a/Geo/GModelFactory.h b/Geo/GModelFactory.h
index a0edcf5ea4..53bb022272 100644
--- a/Geo/GModelFactory.h
+++ b/Geo/GModelFactory.h
@@ -54,10 +54,10 @@ class GModelFactory {
     return 0;
   }
   virtual GEdge *addNURBS(GModel *gm, GVertex *start, GVertex *end,
-			  std::vector<std::vector<double> > controlPoints,
-			  std::vector<double> knots,
-			  std::vector<double> weights,
-			  std::vector<int> multiplicity)
+        std::vector<std::vector<double> > controlPoints,
+        std::vector<double> knots,
+        std::vector<double> weights,
+        std::vector<int> multiplicity)
   {
     Msg::Error("addNURBS not implemented yet");
     return 0;
@@ -66,7 +66,7 @@ class GModelFactory {
   // faces. If boundaries are co-planar, then it's a plane, otherwise,
   // we tru ruled, sweep or other kind of surfaces
   virtual std::vector<GFace *> addRuledFaces(GModel *gm,
-					     std::vector<std::vector<GEdge *> > edges)
+               std::vector<std::vector<GEdge *> > edges)
   {
     Msg::Error("addRuledFaces not implemented yet");
     return std::vector<GFace*>();
@@ -245,11 +245,11 @@ class OCCFactory : public GModelFactory {
                    GVertex *start, GVertex *end,
                    std::vector<std::vector<double> > controlPoints);
   GEdge *addNURBS(GModel *gm,
-		  GVertex *start, GVertex *end,
-		  std::vector<std::vector<double> > controlPoints,
-		  std::vector<double> knots,
-		  std::vector<double> weights,
-		  std::vector<int> multiplicity);
+      GVertex *start, GVertex *end,
+      std::vector<std::vector<double> > controlPoints,
+      std::vector<double> knots,
+      std::vector<double> weights,
+      std::vector<int> multiplicity);
   GEntity *revolve(GModel *gm, GEntity*,std::vector<double> p1,
                    std::vector<double> p2, double angle);
   GEntity *extrude(GModel *gm, GEntity*,std::vector<double> p1,
@@ -276,6 +276,7 @@ class OCCFactory : public GModelFactory {
   void translate(GModel *gm, std::vector<double> dx, int addToTheModel);
   void rotate(GModel *gm, std::vector<double> p1,std::vector<double> p2,
               double angle, int addToTheModel);
+  void dilate(GModel *gm, std::vector<double> s, int addToTheModel);
   GModel *computeBooleanUnion(GModel *obj, GModel *tool, int createNewModel);
   GModel *computeBooleanIntersection(GModel *obj, GModel *tool, int createNewModel);
   GModel *computeBooleanDifference(GModel *obj, GModel *tool, int createNewModel);
diff --git a/Geo/GModelIO_GEO.cpp b/Geo/GModelIO_GEO.cpp
index ac960cc592..db26089ba5 100644
--- a/Geo/GModelIO_GEO.cpp
+++ b/Geo/GModelIO_GEO.cpp
@@ -1278,7 +1278,7 @@ void GEO_Internals::synchronize(GModel *model)
           if(gr) comp.push_back(gr);
         }
         r = new GRegionCompound(model, v->Num, comp);
-	model->add(r);
+  model->add(r);
       }
       else if(!r){
         r = new gmshRegion(model, v);
diff --git a/Geo/GModelIO_GEO.h b/Geo/GModelIO_GEO.h
index f8d38d1dd6..ba4b76caf1 100644
--- a/Geo/GModelIO_GEO.h
+++ b/Geo/GModelIO_GEO.h
@@ -101,7 +101,8 @@ class GEO_Internals{
               double x, double y, double z, double ax, double ay, double az,
               double angle);
   bool dilate(const std::vector<std::pair<int, int> > &dimTags,
-              double x, double y, double z, double a, double b, double c);
+              double x, double y, double z,
+              double a, double b, double c);
   bool symmetry(const std::vector<std::pair<int, int> > &dimTags,
                 double a, double b, double c, double d);
 
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 34db6f6f6b..67716eeede 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -32,6 +32,7 @@
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_GTransform.hxx>
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepFilletAPI_MakeFillet.hxx>
 #include <BRepGProp.hxx>
@@ -1897,6 +1898,27 @@ bool OCC_Internals::_transform(const std::vector<std::pair<int, int> > &inDimTag
   return true;
 }
 
+bool OCC_Internals::_gtransform(const std::vector<std::pair<int, int> > &inDimTags,
+                               BRepBuilderAPI_GTransform *gtfo)
+{
+  for(unsigned int i = 0; i < inDimTags.size(); i++){
+    int dim = inDimTags[i].first;
+    int tag = inDimTags[i].second;
+    if(!isBound(dim, tag)){
+      Msg::Error("Unknown OpenCASCADE entity of dimension %d with tag %d",
+                 dim, tag);
+      return false;
+    }
+    gtfo->Perform(find(dim, tag), Standard_False);
+    if(!gtfo->IsDone()){
+      Msg::Error("Could not apply transformation");
+      return false;
+    }
+    bind(gtfo->Shape(), dim, tag);
+  }
+  return true;
+}
+
 bool OCC_Internals::translate(const std::vector<std::pair<int, int> > &inDimTags,
                               double dx, double dy, double dz)
 {
@@ -1917,6 +1939,15 @@ bool OCC_Internals::rotate(const std::vector<std::pair<int, int> > &inDimTags,
   return _transform(inDimTags, &tfo);
 }
 
+bool OCC_Internals::dilate(const std::vector<std::pair<int, int> > &inDimTags,
+                           double a, double b, double c)
+{
+  gp_GTrsf t;
+  t.SetVectorialPart(gp_Mat(a, 0, 0, 0, b, 0, 0, 0, c));
+  BRepBuilderAPI_GTransform gtfo(t);
+  return _gtransform(inDimTags, &gtfo);
+}
+
 bool OCC_Internals::copy(const std::vector<std::pair<int, int> > &inDimTags,
                          std::vector<std::pair<int, int> > &outDimTags)
 {
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index 2e1a439497..26a023b633 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -33,6 +33,7 @@ class ExtrudeParams;
 class BRepSweep_Prism;
 class BRepSweep_Revol;
 class BRepBuilderAPI_Transform;
+class BRepBuilderAPI_GTransform;
 
 class OCC_Internals {
  public:
@@ -81,10 +82,14 @@ class OCC_Internals {
                   bool fixsmalledges, bool fixspotstripfaces, bool sewfaces,
                   bool makesolids=false, double scaling=0.0);
 
-  // apply a geometrical transformation
+  // apply a geometrical transformation (does not modify Shape)
   bool _transform(const std::vector<std::pair<int, int> > &inDimTags,
                   BRepBuilderAPI_Transform *tfo);
 
+  // apply a G geometrical transformation (modifies Shape : affinity...)
+  bool _gtransform(const std::vector<std::pair<int, int> > &inDimTags,
+                  BRepBuilderAPI_GTransform *gtfo);
+
   // add circle or ellipse arc
   bool _addArc(int tag, int startTag, int centerTag, int endTag, int mode);
 
@@ -220,6 +225,10 @@ class OCC_Internals {
               double x, double y, double z, double ax, double ay, double az,
               double angle);
 
+  // apply gtransformations
+  bool dilate(const std::vector<std::pair<int, int> > &inDimTags,
+              double a, double b, double c);
+
   // copy and remove
   bool copy(const std::vector<std::pair<int, int> > &inDimTags,
             std::vector<std::pair<int, int> > &outDimTags);
-- 
GitLab