1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0026426: Draft angle algorithm modifies input argument + the result of the operation have very large tolerance values

This is not yet final version of the fix.
This commit is contained in:
ifv
2015-07-17 09:43:21 +03:00
committed by msv
parent 2df22251ea
commit f2049a7ff8
12 changed files with 1557 additions and 573 deletions

View File

@@ -46,6 +46,7 @@ uses
Face from TopoDS, Face from TopoDS,
ShapeModification from BRepBuilderAPI, ShapeModification from BRepBuilderAPI,
ListOfShape from TopTools, ListOfShape from TopTools,
DataMapOfShapeShape from TopTools,
Dir from gp, Dir from gp,
Pln from gp, Pln from gp,
ErrorStatus from Draft ErrorStatus from Draft
@@ -261,9 +262,18 @@ is
returns ListOfShape from TopTools returns ListOfShape from TopTools
is redefined virtual; is redefined virtual;
ModifiedShape (me; S : Shape from TopoDS)
---Purpose: Returns the modified shape corresponding to <S>.
-- S can correspond to the entire initial shape or to its subshape.
-- Raises exceptions Standard_NoSuchObject if S is not the initial shape or
-- a subshape of the initial shape to which the transformation has been applied.
returns Shape from TopoDS is redefined virtual;
CorrectVertexTol(me: in out) is private;
fields fields
myModifiedShapes : ListOfShape from TopTools; myVtxToReplace : DataMapOfShapeShape from TopTools;
end DraftAngle; end DraftAngle;

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
#include <Draft_Modification.ixx> #include <Draft_Modification.ixx>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <TopLoc_Location.hxx> #include <TopLoc_Location.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -48,11 +49,83 @@
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
#include <GeomProjLib.hxx> #include <GeomProjLib.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
//
static Standard_Real EvalTol(const Handle(Geom_Curve)& C3d,
const Handle(Geom2d_Curve) C2d,
const Handle(Geom_Surface)& S,
const Standard_Real f,
const Standard_Real l)
{
Standard_Real first = f, last = l;
//Set first, last to avoid ErrosStatus = 2 because of
//too strong checking of limits in class CheckCurveOnSurface
//
if(!C3d->IsPeriodic())
{
first = Max(first, C3d->FirstParameter());
last = Min(last, C3d->LastParameter());
}
if(!C2d->IsPeriodic())
{
first = Max(first, C2d->FirstParameter());
last = Min(last, C2d->LastParameter());
}
#include <Precision.hxx> GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
CT.Perform(C2d);
if(CT.IsDone())
{
return CT.MaxDistance();
}
else
{
if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
(C3d->IsPeriodic() || C2d->IsPeriodic())))
{
//Try to estimate by sample points
Standard_Integer nbint = 22;
Standard_Real dt = (last - first) / nbint;
dt = Max(dt, Precision::Confusion());
Standard_Real d, dmax = 0.;
gp_Pnt2d aP2d;
gp_Pnt aPC, aPS;
Standard_Integer cnt = 0;
Standard_Real t = first;
for(; t <= last; t += dt)
{
cnt++;
C2d->D0(t, aP2d);
C3d->D0(t, aPC);
S->D0(aP2d.X(), aP2d.Y(), aPS);
d = aPS.SquareDistance(aPC);
if(d > dmax)
{
dmax = d;
}
}
if(cnt < nbint + 1)
{
t = last;
C2d->D0(t, aP2d);
C3d->D0(t, aPC);
S->D0(aP2d.X(), aP2d.Y(), aPS);
d = aPS.SquareDistance(aPC);
if(d > dmax)
{
dmax = d;
}
}
#include <BRep_Builder.hxx> dmax = 1.2 * Sqrt(dmax);
#include <BRepTools.hxx> return dmax;
}
else
{
return 0.;
}
}
}
//======================================================================= //=======================================================================
//function : Draft_Modification //function : Draft_Modification
@@ -445,6 +518,15 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
C->Translate(aV2DT); C->Translate(aV2DT);
} }
} }
//
Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp);
Standard_Real newtol = EvalTol(aC3d, C, SB, Fp, Lp);
if(newtol > Tol)
{
Tol = newtol;
BRep_Builder B;
B.UpdateEdge(NewE, newtol);
}
return Standard_True; return Standard_True;
} }

