Salome HOME
PAL7731. Consider volume orientation according to MED convention
authoreap <eap@opencascade.com>
Mon, 17 Jan 2005 11:04:40 +0000 (11:04 +0000)
committereap <eap@opencascade.com>
Mon, 17 Jan 2005 11:04:40 +0000 (11:04 +0000)
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx

index f79e97d7b7fba0e21b5e80f6fe10b1650c60c10b..034486801b7a0e4dbe02099a40681e535cd54c20 100644 (file)
 
 using namespace std;
 
+// ======================================================
+// Node indices in faces depending on volume orientation
+// making most faces normals external
+// ======================================================
+
 /*
 //           N3
 //           +
 //          /|\
 //         / | \
 //        /  |  \
-//    N0 +---|---+ N2                TETRAHEDRON
+//    N0 +---|---+ N1                TETRAHEDRON
 //       \   |   /
 //        \  |  /
 //         \ | /
 //          \|/
 //           +
-//           N1
+//           N2
 */
-static int Tetra_F [4][4] = { // FORWARD == REVERSED EXTERNAL
-  { 0, 1, 2, 0 },             // Bottom face has an internal normal, other - external
+static int Tetra_F [4][4] = { // FORWARD == EXTERNAL
+  { 0, 1, 2, 0 },              // All faces have external normals
+  { 0, 3, 1, 0 },
+  { 1, 3, 2, 1 },
+  { 0, 2, 3, 0 }}; 
+static int Tetra_R [4][4] = { // REVERSED
+  { 0, 1, 2, 0 },             // All faces but a bottom have external normals
   { 0, 1, 3, 0 },
   { 1, 2, 3, 1 },
-  { 0, 3, 2, 0 }}; 
-static int Tetra_R [4][4] = { // REVERSED == FORWARD EXTERNAL
-  { 0, 2, 1, 0 },              // All faces have  external normals
+  { 0, 3, 2, 0 }};
+static int Tetra_RE [4][4] = { // REVERSED -> FORWARD (EXTERNAL)
+  { 0, 2, 1, 0 },              // All faces have external normals
   { 0, 1, 3, 0 },
   { 1, 2, 3, 1 },
-  { 0, 3, 2, 0 }}; 
+  { 0, 3, 2, 0 }};
 static int Tetra_nbN [] = { 3, 3, 3, 3 };
 
