From 09a44c484fc6ae0b00d1319b40334edb9e8b097e Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Thu, 19 Jan 2017 15:11:43 +0000
Subject: [PATCH] addThruSections + temporary hack in Fuse bool op

---
 Fltk/drawContextFltk.h |  8 +++++---
 Geo/GModel.cpp         |  7 +++++++
 Geo/GModel.h           |  3 ++-
 Geo/GModelFactory.cpp  | 21 +++++++++++++++++++++
 Geo/GModelFactory.h    |  6 ++++++
 Geo/GModelIO_OCC.cpp   | 34 +++++++++++++++++++++++++++++-----
 6 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/Fltk/drawContextFltk.h b/Fltk/drawContextFltk.h
index 16c733c0ea..ffd2cd38ed 100644
--- a/Fltk/drawContextFltk.h
+++ b/Fltk/drawContextFltk.h
@@ -128,10 +128,12 @@ class drawContextFltk : public drawContextGlobal{
       else if(w <= 1680) return 13;
       else if(w <= 1920) return 14;
       return (w - 1920) / 160 + 15;
+      /*
+      float dpih, dpiv;
+      Fl::screen_dpi(dpih, dpiv);
+      return (int)(dpih / 8.);
+      */
     }
-    //float dpih, dpiv;
-    //Fl::screen_dpi(dpih, dpiv);
-    //return (int)(dpih * CTX::instance()->fontSize / 96.);
   }
   void setFont(int fontid, int fontsize)
   {
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 6f9eca6ba7..46b22df936 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -3254,6 +3254,13 @@ GEntity *GModel::addPipe(GEntity *e, std::vector<GEdge *>  edges)
   return 0;
 }
 
+GEntity *GModel::addThruSections(std::vector<std::vector<GEdge *> > edges)
+{
+  if(_factory)
+    return _factory->addThruSections(this,edges);
+  return 0;
+}
+
 GEntity *GModel::addSphere(double cx, double cy, double cz, double radius)
 {
   if(_factory) return _factory->addSphere(this, cx, cy, cz, radius);
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 4aa0e6f6f8..3570c55919 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -526,7 +526,8 @@ class GModel
   GEntity *extrude(GEntity *e, std::vector<double> p1, std::vector<double> p2);
   std::vector<GEntity*> extrudeBoundaryLayer(GEntity *e, int nbLayers, double hLayers,
                                              int dir=1, int view=-1);
-  GEntity *addPipe(GEntity *e, std::vector<GEdge *>  edges);
+  GEntity *addPipe(GEntity *e, std::vector<GEdge *> edges);
+  GEntity *addThruSections(std::vector<std::vector<GEdge *> > edges);
 
   std::vector<GFace *> addRuledFaces(std::vector<std::vector<GEdge *> > edges);
   GFace *addFace(std::vector<GEdge *> edges, std::vector< std::vector<double > > points);
diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp
index 1ecfd56461..8d2bba90a4 100644
--- a/Geo/GModelFactory.cpp
+++ b/Geo/GModelFactory.cpp
@@ -1483,6 +1483,27 @@ GEntity *OCCFactory::addPipe(GModel *gm, GEntity *base, std::vector<GEdge *> wir
   return ret;
 }
 
+GEntity *OCCFactory::addThruSections(GModel *gm, std::vector<std::vector<GEdge *> > wire)
+{
+  BRepOffsetAPI_ThruSections aGenerator(Standard_True); // create solid
+  for (unsigned i = 0; i < wire.size(); i++) {
+    BRepBuilderAPI_MakeWire wire_maker;
+    for (unsigned j = 0; j < wire[i].size(); j++) {
+      GEdge *ge = wire[i][j];
+      OCCEdge *occe = dynamic_cast<OCCEdge*>(ge);
+      if (occe){
+        wire_maker.Add(occe->getTopoDS_Edge());
+      }
+    }
+    aGenerator.AddWire(wire_maker.Wire());
+  }
+  aGenerator.CheckCompatibility(Standard_False);
+  aGenerator.Build();
+  TopoDS_Solid result = TopoDS::Solid(aGenerator.Shape());
+  GEntity *ret = gm->_occ_internals->addRegionToModel(gm, result);
+  return ret;
+}
+
 void OCCFactory::healGeometry(GModel *gm, double tolerance)
 {
   if (tolerance < 0.)
diff --git a/Geo/GModelFactory.h b/Geo/GModelFactory.h
index 0c4ca07d9e..2ebafe5416 100644
--- a/Geo/GModelFactory.h
+++ b/Geo/GModelFactory.h
@@ -115,6 +115,11 @@ class GModelFactory {
     Msg::Error("addPipe not implemented yet");
     return 0;
   }
+  virtual GEntity *addThruSections(GModel *gm, std::vector<std::vector<GEdge *> > wire)
+  {
+    Msg::Error("addThruSections not implemented yet");
+    return 0;
+  }
 
   // solid primitives
   virtual GEntity *addSphere(GModel *gm, double cx, double cy, double cz,
@@ -257,6 +262,7 @@ class OCCFactory : public GModelFactory {
   GEntity *extrude(GModel *gm, GEntity*,std::vector<double> p1,
                    std::vector<double> p2);
   GEntity *addPipe(GModel *gm, GEntity *base, std::vector<GEdge *> wire);
+  GEntity *addThruSections(GModel *gm, std::vector<std::vector<GEdge *> > wire);
   GEntity *addSphere(GModel *gm,double cx, double cy, double cz, double radius);
   GEntity *addCylinder(GModel *gm,std::vector<double> p1, std::vector<double> p2,
                        double radius);
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index ad1fc67191..6e7a9ab9d5 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -97,7 +97,6 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
     TopoDS_Solid solid = TopoDS::Solid(exp0.Current());
     if(somap.FindIndex(solid) < 1){
       somap.Add(solid);
-
       for(exp1.Init(solid, TopAbs_SHELL); exp1.More(); exp1.Next()){
         TopoDS_Shell shell = TopoDS::Shell(exp1.Current());
         if(shmap.FindIndex(shell) < 1){
@@ -946,11 +945,36 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
       break;
     case OCC_Internals::Fuse :
       {
-        BRepAlgoAPI_Fuse BO(tool, shape);
-        if(!BO.IsDone()) {
-          Msg::Error("Fuse operation can not be performed on the given shapes");
+        TopoDS_Solid solid1, solid2;
+        int hack = 0;
+        if(shape.ShapeType() != TopAbs_SOLID && tool.ShapeType() != TopAbs_SOLID){
+          TopExp_Explorer exp0;
+          for(exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()){
+            solid1 = TopoDS::Solid(exp0.Current());
+            hack++;
+            break;
+          }
+          for(exp0.Init(tool, TopAbs_SOLID); exp0.More(); exp0.Next()){
+            solid2 = TopoDS::Solid(exp0.Current());
+            hack++;
+            break;
+          }
+        }
+        if(hack == 2){ // FIXME: just a temp hack!
+          Msg::Info("Temporary hack in Fuse :-)");
+          BRepAlgoAPI_Fuse BO(solid1, solid2);
+          if(!BO.IsDone()) {
+            Msg::Error("Fuse operation can not be performed on the given shapes");
+          }
+          shape = BO.Shape();
+        }
+        else{
+          BRepAlgoAPI_Fuse BO(tool, shape);
+          if(!BO.IsDone()) {
+            Msg::Error("Fuse operation can not be performed on the given shapes");
+          }
+          shape = BO.Shape();
         }
-        shape = BO.Shape();
       }
       break;
     case OCC_Internals::Section :
-- 
GitLab