View File

@@ -1505,6 +1505,7 @@ void Draft_Modification::Perform ()
for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) { for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
const TopoDS_Edge& Edg = Vinf.Edge(); const TopoDS_Edge& Edg = Vinf.Edge();
Standard_Real initpar = Vinf.Parameter(Edg);
//const Draft_EdgeInfo& Einf = myEMap(Edg); //const Draft_EdgeInfo& Einf = myEMap(Edg);
Draft_EdgeInfo& Einf = myEMap(Edg); Draft_EdgeInfo& Einf = myEMap(Edg);
//Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt); //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
@@ -1517,7 +1518,19 @@ void Draft_Modification::Perform ()
Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 ); Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
} }
else else
{
if(Abs(initpar - param) > Precision::PConfusion())
{
Standard_Real f, l;
TopLoc_Location Loc;
const Handle(Geom_Curve)& aC = BRep_Tool::Curve(Edg, Loc, f, l);
if(aC->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
{
Einf.SetNewGeometry(Standard_True);
}
}
Vinf.ChangeParameter(Edg) = param; Vinf.ChangeParameter(Edg) = param;
}
} }
itv.Next(); itv.Next();
} }

View File

@@ -1 +1,3 @@
GeomLib_CMPLRS.edl GeomLib_CMPLRS.edl
GeomLib_CheckCurveOnSurface.cxx
GeomLib_CheckCurveOnSurface.hxx

View File

