diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 53bb4c140..745ed6454 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -38,8 +38,8 @@ #include "utilities.h" #include -#include -#include +#include +#include using namespace std; @@ -383,6 +383,7 @@ struct XYZ { inline XYZ Crossed( const XYZ& other ); inline double Dot( const XYZ& other ); inline double Magnitude(); + inline double SquareMagnitude(); }; inline XYZ XYZ::operator-( const XYZ& Right ) { return XYZ(x - Right.x, y - Right.y, z - Right.z); @@ -398,6 +399,9 @@ inline double XYZ::Dot( const XYZ& Other ) { inline double XYZ::Magnitude() { return sqrt (x * x + y * y + z * z); } +inline double XYZ::SquareMagnitude() { + return (x * x + y * y + z * z); +} } //======================================================================= @@ -851,7 +855,7 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const */ //================================================================================ -bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) +bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) const { // LIMITATION: for convex volumes only XYZ p( X,Y,Z ); @@ -886,7 +890,7 @@ void SMDS_VolumeTool::SetExternalNormal () //purpose : Return number of nodes in the array of face nodes //======================================================================= -int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) +int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) const { if ( !setFace( faceIndex )) return 0; @@ -901,7 +905,7 @@ int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) // the last node == the first one. //======================================================================= -const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) +const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) const { if ( !setFace( faceIndex )) return 0; @@ -916,17 +920,18 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) // the last node index == the first one. //======================================================================= -const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) +const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const { if ( !setFace( faceIndex )) return 0; if (myVolume->IsPoly()) { - myPolyIndices.resize( myFaceNbNodes + 1 ); - myFaceNodeIndices = & myPolyIndices[0]; + SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this ); + me->myPolyIndices.resize( myFaceNbNodes + 1 ); + me->myFaceNodeIndices = & me->myPolyIndices[0]; for ( int i = 0; i <= myFaceNbNodes; ++i ) - myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] ); + me->myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] ); } return myFaceNodeIndices; } @@ -937,7 +942,7 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) //======================================================================= bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, - set& theFaceNodes ) + set& theFaceNodes ) const { if ( !setFace( faceIndex )) return false; @@ -955,7 +960,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, //purpose : Check normal orientation of a given face //======================================================================= -bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) +bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const { if ( myExternalFaces || !myVolume ) return true; @@ -997,7 +1002,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) //purpose : Return a normal to a face //======================================================================= -bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) +bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const { if ( !setFace( faceIndex )) return false; @@ -1020,7 +1025,7 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub } double size = cross.Magnitude(); - if ( size <= DBL_MIN ) + if ( size <= numeric_limits::min() ) return false; X = cross.x / size; @@ -1036,7 +1041,7 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub */ //================================================================================ -bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) +bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const { if ( !setFace( faceIndex )) return false; @@ -1056,7 +1061,7 @@ bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, //purpose : Return face area //======================================================================= -double SMDS_VolumeTool::GetFaceArea( int faceIndex ) +double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const { if (myVolume->IsPoly()) { MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume"); @@ -1304,7 +1309,7 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) +int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) const { faces.clear(); faces.reserve( NbFaces() ); @@ -1355,6 +1360,45 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector & edges return edges.size(); } +//================================================================================ +/*! + * \brief Return minimal square distance between connected corner nodes + */ +//================================================================================ + +double SMDS_VolumeTool::MinLinearSize2() const +{ + double minSize = 1e+100; + int iQ = myVolume->IsQuadratic() ? 2 : 1; + + // store current face data + int curFace = myCurFace, nbN = myFaceNbNodes; + int* ind = myFaceNodeIndices; + myFaceNodeIndices = NULL; + const SMDS_MeshNode** nodes = myFaceNodes; + myFaceNodes = NULL; + + // it seems that compute distance twice is faster than organization of a sole computing + myCurFace = -1; + for ( int iF = 0; iF < myNbFaces; ++iF ) + { + setFace( iF ); + for ( int iN = 0; iN < myFaceNbNodes; iN += iQ ) + { + XYZ n1( myFaceNodes[ iN ]); + XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]); + minSize = std::min( minSize, (n1 - n2).SquareMagnitude()); + } + } + // restore current face data + myCurFace = curFace; + myFaceNbNodes = nbN; + myFaceNodeIndices = ind; + delete [] myFaceNodes; myFaceNodes = nodes; + + return minSize; +} + //================================================================================ /*! * \brief check that only one volume is build on the face nodes @@ -1363,7 +1407,7 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector & edges */ //================================================================================ -bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) +bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const { const bool isFree = true; @@ -1483,7 +1527,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV //purpose : Return index of a face formed by theFaceNodes //======================================================================= -int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes ) +int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes ) const { for ( int iFace = 0; iFace < myNbFaces; iFace++ ) { const SMDS_MeshNode** nodes = GetFaceNodes( iFace ); @@ -1521,7 +1565,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes //purpose : //======================================================================= -bool SMDS_VolumeTool::setFace( int faceIndex ) +bool SMDS_VolumeTool::setFace( int faceIndex ) const { if ( !myVolume ) return false; diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index f21a47209..9f35726aa 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -94,7 +94,7 @@ class SMDS_EXPORT SMDS_VolumeTool bool GetBaryCenter (double & X, double & Y, double & Z) const; - bool IsOut(double X, double Y, double Z, double tol); + bool IsOut(double X, double Y, double Z, double tol) const; // Classify a point // ----------------------- @@ -120,6 +120,9 @@ class SMDS_EXPORT SMDS_VolumeTool int GetAllExistingEdges(std::vector & edges) const; // Fill vector with boundary edges existing in the mesh + double MinLinearSize2() const; + // Return minimal square distance between connected corner nodes + // ------------- // info on faces // ------------- @@ -131,10 +134,10 @@ class SMDS_EXPORT SMDS_VolumeTool // Return number of faces of the volume. In the following // methods 0 <= faceIndex < NbFaces() - int NbFaceNodes( int faceIndex ); + int NbFaceNodes( int faceIndex ) const; // Return number of nodes in the array of face nodes - const int* GetFaceNodesIndices( int faceIndex ); + const int* GetFaceNodesIndices( int faceIndex ) const; // Return the array of face nodes indices // To comfort link iteration, the array // length == NbFaceNodes( faceIndex ) + 1 and @@ -142,7 +145,7 @@ class SMDS_EXPORT SMDS_VolumeTool // NOTE: for the quadratic volume, node indoces are in the order the nodes encounter // in face boundary and not the order they are in the mesh face - const SMDS_MeshNode** GetFaceNodes( int faceIndex ); + const SMDS_MeshNode** GetFaceNodes( int faceIndex ) const; // Return the array of face nodes. // To comfort link iteration, the array // length == NbFaceNodes( faceIndex ) + 1 and @@ -153,30 +156,30 @@ class SMDS_EXPORT SMDS_VolumeTool // work basing on its contents bool GetFaceNodes (int faceIndex, - std::set& theFaceNodes ); + std::set& theFaceNodes ) const; // Return a set of face nodes. - bool IsFaceExternal( int faceIndex ); + bool IsFaceExternal( int faceIndex ) const; // Check normal orientation of a face. // SetExternalNormal() is taken into account. - bool IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol=0 ); + bool IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol=0 ) const; // Check that all volumes built on the face nodes lays on one side // otherVol returns another volume sharing the given facet - bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z); + bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const; // Return a normal to a face - bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z); + bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const; // Return barycenter of a face - double GetFaceArea( int faceIndex ); + double GetFaceArea( int faceIndex ) const; // Return face area int GetOppFaceIndex( int faceIndex ) const; // Return index of the opposite face if it exists, else -1. - int GetFaceIndex( const std::set& theFaceNodes ); + int GetFaceIndex( const std::set& theFaceNodes ) const; // Return index of a face formed by theFaceNodes. // Return -1 if a face not found @@ -184,7 +187,7 @@ class SMDS_EXPORT SMDS_VolumeTool // Return index of a face formed by theFaceNodesIndices // Return -1 if a face not found - int GetAllExistingFaces(std::vector & faces); + int GetAllExistingFaces(std::vector & faces) const; // Fill vector with boundary faces existing in the mesh // ------------------------ @@ -214,7 +217,7 @@ class SMDS_EXPORT SMDS_VolumeTool private: - bool setFace( int faceIndex ); + bool setFace( int faceIndex ) const; const SMDS_MeshElement* myVolume; const SMDS_VtkVolume* myPolyedre; @@ -225,12 +228,12 @@ private: const SMDS_MeshNode** myVolumeNodes; std::vector< int > myPolyIndices; - bool myExternalFaces; + mutable bool myExternalFaces; - int myCurFace; - int myFaceNbNodes; - int* myFaceNodeIndices; - const SMDS_MeshNode** myFaceNodes; + mutable int myCurFace; + mutable int myFaceNbNodes; + mutable int* myFaceNodeIndices; + mutable const SMDS_MeshNode** myFaceNodes; }; #endif