Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMDS / SMDS_VolumeTool.cxx
index 9e144a620aaae174eef73eaa48e66d836edb02bd..bd207f84ef6d9ddad4fafa3207c4ec579bc45788 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_VtkVolume.hxx"
 #include "SMDS_Mesh.hxx"
 
-#include "utilities.h"
+#include <utilities.h>
 
 #include <map>
 #include <limits>
 #include <cmath>
+#include <cstring>
 #include <numeric>
 #include <algorithm>
 
-using namespace std;
-
 namespace
 {
 // ======================================================
@@ -361,6 +359,7 @@ struct XYZ {
   XYZ( double X, double Y, double Z ) { x = X; y = Y; z = Z; }
   XYZ( const XYZ& other )             { x = other.x; y = other.y; z = other.z; }
   XYZ( const SMDS_MeshNode* n )       { x = n->X(); y = n->Y(); z = n->Z(); }
+  double* data()                      { return &x; }
   inline XYZ operator-( const XYZ& other );
   inline XYZ operator+( const XYZ& other );
   inline XYZ Crossed( const XYZ& other );
@@ -506,7 +505,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement*                  theVolume,
   myNbFaces = theVolume->NbFaces();
   if ( myVolume->IsPoly() )
   {
-    myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
+    myPolyedre = SMDS_Mesh::DownCast<SMDS_MeshVolume>( myVolume );
     myPolyFacetOri.resize( myNbFaces, 0 );
   }
 
@@ -522,10 +521,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement*                  theVolume,
   }
   else
   {
-    int iNode = 0;
-    SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
-    while ( nodeIt->more() )
-      myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+    myVolumeNodes.assign( myVolume->begin_nodes(), myVolume->end_nodes() );
   }
 
   // check validity
@@ -710,9 +706,11 @@ double SMDS_VolumeTool::GetSize() const
     if ( !myPolyedre )
       return 0.;
 
+    SaveFacet savedFacet( myCurFace );
+
     // split a polyhedron into tetrahedrons
 
-    SaveFacet savedFacet( myCurFace );
+    bool oriOk = true;
     SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
     for ( int f = 0; f < NbFaces(); ++f )
     {
@@ -725,8 +723,11 @@ double SMDS_VolumeTool::GetSize() const
         p1 = p2;
       }
       V += p1.Dot( area );
+      oriOk = oriOk && IsFaceExternal( f );
     }
     V /= 6;