@@ -0,0 +1,653 @@
// Created by: Nikolai BUKHALOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Adaptor2d_HCurve2d.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor_GHCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomLib_CheckCurveOnSurface.hxx>
#include <gp_Pnt.hxx>
#include <math_Matrix.hxx>
#include <math_MultipleVarFunctionWithHessian.hxx>
#include <math_NewtonMinimum.hxx>
#include <math_PSO.hxx>
#include <math_PSOParticlesPool.hxx>
#include <OSD_Parallel.hxx>
#include <Standard_ErrorHandler.hxx>
#include <TColStd_Array1OfReal.hxx>
class GeomLib_CheckCurveOnSurface_TargetFunc;
static
Standard_Boolean MinComputing(
GeomLib_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 : GeomLib_CheckCurveOnSurface_TargetFunc
//purpose : Target function (to be minimized)
//=======================================================================
class GeomLib_CheckCurveOnSurface_TargetFunc :
public math_MultipleVarFunctionWithHessian
{
public:
GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
const Adaptor3d_Curve& theAdCS,
const Standard_Real theFirst,
const Standard_Real theLast):
myCurve1(theC3D),
myCurve2(theAdCS),
myFirst(theFirst),
myLast(theLast)
{
}
//returns the number of parameters of the function
//(the function is one-dimension).
virtual Standard_Integer NbVariables() const {
return 1;
}
//returns value of the function when parameters are equal to theX
virtual Standard_Boolean Value(const math_Vector& theX,
Standard_Real& theFVal)
{
return Value(theX(1), theFVal);
}
//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;
const gp_Pnt aP1(myCurve1.Value(theX)),
aP2(myCurve2.Value(theX));
theFVal = -1.0*aP1.SquareDistance(aP2);
}
catch(Standard_Failure) {
return Standard_False;
}
//
return Standard_True;
}
//see analogical method for abstract owner class math_MultipleVarFunction
virtual Standard_Integer GetStateNumber()
{
return 0;
}
//returns the gradient of the function when parameters are
//equal to theX
virtual Standard_Boolean Gradient(const math_Vector& theX,
math_Vector& theGrad)
{
return Derive(theX(1), theGrad(1));
}
//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;
}
//
gp_Pnt aP1, aP2;
gp_Vec aDC1, aDC2;
//
myCurve1.D1(theX, aP1, aDC1);
myCurve2.D1(theX, aP2, aDC2);
const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
//
theDeriv = -2.0*aVec1.Dot(aVec2);
}
catch(Standard_Failure)
{
return Standard_False;
}
return Standard_True;
}
//returns value and gradient
virtual Standard_Boolean Values(const math_Vector& theX,
Standard_Real& theVal,
math_Vector& theGrad)
{
if (!Value(theX, theVal))
{
return Standard_False;
}
//
if (!Gradient(theX, theGrad)) {
return Standard_False;
}
//
return Standard_True;
}
//returns value, gradient and hessian
virtual Standard_Boolean Values(const math_Vector& theX,
Standard_Real& theVal,
math_Vector& theGrad,
math_Matrix& theHessian)
{
if (!Value(theX, theVal))
{
return Standard_False;
}
//
if (!Gradient(theX, theGrad))
{
return Standard_False;
}
//
theHessian(1,1) = theGrad(1);
//
return Standard_True;
}
//
Standard_Real FirstParameter() const
{
return myFirst;
}
//
Standard_Real LastParameter() const
{
return myLast;
}
private:
GeomLib_CheckCurveOnSurface_TargetFunc operator=(GeomLib_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;
};
//=======================================================================
//class : GeomLib_CheckCurveOnSurface_Local
//purpose : Created for parallelization possibility only
//=======================================================================
class GeomLib_CheckCurveOnSurface_Local
{
public:
GeomLib_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 GeomLib_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);
GeomLib_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:
GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_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 : GeomLib_CheckCurveOnSurface
//purpose :
//=======================================================================
GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
:
myFirst(0.),
myLast(0.),
myErrorStatus(0),
myMaxDistance(RealLast()),
myMaxParameter(0.)
{
}
//=======================================================================
//function : GeomLib_CheckCurveOnSurface
//purpose :
//=======================================================================
GeomLib_CheckCurveOnSurface::
GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
const Handle(Geom_Surface)& theSurface,
const Standard_Real theFirst,
const Standard_Real theLast):
myCurve(theCurve),
mySurface(theSurface),
myFirst(theFirst),
myLast(theLast),
myErrorStatus(0),
myMaxDistance(RealLast()),
myMaxParameter(0.)
{
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomLib_CheckCurveOnSurface::Init()
{
myCurve.Nullify();
mySurface.Nullify();
myFirst = 0.0;
myLast = 0.0;
myErrorStatus = 0;
myMaxDistance = RealLast();
myMaxParameter = 0.0;
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve,
const Handle(Geom_Surface)& theSurface,
const Standard_Real theFirst,
const Standard_Real theLast)
{
myCurve = theCurve;
mySurface = theSurface;
myFirst = theFirst;
myLast = theLast;
myErrorStatus = 0;
myMaxDistance = RealLast();
myMaxParameter = 0.0;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
#ifndef HAVE_TBB
//After fixing bug # 26365, this fragment should be deleted
//(together the text "#ifdef HAVE_TBB")
void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
const Standard_Boolean)
{
const Standard_Boolean isTheMTDisabled = Standard_True;
#else
void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
const Standard_Boolean isTheMTDisabled)
{
#endif
if( myCurve.IsNull() ||
mySurface.IsNull() ||
thePCurve.IsNull())
{
myErrorStatus = 1;
return;
}
if( (myCurve->FirstParameter() > myFirst) ||
(myCurve->LastParameter() < myLast) ||
(thePCurve->FirstParameter() > myFirst) ||
(thePCurve->LastParameter() < myLast))
{
myErrorStatus = 2;
return;
}
const Standard_Real anEpsilonRange = 1.e-3;
Standard_Integer aNbParticles = 3;
//Polynomial function with degree n has not more than n-1 maxima and
//minima (degree of 1st derivative is equal to n-1 => 1st derivative has
//no greater than n-1 roots). Consequently, this function has
//maximum n monotonicity intervals. That is a good idea to try to put
//at least one particle in every monotonicity interval. Therefore,
//number of particles should be equal to n.
const Standard_Integer aNbSubIntervals =
FillSubIntervals( myCurve, thePCurve,
myFirst, myLast, aNbParticles);
if(!aNbSubIntervals)
{
myErrorStatus = 3;
return;
}
try {
OCC_CATCH_SIGNALS
TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
GeomLib_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));
}
catch (Standard_Failure) {
myErrorStatus = 3;
}
}
//=======================================================================
// 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 (
GeomLib_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;
}

View File

