-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021 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
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
-#include "SMDS_VtkVolume.hxx"
#include "SMDS_Mesh.hxx"
-#include "utilities.h"
+#include <utilities.h>
#include <map>
#include <limits>
#include <cmath>
+#include <cstring>
#include <numeric>
#include <algorithm>
-using namespace std;
-
namespace
{
// ======================================================
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 );
myNbFaces = theVolume->NbFaces();
if ( myVolume->IsPoly() )
{
- myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
+ myPolyedre = SMDS_Mesh::DownCast<SMDS_MeshVolume>( myVolume );
myPolyFacetOri.resize( myNbFaces, 0 );
}
}
else
{
- int iNode = 0;
- SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
- while ( nodeIt->more() )
- myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ myVolumeNodes.assign( myVolume->begin_nodes(), myVolume->end_nodes() );
}
// check validity
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 )
{
p1 = p2;
}
V += p1.Dot( area );
+ oriOk = oriOk && IsFaceExternal( f );
}
V /= 6;
+ if ( !oriOk && V > 0 )
+ V *= -1;
}
else
{
//purpose : Return a set of face nodes.
//=======================================================================
-bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
- set<const SMDS_MeshNode*>& theFaceNodes ) const
+bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
+ std::set<const SMDS_MeshNode*>& theFaceNodes ) const
{
if ( !setFace( faceIndex ))
return false;
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 )
{
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
// 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] );
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();
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 )
{
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<double>::min() )
+ if ( size <= std::numeric_limits<double>::min() )
return false;
X = cross.x / size;
case 15:
if ( faceIndex == 0 || faceIndex == 1 )
ind = 1 - faceIndex;
- break;
+ break;
case 8:
case 12:
if ( faceIndex <= 1 ) // top or bottom
} else {
d2 = 0;
}
- vector<const SMDS_MeshNode*>::const_iterator i;
+ std::vector<const SMDS_MeshNode*>::const_iterator i;
for (int iface = 0; iface < myNbFaces; iface++)
{
from = to;
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 > (int)myVolumeNodes.size() - 1 || maxInd == minInd )
return false;
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;
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;
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;
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;
*/
//================================================================================
-int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
+int SMDS_VolumeTool::GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces) const
{
faces.clear();
SaveFacet savedFacet( myCurFace );
*/
//================================================================================
-int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+int SMDS_VolumeTool::GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const
{
edges.clear();
edges.reserve( myVolumeNodes.size() * 2 );
//================================================================================
/*!
- * \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
*/
//================================================================================
// int nb = myCurFace.myNbNodes;
// if ( myVolume->GetEntityType() != vol->GetEntityType() )
// nb -= ( GetCenterNodeIndex(0) > 0 );
- // set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+ // std::set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
// if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
// continue;
// }
//================================================================================
/*!
- * \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
*/
//================================================================================
// 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++ ) {
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;
//purpose : Return index of a face formed by theFaceNodes
//=======================================================================
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes,
+int SMDS_VolumeTool::GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes,
const int theFaceIndexHint ) const
{
if ( theFaceIndexHint >= 0 )
//purpose : Return index of a face formed by theFaceNodes
//=======================================================================
-/*int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
+/*int SMDS_VolumeTool::GetFaceIndex( const std::set<int>& theFaceNodesIndices )
{
for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
const int* nodes = GetFaceNodesIndices( iFace );
int nbFaceNodes = NbFaceNodes( iFace );
- set<int> nodeSet;
+ std::set<int> nodeSet;
for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
nodeSet.insert( nodes[ iNode ] );
if ( theFaceNodesIndices == nodeSet )
if (myVolume->IsPoly())
{
- if (!myPolyedre) {
+ if ( !myPolyedre ) {
MESSAGE("Warning: bad volumic element");
return false;
}
//purpose : return element ID
//=======================================================================
-int SMDS_VolumeTool::ID() const
+smIdType SMDS_VolumeTool::ID() const
{
return myVolume ? myVolume->GetID() : 0;
}