PAL22862: GHS3D gives OCC exception

Protect from FPE on a batterfly quadrangle
This commit is contained in:
eap 2012-04-26 14:34:14 +00:00
parent 2f82761f83
commit 72e62d1bfa

View File

@ -40,6 +40,7 @@
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
#include <numeric> #include <numeric>
#include <limits>
using namespace std; using namespace std;
@ -378,37 +379,41 @@ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor()
myElemSearcher=0; myElemSearcher=0;
} }
//======================================================================= //=======================================================================
//function : FindBestPoint //function : FindBestPoint
//purpose : Return a point P laying on the line (PC,V) so that triangle //purpose : Return a point P laying on the line (PC,V) so that triangle
// (P, P1, P2) to be equilateral as much as possible // (P, P1, P2) to be equilateral as much as possible
// V - normal to (P1,P2,PC) // V - normal to (P1,P2,PC)
//======================================================================= //=======================================================================
static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2, static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2,
const gp_Pnt& PC, const gp_Vec& V) const gp_Pnt& PC, const gp_Vec& V)
{ {
double a = P1.Distance(P2); gp_Pnt Pbest = PC;
double b = P1.Distance(PC); const double a = P1.Distance(P2);
double c = P2.Distance(PC); const double b = P1.Distance(PC);
const double c = P2.Distance(PC);
if( a < (b+c)/2 ) if( a < (b+c)/2 )
return PC; return Pbest;
else { else {
// find shift along V in order a to became equal to (b+c)/2 // find shift along V in order a to became equal to (b+c)/2
double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 ); const double Vsize = V.Magnitude();
gp_Dir aDir(V); if ( fabs( Vsize ) > std::numeric_limits<double>::min() )
gp_Pnt Pbest = PC.XYZ() + aDir.XYZ() * shift; {
return Pbest; const double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 );
Pbest.ChangeCoord() += shift * V.XYZ() / Vsize;
}
} }
return Pbest;
} }
//======================================================================= //=======================================================================
//function : HasIntersection3 //function : HasIntersection3
//purpose : Auxilare for HasIntersection() //purpose : Auxilare for HasIntersection()
// find intersection point between triangle (P1,P2,P3) // find intersection point between triangle (P1,P2,P3)
// and segment [PC,P] // and segment [PC,P]
//======================================================================= //=======================================================================
static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3)
{ {
@ -479,7 +484,6 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
return false; return false;
} }
//======================================================================= //=======================================================================
//function : HasIntersection //function : HasIntersection
//purpose : Auxilare for CheckIntersection() //purpose : Auxilare for CheckIntersection()
@ -1010,10 +1014,12 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
PCbest /= 4; PCbest /= 4;
double height = PC.Distance(PCbest); // pyramid height to precise double height = PC.Distance(PCbest); // pyramid height to precise
if(height<1.e-6) { if ( height < 1.e-6 ) {
// create new PCbest using a bit shift along VNorm // create new PCbest using a bit shift along VNorm
PCbest = PC.XYZ() + VNorm.XYZ() * 0.001; PCbest = PC.XYZ() + VNorm.XYZ() * 0.001;
height = PC.Distance(PCbest); height = PC.Distance(PCbest);
if ( height < std::numeric_limits<double>::min() )
return false; // batterfly element
} }
// Restrict pyramid height by intersection with other faces // Restrict pyramid height by intersection with other faces