Salome HOME
Merge remote branch 'origin/gdd/translations'
[modules/smesh.git] / src / SMDS / SMDS_VolumeTool.cxx
index 841d2354078e16761d4f199c4c189b93391d6c91..1dc3ddaf0c91c3ba910f629e92e223c495c5c011 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // 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.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -132,8 +132,6 @@ static int Penta_nbN [] = { 3, 3, 4, 4, 4 };
 //        /  |       /  |
 //     N4+----------+N7 |
 //       |   |      |   |           HEXAHEDRON
-//       |   |      |   |
-//       |   |      |   |
 //       | N1+------|---+N2
 //       |  /       |  /
 //       | /        | /
@@ -155,6 +153,7 @@ static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL
   { 3, 7, 6, 2, 3 }, 
   { 0, 4, 7, 3, 0 }};
 static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
+static int Hexa_oppF[] = { 1, 0, 4, 5, 2, 3 }; // oppopsite facet indices
 
 /*   
 //      N8 +------+ N9
@@ -279,7 +278,7 @@ static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
 */
 static int QuadPenta_F [5][9] = {  // FORWARD
   { 0, 6, 1, 7, 2, 8, 0, 0, 0 },
-  { 3,11, 5, 10,4, 9, 3, 3, 3 },
+  { 3, 11,5, 10,4, 9, 3, 3, 3 },
   { 0, 12,3, 9, 4, 13,1, 6, 0 },
   { 1, 13,4, 10,5, 14,2, 7, 1 },
   { 0, 8, 2, 14,5, 11,3, 12,0 }}; 
@@ -292,27 +291,27 @@ static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
 static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
 
 /*
-//                 13
-//         N5+-----+-----+N6
-//          /|          /|
-//       12+ |       14+ |
-//        /  |        /  |
-//     N4+-----+-----+N7 |           QUADRATIC
-//       |   | 15    |   |           HEXAHEDRON
-//       |   |       |   |
-//       | 17+       |   +18
-//       |   |       |   |
-//       |   |       |   |
-//       |   |       |   |
-//     16+   |       +19 |
-//       |   |       |   |
-//       |   |     9 |   |
-//       | N1+-----+-|---+N2
-//       |  /        |  /
-//       | +8        | +10
-//       |/          |/
-//     N0+-----+-----+N3
-//             11
+//                 13                                                         
+//         N5+-----+-----+N6                          +-----+-----+
+//          /|          /|                           /|          /| 
+//       12+ |       14+ |                          + |   +25   + |    
+//        /  |        /  |                         /  |        /  |    
+//     N4+-----+-----+N7 |       QUADRATIC        +-----+-----+   |  Central nodes
+//       |   | 15    |   |       HEXAHEDRON       |   |       |   |  of tri-quadratic
+//       |   |       |   |                        |   |       |   |  HEXAHEDRON
+//       | 17+       |   +18                      |   +   22+ |   +  
+//       |   |       |   |                        |21 |       |   | 
+//       |   |       |   |                        | + | 26+   | + |    
+//       |   |       |   |                        |   |       |23 |    
+//     16+   |       +19 |                        +   | +24   +   |    
+//       |   |       |   |                        |   |       |   |    
+//       |   |     9 |   |                        |   |       |   |    
+//       | N1+-----+-|---+N2                      |   +-----+-|---+    
+//       |  /        |  /                         |  /        |  /  
+//       | +8        | +10                        | +   20+   | +      
+//       |/          |/                           |/          |/       
+//     N0+-----+-----+N3                          +-----+-----+    
+//             11                              
 */
 static int QuadHexa_F [6][9] = {  // FORWARD
   { 0, 8, 1, 9, 2, 10,3, 11,0 },   // all face normals are external,
@@ -1147,12 +1146,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
       break;
     case 20:
     case 27:
-      if ( faceIndex <= 1 ) // top or bottom
-        ind = 1 - faceIndex;
-      else {
-        const int nbSideFaces = myAllFacesNbNodes[0] / 2;
-        ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces;
-      }
+      ind = GetOppFaceIndexOfHex( faceIndex );
       break;
     default:;
     }
@@ -1160,6 +1154,16 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
   return ind;
 }
 
+//=======================================================================
+//function : GetOppFaceIndexOfHex
+//purpose  : Return index of the opposite face of the hexahedron
+//=======================================================================
+
+int SMDS_VolumeTool::GetOppFaceIndexOfHex( int faceIndex )
+{
+  return Hexa_oppF[ faceIndex ];
+}
+
 //=======================================================================
 //function : IsLinked
 //purpose  : return true if theNode1 is linked with theNode2