@@ -0,0 +1,117 @@
// Created by: Nikolai BUKHALOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _GeomLib_CheckCurveOnSurface_HeaderFile
#define _GeomLib_CheckCurveOnSurface_HeaderFile
#include <Geom_Curve.hxx>
#include <Standard.hxx>
class Geom_Surface;
class Geom2d_Curve;
//! Computes the max distance between 3D-curve and 2D-curve
//! in some surface.
class GeomLib_CheckCurveOnSurface
{
public:
DEFINE_STANDARD_ALLOC
//! Default contructor
Standard_EXPORT GeomLib_CheckCurveOnSurface(void);
//! Contructor
Standard_EXPORT GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
const Handle(Geom_Surface)& theSurface,
const Standard_Real theFirst,
const Standard_Real theLast);
//! Sets the data for the algorithm
Standard_EXPORT void Init (const Handle(Geom_Curve)& theCurve,
const Handle(Geom_Surface)& theSurface,
const Standard_Real theFirst,
const Standard_Real theLast);
//! Initializes all members by dafault values
Standard_EXPORT void Init();
//! Computes the max distance for the 3d curve <myCurve>
//! and 2d curve <thePCurve>
//! If isTheMultyTheadDisabled == TRUE then computation will be made
//! without any parallelization.
Standard_EXPORT void Perform(const Handle(Geom2d_Curve)& thePCurve,
const Standard_Boolean isTheMultyTheradDisabled = Standard_False);
//! Returns my3DCurve
const Handle(Geom_Curve)& Curve() const
{
return myCurve;
}
//! Returns mySurface
const Handle(Geom_Surface)& Surface() const
{
return mySurface;
}
//! Returns first and last parameter of the curves
//! (2D- and 3D-curves are considered to have same range)
void Range (Standard_Real& theFirst, Standard_Real& theLast)
{
theFirst = myFirst;
theLast = myLast;
}
//! Returns true if the max distance has been found
Standard_Boolean IsDone() const
{
return (myErrorStatus == 0);
}
//! Returns error status
//! The possible values are:
//! 0 - OK;
//! 1 - null curve or surface or 2d curve;
//! 2 - invalid parametric range;
//! 3 - error in calculations.
Standard_Integer ErrorStatus() const
{
return myErrorStatus;
}
//! Returns max distance
Standard_Real MaxDistance() const
{
return myMaxDistance;
}
//! Returns parameter in which the distance is maximal
Standard_Real MaxParameter() const
{
return myMaxParameter;
}
private:
Handle(Geom_Curve) myCurve;
Handle(Geom_Surface) mySurface;
Standard_Real myFirst;
Standard_Real myLast;
Standard_Integer myErrorStatus;
Standard_Real myMaxDistance;
Standard_Real myMaxParameter;
};
#endif // _BRepLib_CheckCurveOnSurface_HeaderFile

View File

@@ -1,5 +1,7 @@
#E6---------------------------------------------- #E6----------------------------------------------
puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_" #puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC26426 ALL: Error: The tolerance of the resulting shape is too big "
ptorus pt 25 24 90 ptorus pt 25 24 90
profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \ profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \

View File

@@ -1,5 +1,5 @@
#C5---------------------------------------------- #C5----------------------------------------------
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6" puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
plane ps 10 -3 0 1 0 0 0 .2 1 plane ps 10 -3 0 1 0 0 0 .2 1
psphere ps ps 20 psphere ps ps 20

View File

@@ -1,5 +1,5 @@
#D3--------------------------------------------- #D3---------------------------------------------
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6" puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is" puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is"
plane pt 0 0 0 1 0 0 plane pt 0 0 0 1 0 0

View File

@@ -1,8 +1,9 @@
# Original bug : pro12877 # Original bug : pro12877
# Date : 02 Dec 98 # Date : 02 Dec 98
puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big" #puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big"
#puts "TODO OCC23511 Linux: The area of the resulting shape is 186543" #puts "TODO OCC23511 Linux: The area of the resulting shape is 186543"
puts "TODO OCC26426 All: Faulty shapes in variables faulty_1 to faulty_"
restore [locate_data_file CFE903_pro12ggx.rle] base restore [locate_data_file CFE903_pro12ggx.rle] base

View File

@@ -1,7 +1,7 @@
# Original bug : pro16449 # Original bug : pro16449
# Date : 18 Dec 98 # Date : 18 Dec 98
puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_4" puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
restore [locate_data_file CFE903_pro16gha.rle] base restore [locate_data_file CFE903_pro16gha.rle] base