Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMDS / SMDS_VolumeTool.cxx
index 6de1ac68e4efc8fed87c1b479ba58b5e261ec452..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
@@ -39,6 +39,7 @@
 #include <map>
 #include <limits>
 #include <cmath>
+#include <cstring>
 #include <numeric>
 #include <algorithm>
 
@@ -358,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 );
@@ -704,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 )
     {
@@ -719,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 
   {
@@ -962,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 )
@@ -1141,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();
@@ -1149,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 )
   {
@@ -1196,11 +1207,13 @@ 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();
@@ -1315,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
@@ -1475,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;
@@ -1486,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;
@@ -1501,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;
@@ -1513,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;
@@ -2197,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;
 }