mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-24 16:30:34 +05:00
#17828 [CEA 17805] Polyhedron Mesh volume calculation and volume orientation criterion
Fix volume calculation of invalid polyhedra
This commit is contained in:
parent
2cc662ea28
commit
b88c2f1bf7
@ -39,6 +39,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -358,6 +359,7 @@ struct XYZ {
|
|||||||
XYZ( double X, double Y, double Z ) { x = X; y = Y; z = Z; }
|
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 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(); }
|
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 operator+( const XYZ& other );
|
inline XYZ operator+( const XYZ& other );
|
||||||
inline XYZ Crossed( const XYZ& other );
|
inline XYZ Crossed( const XYZ& other );
|
||||||
@ -708,6 +710,7 @@ double SMDS_VolumeTool::GetSize() const
|
|||||||
|
|
||||||
SaveFacet savedFacet( myCurFace );
|
SaveFacet savedFacet( myCurFace );
|
||||||
SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
|
SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
|
||||||
|
XYZ origin( 1 + 1e-6, 22 + 2e-6, 333 + 3e-6 ); // for invalid poly: avoid lying on a facet plane
|
||||||
for ( int f = 0; f < NbFaces(); ++f )
|
for ( int f = 0; f < NbFaces(); ++f )
|
||||||
{
|
{
|
||||||
me->setFace( f );
|
me->setFace( f );
|
||||||
@ -718,7 +721,7 @@ double SMDS_VolumeTool::GetSize() const
|
|||||||
area = area + p1.Crossed( p2 );
|
area = area + p1.Crossed( p2 );
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
}
|
}
|
||||||
V += p1.Dot( area );
|
V += ( p1 - origin ).Dot( area );
|
||||||
}
|
}
|
||||||
V /= 6;
|
V /= 6;
|
||||||
}
|
}
|
||||||
@ -1141,7 +1144,8 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
|
|||||||
|
|
||||||
bool SMDS_VolumeTool::projectNodesToNormal( int faceIndex,
|
bool SMDS_VolumeTool::projectNodesToNormal( int faceIndex,
|
||||||
double& minProj,
|
double& minProj,
|
||||||
double& maxProj ) const
|
double& maxProj,
|
||||||
|
double* normalXYZ ) const
|
||||||
{
|
{
|
||||||
minProj = std::numeric_limits<double>::max();
|
minProj = std::numeric_limits<double>::max();
|
||||||
maxProj = std::numeric_limits<double>::min();
|
maxProj = std::numeric_limits<double>::min();
|
||||||
@ -1149,6 +1153,9 @@ bool SMDS_VolumeTool::projectNodesToNormal( int faceIndex,
|
|||||||
XYZ normal;
|
XYZ normal;
|
||||||
if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
|
if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
|
||||||
return false;
|
return false;
|
||||||
|
if ( normalXYZ )
|
||||||
|
memcpy( normalXYZ, normal.data(), 3*sizeof(double));
|
||||||
|
|
||||||
XYZ p0 ( myCurFace.myNodes[0] );
|
XYZ p0 ( myCurFace.myNodes[0] );
|
||||||
for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
|
for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
|
||||||
{
|
{
|
||||||
|
@ -248,7 +248,10 @@ class SMDS_EXPORT SMDS_VolumeTool
|
|||||||
|
|
||||||
bool setFace( int faceIndex ) const;
|
bool setFace( int faceIndex ) const;
|
||||||
|
|
||||||
bool projectNodesToNormal( int faceIndex, double& minProj, double& maxProj ) const;
|
bool projectNodesToNormal( int faceIndex,
|
||||||
|
double& minProj,
|
||||||
|
double& maxProj,
|
||||||
|
double* normal = 0) const;
|
||||||
|
|
||||||
const SMDS_MeshElement* myVolume;
|
const SMDS_MeshElement* myVolume;
|
||||||
const SMDS_MeshVolume* myPolyedre;
|
const SMDS_MeshVolume* myPolyedre;
|
||||||
|
Loading…
Reference in New Issue
Block a user