From 4a05073cdefeb0304c00ede410b44284d4d966c4 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 15 Feb 2011 09:03:09 +0000
Subject: [PATCH] quick hack to enable creation of "box-type" boundary layers

---
 Mesh/BoundaryLayers.cpp | 21 +++++++++++++++++++--
 doc/texinfo/gmsh.texi   |  7 +++++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/Mesh/BoundaryLayers.cpp b/Mesh/BoundaryLayers.cpp
index 992008360d..29871c1d6b 100644
--- a/Mesh/BoundaryLayers.cpp
+++ b/Mesh/BoundaryLayers.cpp
@@ -68,7 +68,7 @@ template<class T>
 static void addExtrudeNormals(std::set<T*> &entities, 
                               std::map<int, infoset> &infos)
 {
-  bool normalize = true;
+  bool normalize = true, special3dbox = false;
   std::vector<OctreePost*> octrees;
 
   for(typename std::set<T*>::iterator it = entities.begin(); it != entities.end(); it++){
@@ -80,14 +80,20 @@ static void addExtrudeNormals(std::set<T*> &entities,
       int view = it2->second.second;
       bool gouraud = true;
       OctreePost *octree = 0;
+      if(view != -1){
 #if defined(HAVE_POST)
-      if(view >= 0){
         if(view >= 0 && view < PView::list.size()){
           octree = new OctreePost(PView::list[view]);
           if(PView::list[view]->getData()->getNumVectors())
             gouraud = false;
           octrees.push_back(octree);
         }
+        else if(view == -3){
+          // Force extrusion normals along x,y,z axes for single
+          // normals or at 45 degrees for multiple normals (allows to
+          // build nice 3D "boxes")
+          special3dbox = true;
+        }
         else
           Msg::Error("Unknown View[%d]: using normals instead", view);
       }
@@ -117,6 +123,17 @@ static void addExtrudeNormals(std::set<T*> &entities,
   if(normalize){
     for(int i = 0; i < 2; i++){
       ExtrudeParams::normals[i]->normalize();
+      if(special3dbox){ // force normals for 3d "box" along x,y,z
+        for(smooth_data::iter it = ExtrudeParams::normals[i]->begin(); 
+            it != ExtrudeParams::normals[i]->end(); it++){
+          double val = (it->nboccurences > 1) ? sqrt(2.) / 2. : 1.;
+          for(int j = 0; j < 3; j++){
+            if(it->vals[j] < -0.1) it->vals[j] = -val;
+            else if(it->vals[j] > 0.1) it->vals[j] = val;
+            else it->vals[j] = 0.;
+          }
+        }
+      }
 #if defined(HAVE_POST)
       if(octrees.size()){ // scale normals by scalar views
         for(smooth_data::iter it = ExtrudeParams::normals[i]->begin(); 
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 675b661130..dfb6d87599 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -2884,8 +2884,11 @@ Extrudes both the geometry and the mesh using a combined translation and
 rotation (@pxref{Extrusions}). The @var{layers} option is defined as
 above.
 
-@item Extrude @{ Surface @{ @var{expression-list} @}; @var{layers} @}
-Extrudes a boundary layer along the normals of the specified surfaces.
+@item Extrude @{ Surface @{ @var{expression-list} @}; @var{layers} < Using Index[@var{expr}]; > < Using View[@var{expr}]; > @}
+Extrudes a boundary layer from the specified surfaces. If no view is
+specified, the boundary layer is created using gouraud-shaped (smoothed)
+normal field. Specifying a boundary layer index allows to extrude
+several independent boundary layers (with independent normal smoothing).
 
 @item Transfinite Line @{ @var{expression-list} @} | "*" = @var{expression} < Using Progression | Bump @var{expression} >;
 Selects the lines in @var{expression-list} to be meshed with the 1D
-- 
GitLab