mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-03-12 19:24:33 +05:00
VolumeTool has been partially adapted for PolyhedralVolumes processing
This commit is contained in:
parent
52edf90f5a
commit
10df32bae6
@ -11,6 +11,10 @@
|
||||
|
||||
#include "SMDS_MeshElement.hxx"
|
||||
#include "SMDS_MeshNode.hxx"
|
||||
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
#include <map>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -200,19 +204,36 @@ double XYZ::Magnitude() {
|
||||
|
||||
SMDS_VolumeTool::SMDS_VolumeTool ()
|
||||
: myVolume( 0 ),
|
||||
myPolyedre( 0 ),
|
||||
myVolForward( true ),
|
||||
myNbFaces( 0 ),
|
||||
myVolumeNbNodes( 0 ),
|
||||
myExternalFaces( false )
|
||||
myVolumeNodes( NULL ),
|
||||
myExternalFaces( false ),
|
||||
myFaceNbNodes( 0 ),
|
||||
myCurFace( -1 ),
|
||||
myFaceNodeIndices( NULL ),
|
||||
myFaceNodes( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SMDS_VolumeTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
|
||||
: myExternalFaces( false )
|
||||
: myVolume( 0 ),
|
||||
myPolyedre( 0 ),
|
||||
myVolForward( true ),
|
||||
myNbFaces( 0 ),
|
||||
myVolumeNbNodes( 0 ),
|
||||
myVolumeNodes( NULL ),
|
||||
myExternalFaces( false ),
|
||||
myFaceNbNodes( 0 ),
|
||||
myCurFace( -1 ),
|
||||
myFaceNodeIndices( NULL ),
|
||||
myFaceNodes( NULL )
|
||||
{
|
||||
Set( theVolume );
|
||||
}
|
||||
@ -224,6 +245,14 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
|
||||
|
||||
SMDS_VolumeTool::~SMDS_VolumeTool()
|
||||
{
|
||||
if (myVolumeNodes != NULL) {
|
||||
delete [] myVolumeNodes;
|
||||
myVolumeNodes = NULL;
|
||||
}
|
||||
if (myFaceNodes != NULL) {
|
||||
delete [] myFaceNodes;
|
||||
myFaceNodes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -234,38 +263,53 @@ SMDS_VolumeTool::~SMDS_VolumeTool()
|
||||
bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
|
||||
{
|
||||
myVolume = 0;
|
||||
myPolyedre = 0;
|
||||
|
||||
myVolForward = true;
|
||||
myCurFace = -1;
|
||||
myVolumeNbNodes = 0;
|
||||
myNbFaces = 0;
|
||||
myVolumeNbNodes = 0;
|
||||
if (myVolumeNodes != NULL) {
|
||||
delete [] myVolumeNodes;
|
||||
myVolumeNodes = NULL;
|
||||
}
|
||||
|
||||
myExternalFaces = false;
|
||||
myFaceNbNodes = 0;
|
||||
|
||||
myCurFace = -1;
|
||||
myFaceNodeIndices = NULL;
|
||||
if (myFaceNodes != NULL) {
|
||||
delete [] myFaceNodes;
|
||||
myFaceNodes = NULL;
|
||||
}
|
||||
|
||||
if ( theVolume && theVolume->GetType() == SMDSAbs_Volume )
|
||||
{
|
||||
myVolume = theVolume;
|
||||
|
||||
myNbFaces = theVolume->NbFaces();
|
||||
myVolumeNbNodes = theVolume->NbNodes();
|
||||
|
||||
// set volume nodes
|
||||
int iNode = 0;
|
||||
myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
|
||||
SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
|
||||
while ( nodeIt->more() ) {
|
||||
myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
|
||||
}
|
||||
|
||||
if (myVolume->IsPoly()) {
|
||||
myPolyedre = static_cast<const SMDS_PolyhedralVolumeOfNodes*>( myVolume );
|
||||
if (!myPolyedre) {
|
||||
MESSAGE("Warning: bad volumic element");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
switch ( myVolumeNbNodes ) {
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 8:
|
||||
{
|
||||
myVolume = theVolume;
|
||||
myNbFaces = theVolume->NbFaces();
|
||||
|
||||
// set volume nodes
|
||||
int iNode = 0;
|
||||
SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
|
||||
while ( nodeIt->more() )
|
||||
myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
|
||||
|
||||
// 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
|
||||
myFaceNbNodes = Hexa_nbN;
|
||||
|
||||
case 8: {
|
||||
// define volume orientation
|
||||
XYZ botNormal;
|
||||
GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
|
||||
@ -277,15 +321,17 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
|
||||
myVolForward = ( botNormal.Dot( upDir ) < 0 );
|
||||
break;
|
||||
}
|
||||
default: myVolume = 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ( myVolume != 0 );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetInverseNodes
|
||||
//purpose : Return nodes vector of an inverse volume
|
||||
//function : Inverse
|
||||
//purpose : Inverse volume
|
||||
//=======================================================================
|
||||
|
||||
#define SWAP_NODES(nodes,i1,i2) \
|
||||
@ -298,6 +344,11 @@ void SMDS_VolumeTool::Inverse ()
|
||||
{
|
||||
if ( !myVolume ) return;
|
||||
|
||||
if (myVolume->IsPoly()) {
|
||||
MESSAGE("Warning: attempt to inverse polyhedral volume");
|
||||
return;
|
||||
}
|
||||
|
||||
myVolForward = !myVolForward;
|
||||
myCurFace = -1;
|
||||
|
||||
@ -374,7 +425,7 @@ int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
|
||||
{
|
||||
if ( !setFace( faceIndex ))
|
||||
return 0;
|
||||
return myFaceNbNodes[ faceIndex ];
|
||||
return myFaceNbNodes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -402,6 +453,10 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex )
|
||||
|
||||
const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
|
||||
{
|
||||
if (myVolume->IsPoly()) {
|
||||
MESSAGE("Warning: attempt to obtain FaceNodesIndices of polyhedral volume");
|
||||
return NULL;
|
||||
}
|
||||
if ( !setFace( faceIndex ))
|
||||
return 0;
|
||||
return myFaceNodeIndices;
|
||||
@ -419,7 +474,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
|
||||
return false;
|
||||
|
||||
theFaceNodes.clear();
|
||||
int iNode, nbNode = myFaceNbNodes[ faceIndex ];
|
||||
int iNode, nbNode = myFaceNbNodes;
|
||||
for ( iNode = 0; iNode < nbNode; iNode++ )
|
||||
theFaceNodes.insert( myFaceNodes[ iNode ]);
|
||||
|
||||
@ -436,6 +491,16 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
|
||||
if ( myExternalFaces || !myVolume )
|
||||
return true;
|
||||
|
||||
if (myVolume->IsPoly()) {
|
||||
XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
|
||||
GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
|
||||
GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
|
||||
XYZ insideVec (baryCenter - p0);
|
||||
if (insideVec.Dot(aNormal) > 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ( myVolumeNbNodes ) {
|
||||
case 4:
|
||||
case 5:
|
||||
@ -482,7 +547,6 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetFaceArea
|
||||
//purpose : Return face area
|
||||
@ -490,6 +554,11 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
|
||||
|
||||
double SMDS_VolumeTool::GetFaceArea( int faceIndex )
|
||||
{
|
||||
if (myVolume->IsPoly()) {
|
||||
MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !setFace( faceIndex ))
|
||||
return 0;
|
||||
|
||||
@ -500,7 +569,7 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
|
||||
XYZ aVec13( p3 - p1 );
|
||||
double area = aVec12.Crossed( aVec13 ).Magnitude() * 0.5;
|
||||
|
||||
if ( myFaceNbNodes[ faceIndex ] == 4 ) {
|
||||
if ( myFaceNbNodes == 4 ) {
|
||||
XYZ p4 ( myFaceNodes[3] );
|
||||
XYZ aVec14( p4 - p1 );
|
||||
area += aVec14.Crossed( aVec13 ).Magnitude() * 0.5;
|
||||
@ -516,6 +585,11 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
|
||||
int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
|
||||
{
|
||||
int ind = -1;
|
||||
if (myVolume->IsPoly()) {
|
||||
MESSAGE("Warning: attempt to obtain opposite face on polyhedral volume");
|
||||
return ind;
|
||||
}
|
||||
|
||||
if ( faceIndex >= 0 && faceIndex < NbFaces() ) {
|
||||
switch ( myVolumeNbNodes ) {
|
||||
case 6:
|
||||
@ -542,6 +616,33 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
|
||||
if ( !myVolume )
|
||||
return false;
|
||||
|
||||
if (myVolume->IsPoly()) {
|
||||
if (!myPolyedre) {
|
||||
MESSAGE("Warning: bad volumic element");
|
||||
return false;
|
||||
}
|
||||
bool isLinked = false;
|
||||
int iface;
|
||||
for (iface = 1; iface <= myNbFaces && !isLinked; iface++) {
|
||||
int inode, nbFaceNodes = myPolyedre->NbFaceNodes(iface);
|
||||
|
||||
for (inode = 1; inode <= nbFaceNodes && !isLinked; inode++) {
|
||||
const SMDS_MeshNode* curNode = myPolyedre->GetFaceNode(iface, inode);
|
||||
|
||||
if (curNode == theNode1 || curNode == theNode2) {
|
||||
int inextnode = (inode == nbFaceNodes) ? 1 : inode + 1;
|
||||
const SMDS_MeshNode* nextNode = myPolyedre->GetFaceNode(iface, inextnode);
|
||||
|
||||
if ((curNode == theNode1 && nextNode == theNode2) ||
|
||||
(curNode == theNode2 && nextNode == theNode1)) {
|
||||
isLinked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isLinked;
|
||||
}
|
||||
|
||||
// find nodes indices
|
||||
int i1 = -1, i2 = -1;
|
||||
for ( int i = 0; i < myVolumeNbNodes; i++ ) {
|
||||
@ -562,6 +663,10 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
|
||||
bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
|
||||
const int theNode2Index) const
|
||||
{
|
||||
if (myVolume->IsPoly()) {
|
||||
return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
|
||||
}
|
||||
|
||||
int minInd = theNode1Index < theNode2Index ? theNode1Index : theNode2Index;
|
||||
int maxInd = theNode1Index < theNode2Index ? theNode2Index : theNode1Index;
|
||||
|
||||
@ -617,7 +722,6 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsFreeFace
|
||||
//purpose : check that only one volume is build on the face nodes
|
||||
@ -626,11 +730,12 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
|
||||
bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
|
||||
{
|
||||
const int free = true;
|
||||
if ( !setFace( faceIndex ))
|
||||
|
||||
if (!setFace( faceIndex ))
|
||||
return !free;
|
||||
|
||||
const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
|
||||
int nbFaceNodes = NbFaceNodes( faceIndex );
|
||||
int nbFaceNodes = myFaceNbNodes;
|
||||
|
||||
// evaluate nb of face nodes shared by other volume
|
||||
int maxNbShared = -1;
|
||||
@ -706,7 +811,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
|
||||
// check traingle parts 1 & 3
|
||||
if ( isShared[1] && isShared[3] )
|
||||
return !free; // is not free
|
||||
// check traingle parts 0 & 2;
|
||||
// check triangle parts 0 & 2;
|
||||
// 0 part could not be checked in the loop; check it here
|
||||
if ( isShared[2] && prevLinkShared &&
|
||||
volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) &&
|
||||
@ -741,7 +846,7 @@ 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 set<int>& theFaceNodesIndices )
|
||||
{
|
||||
for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
|
||||
const int* nodes = GetFaceNodesIndices( iFace );
|
||||
@ -753,7 +858,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
|
||||
return iFace;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}*/
|
||||
|
||||
//=======================================================================
|
||||
//function : setFace
|
||||
@ -768,42 +873,88 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
|
||||
if ( myCurFace == faceIndex )
|
||||
return true;
|
||||
|
||||
myCurFace = -1;
|
||||
|
||||
if ( faceIndex < 0 || faceIndex >= NbFaces() )
|
||||
return false;
|
||||
|
||||
if (myFaceNodes != NULL) {
|
||||
delete [] myFaceNodes;
|
||||
myFaceNodes = NULL;
|
||||
}
|
||||
|
||||
if (myVolume->IsPoly()) {
|
||||
if (!myPolyedre) {
|
||||
MESSAGE("Warning: bad volumic element");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check orientation
|
||||
bool isGoodOri = true;
|
||||
if (myExternalFaces) {
|
||||
// get natural orientation
|
||||
XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
|
||||
SMDS_VolumeTool vTool (myPolyedre);
|
||||
vTool.GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
|
||||
vTool.GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
|
||||
XYZ insideVec (baryCenter - p0);
|
||||
if (insideVec.Dot(aNormal) > 0)
|
||||
isGoodOri = false;
|
||||
}
|
||||
|
||||
// set face nodes
|
||||
int iNode;
|
||||
myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1);
|
||||
myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
|
||||
if (isGoodOri) {
|
||||
for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
|
||||
myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
|
||||
} else {
|
||||
for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
|
||||
myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, myFaceNbNodes - iNode);
|
||||
}
|
||||
myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first
|
||||
|
||||
} else {
|
||||
// choose face node indices
|
||||
switch ( myVolumeNbNodes ) {
|
||||
case 4:
|
||||
myFaceNbNodes = Tetra_nbN[ faceIndex ];
|
||||
if ( myExternalFaces )
|
||||
myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
|
||||
else
|
||||
myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
|
||||
break;
|
||||
case 5:
|
||||
myFaceNbNodes = Pyramid_nbN[ faceIndex ];
|
||||
if ( myExternalFaces )
|
||||
myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
|
||||
else
|
||||
myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
|
||||
break;
|
||||
case 6:
|
||||
myFaceNbNodes = Penta_nbN[ faceIndex ];
|
||||
if ( myExternalFaces )
|
||||
myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
|
||||
else
|
||||
myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
|
||||
break;
|
||||
case 8:
|
||||
myFaceNbNodes = Hexa_nbN[ faceIndex ];
|
||||
if ( myExternalFaces )
|
||||
myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
|
||||
else
|
||||
myFaceNodeIndices = Hexa_F[ faceIndex ];
|
||||
break;
|
||||
default: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// set face nodes
|
||||
int iNode, nbNode = myFaceNbNodes[ faceIndex ];
|
||||
for ( iNode = 0; iNode <= nbNode; iNode++ )
|
||||
myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
|
||||
for ( int iNode = 0; iNode <= myFaceNbNodes; iNode++ )
|
||||
myFaceNodes[ iNode ] = myVolumeNodes[ myFaceNodeIndices[ iNode ]];
|
||||
}
|
||||
|
||||
myCurFace = faceIndex;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
class SMDS_MeshElement;
|
||||
class SMDS_MeshNode;
|
||||
class SMDS_PolyhedralVolumeOfNodes;
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
@ -149,7 +150,7 @@ class SMDS_VolumeTool
|
||||
// Return index of a face formed by theFaceNodes.
|
||||
// Return -1 if a face not found
|
||||
|
||||
int GetFaceIndex( const std::set<int>& theFaceNodesIndices );
|
||||
//int GetFaceIndex( const std::set<int>& theFaceNodesIndices );
|
||||
// Return index of a face formed by theFaceNodesIndices
|
||||
// Return -1 if a face not found
|
||||
|
||||
@ -159,16 +160,19 @@ class SMDS_VolumeTool
|
||||
bool setFace( int faceIndex );
|
||||
|
||||
const SMDS_MeshElement* myVolume;
|
||||
const SMDS_PolyhedralVolumeOfNodes* myPolyedre;
|
||||
|
||||
bool myVolForward;
|
||||
int myNbFaces;
|
||||
int myVolumeNbNodes;
|
||||
const SMDS_MeshNode* myVolumeNodes[ 8 ];
|
||||
const SMDS_MeshNode** myVolumeNodes;
|
||||
|
||||
bool myExternalFaces;
|
||||
int* myFaceNodeIndices;
|
||||
int* myFaceNbNodes;
|
||||
const SMDS_MeshNode* myFaceNodes[ 5 ];
|
||||
|
||||
int myCurFace;
|
||||
int myFaceNbNodes;
|
||||
int* myFaceNodeIndices;
|
||||
const SMDS_MeshNode** myFaceNodes;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user