+    if ( !oriOk && V > 0 )
+      V *= -1;
   }
   else 
   {
@@ -954,8 +955,8 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const
 //purpose  : Return a set of face nodes.
 //=======================================================================
 
-bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
-                                    set<const SMDS_MeshNode*>& theFaceNodes ) const
+bool SMDS_VolumeTool::GetFaceNodes (int                             faceIndex,
+                                    std::set<const SMDS_MeshNode*>& theFaceNodes ) const
 {
   if ( !setFace( faceIndex ))
     return false;
@@ -968,7 +969,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
 
 namespace
 {
-  struct NLink : public std::pair<int,int>
+  struct NLink : public std::pair<smIdType,smIdType>
   {
     int myOri;
     NLink(const SMDS_MeshNode* n1=0, const SMDS_MeshNode* n2=0, int ori=1 )
@@ -1060,7 +1061,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
         {
           ori = ( -minProj < maxProj ? -1 : +1 );
           double convexity = std::min( -minProj, maxProj ) / std::max( -minProj, maxProj );
-          convexity2face.insert( make_pair( convexity, iF * ori ));
+          convexity2face.insert( std::make_pair( convexity, iF * ori ));
         }
       }
       if ( faceMostConvex < 0 ) // none facet has nodes on the same side
@@ -1089,7 +1090,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
   // compare orientation of links of the facet with myFwdLinks
   ori = 0;
   setFace( faceIndex );
-  vector< NLink > links( myCurFace.myNbNodes ), links2;
+  std::vector< NLink > links( myCurFace.myNbNodes ), links2;
   for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
   {
     NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
@@ -1147,7 +1148,8 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
 
 bool SMDS_VolumeTool::projectNodesToNormal( int     faceIndex,
                                             double& minProj,
-                                            double& maxProj ) const
+                                            double& maxProj,
+                                            double* normalXYZ ) const
 {
   minProj = std::numeric_limits<double>::max();
   maxProj = std::numeric_limits<double>::min();
@@ -1155,6 +1157,9 @@ bool SMDS_VolumeTool::projectNodesToNormal( int     faceIndex,
   XYZ normal;
   if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
     return false;
+  if ( normalXYZ )
+    memcpy( normalXYZ, normal.data(), 3*sizeof(double));
+
   XYZ p0 ( myCurFace.myNodes[0] );
   for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
   {
@@ -1202,15 +1207,17 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   XYZ aVec13( p3 - p1 );
   XYZ cross = aVec12.Crossed( aVec13 );
 
-  if ( myCurFace.myNbNodes >3*iQuad ) {
-    XYZ p4 ( myCurFace.myNodes[3*iQuad] );
+  for ( int i = 3*iQuad; i < myCurFace.myNbNodes; i += iQuad )
+  {
+    XYZ p4 ( myCurFace.myNodes[i] );
     XYZ aVec14( p4 - p1 );
     XYZ cross2 = aVec13.Crossed( aVec14 );
     cross = cross + cross2;
+    aVec13 = aVec14;
   }
 
   double size = cross.Magnitude();
-  if ( size <= numeric_limits<double>::min() )
+  if ( size <= std::numeric_limits<double>::min() )
     return false;
 
   X = cross.x / size;
@@ -1321,7 +1328,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
     case 15:
       if ( faceIndex == 0 || faceIndex == 1 )
         ind = 1 - faceIndex;
-        break;
+      break;
     case 8:
     case 12:
       if ( faceIndex <= 1 ) // top or bottom
@@ -1382,7 +1389,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
     } else {
       d2 = 0;
     }
-    vector<const SMDS_MeshNode*>::const_iterator i;
+    std::vector<const SMDS_MeshNode*>::const_iterator i;
     for (int iface = 0; iface < myNbFaces; iface++)
     {
       from = to;
@@ -1429,8 +1436,8 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
   }
 
-  int minInd = min( theNode1Index, theNode2Index );
-  int maxInd = max( theNode1Index, theNode2Index );
+  int minInd = std::min( theNode1Index, theNode2Index );
+  int maxInd = std::max( theNode1Index, theNode2Index );
 
   if ( minInd < 0 || maxInd > (int)myVolumeNodes.size() - 1 || maxInd == minInd )
     return false;
@@ -1481,10 +1488,10 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_TETRA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==4 ||  maxInd==6 ||  maxInd==7 ) return true;
-      case 1: if( maxInd==4 ||  maxInd==5 ||  maxInd==8 ) return true;
-      case 2: if( maxInd==5 ||  maxInd==6 ||  maxInd==9 ) return true;
-      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==9 ) return true;
+      case 0: return ( maxInd==4 ||  maxInd==6 ||  maxInd==7 );
+      case 1: return ( maxInd==4 ||  maxInd==5 ||  maxInd==8 );
+      case 2: return ( maxInd==5 ||  maxInd==6 ||  maxInd==9 );
+      case 3: return ( maxInd==7 ||  maxInd==8 ||  maxInd==9 );
       default:;
       }
       break;
@@ -1492,14 +1499,14 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_HEXA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
-      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
-      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
-      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
-      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
-      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
-      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
-      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
+      case 0: return ( maxInd==8  ||  maxInd==11 ||  maxInd==16 );
+      case 1: return ( maxInd==8  ||  maxInd==9  ||  maxInd==17 );
+      case 2: return ( maxInd==9  ||  maxInd==10 ||  maxInd==18 );
+      case 3: return ( maxInd==10 ||  maxInd==11 ||  maxInd==19 );
+      case 4: return ( maxInd==12 ||  maxInd==15 ||  maxInd==16 );
+      case 5: return ( maxInd==12 ||  maxInd==13 ||  maxInd==17 );
+      case 6: return ( maxInd==13 ||  maxInd==14 ||  maxInd==18 );
+      case 7: return ( maxInd==14 ||  maxInd==15 ||  maxInd==19 );
       default:;
       }
       break;
@@ -1507,11 +1514,11 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_PYRAM:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==5 ||  maxInd==8 ||  maxInd==9 ) return true;
-      case 1: if( maxInd==5 ||  maxInd==6 ||  maxInd==10 ) return true;
-      case 2: if( maxInd==6 ||  maxInd==7 ||  maxInd==11 ) return true;
-      case 3: if( maxInd==7 ||  maxInd==8 ||  maxInd==12 ) return true;
-      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 ) return true;
+      case 0: return ( maxInd==5 ||  maxInd==8  ||  maxInd==9  );
+      case 1: return ( maxInd==5 ||  maxInd==6  ||  maxInd==10 );
+      case 2: return ( maxInd==6 ||  maxInd==7  ||  maxInd==11 );
+      case 3: return ( maxInd==7 ||  maxInd==8  ||  maxInd==12 );
+      case 4: return ( maxInd==9 ||  maxInd==10 ||  maxInd==11 ||  maxInd==12 );
       default:;
       }
       break;