@@ -1454,9 +1458,46 @@ double SMDS_VolumeTool::MinLinearSize2() const
 
 //================================================================================
 /*!
- * \brief check that only one volume is build on the face nodes
- *
- * If a face is shared by one of <ignoreVolumes>, it is considered free
+ * \brief Return maximal square distance between connected corner nodes
+ */
+//================================================================================
+
+double SMDS_VolumeTool::MaxLinearSize2() const
+{
+  double maxSize = -1e+100;
+  int iQ = myVolume->IsQuadratic() ? 2 : 1;
+
+  // store current face data
+  int curFace = myCurFace, nbN = myFaceNbNodes;
+  int* ind = myFaceNodeIndices;
+  myFaceNodeIndices = NULL;
+  const SMDS_MeshNode** nodes = myFaceNodes;
+  myFaceNodes = NULL;
+  
+  // it seems that compute distance twice is faster than organization of a sole computing
+  myCurFace = -1;
+  for ( int iF = 0; iF < myNbFaces; ++iF )
+  {
+    setFace( iF );
+    for ( int iN = 0; iN < myFaceNbNodes; iN += iQ )
+    {
+      XYZ n1( myFaceNodes[ iN ]);
+      XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]);
+      maxSize = std::max( maxSize, (n1 - n2).SquareMagnitude());
+    }
+  }
+  // restore current face data
+  myCurFace         = curFace;
+  myFaceNbNodes     = nbN;
+  myFaceNodeIndices = ind;
+  delete [] myFaceNodes; myFaceNodes = nodes;
+
+  return maxSize;
+}
+
+//================================================================================
+/*!
+ * \brief fast check that only one volume is build on the face nodes
  */
 //================================================================================
 
@@ -1464,6 +1505,49 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
 {
   const bool isFree = true;
 
+  if (!setFace( faceIndex ))
+    return !isFree;
+
+  const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
+
+  // a set of facet nodes w/o medium ones and w/o nodes[0]
+  set< const SMDS_MeshElement* > nodeSet;
+  const int di = myVolume->IsQuadratic() ? 2 : 1;
+  for ( int i = di; i < myFaceNbNodes; i += di )
+    nodeSet.insert( nodes[i] );
+
+  SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+  SMDS_ElemIteratorPtr nIt;
+  while ( eIt->more() ) {
+    const SMDS_MeshElement* vol = eIt->next();
+    if ( vol != myVolume ) {
+      size_t nbShared = 0;
+      if ( const SMDS_VtkVolume* v = dynamic_cast< const SMDS_VtkVolume* >( vol ))
+        nIt = v->uniqueNodesIterator();
+      else
+        nIt = vol->nodesIterator();
+      while ( nIt->more() )
+        if (( nbShared += nodeSet.count( nIt->next() )) == nodeSet.size() )
+        {
+          if ( otherVol ) *otherVol = vol;
+          return !isFree;
+        }
+    }
+  }
+  if ( otherVol ) *otherVol = 0;
+  return isFree;
+}
+
+//================================================================================
+/*!
+ * \brief Thorough check that only one volume is build on the face nodes
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const
+{
+  const bool isFree = true;
+
   if (!setFace( faceIndex ))
     return !isFree;
 
@@ -1580,16 +1664,40 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes ) const
+int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes,
+                                   const int                        theFaceIndexHint ) const
 {
-  for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
-    const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
-    int nbFaceNodes = NbFaceNodes( iFace );
-    set<const SMDS_MeshNode*> nodeSet;
-    for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
-      nodeSet.insert( nodes[ iNode ] );
-    if ( theFaceNodes == nodeSet )
-      return iFace;
+  if ( theFaceIndexHint >= 0 )
+  {
+    int nbNodes = NbFaceNodes( theFaceIndexHint );
+    if ( nbNodes == (int) theFaceNodes.size() )
+    {
+      const SMDS_MeshNode** nodes = GetFaceNodes( theFaceIndexHint );
+      while ( nbNodes )
+        if ( theFaceNodes.count( nodes[ nbNodes-1 ]))
+          --nbNodes;
+        else
+          break;
+      if ( nbNodes == 0 )
+        return theFaceIndexHint;
+    }
+  }
+  for ( int iFace = 0; iFace < myNbFaces; iFace++ )
+  {
+    if ( iFace == theFaceIndexHint )
+      continue;
+    int nbNodes = NbFaceNodes( iFace );
+    if ( nbNodes == (int) theFaceNodes.size() )
+    {
+      const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
+      while ( nbNodes )
+        if ( theFaceNodes.count( nodes[ nbNodes-1 ]))
+          --nbNodes;
+        else
+          break;
+      if ( nbNodes == 0 )
+        return iFace;
+    }
   }
   return -1;
 }