mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0025613: Wrong distance found by xdistef command for attached shapes
1. Divide B-spline curve on sub-intervals (bounded by knots values). 2. Class BRepLib_CheckCurveOnSurface_TargetFunc has been optimized for future implementation to checkshape algorithm (Adaptors are used instead of Geom_Curve(Surface)). 3. Parallelization of new algorithm. The algorithm is based on math_PSO class. Test cases for issue 25613 have been created. Changes in accordance with the last remarks
This commit is contained in:
parent
260f924fe3
commit
769fb6a4ab
@ -105,9 +105,12 @@ is
|
|||||||
|
|
||||||
-- computations
|
-- computations
|
||||||
--
|
--
|
||||||
Perform(me:out);
|
Perform(me:out;
|
||||||
|
isTheMultyTheradDisabled : Boolean from Standard = Standard_False);
|
||||||
---Purpose:
|
---Purpose:
|
||||||
-- Performs the calculation
|
-- Performs the calculation
|
||||||
|
-- If isTheMultyTheadDisabled == TRUE then computation will be made
|
||||||
|
-- without any parallelization.
|
||||||
|
|
||||||
CheckData(me:out)
|
CheckData(me:out)
|
||||||
is protected;
|
is protected;
|
||||||
@ -115,11 +118,14 @@ is
|
|||||||
-- Checks the data
|
-- Checks the data
|
||||||
|
|
||||||
Compute(me:out;
|
Compute(me:out;
|
||||||
thePCurve : Curve from Geom2d)
|
thePCurve : Curve from Geom2d;
|
||||||
|
isTheMultyTheradDisabled : Boolean from Standard)
|
||||||
is protected;
|
is protected;
|
||||||
---Purpose:
|
---Purpose:
|
||||||
-- Computes the max distance for the 3d curve <myCurve>
|
-- Computes the max distance for the 3d curve <myCurve>
|
||||||
-- and 2d curve <thePCurve>
|
-- and 2d curve <thePCurve>
|
||||||
|
-- If isTheMultyTheadDisabled == TRUE then computation will be made
|
||||||
|
-- without any parallelization.
|
||||||
|
|
||||||
-- results
|
-- results
|
||||||
--
|
--
|
||||||
@ -156,6 +162,7 @@ fields
|
|||||||
-- source data
|
-- source data
|
||||||
myCurve : Curve from Geom;
|
myCurve : Curve from Geom;
|
||||||
myPCurve : Curve from Geom2d;
|
myPCurve : Curve from Geom2d;
|
||||||
|
-- 2nd p-curve (for closed surface)
|
||||||
myPCurve2 : Curve from Geom2d;
|
myPCurve2 : Curve from Geom2d;
|
||||||
mySurface : Surface from Geom;
|
mySurface : Surface from Geom;
|
||||||
myFirst : Real from Standard;
|
myFirst : Real from Standard;
|
||||||
|
@ -14,74 +14,107 @@
|
|||||||
|
|
||||||
#include <BRepLib_CheckCurveOnSurface.ixx>
|
#include <BRepLib_CheckCurveOnSurface.ixx>
|
||||||
|
|
||||||
#include <math_GlobOptMin.hxx>
|
#include <Adaptor2d_HCurve2d.hxx>
|
||||||
#include <math_MultipleVarFunctionWithHessian.hxx>
|
#include <Adaptor3d_CurveOnSurface.hxx>
|
||||||
#include <math_Matrix.hxx>
|
#include <Adaptor3d_HSurface.hxx>
|
||||||
|
|
||||||
|
#include <BRep_Tool.hxx>
|
||||||
|
|
||||||
|
#include <Geom2dAdaptor.hxx>
|
||||||
|
#include <Geom2dAdaptor_GHCurve.hxx>
|
||||||
|
#include <Geom2d_BSplineCurve.hxx>
|
||||||
|
#include <Geom2d_TrimmedCurve.hxx>
|
||||||
|
#include <GeomAdaptor_HCurve.hxx>
|
||||||
|
#include <GeomAdaptor_HSurface.hxx>
|
||||||
|
|
||||||
|
#include <GeomProjLib.hxx>
|
||||||
|
|
||||||
|
#include <Geom_BSplineCurve.hxx>
|
||||||
|
|
||||||
#include <Geom_Plane.hxx>
|
#include <Geom_Plane.hxx>
|
||||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||||
#include <Geom_TrimmedCurve.hxx>
|
#include <Geom_TrimmedCurve.hxx>
|
||||||
|
|
||||||
#include <Geom2dAdaptor.hxx>
|
#include <NCollection_Array1.hxx>
|
||||||
|
|
||||||
#include <GeomAdaptor_HSurface.hxx>
|
#include <OSD_Parallel.hxx>
|
||||||
#include <GeomAdaptor_HCurve.hxx>
|
|
||||||
#include <Geom2dAdaptor_HCurve.hxx>
|
|
||||||
|
|
||||||
#include <GeomProjLib.hxx>
|
|
||||||
|
|
||||||
#include <BRep_Tool.hxx>
|
|
||||||
#include <BRep_TEdge.hxx>
|
|
||||||
#include <BRep_CurveRepresentation.hxx>
|
|
||||||
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
|
||||||
|
|
||||||
#include <TopLoc_Location.hxx>
|
|
||||||
|
|
||||||
#include <ProjLib_ProjectedCurve.hxx>
|
#include <ProjLib_ProjectedCurve.hxx>
|
||||||
|
|
||||||
|
#include <Standard_ErrorHandler.hxx>
|
||||||
|
|
||||||
|
#include <TColStd_Array1OfReal.hxx>
|
||||||
|
#include <TopoDS.hxx>
|
||||||
|
|
||||||
|
#include <math_Matrix.hxx>
|
||||||
|
#include <math_MultipleVarFunctionWithHessian.hxx>
|
||||||
|
#include <math_NewtonMinimum.hxx>
|
||||||
|
#include <math_PSO.hxx>
|
||||||
|
#include <math_PSOParticlesPool.hxx>
|
||||||
|
|
||||||
|
class BRepLib_CheckCurveOnSurface_TargetFunc;
|
||||||
|
|
||||||
|
static
|
||||||
|
Standard_Boolean MinComputing(
|
||||||
|
BRepLib_CheckCurveOnSurface_TargetFunc& theFunction,
|
||||||
|
const Standard_Real theEpsilon, //1.0e-3
|
||||||
|
const Standard_Integer theNbParticles,
|
||||||
|
Standard_Real& theBestValue,
|
||||||
|
Standard_Real& theBestParameter);
|
||||||
|
|
||||||
|
static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
|
||||||
|
const Handle(Geom2d_Curve)& theCurve2d,
|
||||||
|
const Standard_Real theFirst,
|
||||||
|
const Standard_Real theLast,
|
||||||
|
Standard_Integer &theNbParticles,
|
||||||
|
TColStd_Array1OfReal* const theSubIntervals = 0);
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//class : BRepLib_CheckCurveOnSurface_GlobOptFunc
|
//class : BRepLib_CheckCurveOnSurface_TargetFunc
|
||||||
//purpose : provides necessary methods to be used in math_GlobOptMin
|
//purpose : Target function (to be minimized)
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
class BRepLib_CheckCurveOnSurface_GlobOptFunc :
|
class BRepLib_CheckCurveOnSurface_TargetFunc :
|
||||||
public math_MultipleVarFunctionWithHessian
|
public math_MultipleVarFunctionWithHessian
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BRepLib_CheckCurveOnSurface_GlobOptFunc
|
BRepLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
|
||||||
(BRepLib_CheckCurveOnSurface_GlobOptFunc&);
|
const Adaptor3d_Curve& theAdCS,
|
||||||
BRepLib_CheckCurveOnSurface_GlobOptFunc
|
const Standard_Real theFirst,
|
||||||
(const Handle(Geom_Curve)& theC3D,
|
const Standard_Real theLast):
|
||||||
const Handle(Geom2d_Curve)& theC2D,
|
myCurve1(theC3D),
|
||||||
const Handle(Geom_Surface)& theSurf,
|
myCurve2(theAdCS),
|
||||||
const Standard_Real theFirst,
|
myFirst(theFirst),
|
||||||
const Standard_Real theLast)
|
myLast(theLast)
|
||||||
:
|
|
||||||
myFirst(theFirst),
|
|
||||||
myLast(theLast)
|
|
||||||
{
|
{
|
||||||
myCurve = new GeomAdaptor_HCurve(theC3D);
|
|
||||||
myPCurve = new Geom2dAdaptor_HCurve(theC2D);
|
|
||||||
mySurf = new GeomAdaptor_HSurface(theSurf);
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
//returns the number of parameters of the function
|
||||||
|
//(the function is one-dimension).
|
||||||
virtual Standard_Integer NbVariables() const {
|
virtual Standard_Integer NbVariables() const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
//returns value of the function when parameters are equal to theX
|
||||||
virtual Standard_Boolean Value(const math_Vector& theX,
|
virtual Standard_Boolean Value(const math_Vector& theX,
|
||||||
Standard_Real& theFVal) {
|
Standard_Real& theFVal)
|
||||||
try {
|
{
|
||||||
const Standard_Real aPar = theX(1);
|
return Value(theX(1), theFVal);
|
||||||
if (!CheckParameter(aPar))
|
}
|
||||||
|
|
||||||
|
//returns value of the one-dimension-function when parameter
|
||||||
|
//is equal to theX
|
||||||
|
Standard_Boolean Value( const Standard_Real theX,
|
||||||
|
Standard_Real& theFVal) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
if (!CheckParameter(theX))
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
gp_Pnt aP1, aP2;
|
|
||||||
gp_Pnt2d aP2d;
|
const gp_Pnt aP1(myCurve1.Value(theX)),
|
||||||
//
|
aP2(myCurve2.Value(theX));
|
||||||
myCurve->D0(aPar, aP1);
|
|
||||||
myPCurve->D0(aPar, aP2d);
|
|
||||||
mySurf->D0(aP2d.X(), aP2d.Y(), aP2);
|
|
||||||
//
|
|
||||||
theFVal = -1.0*aP1.SquareDistance(aP2);
|
theFVal = -1.0*aP1.SquareDistance(aP2);
|
||||||
}
|
}
|
||||||
catch(Standard_Failure) {
|
catch(Standard_Failure) {
|
||||||
@ -90,44 +123,58 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
|
|||||||
//
|
//
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
virtual Standard_Integer GetStateNumber() {
|
//see analogical method for abstract owner class math_MultipleVarFunction
|
||||||
|
virtual Standard_Integer GetStateNumber()
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
//returns the gradient of the function when parameters are
|
||||||
|
//equal to theX
|
||||||
virtual Standard_Boolean Gradient(const math_Vector& theX,
|
virtual Standard_Boolean Gradient(const math_Vector& theX,
|
||||||
math_Vector& theGrad) {
|
math_Vector& theGrad)
|
||||||
try {
|
{
|
||||||
const Standard_Real aPar = theX(1);
|
return Derive(theX(1), theGrad(1));
|
||||||
if (!CheckParameter(aPar)) {
|
}
|
||||||
|
|
||||||
|
//returns 1st derivative of the the one-dimension-function when
|
||||||
|
//parameter is equal to theX
|
||||||
|
Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
if (!CheckParameter(theX))
|
||||||
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
gp_Pnt aP1, aP2;
|
gp_Pnt aP1, aP2;
|
||||||
gp_Vec aDC3D, aDSU, aDSV;
|
gp_Vec aDC1, aDC2;
|
||||||
gp_Pnt2d aP2d;
|
|
||||||
gp_Vec2d aDC2D;
|
|
||||||
//
|
//
|
||||||
myCurve->D1(aPar, aP1, aDC3D);
|
myCurve1.D1(theX, aP1, aDC1);
|
||||||
myPCurve->D1(aPar, aP2d, aDC2D);
|
myCurve2.D1(theX, aP2, aDC2);
|
||||||
mySurf->D1(aP2d.X(), aP2d.Y(), aP2, aDSU, aDSV);
|
|
||||||
|
const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
|
||||||
//
|
//
|
||||||
aP1.SetXYZ(aP1.XYZ() - aP2.XYZ());
|
theDeriv = -2.0*aVec1.Dot(aVec2);
|
||||||
aP2.SetXYZ(aDC3D.XYZ() - aDC2D.X()*aDSU.XYZ() - aDC2D.Y()*aDSV.XYZ());
|
|
||||||
//
|
|
||||||
theGrad(1) = -2.0*aP1.XYZ().Dot(aP2.XYZ());
|
|
||||||
}
|
}
|
||||||
catch(Standard_Failure) {
|
catch(Standard_Failure)
|
||||||
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
//returns value and gradient
|
||||||
virtual Standard_Boolean Values(const math_Vector& theX,
|
virtual Standard_Boolean Values(const math_Vector& theX,
|
||||||
Standard_Real& theVal,
|
Standard_Real& theVal,
|
||||||
math_Vector& theGrad) {
|
math_Vector& theGrad)
|
||||||
if (!Value(theX, theVal)) {
|
{
|
||||||
|
if (!Value(theX, theVal))
|
||||||
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -137,16 +184,20 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
|
|||||||
//
|
//
|
||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
//returns value, gradient and hessian
|
||||||
virtual Standard_Boolean Values(const math_Vector& theX,
|
virtual Standard_Boolean Values(const math_Vector& theX,
|
||||||
Standard_Real& theVal,
|
Standard_Real& theVal,
|
||||||
math_Vector& theGrad,
|
math_Vector& theGrad,
|
||||||
math_Matrix& theHessian) {
|
math_Matrix& theHessian)
|
||||||
if (!Value(theX, theVal)) {
|
{
|
||||||
|
if (!Value(theX, theVal))
|
||||||
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (!Gradient(theX, theGrad)) {
|
if (!Gradient(theX, theGrad))
|
||||||
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -155,27 +206,117 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
|
|||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
private:
|
Standard_Real FirstParameter() const
|
||||||
|
{
|
||||||
Standard_Boolean CheckParameter(const Standard_Real theParam) {
|
return myFirst;
|
||||||
return ((myFirst <= theParam) && (theParam <= myLast));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(GeomAdaptor_HCurve) myCurve;
|
//
|
||||||
Handle(Geom2dAdaptor_HCurve) myPCurve;
|
Standard_Real LastParameter() const
|
||||||
Handle(GeomAdaptor_HSurface) mySurf;
|
{
|
||||||
Standard_Real myFirst;
|
return myLast;
|
||||||
Standard_Real myLast;
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BRepLib_CheckCurveOnSurface_TargetFunc operator=(BRepLib_CheckCurveOnSurface_TargetFunc&);
|
||||||
|
|
||||||
|
//checks if the function can be computed when its parameter is
|
||||||
|
//equal to theParam
|
||||||
|
Standard_Boolean CheckParameter(const Standard_Real theParam) const
|
||||||
|
{
|
||||||
|
return ((myFirst <= theParam) && (theParam <= myLast));
|
||||||
|
}
|
||||||
|
|
||||||
|
const Adaptor3d_Curve& myCurve1;
|
||||||
|
const Adaptor3d_Curve& myCurve2;
|
||||||
|
const Standard_Real myFirst;
|
||||||
|
const Standard_Real myLast;
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
//=======================================================================
|
||||||
void MinComputing(BRepLib_CheckCurveOnSurface_GlobOptFunc& theFunction,
|
//class : BRepLib_CheckCurveOnSurface_Local
|
||||||
const Standard_Real theFirst,
|
//purpose : Created for parallelization possibility only
|
||||||
const Standard_Real theLast,
|
//=======================================================================
|
||||||
const Standard_Real theEpsilon,
|
class BRepLib_CheckCurveOnSurface_Local
|
||||||
Standard_Real& theBestValue,
|
{
|
||||||
Standard_Real& theBestParameter);
|
public:
|
||||||
|
BRepLib_CheckCurveOnSurface_Local(
|
||||||
|
const Handle(Geom_Curve)& theCurve3D,
|
||||||
|
const Handle(Geom2d_Curve)& theCurve2D,
|
||||||
|
const Handle(Geom_Surface)& theSurface,
|
||||||
|
const TColStd_Array1OfReal& theIntervalsArr,
|
||||||
|
const Standard_Real theEpsilonRange,
|
||||||
|
const Standard_Integer theNbParticles):
|
||||||
|
myCurve3D(theCurve3D),
|
||||||
|
myCurve2D(theCurve2D),
|
||||||
|
mySurface(theSurface),
|
||||||
|
mySubIntervals(theIntervalsArr),
|
||||||
|
myEpsilonRange(theEpsilonRange),
|
||||||
|
myNbParticles(theNbParticles),
|
||||||
|
myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1),
|
||||||
|
myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const Standard_Integer& theIndex) const
|
||||||
|
{
|
||||||
|
//For every sub-interval (which is set by mySubIntervals array) this method
|
||||||
|
//computes optimal value of BRepLib_CheckCurveOnSurface_TargetFunc function.
|
||||||
|
//This optimal value will be put in corresponding (depending on theIndex - the
|
||||||
|
//identificator of the current interval in mySubIntervals array) cell of
|
||||||
|
//myArrOfDist and myArrOfParam arrays.
|
||||||
|
const GeomAdaptor_Curve anAC(myCurve3D);
|
||||||
|
const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D);
|
||||||
|
const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface);
|
||||||
|
|
||||||
|
const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
|
||||||
|
|
||||||
|
BRepLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
|
||||||
|
mySubIntervals.Value(theIndex),
|
||||||
|
mySubIntervals.Value(theIndex+1));
|
||||||
|
|
||||||
|
Standard_Real aMinDist = RealLast(), aPar = 0.0;
|
||||||
|
if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
|
||||||
|
{
|
||||||
|
myArrOfDist(theIndex) = RealLast();
|
||||||
|
myArrOfParam(theIndex) = aFunc.FirstParameter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myArrOfDist(theIndex) = aMinDist;
|
||||||
|
myArrOfParam(theIndex) = aPar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns optimal value (inverse of square of maximal distance)
|
||||||
|
void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const
|
||||||
|
{
|
||||||
|
//This method looks for the minimal value of myArrOfDist.
|
||||||
|
|
||||||
|
const Standard_Integer aStartInd = myArrOfDist.Lower();
|
||||||
|
theMinimalValue = myArrOfDist(aStartInd);
|
||||||
|
theParameter = myArrOfParam(aStartInd);
|
||||||
|
for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++)
|
||||||
|
{
|
||||||
|
if(myArrOfDist(i) < theMinimalValue)
|
||||||
|
{
|
||||||
|
theMinimalValue = myArrOfDist(i);
|
||||||
|
theParameter = myArrOfParam(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BRepLib_CheckCurveOnSurface_Local operator=(BRepLib_CheckCurveOnSurface_Local&);
|
||||||
|
const Handle(Geom_Curve)& myCurve3D;
|
||||||
|
const Handle(Geom2d_Curve)& myCurve2D;
|
||||||
|
const Handle(Geom_Surface)& mySurface;
|
||||||
|
|
||||||
|
const TColStd_Array1OfReal& mySubIntervals;
|
||||||
|
const Standard_Real myEpsilonRange;
|
||||||
|
const Standard_Integer myNbParticles;
|
||||||
|
mutable NCollection_Array1<Standard_Real> myArrOfDist;
|
||||||
|
mutable NCollection_Array1<Standard_Real> myArrOfParam;
|
||||||
|
};
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : BRepLib_CheckCurveOnSurface
|
//function : BRepLib_CheckCurveOnSurface
|
||||||
@ -186,7 +327,7 @@ BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface()
|
|||||||
myFirst(0.),
|
myFirst(0.),
|
||||||
myLast(0.),
|
myLast(0.),
|
||||||
myErrorStatus(0),
|
myErrorStatus(0),
|
||||||
myMaxDistance(0.),
|
myMaxDistance(RealLast()),
|
||||||
myMaxParameter(0.)
|
myMaxParameter(0.)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -200,7 +341,7 @@ BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface
|
|||||||
const TopoDS_Face& theFace)
|
const TopoDS_Face& theFace)
|
||||||
:
|
:
|
||||||
myErrorStatus(0),
|
myErrorStatus(0),
|
||||||
myMaxDistance(0.),
|
myMaxDistance(RealLast()),
|
||||||
myMaxParameter(0.)
|
myMaxParameter(0.)
|
||||||
{
|
{
|
||||||
Init(theEdge, theFace);
|
Init(theEdge, theFace);
|
||||||
@ -218,7 +359,7 @@ BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface
|
|||||||
const Standard_Real theLast)
|
const Standard_Real theLast)
|
||||||
:
|
:
|
||||||
myErrorStatus(0),
|
myErrorStatus(0),
|
||||||
myMaxDistance(0.),
|
myMaxDistance(RealLast()),
|
||||||
myMaxParameter(0.)
|
myMaxParameter(0.)
|
||||||
{
|
{
|
||||||
Init(the3DCurve, the2DCurve, theSurface, theFirst, theLast);
|
Init(the3DCurve, the2DCurve, theSurface, theFirst, theLast);
|
||||||
@ -232,6 +373,16 @@ void BRepLib_CheckCurveOnSurface::Init
|
|||||||
(const TopoDS_Edge& theEdge,
|
(const TopoDS_Edge& theEdge,
|
||||||
const TopoDS_Face& theFace)
|
const TopoDS_Face& theFace)
|
||||||
{
|
{
|
||||||
|
myCurve.Nullify();
|
||||||
|
myPCurve.Nullify();
|
||||||
|
myPCurve2.Nullify();
|
||||||
|
mySurface.Nullify();
|
||||||
|
myErrorStatus = 0;
|
||||||
|
myMaxDistance = RealLast();
|
||||||
|
myMaxParameter = 0.0;
|
||||||
|
myFirst = 0.0;
|
||||||
|
myLast = 0.0;
|
||||||
|
|
||||||
if (theEdge.IsNull() || theFace.IsNull()) {
|
if (theEdge.IsNull() || theFace.IsNull()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -241,69 +392,22 @@ void BRepLib_CheckCurveOnSurface::Init
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
Standard_Boolean isPCurveFound;
|
|
||||||
TopLoc_Location aLocE, aLocF, aLocC2D;
|
TopLoc_Location aLocE, aLocF, aLocC2D;
|
||||||
//
|
//
|
||||||
// 3D curve initialization
|
// 3D curve initialization
|
||||||
myCurve = Handle(Geom_Curve)::
|
const Handle(Geom_Curve)& aC = BRep_Tool::Curve(theEdge, aLocE, myFirst, myLast);
|
||||||
DownCast(BRep_Tool::Curve(theEdge, aLocE, myFirst, myLast)->Copy());
|
myCurve = Handle(Geom_Curve)::DownCast(aC->Transformed(aLocE.Transformation()));
|
||||||
myCurve->Transform(aLocE.Transformation());
|
|
||||||
//
|
|
||||||
// Surface initialization
|
// Surface initialization
|
||||||
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLocF);
|
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLocF);
|
||||||
mySurface = Handle(Geom_Surface)::
|
mySurface = Handle(Geom_Surface)::DownCast(aS->Transformed(aLocF.Transformation()));
|
||||||
DownCast(aS->Copy()->Transformed(aLocF.Transformation()));
|
|
||||||
//
|
//
|
||||||
// 2D curves initialization
|
// 2D curves initialization
|
||||||
isPCurveFound = Standard_False;
|
myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, myFirst, myLast);
|
||||||
aLocC2D = aLocF.Predivided(aLocE);
|
|
||||||
const Handle(BRep_TEdge)& aTE = *((Handle(BRep_TEdge)*)&theEdge.TShape());
|
if(BRep_Tool::IsClosed(theEdge, theFace))
|
||||||
BRep_ListIteratorOfListOfCurveRepresentation itcr(aTE->Curves());
|
myPCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()),
|
||||||
//
|
theFace, myFirst, myLast);
|
||||||
for (; itcr.More(); itcr.Next()) {
|
|
||||||
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
|
|
||||||
if (cr->IsCurveOnSurface(aS, aLocC2D)) {
|
|
||||||
isPCurveFound = Standard_True;
|
|
||||||
myPCurve = cr->PCurve();
|
|
||||||
//
|
|
||||||
if (cr->IsCurveOnClosedSurface()) {
|
|
||||||
myPCurve2 = cr->PCurve2();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (isPCurveFound) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
Handle(Geom_Plane) aPlane;
|
|
||||||
Handle(Standard_Type) dtyp = mySurface->DynamicType();
|
|
||||||
//
|
|
||||||
if (dtyp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
|
|
||||||
aPlane = Handle(Geom_Plane)::
|
|
||||||
DownCast(Handle(Geom_RectangularTrimmedSurface)::
|
|
||||||
DownCast(mySurface)->BasisSurface()->Copy());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aPlane = Handle(Geom_Plane)::DownCast(mySurface->Copy());
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (aPlane.IsNull()) { // not a plane
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
aPlane = Handle(Geom_Plane)::DownCast(aPlane);
|
|
||||||
//
|
|
||||||
Handle(GeomAdaptor_HSurface) aGAHS = new GeomAdaptor_HSurface(aPlane);
|
|
||||||
Handle(Geom_Curve) aProjOnPlane =
|
|
||||||
GeomProjLib::ProjectOnPlane (new Geom_TrimmedCurve(myCurve, myFirst, myLast),
|
|
||||||
aPlane, aPlane->Position().Direction(),
|
|
||||||
Standard_True);
|
|
||||||
Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(aProjOnPlane);
|
|
||||||
//
|
|
||||||
ProjLib_ProjectedCurve aProj(aGAHS, aHCurve);
|
|
||||||
myPCurve = Geom2dAdaptor::MakeCurve(aProj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -319,32 +423,46 @@ void BRepLib_CheckCurveOnSurface::Init
|
|||||||
{
|
{
|
||||||
myCurve = the3DCurve;
|
myCurve = the3DCurve;
|
||||||
myPCurve = the2DCurve;
|
myPCurve = the2DCurve;
|
||||||
|
myPCurve2.Nullify();
|
||||||
mySurface = theSurface;
|
mySurface = theSurface;
|
||||||
myFirst = theFirst;
|
myFirst = theFirst;
|
||||||
myLast = theLast;
|
myLast = theLast;
|
||||||
|
myErrorStatus = 0;
|
||||||
|
myMaxDistance = RealLast();
|
||||||
|
myMaxParameter = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Perform
|
//function : Perform
|
||||||
//purpose :
|
//purpose : if isTheMTDisabled == TRUE parallelization is not used
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void BRepLib_CheckCurveOnSurface::Perform()
|
#ifndef HAVE_TBB
|
||||||
|
//After fixing bug # 26365, this fragment should be deleted
|
||||||
|
//(together the text "#ifdef HAVE_TBB")
|
||||||
|
|
||||||
|
void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean)
|
||||||
{
|
{
|
||||||
|
const Standard_Boolean isTheMTDisabled = Standard_True;
|
||||||
|
#else
|
||||||
|
void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
try {
|
try {
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
//
|
//
|
||||||
// 1. Check data
|
// 1. Check data
|
||||||
CheckData();
|
CheckData();
|
||||||
if (myErrorStatus) {
|
if (myErrorStatus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// 2. Compute the max distance
|
// 2. Compute the max distance
|
||||||
Compute(myPCurve);
|
Compute(myPCurve, isTheMTDisabled);
|
||||||
//
|
//
|
||||||
if (!myPCurve2.IsNull()) {
|
if (!myPCurve2.IsNull()) {
|
||||||
// compute max distance for myPCurve2
|
// compute max distance for myPCurve2
|
||||||
// (for the second curve on closed surface)
|
// (for the second curve on closed surface)
|
||||||
Compute(myPCurve2);
|
Compute(myPCurve2, isTheMTDisabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Standard_Failure) {
|
catch (Standard_Failure) {
|
||||||
@ -354,108 +472,252 @@ void BRepLib_CheckCurveOnSurface::Perform()
|
|||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Compute
|
//function : Compute
|
||||||
//purpose :
|
//purpose : if isTheMTDisabled == TRUE parallelization is not used
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void BRepLib_CheckCurveOnSurface::Compute
|
void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve,
|
||||||
(const Handle(Geom2d_Curve)& thePCurve)
|
const Standard_Boolean isTheMTDisabled)
|
||||||
{
|
{
|
||||||
Standard_Integer aNbIt, aStatus;
|
const Standard_Real anEpsilonRange = 1.e-3;
|
||||||
Standard_Real anEpsilonRange, aMinDelta;
|
|
||||||
Standard_Real aFirst, aLast;
|
|
||||||
Standard_Real aValue, aParam, aBP;
|
|
||||||
Standard_Real theMaxDist, theMaxPar;
|
|
||||||
//
|
|
||||||
anEpsilonRange = 1.e-3;
|
|
||||||
aMinDelta = 1.e-5;
|
|
||||||
aFirst = myFirst;
|
|
||||||
aLast = myLast;
|
|
||||||
//
|
|
||||||
BRepLib_CheckCurveOnSurface_GlobOptFunc aFunc
|
|
||||||
(myCurve, thePCurve, mySurface, myFirst, myLast);
|
|
||||||
//
|
|
||||||
math_Vector anOutputParam(1, 1);
|
|
||||||
anOutputParam(1) = aFirst;
|
|
||||||
theMaxDist = 0.;
|
|
||||||
theMaxPar = aFirst;
|
|
||||||
aNbIt = 100;
|
|
||||||
aStatus = Standard_True;
|
|
||||||
//
|
|
||||||
MinComputing(aFunc, aFirst, aLast, anEpsilonRange, theMaxDist, theMaxPar);
|
|
||||||
//
|
|
||||||
while((aNbIt-- >= 0) && aStatus) {
|
|
||||||
aValue = theMaxDist;
|
|
||||||
aParam = theMaxPar;
|
|
||||||
aBP = theMaxPar - aMinDelta;
|
|
||||||
|
|
||||||
if((aBP - aFirst) > Precision::PConfusion())
|
Standard_Integer aNbParticles = 3;
|
||||||
MinComputing(aFunc, aFirst, aBP, anEpsilonRange, theMaxDist, theMaxPar);
|
|
||||||
//
|
|
||||||
if(theMaxDist < aValue) {
|
|
||||||
aLast = aBP;
|
|
||||||
aStatus = Standard_True;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
theMaxDist = aValue;
|
|
||||||
theMaxPar = aParam;
|
|
||||||
aStatus = Standard_False;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if(!aStatus) {
|
|
||||||
aBP = theMaxPar + aMinDelta;
|
|
||||||
|
|
||||||
if((aLast - aBP) > Precision::PConfusion())
|
//Polynomial function with degree n has not more than n-1 maxima and
|
||||||
MinComputing(aFunc, aBP, aLast, 1.0e-3, theMaxDist, theMaxPar);
|
//minima (degree of 1st derivative is equal to n-1 => 1st derivative has
|
||||||
//
|
//no greater than n-1 roots). Consequently, this function has
|
||||||
if(theMaxDist < aValue) {
|
//maximum n monotonicity intervals. That is a good idea to try to put
|
||||||
aFirst = aBP;
|
//at least one particle in every monotonicity interval. Therefore,
|
||||||
aStatus = Standard_True;
|
//number of particles should be equal to n.
|
||||||
}
|
|
||||||
else {
|
|
||||||
theMaxDist = aValue;
|
|
||||||
theMaxPar = aParam;
|
|
||||||
aStatus = Standard_False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
theMaxDist = sqrt(Abs(theMaxDist));
|
|
||||||
if (theMaxDist > myMaxDistance) {
|
|
||||||
myMaxDistance = theMaxDist;
|
|
||||||
myMaxParameter = theMaxPar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
const Standard_Integer aNbSubIntervals =
|
||||||
// Function : MinComputing
|
FillSubIntervals( myCurve, thePCurve,
|
||||||
// purpose :
|
myFirst, myLast, aNbParticles);
|
||||||
//=======================================================================
|
|
||||||
void MinComputing
|
if(!aNbSubIntervals)
|
||||||
(BRepLib_CheckCurveOnSurface_GlobOptFunc& theFunction,
|
|
||||||
const Standard_Real theFirst,
|
|
||||||
const Standard_Real theLast,
|
|
||||||
const Standard_Real theEpsilon, //1.0e-3
|
|
||||||
Standard_Real& theBestValue,
|
|
||||||
Standard_Real& theBestParameter)
|
|
||||||
{
|
|
||||||
const Standard_Real aStepMin = 1.0e-2;
|
|
||||||
math_Vector aFirstV(1, 1), aLastV(1, 1), anOutputParam(1, 1);
|
|
||||||
aFirstV(1) = theFirst;
|
|
||||||
aLastV(1) = theLast;
|
|
||||||
//
|
|
||||||
math_GlobOptMin aFinder(&theFunction, aFirstV, aLastV);
|
|
||||||
aFinder.SetTol(aStepMin, theEpsilon);
|
|
||||||
aFinder.Perform();
|
|
||||||
//
|
|
||||||
const Standard_Integer aNbExtr = aFinder.NbExtrema();
|
|
||||||
for(Standard_Integer i = 1; i <= aNbExtr; i++)
|
|
||||||
{
|
{
|
||||||
Standard_Real aValue = 0.0;
|
myErrorStatus = 3;
|
||||||
aFinder.Points(i, anOutputParam);
|
return;
|
||||||
theFunction.Value(anOutputParam, aValue);
|
}
|
||||||
//
|
|
||||||
if(aValue < theBestValue) {
|
TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
|
||||||
theBestValue = aValue;
|
FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
|
||||||
theBestParameter = anOutputParam(1);
|
|
||||||
|
BRepLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve,
|
||||||
|
mySurface, anIntervals, anEpsilonRange, aNbParticles);
|
||||||
|
|
||||||
|
OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled);
|
||||||
|
|
||||||
|
aComp.OptimalValues(myMaxDistance, myMaxParameter);
|
||||||
|
|
||||||
|
myMaxDistance = sqrt(Abs(myMaxDistance));
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function : FillSubIntervals
|
||||||
|
// purpose : Divides [theFirst, theLast] interval on parts
|
||||||
|
// in order to make searching-algorithm more precisely
|
||||||
|
// (fills theSubIntervals array).
|
||||||
|
// Returns number of subintervals.
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
|
||||||
|
const Handle(Geom2d_Curve)& theCurve2d,
|
||||||
|
const Standard_Real theFirst,
|
||||||
|
const Standard_Real theLast,
|
||||||
|
Standard_Integer &theNbParticles,
|
||||||
|
TColStd_Array1OfReal* const theSubIntervals)
|
||||||
|
{
|
||||||
|
const Standard_Real anArrTempC[2] = {theFirst, theLast};
|
||||||
|
const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2);
|
||||||
|
|
||||||
|
theNbParticles = 3;
|
||||||
|
Handle(Geom2d_BSplineCurve) aBS2DCurv;
|
||||||
|
Handle(Geom_BSplineCurve) aBS3DCurv;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
|
||||||
|
{
|
||||||
|
aBS3DCurv = Handle(Geom_BSplineCurve)::
|
||||||
|
DownCast(Handle(Geom_TrimmedCurve)::
|
||||||
|
DownCast(theCurve3d)->BasisCurve());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
||||||
|
{
|
||||||
|
aBS2DCurv = Handle(Geom2d_BSplineCurve)::
|
||||||
|
DownCast(Handle(Geom2d_TrimmedCurve)::
|
||||||
|
DownCast(theCurve2d)->BasisCurve());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ?
|
||||||
|
aBS3DCurv->Knots() :
|
||||||
|
anArrTemp;
|
||||||
|
const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ?
|
||||||
|
aBS2DCurv->Knots() :
|
||||||
|
anArrTemp;
|
||||||
|
|
||||||
|
Standard_Integer aNbSubIntervals = 1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
const Standard_Integer anIndMax3D = anArrKnots3D.Upper(),
|
||||||
|
anIndMax2D = anArrKnots2D.Upper();
|
||||||
|
|
||||||
|
Standard_Integer anIndex3D = anArrKnots3D.Lower(),
|
||||||
|
anIndex2D = anArrKnots2D.Lower();
|
||||||
|
|
||||||
|
if(theSubIntervals)
|
||||||
|
theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst;
|
||||||
|
|
||||||
|
while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D))
|
||||||
|
{
|
||||||
|
const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D),
|
||||||
|
aVal2D = anArrKnots2D.Value(anIndex2D);
|
||||||
|
const Standard_Real aDelta = aVal3D - aVal2D;
|
||||||
|
|
||||||
|
if(aDelta < Precision::PConfusion())
|
||||||
|
{//aVal3D <= aVal2D
|
||||||
|
if((aVal3D > theFirst) && (aVal3D < theLast))
|
||||||
|
{
|
||||||
|
aNbSubIntervals++;
|
||||||
|
|
||||||
|
if(theSubIntervals)
|
||||||
|
theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
anIndex3D++;
|
||||||
|
|
||||||
|
if(-aDelta < Precision::PConfusion())
|
||||||
|
{//aVal3D == aVal2D
|
||||||
|
anIndex2D++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{//aVal2D < aVal3D
|
||||||
|
if((aVal2D > theFirst) && (aVal2D < theLast))
|
||||||
|
{
|
||||||
|
aNbSubIntervals++;
|
||||||
|
|
||||||
|
if(theSubIntervals)
|
||||||
|
theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
anIndex2D++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(theSubIntervals)
|
||||||
|
theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast;
|
||||||
|
|
||||||
|
if(!aBS3DCurv.IsNull())
|
||||||
|
{
|
||||||
|
theNbParticles = Max(theNbParticles, aBS3DCurv->Degree());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!aBS2DCurv.IsNull())
|
||||||
|
{
|
||||||
|
theNbParticles = Max(theNbParticles, aBS2DCurv->Degree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(Standard_Failure)
|
||||||
|
{
|
||||||
|
#ifdef OCCT_DEBUG
|
||||||
|
cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, "
|
||||||
|
"FillSubIntervals(): Incorrect filling!" << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
aNbSubIntervals = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aNbSubIntervals;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//class : MinComputing
|
||||||
|
//purpose : Performs computing minimal value
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Boolean MinComputing (
|
||||||
|
BRepLib_CheckCurveOnSurface_TargetFunc& theFunction,
|
||||||
|
const Standard_Real theEpsilon, //1.0e-3
|
||||||
|
const Standard_Integer theNbParticles,
|
||||||
|
Standard_Real& theBestValue,
|
||||||
|
Standard_Real& theBestParameter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
|
//They are used for finding a position of theNbParticles worst places
|
||||||
|
const Standard_Integer aNbControlPoints = 3*theNbParticles;
|
||||||
|
//
|
||||||
|
math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1);
|
||||||
|
aParInf(1) = theFunction.FirstParameter();
|
||||||
|
aParSup(1) = theFunction.LastParameter();
|
||||||
|
theBestParameter = aParInf(1);
|
||||||
|
theBestValue = RealLast();
|
||||||
|
|
||||||
|
const Standard_Real aDeltaParam = aParSup(1) - aParInf(1);
|
||||||
|
if(aDeltaParam < Precision::PConfusion())
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
aStepPar(1) = theEpsilon*aDeltaParam;
|
||||||
|
|
||||||
|
math_PSOParticlesPool aParticles(theNbParticles, 1);
|
||||||
|
|
||||||
|
const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1);
|
||||||
|
Standard_Integer aCount = 1;
|
||||||
|
for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++,
|
||||||
|
aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep)
|
||||||
|
{
|
||||||
|
Standard_Real aVal = RealLast();
|
||||||
|
theFunction.Value(aPrm, aVal);
|
||||||
|
|
||||||
|
PSO_Particle* aParticle = aParticles.GetWorstParticle();
|
||||||
|
|
||||||
|
if(aVal > aParticle->BestDistance)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
aParticle->Position[0] = aPrm;
|
||||||
|
aParticle->BestPosition[0] = aPrm;
|
||||||
|
aParticle->Distance = aVal;
|
||||||
|
aParticle->BestDistance = aVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar);
|
||||||
|
aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam);
|
||||||
|
|
||||||
|
//Here, anOutputParam contains parameter, which is near to optimal.
|
||||||
|
//It needs to be more precise. Precision is made by math_NewtonMinimum.
|
||||||
|
math_NewtonMinimum anA(theFunction);
|
||||||
|
anA.Perform(theFunction, anOutputParam);
|
||||||
|
|
||||||
|
if(!anA.IsDone())
|
||||||
|
{
|
||||||
|
#ifdef OCCT_DEBUG
|
||||||
|
cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl;
|
||||||
|
#endif
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
anA.Location(anOutputParam);
|
||||||
|
theBestParameter = anOutputParam(1);
|
||||||
|
theBestValue = anA.Minimum();
|
||||||
|
}
|
||||||
|
catch(Standard_Failure)
|
||||||
|
{
|
||||||
|
#ifdef OCCT_DEBUG
|
||||||
|
cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl;
|
||||||
|
#endif
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
50
tests/bugs/modalg_6/bug25613_1
Normal file
50
tests/bugs/modalg_6/bug25613_1
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
puts "========="
|
||||||
|
puts "CR25613"
|
||||||
|
puts "========="
|
||||||
|
puts ""
|
||||||
|
###############################
|
||||||
|
## Wrong distance found by xdistef command for attached shapes
|
||||||
|
###############################
|
||||||
|
|
||||||
|
set Tol 1.0e-14
|
||||||
|
set dist_good 8.5127062130336385e-006
|
||||||
|
|
||||||
|
restore [locate_data_file bug698_f.brep] f
|
||||||
|
nexplode f e
|
||||||
|
copy f_4 e
|
||||||
|
don f e
|
||||||
|
|
||||||
|
set log [xdistef e f]
|
||||||
|
|
||||||
|
regexp {Max Distance = +([-0-9.+eE]+); Parameter on curve = +([-0-9.+eE]+)} ${log} full dist param
|
||||||
|
|
||||||
|
if { [ expr ($dist - $dist_good) ] < -$Tol } {
|
||||||
|
puts "Error in xdistef command (cannot find maximal distance)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if { $dist > $dist_good } {
|
||||||
|
#Check if distance found is correct
|
||||||
|
|
||||||
|
mkcurve c3d e
|
||||||
|
mk2dcurve c2d e f
|
||||||
|
mksurface ss f
|
||||||
|
|
||||||
|
cvalue c3d $param xx yy zz
|
||||||
|
vertex v1 xx yy zz
|
||||||
|
|
||||||
|
2dcvalue c2d $param uu vv
|
||||||
|
svalue ss uu vv xx yy zz
|
||||||
|
vertex v2 xx yy zz
|
||||||
|
|
||||||
|
distmini dm v1 v2
|
||||||
|
|
||||||
|
if { [ expr abs([dval dm_val] - $dist) ] > $Tol } {
|
||||||
|
if { [dval dm_val] != $dist } {
|
||||||
|
puts "Error. xdistef has failed when computing (dist_V1V2 =[dval dm_val], FoundDist=$dist)"
|
||||||
|
} else {
|
||||||
|
puts "Error. xdistef command works better than on MASTER. Please set \"dist_good\" value to $dist."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts "OK: xdistef algorithm works properly"
|
||||||
|
}
|
||||||
|
}
|
50
tests/bugs/modalg_6/bug25613_2
Normal file
50
tests/bugs/modalg_6/bug25613_2
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
puts "========="
|
||||||
|
puts "CR25613"
|
||||||
|
puts "========="
|
||||||
|
puts ""
|
||||||
|
###############################
|
||||||
|
## Wrong distance found by xdistef command for attached shapes
|
||||||
|
###############################
|
||||||
|
|
||||||
|
set Tol 1.0e-14
|
||||||
|
set dist_good 0.002371098605239398
|
||||||
|
|
||||||
|
restore [locate_data_file bug22790_f.brep] f
|
||||||
|
nexplode f e
|
||||||
|
copy f_2 e
|
||||||
|
don f e
|
||||||
|
|
||||||
|
set log [xdistef e f]
|
||||||
|
|
||||||
|
regexp {Max Distance = +([-0-9.+eE]+); Parameter on curve = +([-0-9.+eE]+)} ${log} full dist param
|
||||||
|
|
||||||
|
if { [ expr ($dist - $dist_good) ] < -$Tol } {
|
||||||
|
puts "Error in xdistef command (cannot find maximal distance)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if { $dist > $dist_good } {
|
||||||
|
#Check if distance found is correct
|
||||||
|
|
||||||
|
mkcurve c3d e
|
||||||
|
mk2dcurve c2d e f
|
||||||
|
mksurface ss f
|
||||||
|
|
||||||
|
cvalue c3d $param xx yy zz
|
||||||
|
vertex v1 xx yy zz
|
||||||
|
|
||||||
|
2dcvalue c2d $param uu vv
|
||||||
|
svalue ss uu vv xx yy zz
|
||||||
|
vertex v2 xx yy zz
|
||||||
|
|
||||||
|
distmini dm v1 v2
|
||||||
|
|
||||||
|
if { [ expr abs([dval dm_val] - $dist) ] > $Tol } {
|
||||||
|
if { [dval dm_val] != $dist } {
|
||||||
|
puts "Error. xdistef has failed when computing (dist_V1V2 =[dval dm_val], FoundDist=$dist)"
|
||||||
|
} else {
|
||||||
|
puts "Error. xdistef command works better than on MASTER. Please set \"dist_good\" value to $dist."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts "OK: xdistef algorithm works properly"
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user