#include "utilities.h"
#include <map>
-#include <float.h>
-#include <math.h>
+#include <limits>
+#include <cmath>
using namespace std;
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);
inline double XYZ::Magnitude() {
return sqrt (x * x + y * y + z * z);
}
+inline double XYZ::SquareMagnitude() {
+ return (x * x + y * y + z * z);
+}
}
//=======================================================================
*/
//================================================================================
-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 );
//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;
// 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;
// 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;
}
//=======================================================================
bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
- set<const SMDS_MeshNode*>& theFaceNodes )
+ set<const SMDS_MeshNode*>& theFaceNodes ) const
{
if ( !setFace( faceIndex ))
return false;
//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;
//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;
}
double size = cross.Magnitude();
- if ( size <= DBL_MIN )
+ if ( size <= numeric_limits<double>::min() )
return false;
X = cross.x / size;
*/
//================================================================================
-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;
//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");
*/
//================================================================================
-int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces)
+int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
{
faces.clear();
faces.reserve( NbFaces() );
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
*/
//================================================================================
-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;
//purpose : Return index of a face formed by theFaceNodes
//=======================================================================
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes )
+int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes ) const
{
for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
//purpose :
//=======================================================================
-bool SMDS_VolumeTool::setFace( int faceIndex )
+bool SMDS_VolumeTool::setFace( int faceIndex ) const
{
if ( !myVolume )
return false;
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
// -----------------------
int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & 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
// -------------
// 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
// 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
// work basing on its contents
bool GetFaceNodes (int faceIndex,
- std::set<const SMDS_MeshNode*>& theFaceNodes );
+ std::set<const SMDS_MeshNode*>& 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<const SMDS_MeshNode*>& theFaceNodes );
+ int GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes ) const;
// Return index of a face formed by theFaceNodes.
// Return -1 if a face not found
// Return index of a face formed by theFaceNodesIndices
// Return -1 if a face not found
- int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces);
+ int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces) const;
// Fill vector with boundary faces existing in the mesh
// ------------------------
private:
- bool setFace( int faceIndex );
+ bool setFace( int faceIndex ) const;
const SMDS_MeshElement* myVolume;
const SMDS_VtkVolume* myPolyedre;
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