From 7f952353a9d1ecfb6fa6c1de2a7ce40539f3edf6 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 4 Aug 2017 14:18:57 +0200
Subject: [PATCH] make autoFix of orientation of wires, faces, shells and
 solids optional (this allows to speed up entity creation for experts; it also
 avoids creating duplicates when not necessary)

---
 Common/Context.h          |  2 +-
 Common/DefaultOptions.h   |  5 ++++-
 Common/Options.cpp        |  7 +++++++
 Common/Options.h          |  1 +
 Geo/GModelIO_OCC.cpp      | 12 +++---------
 demos/boolean/simple4.geo |  1 -
 6 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/Common/Context.h b/Common/Context.h
index 3c80c25d4b..11802ececb 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -74,7 +74,7 @@ struct contextGeometryOptions {
   double normals, tangents, scalingFactor;
   int autoCoherence, highlightOrphans, clip, useTransform;
   double tolerance, toleranceBoolean, snap[3], transform[3][3], offset[3];
-  int occFixDegenerated, occFixSmallEdges, occFixSmallFaces;
+  int occAutoFix, occFixDegenerated, occFixSmallEdges, occFixSmallFaces;
   int occSewFaces, occParallel, occBooleanPreserveNumbering;
   double occScaling;
   int copyMeshingMethod, exactExtrusion;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 7dbcb5cf43..471f794d4a 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -860,6 +860,9 @@ StringXNumber GeometryOptions_Number[] = {
   { F|O, "NumSubEdges" , opt_geometry_num_sub_edges , 20. ,
     "Number of edge subdivisions between control points when displaying curves" },
 
+  { F|O, "OCCAutoFix" , opt_geometry_occ_auto_fix , 1. ,
+    "Automatically fix orientation of wires, faces, shells and volumes when creating"
+    " new entities" },
   { F|O, "OCCFixDegenerated" , opt_geometry_occ_fix_degenerated , 0. ,
     "Fix degenerated edges/faces in STEP, IGES and BRep models" },
   { F|O, "OCCFixSmallEdges" , opt_geometry_occ_fix_small_edges , 0. ,
@@ -902,7 +905,7 @@ StringXNumber GeometryOptions_Number[] = {
   { F|O, "ReparamOnFaceRobust" , opt_geometry_reparam_on_face_robust, 0 ,
     "Use projection for reparametrization of a point classified on GEdge on a GFace" },
 
-  
+
   { F|O, "ScalingFactor" , opt_geometry_scaling_factor , 1.0 ,
     "Global geometry scaling factor" },
   { F|O, "OrientedPhysicals" , opt_geometry_oriented_physicals, 1. ,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 91f7c249e2..ca8f85104b 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -4695,6 +4695,13 @@ double opt_geometry_light_two_side(OPT_ARGS_NUM)
   return CTX::instance()->geom.lightTwoSide;
 }
 
+double opt_geometry_occ_auto_fix(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->geom.occAutoFix = val ? 1 : 0;
+  return CTX::instance()->geom.occAutoFix;
+}
+
 double opt_geometry_occ_fix_degenerated(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
diff --git a/Common/Options.h b/Common/Options.h
index 1acf4fd406..7b04adbe7b 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -383,6 +383,7 @@ double opt_geometry_line_type(OPT_ARGS_NUM);
 double opt_geometry_surface_type(OPT_ARGS_NUM);
 double opt_geometry_light(OPT_ARGS_NUM);
 double opt_geometry_light_two_side(OPT_ARGS_NUM);
+double opt_geometry_occ_auto_fix(OPT_ARGS_NUM);
 double opt_geometry_occ_fix_degenerated(OPT_ARGS_NUM);
 double opt_geometry_occ_fix_small_edges(OPT_ARGS_NUM);
 double opt_geometry_occ_fix_small_faces(OPT_ARGS_NUM);
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index f5bf1df267..6faa3a0ea2 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -1146,8 +1146,6 @@ bool OCC_Internals::addDisk(int &tag, double xc, double yc, double zc,
 
 bool OCC_Internals::addPlaneSurface(int &tag, const std::vector<int> &wireTags)
 {
-  const bool autoFix = true;
-
   if(tag >= 0 && _tagFace.IsBound(tag)){
     Msg::Error("OpenCASCADE face with tag %d already exists", tag);
     return false;
@@ -1183,7 +1181,7 @@ bool OCC_Internals::addPlaneSurface(int &tag, const std::vector<int> &wireTags)
       return false;
     }
     result = f.Face();
-    if(autoFix){
+    if(CTX::instance()->geom.occAutoFix){
       // make sure wires are oriented correctly
       ShapeFix_Face fix(result);
       fix.Perform();
@@ -1244,8 +1242,6 @@ bool OCC_Internals::addSurfaceFilling(int &tag, int wireTag)
 
 bool OCC_Internals::addSurfaceLoop(int &tag, const std::vector<int> &faceTags)
 {
-  const bool autoFix = true;
-
   if(tag >= 0 && _tagShell.IsBound(tag)){
     Msg::Error("OpenCASCADE surface loop with tag %d already exists", tag);
     return false;
@@ -1274,7 +1270,7 @@ bool OCC_Internals::addSurfaceLoop(int &tag, const std::vector<int> &faceTags)
   TopExp_Explorer exp0;
   for(exp0.Init(result, TopAbs_SHELL); exp0.More(); exp0.Next()){
     TopoDS_Shell shell = TopoDS::Shell(exp0.Current());
-    if(autoFix){
+    if(CTX::instance()->geom.occAutoFix){
       // make sure faces in shell are oriented correctly
       ShapeFix_Shell fix(shell);
       fix.Perform();
@@ -1295,8 +1291,6 @@ bool OCC_Internals::addSurfaceLoop(int &tag, const std::vector<int> &faceTags)
 
 bool OCC_Internals::addVolume(int &tag, const std::vector<int> &shellTags)
 {
-  const bool autoFix = true;
-
   if(tag >= 0 && _tagSolid.IsBound(tag)){
     Msg::Error("OpenCASCADE region with tag %d already exists", tag);
     return false;
@@ -1314,7 +1308,7 @@ bool OCC_Internals::addVolume(int &tag, const std::vector<int> &shellTags)
       s.Add(shell);
     }
     result = s.Solid();
-    if(autoFix){
+    if(CTX::instance()->geom.occAutoFix){
       // make sure the volume is finite
       ShapeFix_Solid fix(result);
       fix.Perform();
diff --git a/demos/boolean/simple4.geo b/demos/boolean/simple4.geo
index 65846891ac..548f2a5b33 100644
--- a/demos/boolean/simple4.geo
+++ b/demos/boolean/simple4.geo
@@ -29,6 +29,5 @@ Plane Surface(4) = {4};
 Plane Surface(5) = {5};
 Surface Loop(1) = {1,2,3,4,5};
 Volume(1) = {1};
-
 Cylinder(2) = {0.5,0.5,-0.5, 0,0,2, 0.2};
 BooleanFragments{ Volume{1,2}; Delete; }{}
-- 
GitLab