X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_VolumeTool.cxx;h=bd207f84ef6d9ddad4fafa3207c4ec579bc45788;hp=c0c506d9cc13ba79e607cbf392d6f612bd1cd4e2;hb=499f29d24922cec66e41b41a0039a954993bc6df;hpb=193c49c87753b6ccabb2b5e6dc935aa480d2d43e diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index c0c506d9c..bd207f84e 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 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 @@ -32,19 +32,17 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_VtkVolume.hxx" #include "SMDS_Mesh.hxx" -#include "utilities.h" +#include #include #include #include +#include #include #include -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 ); @@ -425,11 +424,13 @@ struct SMDS_VolumeTool::SaveFacet SaveFacet( SMDS_VolumeTool::Facet& facet ): myToRestore( facet ) { mySaved = facet; + mySaved.myNodes.swap( facet.myNodes ); } ~SaveFacet() { if ( myToRestore.myIndex != mySaved.myIndex ) myToRestore = mySaved; + myToRestore.myNodes.swap( mySaved.myNodes ); } }; @@ -469,8 +470,9 @@ SMDS_VolumeTool::~SMDS_VolumeTool() //purpose : Set volume to iterate on //======================================================================= -bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, - const bool ignoreCentralNodes) +bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, + const bool ignoreCentralNodes, + const std::vector* otherNodes) { // reset fields myVolume = 0; @@ -503,16 +505,24 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, myNbFaces = theVolume->NbFaces(); if ( myVolume->IsPoly() ) { - myPolyedre = dynamic_cast( myVolume ); + myPolyedre = SMDS_Mesh::DownCast( myVolume ); myPolyFacetOri.resize( myNbFaces, 0 ); } // set nodes - int iNode = 0; myVolumeNodes.resize( myVolume->NbNodes() ); - SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator(); - while ( nodeIt->more() ) - myVolumeNodes[ iNode++ ] = static_cast( nodeIt->next() ); + if ( otherNodes ) + { + if ( otherNodes->size() != myVolumeNodes.size() ) + return ( myVolume = 0 ); + for ( size_t i = 0; i < otherNodes->size(); ++i ) + if ( ! ( myVolumeNodes[i] = (*otherNodes)[0] )) + return ( myVolume = 0 ); + } + else + { + myVolumeNodes.assign( myVolume->begin_nodes(), myVolume->end_nodes() ); + } // check validity if ( !setFace(0) ) @@ -696,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 ) { @@ -711,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 { @@ -843,7 +858,7 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const if ( !myVolume ) return false; - for ( int i = 0; i < myVolumeNodes.size(); i++ ) { + for ( size_t i = 0; i < myVolumeNodes.size(); i++ ) { X += myVolumeNodes[ i ]->X(); Y += myVolumeNodes[ i ]->Y(); Z += myVolumeNodes[ i ]->Z(); @@ -940,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& theFaceNodes ) const +bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, + std::set& theFaceNodes ) const { if ( !setFace( faceIndex )) return false; @@ -954,7 +969,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, namespace { - struct NLink : public std::pair + struct NLink : public std::pair { int myOri; NLink(const SMDS_MeshNode* n1=0, const SMDS_MeshNode* n2=0, int ori=1 ) @@ -1046,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 @@ -1075,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] ); @@ -1133,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::max(); maxProj = std::numeric_limits::min(); @@ -1141,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 ) { @@ -1188,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::min() ) + if ( size <= std::numeric_limits::min() ) return false; X = cross.x / size; @@ -1307,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 @@ -1368,7 +1389,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, } else { d2 = 0; } - vector::const_iterator i; + std::vector::const_iterator i; for (int iface = 0; iface < myNbFaces; iface++) { from = to; @@ -1390,7 +1411,7 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, // find nodes indices int i1 = -1, i2 = -1, nbFound = 0; - for ( int i = 0; i < myVolumeNodes.size() && nbFound < 2; i++ ) + for ( size_t i = 0; i < myVolumeNodes.size() && nbFound < 2; i++ ) { if ( myVolumeNodes[ i ] == theNode1 ) i1 = i, ++nbFound; @@ -1415,10 +1436,10 @@ 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 > myVolumeNodes.size() - 1 || maxInd == minInd ) + if ( minInd < 0 || maxInd > (int)myVolumeNodes.size() - 1 || maxInd == minInd ) return false; VolumeType type = GetVolumeType(); @@ -1467,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; @@ -1478,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; @@ -1493,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; @@ -1505,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; @@ -1535,7 +1556,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const { if ( myVolume ) { - for ( int i = 0; i < myVolumeNodes.size(); i++ ) { + for ( size_t i = 0; i < myVolumeNodes.size(); i++ ) { if ( myVolumeNodes[ i ] == theNode ) return i; } @@ -1551,7 +1572,7 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) const +int SMDS_VolumeTool::GetAllExistingFaces(std::vector & faces) const { faces.clear(); SaveFacet savedFacet( myCurFace ); @@ -1592,12 +1613,12 @@ int SMDS_VolumeTool::GetAllExistingFaces(vector & faces */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingEdges(vector & edges) const +int SMDS_VolumeTool::GetAllExistingEdges(std::vector & edges) const { edges.clear(); edges.reserve( myVolumeNodes.size() * 2 ); - for ( int i = 0; i < myVolumeNodes.size()-1; ++i ) { - for ( int j = i + 1; j < myVolumeNodes.size(); ++j ) { + for ( size_t i = 0; i < myVolumeNodes.size()-1; ++i ) { + for ( size_t j = i + 1; j < myVolumeNodes.size(); ++j ) { if ( IsLinked( i, j )) { const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] ); @@ -1669,7 +1690,7 @@ double SMDS_VolumeTool::MaxLinearSize2() const //================================================================================ /*! - * \brief fast check that only one volume is build on the face nodes + * \brief Fast quickly check that only one volume is built on the face nodes * This check is valid for conformal meshes only */ //================================================================================ @@ -1703,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 faceNodes( nodes, nodes + nb ); + // std::set faceNodes( nodes, nodes + nb ); // if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 ) // continue; // } @@ -1717,7 +1738,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV //================================================================================ /*! - * \brief Thorough check that only one volume is build on the face nodes + * \brief Thorough check that only one volume is built on the face nodes */ //================================================================================ @@ -1733,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++ ) { @@ -1742,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; @@ -1841,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& theFaceNodes, +int SMDS_VolumeTool::GetFaceIndex( const std::set& theFaceNodes, const int theFaceIndexHint ) const { if ( theFaceIndexHint >= 0 ) @@ -1884,12 +1905,12 @@ int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes //purpose : Return index of a face formed by theFaceNodes //======================================================================= -/*int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodesIndices ) +/*int SMDS_VolumeTool::GetFaceIndex( const std::set& theFaceNodesIndices ) { for ( int iFace = 0; iFace < myNbFaces; iFace++ ) { const int* nodes = GetFaceNodesIndices( iFace ); int nbFaceNodes = NbFaceNodes( iFace ); - set nodeSet; + std::set nodeSet; for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) nodeSet.insert( nodes[ iNode ] ); if ( theFaceNodesIndices == nodeSet ) @@ -1918,7 +1939,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const if (myVolume->IsPoly()) { - if (!myPolyedre) { + if ( !myPolyedre ) { MESSAGE("Warning: bad volumic element"); return false; } @@ -2189,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; }