Salome HOME
0021358: [CEA 500] SMESH HEXAHEDRA from 2D quad skin detect a error
[modules/smesh.git] / src / StdMeshers / StdMeshers_HexaFromSkin_3D.cxx
index e7409c1089b1c5b8473a7f9db0244cc442cf283b..0a235e48bfd49ff50b64b351959f29cede18421a 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 // File      : StdMeshers_HexaFromSkin_3D.cxx
 //#include "utilities.h"
 #include <limits>
 
-// Define error message
+// Define error message and _MYDEBUG_ if needed
 #ifdef _DEBUG_
 #define BAD_MESH_ERR \
   error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh.\n" \
                       __FILE__ ":" )<<__LINE__)
+//#define _MYDEBUG_
 #else
 #define BAD_MESH_ERR \
   error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh"))
 #endif
 
-// Debug output
-#define _DUMP_(msg) //cout << msg << endl
 
+// Debug output
+#ifdef _MYDEBUG_
+#define _DUMP_(msg) cout << msg << endl
+#else
+#define _DUMP_(msg)
+#endif
 
 
 namespace
@@ -54,8 +59,8 @@ namespace
     {
       B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES
     };
-#ifdef _DEBUG_ // avoid unused variables in release mode
-  const char* SBoxSides[] = //!< names of block sides
+#ifdef _MYDEBUG_
+  const char* SBoxSides[] = //!< names of block sides -- needed for DEBUG only
     {
       "BOTTOM", "RIGHT", "TOP", "LEFT", "FRONT", "BACK", "UNDEFINED"
     };
@@ -87,37 +92,6 @@ namespace
     return true;
   }
 
-  //================================================================================
-  /*!
-   * \brief Description of node used to detect corner nodes
-   */
-  struct _NodeDescriptor
-  {
-    int nbInverseFaces, nbNodesInInverseFaces;
-
-    _NodeDescriptor(const SMDS_MeshNode* n): nbInverseFaces(0), nbNodesInInverseFaces(0)
-    {
-      if ( n )
-      {
-        set<const SMDS_MeshNode*> nodes;
-        SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face );
-        while ( fIt->more() )
-        {
-          const SMDS_MeshElement* face = fIt->next();
-          nodes.insert( face->begin_nodes(), face->end_nodes() );
-          nbInverseFaces++;
-        }
-        nbNodesInInverseFaces = nodes.size();
-      }
-    }
-    bool operator==(const _NodeDescriptor& other) const
-    {
-      return
-        nbInverseFaces == other.nbInverseFaces &&
-        nbNodesInInverseFaces == other.nbNodesInInverseFaces;
-    }
-  };
-
   //================================================================================
   /*!
    * \brief return true if a node is at block corner
@@ -128,7 +102,19 @@ namespace
 
   bool isCornerNode( const SMDS_MeshNode* n )
   {
-    return n && n->NbInverseElements( SMDSAbs_Face ) % 2;
+    int nbF = n ? n->NbInverseElements( SMDSAbs_Face ) : 1;
+    if ( nbF % 2 )
+      return true;
+
+    set<const SMDS_MeshNode*> nodesInInverseFaces;
+    SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face );
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* face = fIt->next();
+      nodesInInverseFaces.insert( face->begin_nodes(), face->end_nodes() );
+    }
+
+    return nodesInInverseFaces.size() != ( 6 + (nbF/2-1)*3 );
   }
 
   //================================================================================
@@ -249,7 +235,7 @@ namespace
     //!< True if all blocks this side belongs to have beem found
     bool isBound() const { return _nbBlocksExpected <= _nbBlocksFound; }
     //!< Return coordinates of node at XY
-    gp_XYZ getXYZ(int x, int y) const { return SMESH_MeshEditor::TNodeXYZ( getNode( x, y )); }
+    gp_XYZ getXYZ(int x, int y) const { return SMESH_TNodeXYZ( getNode( x, y )); }
     //!< Return gravity center of the four corners and the middle node
     gp_XYZ getGC() const
     {
@@ -278,7 +264,7 @@ namespace
     //!< return coordinates by XY
     gp_XYZ xyz(int x, int y) const
     {
-      return SMESH_MeshEditor::TNodeXYZ( _grid_access_(_side, _index( x, y )) );
+      return SMESH_TNodeXYZ( _grid_access_(_side, _index( x, y )) );
     }
     //!< safely return a node by XY
     const SMDS_MeshNode* node(int x, int y) const
@@ -747,7 +733,7 @@ namespace
         gp_Vec p1p2( p1, p2 );
 
         const SMDS_MeshElement* face1 = side1->getCornerFace( n1 );
-        gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1)));
+        gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1)));
         gp_Vec side1Dir( p1, p1Op );
         gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir
         _DUMP_("  Select adjacent for "<< side1._side << " - side dir ("
@@ -758,7 +744,7 @@ namespace
         {
           _BlockSide* sideI = *sideIt;
           const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 );
-          gp_XYZ p1Op = SMESH_MeshEditor::TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1)));
+          gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1)));
           gp_Vec sideIDir( p1, p1Op );
           // compute angle of (sideIDir projection to pln) and (X dir of pln)
           gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection());
@@ -851,14 +837,12 @@ namespace
       row2.push_back( n1 = oppositeNode( quad, i1 ));
     }
 
-    _NodeDescriptor nDesc( row1[1] );
-    if ( nDesc == _NodeDescriptor( row1[0] ))
-      return true; // row of 2 nodes
+    if ( isCornerNode( row1[1] ))
+      return true;
 
     // Find the rest nodes
     TIDSortedElemSet emptySet, avoidSet;
-    //while ( !isCornerNode( n2 ))
-    while ( nDesc == _NodeDescriptor( n2 ))
+    while ( !isCornerNode( n2 ) )
     {
       avoidSet.clear(); avoidSet.insert( quad );
       quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 );