+//
+//     PYRAMID
+//
+static int Pyramid_F [5][5] = { // FORWARD == EXTERNAL
+  { 0, 1, 2, 3, 0 },            // All faces have external normals
+  { 0, 4, 1, 0, 4 },
+  { 1, 4, 2, 1, 4 },
+  { 2, 4, 3, 2, 4 },
+  { 3, 4, 0, 3, 4 }}; 
+static int Pyramid_R [5][5] = { // REVERSED
+  { 0, 1, 2, 3, 0 },            // All faces but a bottom have external normals
+  { 0, 1, 4, 0, 4 },
+  { 1, 2, 4, 1, 4 },
+  { 2, 3, 4, 2, 4 },
+  { 3, 0, 4, 3, 4 }}; 
+static int Pyramid_RE [5][5] = { // REVERSED -> FORWARD (EXTERNAL)
+  { 0, 3, 2, 1, 0 },             // All faces but a bottom have external normals
+  { 0, 1, 4, 0, 4 },
+  { 1, 2, 4, 1, 4 },
+  { 2, 3, 4, 2, 4 },
+  { 3, 0, 4, 3, 4 }}; 
+static int Pyramid_nbN [] = { 4, 3, 3, 3, 3 };
+
 /*   
 //            + N4
 //           /|\
@@ -62,71 +95,71 @@ static int Penta_F [5][5] = { // FORWARD
   { 0, 1, 2, 0, 0 },          // Top face has an internal normal, other - external
   { 3, 4, 5, 3, 3 },          // 0 is bottom, 1 is top face
   { 0, 2, 5, 3, 0 },
-  { 1, 2, 5, 4, 1 },
-  { 1, 0, 3, 4, 1 }}; 
+  { 1, 4, 5, 2, 1 },
+  { 0, 3, 4, 1, 0 }}; 
 static int Penta_R [5][5] = { // REVERSED
-  { 0, 2, 1, 0, 0 },          // Bottom face has an internal normal, other - external
-  { 3, 5, 4, 3, 3 },          // 0 is bottom, 1 is top face
-  { 0, 2, 5, 3, 0 },
+  { 0, 1, 2, 0, 0 },          // Bottom face has an internal normal, other - external
+  { 3, 4, 5, 3, 3 },          // 0 is bottom, 1 is top face
+  { 0, 3, 5, 2, 0 },
   { 1, 2, 5, 4, 1 },
-  { 1, 0, 3, 4, 1 }}; 
-static int Penta_FE [5][5] = { // EXTERNAL
+  { 0, 1, 4, 3, 0 }}; 
+static int Penta_FE [5][5] = { // FORWARD -> EXTERNAL
   { 0, 1, 2, 0, 0 },
   { 3, 5, 4, 3, 3 },
   { 0, 2, 5, 3, 0 },
+  { 1, 4, 5, 2, 1 },
+  { 0, 3, 4, 1, 0 }}; 
+static int Penta_RE [5][5] = { // REVERSED -> EXTERNAL
+  { 0, 2, 1, 0, 0 },
+  { 3, 4, 5, 3, 3 },
+  { 0, 3, 5, 2, 0 },
   { 1, 2, 5, 4, 1 },
-  { 1, 0, 3, 4, 1 }}; 
-static int Penta_RE [5][5] = { // REVERSED EXTERNAL
-  { 0, 0, 2, 1, 0 },
-  { 3, 3, 4, 5, 3 },
-  { 0, 2, 5, 3, 0 },
-  { 1, 2, 5, 4, 1 },
-  { 1, 0, 3, 4, 1 }}; 
+  { 0, 1, 4, 3, 0 }}; 
 static int Penta_nbN [] = { 3, 3, 4, 4, 4 };
 
 /*
-//         N7+----------+N6
+//         N5+----------+N6
 //          /|         /|
 //         / |        / |
 //        /  |       /  |
-//     N4+----------+N5 |
+//     N4+----------+N7 |
 //       |   |      |   |           HEXAHEDRON
 //       |   |      |   |
 //       |   |      |   |
-//       | N3+------|---+N2
+//       | N1+------|---+N2
 //       |  /       |  /
 //       | /        | /
 //       |/         |/
-//     N0+----------+N1
+//     N0+----------+N3
 */
 static int Hexa_F [6][5] = { // FORWARD
   { 0, 1, 2, 3, 0 },         // opposite faces are neighbouring,
-  { 4, 5, 6, 7, 4 },         // even face normal is internal, odd - external
+  { 4, 5, 6, 7, 4 },         // odd face(1,3,5) normal is internal, even(0,2,4) - external
   { 1, 0, 4, 5, 1 },         // same index nodes of opposite faces are linked
   { 2, 3, 7, 6, 2 }, 
   { 0, 3, 7, 4, 0 }, 
-  { 1, 2, 6, 5, 1 }}; 
-static int Hexa_R [6][5] = { // REVERSED
-  { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
-  { 4, 7, 6, 5, 4 },         // even face normal is external, odd - internal
-  { 1, 5, 4, 0, 1 },         // same index nodes of opposite faces are linked
-  { 2, 6, 7, 3, 2 }, 
-  { 0, 4, 7, 3, 0 }, 
-  { 1, 5, 6, 2, 1 }}; 
-static int Hexa_FE [6][5] = { // EXTERNAL
-  { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
-  { 4, 5, 6, 7, 4 },         // all face normals are external,
-  { 0, 1, 5, 4, 0 },         // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 1, 2, 6, 5, 1 }};
+// static int Hexa_R [6][5] = { // REVERSED
+//   { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
+//   { 4, 7, 6, 5, 4 },         // odd face(1,3,5) normal is external, even(0,2,4) - internal
+//   { 1, 5, 4, 0, 1 },         // same index nodes of opposite faces are linked
+//   { 2, 6, 7, 3, 2 }, 
+//   { 0, 4, 7, 3, 0 }, 
+//   { 1, 5, 6, 2, 1 }};
+static int Hexa_FE [6][5] = { // FORWARD -> EXTERNAL
+  { 0, 1, 2, 3, 0 } ,         // opposite faces are neighbouring,
+  { 4, 7, 6, 5, 4 },          // all face normals are external,
+  { 0, 4, 5, 1, 0 },          // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 3, 2, 6, 7, 3 }, 
+  { 0, 3, 7, 4, 0 },
+  { 1, 5, 6, 2, 1 }};
+static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL
+  { 0, 3, 2, 1, 0 },          // opposite faces are neighbouring,
+  { 4, 5, 6, 7, 4 },          // all face normals are external,
+  { 0, 1, 5, 4, 0 },          // links in opposite faces: 0-0, 1-3, 2-2, 3-1
   { 3, 7, 6, 2, 3 }, 
-  { 1, 2, 6, 5, 1 }, 
-  { 0, 4, 7, 3, 0 }};
-static int Hexa_RE [6][5] = { // REVERSED EXTERNAL
-  { 0, 1, 2, 3, 0 },         // opposite faces are neighbouring,
-  { 4, 7, 6, 5, 4 },         // all face normals are external,
-  { 0, 1, 5, 4, 0 },         // links in opposite faces: 0-0, 1-3, 2-2, 3-1
-  { 3, 7, 6, 2, 3 }, 
-  { 1, 2, 6, 5, 1 }, 
-  { 0, 4, 7, 3, 0 }};
+  { 0, 4, 7, 3, 0 },
+  { 1, 2, 6, 5, 1 }};
 static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
 
 // ========================================================
@@ -170,7 +203,6 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
        myVolForward( true ),
        myNbFaces( 0 ),
        myVolumeNbNodes( 0 ),
-       myForwardFaces( false ),
        myExternalFaces( false )
 {
 }
@@ -180,8 +212,7 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
 //=======================================================================
 
 SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
-     : myForwardFaces( false ),
-       myExternalFaces( false )
+     : myExternalFaces( false )
 {
   Set( theVolume );
 }
@@ -212,6 +243,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
     myVolumeNbNodes = theVolume->NbNodes();
     switch ( myVolumeNbNodes ) {
     case 4:
+    case 5:
     case 6:
     case 8:
       {
@@ -227,6 +259,8 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
       // nb nodes in each face
       if ( myVolumeNbNodes == 4 )
         myFaceNbNodes = Tetra_nbN;
+      else if ( myVolumeNbNodes == 5 )
+        myFaceNbNodes = Pyramid_nbN;
       else if ( myVolumeNbNodes == 6 )
         myFaceNbNodes = Penta_nbN;
       else
@@ -240,8 +274,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
       XYZ upDir (topNode->X() - botNode->X(),
                  topNode->Y() - botNode->Y(),
                  topNode->Z() - botNode->Z() );
-      bool diffDir = ( botNormal.Dot( upDir ) < 0 );
-      myVolForward = ( myVolumeNbNodes == 6 ? diffDir : !diffDir );
+      myVolForward = ( botNormal.Dot( upDir ) < 0 );
       break;
     }
     default: myVolume = 0;
@@ -273,6 +306,9 @@ void SMDS_VolumeTool::Inverse ()
   case 4:
     SWAP_NODES( myVolumeNodes, 1, 2 );
     break;
+  case 5:
+    SWAP_NODES( myVolumeNodes, 1, 3 );
+    break;
   case 6:
     SWAP_NODES( myVolumeNodes, 1, 2 );
     SWAP_NODES( myVolumeNodes, 4, 5 );
@@ -318,16 +354,6 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const
   return true;
 }
 
-//=======================================================================
-//function : SetForwardOrientation
-//purpose  : Node order will be as for forward orientation
-//=======================================================================
-
-void SMDS_VolumeTool::SetForwardOrientation ()
-{
-  myForwardFaces = true;
-}
-
 //=======================================================================
 //function : SetExternalNormal
 //purpose  : Node order will be so that faces normals are external
@@ -336,6 +362,7 @@ void SMDS_VolumeTool::SetForwardOrientation ()
 void SMDS_VolumeTool::SetExternalNormal ()
 {
   myExternalFaces = true;
+  myCurFace = -1;
 }
 
 //=======================================================================
@@ -385,8 +412,8 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
 //purpose  : Return a set of face nodes.
 //=======================================================================
 
-bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
-                                    std::set<const SMDS_MeshNode*>& theFaceNodes )
+bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
+                                    set<const SMDS_MeshNode*>& theFaceNodes )
 {
   if ( !setFace( faceIndex ))
     return false;
@@ -409,18 +436,18 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
   if ( myExternalFaces || !myVolume )
     return true;
 
-  bool reversed = ( !myForwardFaces && !myVolForward );
   switch ( myVolumeNbNodes ) {
   case 4:
-    // only the bottom of a forward tetrahedron can be internal
-    return ( reversed || faceIndex != 0 );
+  case 5:
+    // only the bottom of a reversed tetrahedron can be internal
+    return ( myVolForward || faceIndex != 0 );
   case 6:
     // in a forward pentahedron, the top is internal, in a reversed one - bottom
-    return ( reversed ? faceIndex != 0 : faceIndex != 1 );
+    return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
   case 8: {
-    // in a forward hexahedron, odd face normal is external, else vice versa
-    bool odd = (faceIndex % 2 != 0);
-    return ( reversed ? !odd : odd );
+    // in a forward hexahedron, even face normal is external, odd - internal
+    bool odd = faceIndex % 2;
+    return ( myVolForward ? !odd : odd );
   }
   default:;
   }
@@ -544,6 +571,15 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   switch ( myVolumeNbNodes ) {
   case 4:
     return true;
+  case 5:
+    if ( maxInd == 4 )
+      return true;
+    switch ( maxInd - minInd ) {
+    case 1:
+    case 3: return true;
+    default:;
+    }
+    break;
   case 6:
     switch ( maxInd - minInd ) {
     case 1: return minInd != 2;
@@ -739,25 +775,25 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
   switch ( myVolumeNbNodes ) {
   case 4:
     if ( myExternalFaces )
-      myFaceNodeIndices = myVolForward ? Tetra_R[ faceIndex ] : Tetra_F[ faceIndex ];
-    else if ( myForwardFaces )
+      myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
+    else
       myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
+    break;
+  case 5:
+    if ( myExternalFaces )
+      myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
     else
-      myFaceNodeIndices = Tetra_F[ faceIndex ];
+      myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
     break;
   case 6:
     if ( myExternalFaces )
       myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
-    else if ( myForwardFaces )
-      myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
     else
-      myFaceNodeIndices = Penta_F[ faceIndex ];
+      myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
     break;
   case 8:
     if ( myExternalFaces )
       myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
-    else if ( myForwardFaces )
-      myFaceNodeIndices = myVolForward ? Hexa_F[ faceIndex ] : Hexa_R[ faceIndex ];
     else
       myFaceNodeIndices = Hexa_F[ faceIndex ];
     break;
index 0c840a512c09371fcc83173b5d18dacee704559f..99e7dc1763800377f1cd6a851f6fcac4da59635b 100644 (file)
@@ -62,7 +62,7 @@ class SMDS_VolumeTool
 
   bool IsForward() const { return myVolForward; }
   // Check volume orientation. can be changed by Inverse().
-  // See node order of forward volumes at file bottom
+  // See node order of forward volumes at the file bottom
 
   void Inverse();
   // Change nodes order as if the volume changes its orientation:
@@ -101,12 +101,8 @@ class SMDS_VolumeTool
   // info on faces
   // -------------
 
-  void SetForwardOrientation ();
-  // Node order in faces will be as for forward orientation
-
   void SetExternalNormal ();
   // Node order in faces  will be so that faces normals are external.
-  // It overrides SetForwardOrientation()
 
   int NbFaces() const { return myNbFaces; }
   // Return number of faces of the volume. In the following
@@ -135,8 +131,7 @@ class SMDS_VolumeTool
 
   bool IsFaceExternal( int faceIndex );
   // Check normal orientation of a face.
-  // SetForwardOrientation() and SetForwardOrientation() are taken
-  // into account.
+  // SetExternalNormal() is taken into account.
 
   bool IsFreeFace(  int faceIndex );
   // Check that all volumes built on the face nodes lays on one side
@@ -169,7 +164,6 @@ class SMDS_VolumeTool
   int                     myVolumeNbNodes;
   const SMDS_MeshNode*    myVolumeNodes[ 8 ];
 
-  bool                    myForwardFaces;
   bool                    myExternalFaces;
   int*                    myFaceNodeIndices;
   int*                    myFaceNbNodes;
@@ -191,13 +185,13 @@ class SMDS_VolumeTool
 //          /|\
 //         / | \
 //        /  |  \
-//    N0 +---|---+ N2                TETRAHEDRON
+//    N0 +---|---+ N1                TETRAHEDRON
 //       \   |   /
 //        \  |  /
 //         \ | /
 //          \|/
 //           +
-//           N1
+//           N2
 
 //            + N4
 //           /|\
@@ -213,18 +207,18 @@ class SMDS_VolumeTool
 //       |/       \|
 //    N0 +---------+ N2
 
-//         N7+----------+N6
+//         N5+----------+N6
 //          /|         /|
 //         / |        / |
 //        /  |       /  |
-//     N4+----------+N5 |
+//     N4+----------+N7 |
 //       |   |      |   |           HEXAHEDRON
 //       |   |      |   |
 //       |   |      |   |
-//       | N3+------|---+N2
+//       | N1+------|---+N2
 //       |  /       |  /
 //       | /        | /
 //       |/         |/
-//     N0+----------+N1
+//     N0+----------+N3
 //
 */