mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-24 13:50:49 +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:
@@ -46,6 +46,7 @@ uses
|
||||
Face from TopoDS,
|
||||
ShapeModification from BRepBuilderAPI,
|
||||
ListOfShape from TopTools,
|
||||
DataMapOfShapeShape from TopTools,
|
||||
Dir from gp,
|
||||
Pln from gp,
|
||||
ErrorStatus from Draft
|
||||
@@ -261,9 +262,18 @@ is
|
||||
returns ListOfShape from TopTools
|
||||
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
|
||||
|
||||
myModifiedShapes : ListOfShape from TopTools;
|
||||
myVtxToReplace : DataMapOfShapeShape from TopTools;
|
||||
|
||||
end DraftAngle;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
||||
#include <Draft_Modification.ixx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
@@ -48,11 +49,83 @@
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopExp.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>
|
||||
#include <BRepTools.hxx>
|
||||
dmax = 1.2 * Sqrt(dmax);
|
||||
return dmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Draft_Modification
|
||||
@@ -445,6 +518,15 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -1505,6 +1505,7 @@ void Draft_Modification::Perform ()
|
||||
|
||||
for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
|
||||
const TopoDS_Edge& Edg = Vinf.Edge();
|
||||
Standard_Real initpar = Vinf.Parameter(Edg);
|
||||
//const Draft_EdgeInfo& Einf = myEMap(Edg);
|
||||
Draft_EdgeInfo& Einf = myEMap(Edg);
|
||||
//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 );
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
itv.Next();
|
||||
}
|
||||
|
@@ -1 +1,3 @@
|
||||
GeomLib_CMPLRS.edl
|
||||
GeomLib_CheckCurveOnSurface.cxx
|
||||
GeomLib_CheckCurveOnSurface.hxx
|
||||
|
653
src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
Normal file
653
src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
Normal 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;
|
||||
}
|
117
src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
Normal file
117
src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
Normal 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
|
@@ -1,5 +1,7 @@
|
||||
#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
|
||||
profile pr o 20 18 5 p 0 -1 0 1 0 0 l 10 t 0 30 \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#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
|
||||
psphere ps ps 20
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#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"
|
||||
|
||||
plane pt 0 0 0 1 0 0
|
||||
|
@@ -1,8 +1,9 @@
|
||||
# Original bug : pro12877
|
||||
# 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 OCC26426 All: Faulty shapes in variables faulty_1 to faulty_"
|
||||
|
||||
restore [locate_data_file CFE903_pro12ggx.rle] base
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Original bug : pro16449
|
||||
# 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
|
||||
|
||||
|
Reference in New Issue
Block a user