From 64798bc410cb826b840d5ef459e865b6ac91bb99 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 25 Feb 2017 11:36:21 +0000
Subject: [PATCH] refactoring DeleteShape

---
 Geo/GModel.cpp       | 24 +++++++++-----
 Geo/GModel.h         | 11 ++++++-
 Geo/GModelIO_GEO.cpp | 35 +++++++++++++++++++++
 Geo/GModelIO_GEO.h   | 14 +++++++++
 Geo/GModelIO_OCC.cpp | 54 +++++++++++++++++---------------
 Geo/GModelIO_OCC.h   | 10 ++++--
 Geo/Geo.cpp          | 74 +++++---------------------------------------
 Geo/Geo.h            |  5 ++-
 Mesh/meshGFace.cpp   |  3 +-
 Parser/Gmsh.tab.cpp  | 18 +++++------
 Parser/Gmsh.y        | 19 ++++++------
 11 files changed, 145 insertions(+), 122 deletions(-)

diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 5e8b7344fd..73872386cd 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -298,17 +298,17 @@ GVertex *GModel::getVertexByTag(int n) const
     return 0;
 }
 
-std::vector<int> GModel::getEdgesByStringTag(const std::string tag)
+std::vector<int> GModel::getTagsForPhysicalName(int dim, const std::string tag)
 {
-  std::vector<int> nums;
+  std::vector<int> tags;
   std::map<int, std::vector<GEntity*> > physicalGroups;
-  getPhysicalGroups(1, physicalGroups);
-  std::vector<GEntity*> allEdges = physicalGroups[this->getPhysicalNumber(1, tag)];
-  for (std::vector<GEntity*>::iterator it = allEdges.begin(); it != allEdges.end(); it++){
+  getPhysicalGroups(dim, physicalGroups);
+  std::vector<GEntity*> entities = physicalGroups[getPhysicalNumber(dim, tag)];
+  for (std::vector<GEntity*>::iterator it = entities.begin(); it != entities.end(); it++){
     GEntity *ge = *it;
-    nums.push_back(ge->tag());
+    tags.push_back(ge->tag());
   }
-  return nums;
+  return tags;
 }
 
 void GModel::remove(GRegion *r)
@@ -335,6 +335,16 @@ void GModel::remove(GVertex *v)
   if(it != vertices.end()) vertices.erase(it);
 }
 
+void GModel::remove(int dim, int tag)
+{
+  switch(dim){
+  case 0: remove(getVertexByTag(tag)); break;
+  case 1: remove(getEdgeByTag(tag)); break;
+  case 2: remove(getFaceByTag(tag)); break;
+  case 3: remove(getRegionByTag(tag)); break;
+  }
+}
+
 void GModel::snapVertices()
 {
   viter vit = firstVertex();
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 9c5df95831..5cd3aeb397 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -267,7 +267,6 @@ class GModel
   GFace *getFaceByTag(int n) const;
   GEdge *getEdgeByTag(int n) const;
   GVertex *getVertexByTag(int n) const;
-  std::vector<int> getEdgesByStringTag(const std::string tag);
 
   // add/remove an entity in the model
   void add(GRegion *r) { regions.insert(r); }
@@ -278,6 +277,7 @@ class GModel
   void remove(GFace *f);
   void remove(GEdge *e);
   void remove(GVertex *v);
+  void remove(int dim, int tag);
 
   // snap vertices on model edges by using geometry tolerance
   void snapVertices();
@@ -332,6 +332,15 @@ class GModel
   // "dim" and name "name". return -1 if not found
   int getPhysicalNumber(const int &dim, const std::string & name);
 
+  // get all tags of elementary entities associated with a given physical group
+  // name
+  std::vector<int> getTagsForPhysicalName(int dim, const std::string name);
+  // deprecated
+  std::vector<int> getEdgesByStringTag(const std::string name)
+  {
+    return getTagsForPhysicalName(1, name);
+  }
+
   // set physical tags to entities in a given bounding box
   void setPhysicalNumToEntitiesInBox(int EntityDimension, int PhysicalNumber,
                                      std::vector<double> p1, std::vector<double> p2);
diff --git a/Geo/GModelIO_GEO.cpp b/Geo/GModelIO_GEO.cpp
index a0e75f7ef5..5c027b3668 100644
--- a/Geo/GModelIO_GEO.cpp
+++ b/Geo/GModelIO_GEO.cpp
@@ -430,6 +430,41 @@ void GEO_Internals::addCompoundVolume(int num, std::vector<int> regionTags)
   _changed = true;
 }
 
