PAL7731. Consider volume orientation according to MED convention

This commit is contained in:
eap 2005-01-17 11:04:40 +00:00
parent c0faddf82f
commit b9a4ef3658
2 changed files with 125 additions and 95 deletions

View File

@ -17,32 +17,65 @@
using namespace std; using namespace std;
// ======================================================
// Node indices in faces depending on volume orientation
// making most faces normals external
// ======================================================
/* /*
// N3 // N3
// + // +
// /|\ // /|\
// / | \ // / | \
// / | \ // / | \
// N0 +---|---+ N2 TETRAHEDRON // N0 +---|---+ N1 TETRAHEDRON
// \ | / // \ | /
// \ | / // \ | /
// \ | / // \ | /
// \|/ // \|/
// + // +
// N1 // N2
*/ */
static int Tetra_F [4][4] = { // FORWARD == REVERSED EXTERNAL static int Tetra_F [4][4] = { // FORWARD == EXTERNAL
{ 0, 1, 2, 0 }, // Bottom face has an internal normal, other - 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 }, { 0, 1, 3, 0 },
{ 1, 2, 3, 1 }, { 1, 2, 3, 1 },
{ 0, 3, 2, 0 }}; { 0, 3, 2, 0 }};
static int Tetra_R [4][4] = { // REVERSED == FORWARD EXTERNAL static int Tetra_RE [4][4] = { // REVERSED -> FORWARD (EXTERNAL)
{ 0, 2, 1, 0 }, // All faces have external normals { 0, 2, 1, 0 }, // All faces have external normals
{ 0, 1, 3, 0 }, { 0, 1, 3, 0 },
{ 1, 2, 3, 1 }, { 1, 2, 3, 1 },
{ 0, 3, 2, 0 }}; { 0, 3, 2, 0 }};
static int Tetra_nbN [] = { 3, 3, 3, 3 }; 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 // + 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 { 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 { 3, 4, 5, 3, 3 }, // 0 is bottom, 1 is top face
{ 0, 2, 5, 3, 0 }, { 0, 2, 5, 3, 0 },
{ 1, 2, 5, 4, 1 }, { 1, 4, 5, 2, 1 },
{ 1, 0, 3, 4, 1 }}; { 0, 3, 4, 1, 0 }};
static int Penta_R [5][5] = { // REVERSED static int Penta_R [5][5] = { // REVERSED
{ 0, 2, 1, 0, 0 }, // Bottom face has an internal normal, other - external { 0, 1, 2, 0, 0 }, // Bottom face has an internal normal, other - external
{ 3, 5, 4, 3, 3 }, // 0 is bottom, 1 is top face { 3, 4, 5, 3, 3 }, // 0 is bottom, 1 is top face
{ 0, 2, 5, 3, 0 }, { 0, 3, 5, 2, 0 },
{ 1, 2, 5, 4, 1 }, { 1, 2, 5, 4, 1 },
{ 1, 0, 3, 4, 1 }}; { 0, 1, 4, 3, 0 }};
static int Penta_FE [5][5] = { // EXTERNAL static int Penta_FE [5][5] = { // FORWARD -> EXTERNAL
{ 0, 1, 2, 0, 0 }, { 0, 1, 2, 0, 0 },
{ 3, 5, 4, 3, 3 }, { 3, 5, 4, 3, 3 },
{ 0, 2, 5, 3, 0 }, { 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, 2, 5, 4, 1 },
{ 1, 0, 3, 4, 1 }}; { 0, 1, 4, 3, 0 }};
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 }};
static int Penta_nbN [] = { 3, 3, 4, 4, 4 }; static int Penta_nbN [] = { 3, 3, 4, 4, 4 };
/* /*
// N7+----------+N6 // N5+----------+N6
// /| /| // /| /|
// / | / | // / | / |
// / | / | // / | / |
// N4+----------+N5 | // N4+----------+N7 |
// | | | | HEXAHEDRON // | | | | HEXAHEDRON
// | | | | // | | | |
// | | | | // | | | |
// | N3+------|---+N2 // | N1+------|---+N2
// | / | / // | / | /
// | / | / // | / | /
// |/ |/ // |/ |/
// N0+----------+N1 // N0+----------+N3
*/ */
static int Hexa_F [6][5] = { // FORWARD static int Hexa_F [6][5] = { // FORWARD
{ 0, 1, 2, 3, 0 }, // opposite faces are neighbouring, { 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 { 1, 0, 4, 5, 1 }, // same index nodes of opposite faces are linked
{ 2, 3, 7, 6, 2 }, { 2, 3, 7, 6, 2 },
{ 0, 3, 7, 4, 0 }, { 0, 3, 7, 4, 0 },
{ 1, 2, 6, 5, 1 }}; { 1, 2, 6, 5, 1 }};
static int Hexa_R [6][5] = { // REVERSED // static int Hexa_R [6][5] = { // REVERSED
{ 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, // { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring,
{ 4, 7, 6, 5, 4 }, // even face normal is external, odd - internal // { 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 // { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked
{ 2, 6, 7, 3, 2 }, // { 2, 6, 7, 3, 2 },
{ 0, 4, 7, 3, 0 }, // { 0, 4, 7, 3, 0 },
{ 1, 5, 6, 2, 1 }}; // { 1, 5, 6, 2, 1 }};
static int Hexa_FE [6][5] = { // EXTERNAL static int Hexa_FE [6][5] = { // FORWARD -> EXTERNAL
{ 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, { 0, 1, 2, 3, 0 } , // opposite faces are neighbouring,
{ 4, 5, 6, 7, 4 }, // all face normals are external, { 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 { 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 }, { 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_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 }};
static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
// ======================================================== // ========================================================
@ -170,7 +203,6 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
myVolForward( true ), myVolForward( true ),
myNbFaces( 0 ), myNbFaces( 0 ),
myVolumeNbNodes( 0 ), myVolumeNbNodes( 0 ),
myForwardFaces( false ),
myExternalFaces( false ) myExternalFaces( false )
{ {
} }
@ -180,8 +212,7 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
//======================================================================= //=======================================================================
SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume) SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
: myForwardFaces( false ), : myExternalFaces( false )
myExternalFaces( false )
{ {
Set( theVolume ); Set( theVolume );
} }
@ -212,6 +243,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
myVolumeNbNodes = theVolume->NbNodes(); myVolumeNbNodes = theVolume->NbNodes();
switch ( myVolumeNbNodes ) { switch ( myVolumeNbNodes ) {
case 4: case 4:
case 5:
case 6: case 6:
case 8: case 8:
{ {
@ -227,6 +259,8 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
// nb nodes in each face // nb nodes in each face
if ( myVolumeNbNodes == 4 ) if ( myVolumeNbNodes == 4 )
myFaceNbNodes = Tetra_nbN; myFaceNbNodes = Tetra_nbN;
else if ( myVolumeNbNodes == 5 )
myFaceNbNodes = Pyramid_nbN;
else if ( myVolumeNbNodes == 6 ) else if ( myVolumeNbNodes == 6 )
myFaceNbNodes = Penta_nbN; myFaceNbNodes = Penta_nbN;
else else
@ -240,8 +274,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
XYZ upDir (topNode->X() - botNode->X(), XYZ upDir (topNode->X() - botNode->X(),
topNode->Y() - botNode->Y(), topNode->Y() - botNode->Y(),
topNode->Z() - botNode->Z() ); topNode->Z() - botNode->Z() );
bool diffDir = ( botNormal.Dot( upDir ) < 0 ); myVolForward = ( botNormal.Dot( upDir ) < 0 );
myVolForward = ( myVolumeNbNodes == 6 ? diffDir : !diffDir );
break; break;
} }
default: myVolume = 0; default: myVolume = 0;
@ -273,6 +306,9 @@ void SMDS_VolumeTool::Inverse ()
case 4: case 4:
SWAP_NODES( myVolumeNodes, 1, 2 ); SWAP_NODES( myVolumeNodes, 1, 2 );
break; break;
case 5:
SWAP_NODES( myVolumeNodes, 1, 3 );
break;
case 6: case 6:
SWAP_NODES( myVolumeNodes, 1, 2 ); SWAP_NODES( myVolumeNodes, 1, 2 );
SWAP_NODES( myVolumeNodes, 4, 5 ); SWAP_NODES( myVolumeNodes, 4, 5 );
@ -318,16 +354,6 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const
return true; return true;
} }
//=======================================================================
//function : SetForwardOrientation
//purpose : Node order will be as for forward orientation
//=======================================================================
void SMDS_VolumeTool::SetForwardOrientation ()
{
myForwardFaces = true;
}
//======================================================================= //=======================================================================
//function : SetExternalNormal //function : SetExternalNormal
//purpose : Node order will be so that faces normals are external //purpose : Node order will be so that faces normals are external
@ -336,6 +362,7 @@ void SMDS_VolumeTool::SetForwardOrientation ()
void SMDS_VolumeTool::SetExternalNormal () void SMDS_VolumeTool::SetExternalNormal ()
{ {
myExternalFaces = true; myExternalFaces = true;
myCurFace = -1;
} }
//======================================================================= //=======================================================================
@ -385,8 +412,8 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
//purpose : Return a set of face nodes. //purpose : Return a set of face nodes.
//======================================================================= //=======================================================================
bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
std::set<const SMDS_MeshNode*>& theFaceNodes ) set<const SMDS_MeshNode*>& theFaceNodes )
{ {
if ( !setFace( faceIndex )) if ( !setFace( faceIndex ))
return false; return false;
@ -409,18 +436,18 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
if ( myExternalFaces || !myVolume ) if ( myExternalFaces || !myVolume )
return true; return true;
bool reversed = ( !myForwardFaces && !myVolForward );
switch ( myVolumeNbNodes ) { switch ( myVolumeNbNodes ) {
case 4: case 4:
// only the bottom of a forward tetrahedron can be internal case 5:
return ( reversed || faceIndex != 0 ); // only the bottom of a reversed tetrahedron can be internal
return ( myVolForward || faceIndex != 0 );
case 6: case 6:
// in a forward pentahedron, the top is internal, in a reversed one - bottom // 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: { case 8: {
// in a forward hexahedron, odd face normal is external, else vice versa // in a forward hexahedron, even face normal is external, odd - internal
bool odd = (faceIndex % 2 != 0); bool odd = faceIndex % 2;
return ( reversed ? !odd : odd ); return ( myVolForward ? !odd : odd );
} }
default:; default:;
} }
@ -544,6 +571,15 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
switch ( myVolumeNbNodes ) { switch ( myVolumeNbNodes ) {
case 4: case 4:
return true; return true;
case 5:
if ( maxInd == 4 )
return true;
switch ( maxInd - minInd ) {
case 1:
case 3: return true;
default:;
}
break;
case 6: case 6:
switch ( maxInd - minInd ) { switch ( maxInd - minInd ) {
case 1: return minInd != 2; case 1: return minInd != 2;
@ -739,25 +775,25 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
switch ( myVolumeNbNodes ) { switch ( myVolumeNbNodes ) {
case 4: case 4:
if ( myExternalFaces ) if ( myExternalFaces )
myFaceNodeIndices = myVolForward ? Tetra_R[ faceIndex ] : Tetra_F[ faceIndex ]; myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
else if ( myForwardFaces )
myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
else else
myFaceNodeIndices = Tetra_F[ faceIndex ]; myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
break;
case 5:
if ( myExternalFaces )
myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
else
myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
break; break;
case 6: case 6:
if ( myExternalFaces ) if ( myExternalFaces )
myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ]; myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
else if ( myForwardFaces )
myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
else else
myFaceNodeIndices = Penta_F[ faceIndex ]; myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
break; break;
case 8: case 8:
if ( myExternalFaces ) if ( myExternalFaces )
myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ]; myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
else if ( myForwardFaces )
myFaceNodeIndices = myVolForward ? Hexa_F[ faceIndex ] : Hexa_R[ faceIndex ];
else else
myFaceNodeIndices = Hexa_F[ faceIndex ]; myFaceNodeIndices = Hexa_F[ faceIndex ];
break; break;

View File

@ -62,7 +62,7 @@ class SMDS_VolumeTool
bool IsForward() const { return myVolForward; } bool IsForward() const { return myVolForward; }
// Check volume orientation. can be changed by Inverse(). // 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(); void Inverse();
// Change nodes order as if the volume changes its orientation: // Change nodes order as if the volume changes its orientation:
@ -101,12 +101,8 @@ class SMDS_VolumeTool
// info on faces // info on faces
// ------------- // -------------
void SetForwardOrientation ();
// Node order in faces will be as for forward orientation
void SetExternalNormal (); void SetExternalNormal ();
// Node order in faces will be so that faces normals are external. // Node order in faces will be so that faces normals are external.
// It overrides SetForwardOrientation()
int NbFaces() const { return myNbFaces; } int NbFaces() const { return myNbFaces; }
// Return number of faces of the volume. In the following // Return number of faces of the volume. In the following
@ -135,8 +131,7 @@ class SMDS_VolumeTool
bool IsFaceExternal( int faceIndex ); bool IsFaceExternal( int faceIndex );
// Check normal orientation of a face. // Check normal orientation of a face.
// SetForwardOrientation() and SetForwardOrientation() are taken // SetExternalNormal() is taken into account.
// into account.
bool IsFreeFace( int faceIndex ); bool IsFreeFace( int faceIndex );
// Check that all volumes built on the face nodes lays on one side // Check that all volumes built on the face nodes lays on one side
@ -169,7 +164,6 @@ class SMDS_VolumeTool
int myVolumeNbNodes; int myVolumeNbNodes;
const SMDS_MeshNode* myVolumeNodes[ 8 ]; const SMDS_MeshNode* myVolumeNodes[ 8 ];
bool myForwardFaces;
bool myExternalFaces; bool myExternalFaces;
int* myFaceNodeIndices; int* myFaceNodeIndices;
int* myFaceNbNodes; int* myFaceNbNodes;
@ -191,13 +185,13 @@ class SMDS_VolumeTool
// /|\ // /|\
// / | \ // / | \
// / | \ // / | \
// N0 +---|---+ N2 TETRAHEDRON // N0 +---|---+ N1 TETRAHEDRON
// \ | / // \ | /
// \ | / // \ | /
// \ | / // \ | /
// \|/ // \|/
// + // +
// N1 // N2
// + N4 // + N4
// /|\ // /|\
@ -213,18 +207,18 @@ class SMDS_VolumeTool
// |/ \| // |/ \|
// N0 +---------+ N2 // N0 +---------+ N2
// N7+----------+N6 // N5+----------+N6
// /| /| // /| /|
// / | / | // / | / |
// / | / | // / | / |
// N4+----------+N5 | // N4+----------+N7 |
// | | | | HEXAHEDRON // | | | | HEXAHEDRON
// | | | | // | | | |
// | | | | // | | | |
// | N3+------|---+N2 // | N1+------|---+N2
// | / | / // | / | /
// | / | / // | / | /
// |/ |/ // |/ |/
// N0+----------+N1 // N0+----------+N3
// //
*/ */