// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <Adaptor3d_CurveOnSurface.hxx>
#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
#include <BRepLib_CheckCurveOnSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Standard_ErrorHandler.hxx>
#include <TopoDS.hxx>
//function : Init
//purpose :
//=======================================================================
-void BRepLib_CheckCurveOnSurface::Init
- (const TopoDS_Edge& theEdge,
- const TopoDS_Face& theFace)
+void BRepLib_CheckCurveOnSurface::Init(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
{
myCOnSurfGeom.Init();
return;
}
- //
- TopLoc_Location aLocE, aLocF, aLocC2D;
- Standard_Real aFirst = 0.0, aLast = 0.0;
- //
// 3D curve initialization
- const Handle(Geom_Curve)& aC3dTmp = BRep_Tool::Curve(theEdge, aLocE, aFirst, aLast);
- const Handle(Geom_Curve) aC3d(Handle(Geom_Curve)::DownCast(aC3dTmp->Transformed(aLocE.Transformation())));
+ const Handle(Adaptor3d_Curve) anAdaptor3dCurve = new BRepAdaptor_Curve(theEdge);
// Surface initialization
- const Handle(Geom_Surface)& aSTmp = BRep_Tool::Surface(theFace, aLocF);
- const Handle(Geom_Surface) aS(Handle(Geom_Surface)::DownCast(aSTmp->Transformed(aLocF.Transformation())));
- //
+
+ TopLoc_Location aLocation;
+ Standard_Real aFirstParam, aLastParam;
+
+ Handle(Geom2d_Curve) aGeom2dCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirstParam, aLastParam);
+ Handle(Geom_Surface) aGeomSurface = BRep_Tool::Surface(theFace);
+
// 2D curves initialization
- myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast);
+ Handle(Adaptor2d_Curve2d) anAdaptorCurve =
+ new Geom2dAdaptor_Curve(aGeom2dCurve, aFirstParam, aLastParam);
+ Handle(GeomAdaptor_Surface) aGeomAdaptorSurface = new GeomAdaptor_Surface(aGeomSurface);
+
+ myAdaptorCurveOnSurface = new Adaptor3d_CurveOnSurface(anAdaptorCurve, aGeomAdaptorSurface);
if(BRep_Tool::IsClosed(theEdge, theFace))
- myPCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()),
- theFace, aFirst, aLast);
+ {
+ Handle(Geom2d_Curve) aGeom2dReversedCurve =
+ BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()), theFace, aFirstParam, aLastParam);
+ Handle(Adaptor2d_Curve2d) anAdaptorReversedCurve =
+ new Geom2dAdaptor_Curve(aGeom2dReversedCurve, aFirstParam, aLastParam);
+ myAdaptorCurveOnSurface2 = new Adaptor3d_CurveOnSurface(anAdaptorReversedCurve, aGeomAdaptorSurface);
+ }
- myCOnSurfGeom.Init(aC3d, aS, aFirst, aLast);
+ myCOnSurfGeom.Init(anAdaptor3dCurve);
}
//=======================================================================
void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isMultiThread)
{
// Compute the max distance
- Compute(myPCurve, isMultiThread);
+ Compute(myAdaptorCurveOnSurface, isMultiThread);
if (ErrorStatus())
{
return;
}
//
- if (!myPCurve2.IsNull())
+ if (!myAdaptorCurveOnSurface2.IsNull())
{
- // compute max distance for myPCurve2
+ // compute max distance for myAdaptorCurveOnSurface2
// (for the second curve on closed surface)
- Compute(myPCurve2, isMultiThread);
+ Compute(myAdaptorCurveOnSurface2, isMultiThread);
}
}
//function : Compute
//purpose : if isTheMTDisabled == TRUE parallelization is not used
//=======================================================================
-void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve,
+void BRepLib_CheckCurveOnSurface::Compute(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
const Standard_Boolean isMultiThread)
{
- myCOnSurfGeom.Perform(thePCurve, isMultiThread);
+ myCOnSurfGeom.Perform(theCurveOnSurface, isMultiThread);
}
Standard_Real& theBestValue,
Standard_Real& theBestParameter);
-static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
- const Handle(Geom2d_Curve)& theCurve2d,
+static Standard_Integer FillSubIntervals( const Handle(Adaptor3d_Curve)& theCurve3d,
+ const Handle(Adaptor2d_Curve2d)& theCurve2d,
const Standard_Real theFirst,
const Standard_Real theLast,
- Standard_Integer &theNbParticles,
+ Standard_Integer& theNbParticles,
TColStd_Array1OfReal* const theSubIntervals = 0);
//=======================================================================
public math_MultipleVarFunctionWithHessian
{
public:
- GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
- const Adaptor3d_Curve& theAdCS,
+ GeomLib_CheckCurveOnSurface_TargetFunc( const Handle(Adaptor3d_Curve)& theC3D,
+ const Handle(Adaptor3d_Curve)& theCurveOnSurface,
const Standard_Real theFirst,
const Standard_Real theLast):
myCurve1(theC3D),
- myCurve2(theAdCS),
+ myCurve2(theCurveOnSurface),
myFirst(theFirst),
myLast(theLast)
{
//returns value of the function when parameters are equal to theX
virtual Standard_Boolean Value(const math_Vector& theX,
- Standard_Real& theFVal)
- {
+ Standard_Real& theFVal) {
return Value(theX(1), theFVal);
}
if (!CheckParameter(theX))
return Standard_False;
- const gp_Pnt aP1(myCurve1.Value(theX)),
- aP2(myCurve2.Value(theX));
-
+ const gp_Pnt aP1(myCurve1->Value(theX)),
+ aP2(myCurve2->Value(theX));
+
theFVal = -1.0*aP1.SquareDistance(aP2);
}
catch(Standard_Failure const&) {
//
if (!theDeriv2)
{
- myCurve1.D1(theX, aP1, aDC1);
- myCurve2.D1(theX, aP2, aDC2);
+ myCurve1->D1(theX, aP1, aDC1);
+ myCurve2->D1(theX, aP2, aDC2);
}
else
{
- myCurve1.D2(theX, aP1, aDC1, aDCC1);
- myCurve2.D2(theX, aP2, aDC2, aDCC2);
+ myCurve1->D2(theX, aP1, aDC1, aDCC1);
+ myCurve2->D2(theX, aP2, aDC2, aDCC2);
}
- const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
+ const gp_Vec aVec1(aP1, aP2), aVec2(aDC2 - aDC1);
//
theDeriv1 = -2.0*aVec1.Dot(aVec2);
return ((myFirst <= theParam) && (theParam <= myLast));
}
- const Adaptor3d_Curve& myCurve1;
- const Adaptor3d_Curve& myCurve2;
+ const Handle(Adaptor3d_Curve)& myCurve1;
+ const Handle(Adaptor3d_Curve)& myCurve2;
const Standard_Real myFirst;
const Standard_Real myLast;
};
{
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)
+ const Handle(HArray1OfHCurve) theCurveArray,
+ const Handle(HArray1OfHCurve) theCurveOnSurfaceArray,
+ const TColStd_Array1OfReal& theIntervalsArr,
+ const Standard_Real theEpsilonRange,
+ const Standard_Integer theNbParticles):
+ myCurveArray(theCurveArray),
+ myCurveOnSurfaceArray(theCurveOnSurfaceArray),
+ mySubIntervals(theIntervalsArr),
+ myEpsilonRange(theEpsilonRange),
+ myNbParticles(theNbParticles),
+ myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper() - 1),
+ myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper() - 1)
{
}
//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_Curve2d) anAd2dC = new Geom2dAdaptor_Curve(myCurve2D);
- const Handle(Adaptor3d_Surface) anAdS = new GeomAdaptor_Surface(mySurface);
-
- const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
-
- GeomLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
- mySubIntervals.Value(theIndex),
- mySubIntervals.Value(theIndex+1));
+ GeomLib_CheckCurveOnSurface_TargetFunc aFunc(myCurveArray->Value(0),
+ myCurveOnSurfaceArray->Value(0),
+ mySubIntervals.Value(theIndex),
+ mySubIntervals.Value(theIndex + 1));
Standard_Real aMinDist = RealLast(), aPar = 0.0;
if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
myArrOfParam(theIndex) = aPar;
}
+ void operator()(int theThreadIndex, int theElemIndex) const
+ {
+ GeomLib_CheckCurveOnSurface_TargetFunc aFunc(myCurveArray->Value(theThreadIndex),
+ myCurveOnSurfaceArray->Value(theThreadIndex),
+ mySubIntervals.Value(theElemIndex),
+ mySubIntervals.Value(theElemIndex + 1));
+
+ Standard_Real aMinDist = RealLast(), aPar = 0.0;
+ if (!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
+ {
+ myArrOfDist(theElemIndex) = RealLast();
+ myArrOfParam(theElemIndex) = aFunc.FirstParameter();
+ return;
+ }
+
+ myArrOfDist(theElemIndex) = aMinDist;
+ myArrOfParam(theElemIndex) = aPar;
+ }
+
//Returns optimal value (inverse of square of maximal distance)
void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const
{
}
private:
- GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_CheckCurveOnSurface_Local&);
- const Handle(Geom_Curve)& myCurve3D;
- const Handle(Geom2d_Curve)& myCurve2D;
- const Handle(Geom_Surface)& mySurface;
+ GeomLib_CheckCurveOnSurface_Local operator=(const GeomLib_CheckCurveOnSurface_Local&) Standard_DELETE;
+
+private:
+ Handle(HArray1OfHCurve) myCurveArray;
+ Handle(HArray1OfHCurve) myCurveOnSurfaceArray;
const TColStd_Array1OfReal& mySubIntervals;
const Standard_Real myEpsilonRange;
//=======================================================================
GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
:
- myFirst(0.),
- myLast(0.),
myErrorStatus(0),
myMaxDistance(RealLast()),
myMaxParameter(0.),
//purpose :
//=======================================================================
GeomLib_CheckCurveOnSurface::
- GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
- const Handle(Geom_Surface)& theSurface,
- const Standard_Real theFirst,
- const Standard_Real theLast,
+ GeomLib_CheckCurveOnSurface(const Handle(Adaptor3d_Curve)& theCurve,
const Standard_Real theTolRange):
myCurve(theCurve),
- mySurface(theSurface),
- myFirst(theFirst),
- myLast(theLast),
myErrorStatus(0),
myMaxDistance(RealLast()),
myMaxParameter(0.),
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,
+void GeomLib_CheckCurveOnSurface::Init( const Handle(Adaptor3d_Curve)& theCurve,
const Standard_Real theTolRange)
{
myCurve = theCurve;
- mySurface = theSurface;
- myFirst = theFirst;
- myLast = theLast;
myErrorStatus = 0;
myMaxDistance = RealLast();
myMaxParameter = 0.0;
//function : Perform
//purpose :
//=======================================================================
-void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
const Standard_Boolean isMultiThread)
{
if( myCurve.IsNull() ||
- mySurface.IsNull() ||
- thePCurve.IsNull())
+ theCurveOnSurface.IsNull())
{
myErrorStatus = 1;
return;
}
- if(((myCurve->FirstParameter() - myFirst) > myTolRange) ||
- ((myCurve->LastParameter() - myLast) < -myTolRange) ||
- ((thePCurve->FirstParameter() - myFirst) > myTolRange) ||
- ((thePCurve->LastParameter() - myLast) < -myTolRange))
- {
- myErrorStatus = 2;
- return;
- }
-
const Standard_Real anEpsilonRange = 1.e-3;
Standard_Integer aNbParticles = 3;
//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);
+ const Standard_Integer aNbSubIntervals =
+ FillSubIntervals(myCurve, theCurveOnSurface->GetCurve(),
+ myCurve->FirstParameter(), myCurve->LastParameter(), aNbParticles);
if(!aNbSubIntervals)
{
return;
}
- try {
+ 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);
+ TColStd_Array1OfReal anIntervals(1, aNbSubIntervals + 1);
+ FillSubIntervals(myCurve, theCurveOnSurface->GetCurve(),
+ myCurve->FirstParameter(), myCurve->LastParameter(), aNbParticles, &anIntervals);
- OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, !isMultiThread);
+ if (isMultiThread)
+ {
+ const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+ const int aNbThreads = isMultiThread ? Min(anIntervals.Size(), aThreadPool->NbDefaultThreadsToLaunch()) : 1;
+ Handle(HArray1OfHCurve) aCurveArray = new HArray1OfHCurve(0, aNbThreads - 1);
+ Handle(HArray1OfHCurve) aCurveOnSurfaceArray = new HArray1OfHCurve(0, aNbThreads - 1);
+ for (Standard_Integer anI = 0; anI < aNbThreads; ++anI)
+ {
+ aCurveArray->SetValue(anI, myCurve->ShallowCopy());
+ aCurveOnSurfaceArray->SetValue(anI, theCurveOnSurface->ShallowCopy());
+ }
+ GeomLib_CheckCurveOnSurface_Local aComp(aCurveArray, aCurveOnSurfaceArray, anIntervals,
+ anEpsilonRange, aNbParticles);
+ OSD_ThreadPool::Launcher aLauncher(*aThreadPool, aNbThreads);
+ aLauncher.Perform(anIntervals.Lower(), anIntervals.Upper(), aComp);
- aComp.OptimalValues(myMaxDistance, myMaxParameter);
+ aComp.OptimalValues(myMaxDistance, myMaxParameter);
+ }
+ else
+ {
+ Handle(HArray1OfHCurve) aCurveArray = new HArray1OfHCurve(0, 0);
+ aCurveArray->SetValue(0, myCurve);
+ Handle(HArray1OfHCurve) aCurveOnSurfaceArray = new HArray1OfHCurve(0, 0);
+ aCurveOnSurfaceArray->SetValue(0, myCurve);
+ GeomLib_CheckCurveOnSurface_Local aComp(aCurveArray, aCurveOnSurfaceArray, anIntervals,
+ anEpsilonRange, aNbParticles);
+ for (Standard_Integer anI = anIntervals.Lower(); anI < anIntervals.Upper(); ++anI)
+ {
+ aComp(anI);
+ }
+ aComp.OptimalValues(myMaxDistance, myMaxParameter);
+ }
myMaxDistance = sqrt(Abs(myMaxDistance));
}
- catch (Standard_Failure const&) {
+ catch (Standard_Failure const&)
+ {
myErrorStatus = 3;
}
}
// (fills theSubIntervals array).
// Returns number of subintervals.
//=======================================================================
-Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
- const Handle(Geom2d_Curve)& theCurve2d,
+Standard_Integer FillSubIntervals(const Handle(Adaptor3d_Curve)& theCurve3d,
+ const Handle(Adaptor2d_Curve2d)& theCurve2d,
const Standard_Real theFirst,
const Standard_Real theLast,
- Standard_Integer &theNbParticles,
+ Standard_Integer& theNbParticles,
TColStd_Array1OfReal* const theSubIntervals)
{
const Standard_Integer aMaxKnots = 101;
Standard_Boolean isTrimmed3D = Standard_False, isTrimmed2D = Standard_False;
//
- if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+ if (theCurve3d->GetType() == GeomAbs_BSplineCurve)
{
- aBS3DCurv = Handle(Geom_BSplineCurve)::
- DownCast(Handle(Geom_TrimmedCurve)::
- DownCast(theCurve3d)->BasisCurve());
- isTrimmed3D = Standard_True;
+ aBS3DCurv = theCurve3d->BSpline();
}
- else
+ if (theCurve2d->GetType() == GeomAbs_BSplineCurve)
{
- aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
+ aBS2DCurv = theCurve2d->BSpline();
}
- if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
- {
- aBS2DCurv = Handle(Geom2d_BSplineCurve)::
- DownCast(Handle(Geom2d_TrimmedCurve)::
- DownCast(theCurve2d)->BasisCurve());
- isTrimmed2D = Standard_True;
- }
- else
- {
- aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
- }
+ Handle(TColStd_HArray1OfReal) anArrKnots3D, anArrKnots2D;
- Handle(TColStd_HArray1OfReal) anArrKnots3D, anArrKnots2D;
-
- if(!aBS3DCurv.IsNull())
+ if (!aBS3DCurv.IsNull())
{
if(aBS3DCurv->NbKnots() <= aMaxKnots)
{
//purpose : Searches minimal distance with math_PSO class
//=======================================================================
Standard_Boolean PSO_Perform(GeomLib_CheckCurveOnSurface_TargetFunc& theFunction,
- const math_Vector &theParInf,
- const math_Vector &theParSup,
+ const math_Vector& theParInf,
+ const math_Vector& theParSup,
const Standard_Real theEpsilon,
- const Standard_Integer theNbParticles,
+ const Standard_Integer theNbParticles,
Standard_Real& theBestValue,
- math_Vector &theOutputParam)
+ math_Vector& theOutputParam)
{
const Standard_Real aDeltaParam = theParSup(1) - theParInf(1);
if(aDeltaParam < Precision::PConfusion())