+void GEO_Internals::getBoundary(std::vector<int> inTags[4],
+                                std::vector<int> outTags[4],
+                                bool combined)
+{
+
+}
+
+void GEO_Internals::translate(std::vector<int> inTags[4],
+                              double dx, double dy, double dz)
+{
+
+}
+
+void GEO_Internals::rotate(std::vector<int> inTags[4],
+                           double x, double y, double z,
+                           double dx, double dy, double dz, double angle)
+{
+
+}
+
+void GEO_Internals::copy(std::vector<int> inTags[4], std::vector<int> outTags[4])
+{
+
+}
+
+void GEO_Internals::remove(int dim, int tag)
+{
+  switch(dim){
+  case 0: DeletePoint(tag); break;
+  case 1: DeleteCurve(tag); DeleteCurve(-tag); break;
+  case 2: DeleteSurface(tag); break;
+  case 3: DeleteVolume(tag); break;
+  }
+}
+
 void GEO_Internals::resetPhysicalGroups()
 {
   List_Action(PhysicalGroups, Free_PhysicalGroup);
diff --git a/Geo/GModelIO_GEO.h b/Geo/GModelIO_GEO.h
index ac66dbd24f..be70d346ff 100644
--- a/Geo/GModelIO_GEO.h
+++ b/Geo/GModelIO_GEO.h
@@ -54,6 +54,20 @@ class GEO_Internals{
   void addVolume(int num, std::vector<int> shellTags);
   void addCompoundVolume(int num, std::vector<int> regionTags);
 
+  // get boundary of shapes of dimension dim (this will bind the boundary parts
+  // to new tags, returned in outTags)
+  void getBoundary(std::vector<int> inTags[4], std::vector<int> outTags[4],
+                   bool combined=false);
+
+  // apply transformations
+  void translate(std::vector<int> inTags[4], double dx, double dy, double dz);
+  void rotate(std::vector<int> inTags[4], double x, double y, double z,
+              double dx, double dy, double dz, double angle);
+
+  // copy and remove
+  void copy(std::vector<int> inTags[4], std::vector<int> outTags[4]);
+  void remove(int dim, int tag);
+
   // manipulate physical groups
   void resetPhysicalGroups();
   void modifyPhysicalGroup(int dim, int num, int op, std::vector<int> tags);
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 7c2440b6e7..11fe693b8d 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -1671,37 +1671,41 @@ void OCC_Internals::rotate(std::vector<int> inTags[4],
   _transform(inTags, tfo);
 }
 
-void OCC_Internals::copy(std::vector<int> inTags[4], std::vector<int> outTags[4])
+int OCC_Internals::copy(int dim, int tag)
 {
-  for(unsigned int dim = 0; dim < 4; dim++){
-    for(unsigned int i = 0; i < inTags[dim].size(); i++){
-      int tag = inTags[dim][i];
-      if(!isBound(dim, tag)){
-        Msg::Error("Unknown OpenCASCADE entity of dimension %d with tag %d",
-                   dim, tag);
-        return;
-      }
-      TopoDS_Shape result = BRepBuilderAPI_Copy(find(dim, tag)).Shape();
-      int newtag = getMaxTag(dim) + 1;
-      bind(result, dim, newtag);
-      outTags[dim].push_back(newtag);
-    }
+  if(!isBound(dim, tag)){
+    Msg::Error("Unknown OpenCASCADE entity of dimension %d with tag %d",
+               dim, tag);
+    return tag;
   }
+  TopoDS_Shape result = BRepBuilderAPI_Copy(find(dim, tag)).Shape();
+  int newtag = getMaxTag(dim) + 1;
+  bind(result, dim, newtag);
+  return newtag;
 }
 
-void OCC_Internals::remove(std::vector<int> inTags[4])
+void OCC_Internals::copy(std::vector<int> inTags[4], std::vector<int> outTags[4])
 {
-  for(unsigned int dim = 0; dim < 4; dim++){
-    for(unsigned int i = 0; i < inTags[dim].size(); i++){
-      int tag = inTags[dim][i];
-      if(!isBound(dim, tag)){
-        Msg::Error("Unknown OpenCASCADE entity of dimension %d with tag %d",
-                   dim, tag);
-        return;
-      }
-      unbind(find(dim, tag), dim, tag);
-    }
+  for(int dim = 0; dim < 4; dim++)
+    for(unsigned int i = 0; i < inTags[dim].size(); i++)
+      outTags[dim].push_back(copy(dim, inTags[dim][i]));
+}
+
+void OCC_Internals::remove(int dim, int tag)
+{
+  if(!isBound(dim, tag)){
+    Msg::Error("Unknown OpenCASCADE entity of dimension %d with tag %d",
+               dim, tag);
+    return;
   }
+  unbind(find(dim, tag), dim, tag);
+}
+
+void OCC_Internals::remove(std::vector<int> tags[4])
+{
+  for(int dim = 0; dim < 4; dim++)
+    for(unsigned int i = 0; i < tags[dim].size(); i++)
+      remove(dim, tags[dim][i]);
 }
 
 void OCC_Internals::importShapes(const std::string &fileName, bool highestDimOnly,
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index 22b07a0d54..136c073ac4 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -198,8 +198,10 @@ class OCC_Internals {
               double dx, double dy, double dz, double angle);
 
   // copy and remove
+  int copy(int dim, int tag);
   void copy(std::vector<int> inTags[4], std::vector<int> outTags[4]);
-  void remove(std::vector<int> inTags[4]);
+  void remove(int dim, int tag);
+  void remove(std::vector<int> tags[4]);
 
   // import shapes from file
   void importShapes(const std::string &fileName, bool highestDimOnly,
@@ -336,9 +338,11 @@ public:
   { _error("apply translation"); }
   void rotate(std::vector<int> inTags[4], double x, double y, double z,
               double dx, double dy, double dz, double angle){ _error("apply rotation"); }
+  int copy(int dim, int tag){ _error("copy shape"); }
   void copy(std::vector<int> inTags[4], std::vector<int> outTags[4])
-  { _error("copy shape"); }
-  void remove(std::vector<int> inTags[4]){}
+  { _error("copy shapes"); }
+  void remove(int dim, int tag){}
+  void remove(std::vector<int> tags[4]){}
   void importShapes(const std::string &fileName, bool highestDimOnly,
                     std::vector<int> outTags[4], const std::string &format="")
   { _error("import shape"); }
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 51acff955a..3570ecc16d 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -15,10 +15,6 @@
 #include "MVertexRTree.h"
 #include "Parser.h"
 
-#if defined(HAVE_MESH)
-#include "Field.h"
-#endif
-
 static List_T *ListOfTransformedPoints = NULL;
 
 // Comparison routines
@@ -234,8 +230,8 @@ static void direction(Vertex *v1, Vertex *v2, double d[3])
 
 void End_Curve(Curve *c)
 {
-  // if all control points of a curve are on the same geometry, then
-  // the curve is also on the geometry
+  // if all control points of a curve are on the same geometry, then the curve
+  // is also on the geometry
   int NN = List_Nbr(c->Control_Points);
   if(NN){
     Vertex *pV;
@@ -1183,7 +1179,7 @@ void CopyShape(int Type, int Num, int *New)
   }
 }
 
-static void DeletePoint(int ip)
+void DeletePoint(int ip)
 {
   Vertex *v = FindPoint(ip);
   if(!v)
@@ -1208,7 +1204,7 @@ static void DeletePoint(int ip)
   Free_Vertex(&v, NULL);
 }
 
-static void DeleteCurve(int ip)
+void DeleteCurve(int ip)
 {
   Curve *c = FindCurve(ip);
   if(!c)
@@ -1233,7 +1229,7 @@ static void DeleteCurve(int ip)
   Free_Curve(&c, NULL);
 }
 
-static void DeleteSurface(int is)
+void DeleteSurface(int is)
 {
   Surface *s = FindSurface(is);
   if(!s)
@@ -1257,7 +1253,7 @@ static void DeleteSurface(int is)
   Free_Surface(&s, NULL);
 }
 
-static void DeleteVolume(int iv)
+void DeleteVolume(int iv)
 {
   Volume *v = FindVolume(iv);
   if(!v)
@@ -1312,61 +1308,6 @@ void DeletePhysicalVolume(int num)
   GModel::current()->deletePhysicalGroup(3, num);
 }
 
-void DeleteShape(int Type, int Num)
-{
-  switch (Type) {
-  case MSH_POINT:
-  case MSH_POINT_FROM_GMODEL:
-    {
-      DeletePoint(Num);
-      GVertex *gv = GModel::current()->getVertexByTag(Num);
-      if(gv) GModel::current()->remove(gv);
-    }
-    break;
-  case MSH_SEGM_LINE:
-  case MSH_SEGM_SPLN:
-  case MSH_SEGM_BSPLN:
-  case MSH_SEGM_BEZIER:
-  case MSH_SEGM_CIRC:
-  case MSH_SEGM_CIRC_INV:
-  case MSH_SEGM_ELLI:
-  case MSH_SEGM_ELLI_INV:
-  case MSH_SEGM_NURBS:
-  case MSH_SEGM_COMPOUND:
-  case MSH_SEGM_FROM_GMODEL:
-    {
-      DeleteCurve(Num);
-      DeleteCurve(-Num);
-      GEdge *ge = GModel::current()->getEdgeByTag(Num);
-      if(ge) GModel::current()->remove(ge);
-    }
-    break;
-  case MSH_SURF_TRIC:
-  case MSH_SURF_REGL:
-  case MSH_SURF_PLAN:
-  case MSH_SURF_COMPOUND:
-  case MSH_SURF_FROM_GMODEL:
-    {
-      DeleteSurface(Num);
-      GFace *gf = GModel::current()->getFaceByTag(Num);
-      if(gf) GModel::current()->remove(gf);
-    }
-    break;
-  case MSH_VOLUME:
-  case MSH_VOLUME_COMPOUND:
-  case MSH_VOLUME_FROM_GMODEL:
-    {
-      DeleteVolume(Num);
-      GRegion *gr = GModel::current()->getRegionByTag(Num);
-      if(gr) GModel::current()->remove(gr);
-    }
-    break;
-  default:
-    Msg::Error("Impossible to delete entity %d (of type %d)", Num, Type);
-    break;
-  }
-}
-
 void ColorShape(int Type, int Num, unsigned int Color, bool Recursive)
 {
   Curve *c;
@@ -4183,7 +4124,8 @@ bool SplitCurve(int line_id, List_T *vertices_id, List_T *shapes)
     }
   }
 
-  DeleteShape(c->Typ, c->Num);
+  DeleteCurve(c->Num);
+  DeleteCurve(-c->Num);
   List_Delete(new_list);
   List_Delete(rshapes);
   List_Delete(num_shapes);
diff --git a/Geo/Geo.h b/Geo/Geo.h
index 027be6fbea..9688c28717 100644
--- a/Geo/Geo.h
+++ b/Geo/Geo.h
@@ -337,7 +337,10 @@ void RotateShapes(double Ax,double Ay,double Az,
 void SymmetryShapes(double A,double B,double C, double D, List_T *shapes);
 void BoundaryShapes(List_T *shapes, List_T *shapesBoundary, bool combined);
 void CopyShape(int Type, int Num, int *New);
-void DeleteShape(int Type, int Num);
+void DeletePoint(int Num);
+void DeleteCurve(int Num);
+void DeleteSurface(int Num);
+void DeleteVolume(int Num);
 void DeletePhysicalPoint(int Num);
 void DeletePhysicalLine(int Num);
 void DeletePhysicalSurface(int Num);
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 8de0ee0565..b69abd3fae 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -635,7 +635,8 @@ void BDS2GMSH(BDS_Mesh *m, GFace *gf,
   }
 }
 
-static void addOrRemove(MVertex *v1, MVertex *v2, std::set<MEdge,Less_Edge> & bedges, std::set<MEdge,Less_Edge> &removed)
+static void addOrRemove(MVertex *v1, MVertex *v2, std::set<MEdge,Less_Edge> & bedges,
+                        std::set<MEdge,Less_Edge> &removed)
 {
   MEdge e(v1,v2);
   if (removed.find(e) != removed.end())return;
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 30488434e2..0be53d835d 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -9352,15 +9352,15 @@ yyreduce:
   case 238:
 #line 2969 "Gmsh.y"
     {
-      if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        std::vector<int> tags[4]; ListOfShapes2Vectors((yyvsp[(3) - (4)].l), tags);
-        GModel::current()->getOCCInternals()->remove(tags);
-      }
-      // FIXME use GEOInternals + int api
-      for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
-        Shape TheShape;
-        List_Read((yyvsp[(3) - (4)].l), i, &TheShape);
-        DeleteShape(TheShape.Type, TheShape.Num);
+      std::vector<int> tags[4]; ListOfShapes2Vectors((yyvsp[(3) - (4)].l), tags);
+      for(int dim = 0; dim < 4; dim++){
+        for(unsigned int i = 0; i < tags[dim].size(); i++){
+          if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
+            GModel::current()->getOCCInternals()->remove(dim, tags[dim][i]);
+          }
+          GModel::current()->getGEOInternals()->remove(dim, tags[dim][i]);
+          GModel::current()->remove(dim, tags[dim][i]);
+        }
       }
       List_Delete((yyvsp[(3) - (4)].l));
     ;}
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 31be31b474..31830d0147 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -2431,6 +2431,7 @@ Transform :
           Vectors2ListOfShapes(out, $$);
         }
         else{
+          // FIXME use INT API HERE
           for(int i = 0; i < List_Nbr($3); i++){
             Shape TheShape;
             List_Read($3, i, &TheShape);
@@ -2967,15 +2968,15 @@ LevelSet :
 Delete :
     tDelete '{' ListOfShapes '}'
     {
-      if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
-        std::vector<int> tags[4]; ListOfShapes2Vectors($3, tags);
-        GModel::current()->getOCCInternals()->remove(tags);
-      }
-      // FIXME use GEOInternals + int api
-      for(int i = 0; i < List_Nbr($3); i++){
-        Shape TheShape;
-        List_Read($3, i, &TheShape);
-        DeleteShape(TheShape.Type, TheShape.Num);
+      std::vector<int> tags[4]; ListOfShapes2Vectors($3, tags);
+      for(int dim = 0; dim < 4; dim++){
+        for(unsigned int i = 0; i < tags[dim].size(); i++){
+          if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
+            GModel::current()->getOCCInternals()->remove(dim, tags[dim][i]);
+          }
+          GModel::current()->getGEOInternals()->remove(dim, tags[dim][i]);
+          GModel::current()->remove(dim, tags[dim][i]);
+        }
       }
       List_Delete($3);
     }
-- 
GitLab