@@ -1519,12 +1526,12 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   case QUAD_PENTA:
     {
       switch ( minInd ) {
-      case 0: if( maxInd==6 ||  maxInd==8 ||  maxInd==12 ) return true;
-      case 1: if( maxInd==6 ||  maxInd==7 ||  maxInd==13 ) return true;
-      case 2: if( maxInd==7 ||  maxInd==8 ||  maxInd==14 ) return true;
-      case 3: if( maxInd==9 ||  maxInd==11 ||  maxInd==12 ) return true;
-      case 4: if( maxInd==9 ||  maxInd==10 ||  maxInd==13 ) return true;
-      case 5: if( maxInd==10 ||  maxInd==11 ||  maxInd==14 ) return true;
+      case 0: return ( maxInd==6  ||  maxInd==8  ||  maxInd==12 );
+      case 1: return ( maxInd==6  ||  maxInd==7  ||  maxInd==13 );
+      case 2: return ( maxInd==7  ||  maxInd==8  ||  maxInd==14 );
+      case 3: return ( maxInd==9  ||  maxInd==11 ||  maxInd==12 );
+      case 4: return ( maxInd==9  ||  maxInd==10 ||  maxInd==13 );
+      case 5: return ( maxInd==10 ||  maxInd==11 ||  maxInd==14 );
       default:;
       }
       break;
@@ -1565,7 +1572,7 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
  */
 //================================================================================
 
-int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
+int SMDS_VolumeTool::GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces) const
 {
   faces.clear();
   SaveFacet savedFacet( myCurFace );
@@ -1606,7 +1613,7 @@ int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces
  */
 //================================================================================
 
-int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+int SMDS_VolumeTool::GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const
 {
   edges.clear();
   edges.reserve( myVolumeNodes.size() * 2 );
@@ -1717,7 +1724,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
       //   int nb = myCurFace.myNbNodes;
       //   if ( myVolume->GetEntityType() != vol->GetEntityType() )
       //     nb -= ( GetCenterNodeIndex(0) > 0 );
-      //   set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+      //   std::set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
       //   if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
       //     continue;
       // }
@@ -1747,7 +1754,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
 
   // evaluate nb of face nodes shared by other volumes
   int maxNbShared = -1;
-  typedef map< const SMDS_MeshElement*, int > TElemIntMap;
+  typedef std::map< const SMDS_MeshElement*, int > TElemIntMap;
   TElemIntMap volNbShared;
   TElemIntMap::iterator vNbIt;
   for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
@@ -1756,7 +1763,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
     while ( eIt->more() ) {
       const SMDS_MeshElement* elem = eIt->next();
       if ( elem != myVolume ) {
-        vNbIt = volNbShared.insert( make_pair( elem, 0 )).first;
+        vNbIt = volNbShared.insert( std::make_pair( elem, 0 )).first;
         (*vNbIt).second++;
         if ( vNbIt->second > maxNbShared )
           maxNbShared = vNbIt->second;
@@ -1855,7 +1862,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes,
+int SMDS_VolumeTool::GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes,
                                    const int                        theFaceIndexHint ) const
 {
   if ( theFaceIndexHint >= 0 )
@@ -1898,12 +1905,12 @@ int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-/*int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
+/*int SMDS_VolumeTool::GetFaceIndex( const std::set<int>& theFaceNodesIndices )
 {
   for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
     const int* nodes = GetFaceNodesIndices( iFace );
     int nbFaceNodes = NbFaceNodes( iFace );
-    set<int> nodeSet;
+    std::set<int> nodeSet;
     for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
       nodeSet.insert( nodes[ iNode ] );
     if ( theFaceNodesIndices == nodeSet )
@@ -1932,7 +1939,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
 
   if (myVolume->IsPoly())
   {
-    if (!myPolyedre) {
+    if ( !myPolyedre ) {
       MESSAGE("Warning: bad volumic element");
       return false;
     }
@@ -2203,7 +2210,7 @@ const SMDS_MeshVolume* SMDS_VolumeTool::Element() const
 //purpose  : return element ID
 //=======================================================================
 
-int SMDS_VolumeTool::ID() const
+smIdType SMDS_VolumeTool::ID() const
 {
   return myVolume ? myVolume->GetID() : 0;
 }