0021371: EDF SMESH: The propagation of elements courbure is sometimes wrong in quadratic conversion with nodes on geometry

+  double MinLinearSize2() const;
+  // Return minimal square distance between connected corner nodes
This commit is contained in:
eap 2011-10-06 15:59:05 +00:00
parent bc5760bd4e
commit 1d668d5560
2 changed files with 84 additions and 37 deletions

View File

@ -38,8 +38,8 @@
#include "utilities.h" #include "utilities.h"
#include <map> #include <map>
#include <float.h> #include <limits>
#include <math.h> #include <cmath>
using namespace std; using namespace std;
@ -383,6 +383,7 @@ struct XYZ {
inline XYZ Crossed( const XYZ& other ); inline XYZ Crossed( const XYZ& other );
inline double Dot( const XYZ& other ); inline double Dot( const XYZ& other );
inline double Magnitude(); inline double Magnitude();
inline double SquareMagnitude();
}; };
inline XYZ XYZ::operator-( const XYZ& Right ) { inline XYZ XYZ::operator-( const XYZ& Right ) {
return XYZ(x - Right.x, y - Right.y, z - Right.z); 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() { inline double XYZ::Magnitude() {
return sqrt (x * x + y * y + z * z); 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 // LIMITATION: for convex volumes only
XYZ p( X,Y,Z ); XYZ p( X,Y,Z );
@ -886,7 +890,7 @@ void SMDS_VolumeTool::SetExternalNormal ()
//purpose : Return number of nodes in the array of face nodes //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 )) if ( !setFace( faceIndex ))
return 0; return 0;
@ -901,7 +905,7 @@ int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
// the last node == the first one. // 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 )) if ( !setFace( faceIndex ))
return 0; return 0;
@ -916,17 +920,18 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex )
// the last node index == the first one. // 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 )) if ( !setFace( faceIndex ))
return 0; return 0;
if (myVolume->IsPoly()) if (myVolume->IsPoly())
{ {
myPolyIndices.resize( myFaceNbNodes + 1 ); SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
myFaceNodeIndices = & myPolyIndices[0]; me->myPolyIndices.resize( myFaceNbNodes + 1 );
me->myFaceNodeIndices = & me->myPolyIndices[0];
for ( int i = 0; i <= myFaceNbNodes; ++i ) for ( int i = 0; i <= myFaceNbNodes; ++i )
myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] ); me->myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] );
} }
return myFaceNodeIndices; return myFaceNodeIndices;
} }
@ -937,7 +942,7 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
//======================================================================= //=======================================================================
bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
set<const SMDS_MeshNode*>& theFaceNodes ) set<const SMDS_MeshNode*>& theFaceNodes ) const
{ {
if ( !setFace( faceIndex )) if ( !setFace( faceIndex ))
return false; return false;
@ -955,7 +960,7 @@ bool SMDS_VolumeTool::GetFaceNodes (int faceIndex,
//purpose : Check normal orientation of a given face //purpose : Check normal orientation of a given face
//======================================================================= //=======================================================================
bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
{ {
if ( myExternalFaces || !myVolume ) if ( myExternalFaces || !myVolume )
return true; return true;
@ -997,7 +1002,7 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
//purpose : Return a normal to a face //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 )) if ( !setFace( faceIndex ))
return false; return false;
@ -1020,7 +1025,7 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
} }
double size = cross.Magnitude(); double size = cross.Magnitude();
if ( size <= DBL_MIN ) if ( size <= numeric_limits<double>::min() )
return false; return false;
X = cross.x / size; 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 )) if ( !setFace( faceIndex ))
return false; return false;
@ -1056,7 +1061,7 @@ bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y,
//purpose : Return face area //purpose : Return face area
//======================================================================= //=======================================================================
double SMDS_VolumeTool::GetFaceArea( int faceIndex ) double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const
{ {
if (myVolume->IsPoly()) { if (myVolume->IsPoly()) {
MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume"); 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<const SMDS_MeshElement*> & faces) int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
{ {
faces.clear(); faces.clear();
faces.reserve( NbFaces() ); faces.reserve( NbFaces() );
@ -1355,6 +1360,45 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges
return edges.size(); 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 * \brief check that only one volume is build on the face nodes
@ -1363,7 +1407,7 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & 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; 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 //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++ ) { for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
const SMDS_MeshNode** nodes = GetFaceNodes( iFace ); const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
@ -1521,7 +1565,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes
//purpose : //purpose :
//======================================================================= //=======================================================================
bool SMDS_VolumeTool::setFace( int faceIndex ) bool SMDS_VolumeTool::setFace( int faceIndex ) const
{ {
if ( !myVolume ) if ( !myVolume )
return false; return false;

View File

@ -94,7 +94,7 @@ class SMDS_EXPORT SMDS_VolumeTool
bool GetBaryCenter (double & X, double & Y, double & Z) const; 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 // Classify a point
// ----------------------- // -----------------------
@ -120,6 +120,9 @@ class SMDS_EXPORT SMDS_VolumeTool
int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const; int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const;
// Fill vector with boundary edges existing in the mesh // Fill vector with boundary edges existing in the mesh
double MinLinearSize2() const;
// Return minimal square distance between connected corner nodes
// ------------- // -------------
// info on faces // info on faces
// ------------- // -------------
@ -131,10 +134,10 @@ class SMDS_EXPORT SMDS_VolumeTool
// Return number of faces of the volume. In the following // Return number of faces of the volume. In the following
// methods 0 <= faceIndex < NbFaces() // methods 0 <= faceIndex < NbFaces()
int NbFaceNodes( int faceIndex ); int NbFaceNodes( int faceIndex ) const;
// Return number of nodes in the array of face nodes // 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 // Return the array of face nodes indices
// To comfort link iteration, the array // To comfort link iteration, the array
// length == NbFaceNodes( faceIndex ) + 1 and // 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 // 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 // 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. // Return the array of face nodes.
// To comfort link iteration, the array // To comfort link iteration, the array
// length == NbFaceNodes( faceIndex ) + 1 and // length == NbFaceNodes( faceIndex ) + 1 and
@ -153,30 +156,30 @@ class SMDS_EXPORT SMDS_VolumeTool
// work basing on its contents // work basing on its contents
bool GetFaceNodes (int faceIndex, bool GetFaceNodes (int faceIndex,
std::set<const SMDS_MeshNode*>& theFaceNodes ); std::set<const SMDS_MeshNode*>& theFaceNodes ) const;
// Return a set of face nodes. // Return a set of face nodes.
bool IsFaceExternal( int faceIndex ); bool IsFaceExternal( int faceIndex ) const;
// Check normal orientation of a face. // Check normal orientation of a face.
// SetExternalNormal() is taken into account. // 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 // Check that all volumes built on the face nodes lays on one side
// otherVol returns another volume sharing the given facet // 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 // 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 // Return barycenter of a face
double GetFaceArea( int faceIndex ); double GetFaceArea( int faceIndex ) const;
// Return face area // Return face area
int GetOppFaceIndex( int faceIndex ) const; int GetOppFaceIndex( int faceIndex ) const;
// Return index of the opposite face if it exists, else -1. // 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 index of a face formed by theFaceNodes.
// Return -1 if a face not found // 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 index of a face formed by theFaceNodesIndices
// Return -1 if a face not found // 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 // Fill vector with boundary faces existing in the mesh
// ------------------------ // ------------------------
@ -214,7 +217,7 @@ class SMDS_EXPORT SMDS_VolumeTool
private: private:
bool setFace( int faceIndex ); bool setFace( int faceIndex ) const;
const SMDS_MeshElement* myVolume; const SMDS_MeshElement* myVolume;
const SMDS_VtkVolume* myPolyedre; const SMDS_VtkVolume* myPolyedre;
@ -225,12 +228,12 @@ private:
const SMDS_MeshNode** myVolumeNodes; const SMDS_MeshNode** myVolumeNodes;
std::vector< int > myPolyIndices; std::vector< int > myPolyIndices;
bool myExternalFaces; mutable bool myExternalFaces;
int myCurFace; mutable int myCurFace;
int myFaceNbNodes; mutable int myFaceNbNodes;
int* myFaceNodeIndices; mutable int* myFaceNodeIndices;
const SMDS_MeshNode** myFaceNodes; mutable const SMDS_MeshNode** myFaceNodes;
}; };
#endif #endif