0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepLib / BRepLib_CheckCurveOnSurface.cxx
CommitLineData
1b7ae951 1// Created by: Eugeny MALTCHIKOV
2// Copyright (c) 2014 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
1b7ae951 15
769fb6a4 16#include <Adaptor2d_HCurve2d.hxx>
17#include <Adaptor3d_CurveOnSurface.hxx>
18#include <Adaptor3d_HSurface.hxx>
769fb6a4 19#include <BRep_Tool.hxx>
42cf5bc1 20#include <BRepLib_CheckCurveOnSurface.hxx>
769fb6a4 21#include <Geom2d_BSplineCurve.hxx>
42cf5bc1 22#include <Geom2d_Curve.hxx>
769fb6a4 23#include <Geom2d_TrimmedCurve.hxx>
42cf5bc1 24#include <Geom2dAdaptor.hxx>
25#include <Geom2dAdaptor_GHCurve.hxx>
769fb6a4 26#include <Geom_BSplineCurve.hxx>
42cf5bc1 27#include <Geom_Curve.hxx>
769fb6a4 28#include <Geom_Plane.hxx>
29#include <Geom_RectangularTrimmedSurface.hxx>
42cf5bc1 30#include <Geom_Surface.hxx>
769fb6a4 31#include <Geom_TrimmedCurve.hxx>
42cf5bc1 32#include <GeomAdaptor_HCurve.hxx>
33#include <GeomAdaptor_HSurface.hxx>
34#include <GeomProjLib.hxx>
35#include <math_Matrix.hxx>
36#include <math_MultipleVarFunctionWithHessian.hxx>
37#include <math_NewtonMinimum.hxx>
38#include <math_PSO.hxx>
39#include <math_PSOParticlesPool.hxx>
769fb6a4 40#include <NCollection_Array1.hxx>
769fb6a4 41#include <OSD_Parallel.hxx>
1b7ae951 42#include <ProjLib_ProjectedCurve.hxx>
769fb6a4 43#include <Standard_ErrorHandler.hxx>
769fb6a4 44#include <TColStd_Array1OfReal.hxx>
45#include <TopoDS.hxx>
42cf5bc1 46#include <TopoDS_Edge.hxx>
47#include <TopoDS_Face.hxx>
769fb6a4 48
49class BRepLib_CheckCurveOnSurface_TargetFunc;
50
51static
52Standard_Boolean MinComputing(
53 BRepLib_CheckCurveOnSurface_TargetFunc& theFunction,
54 const Standard_Real theEpsilon, //1.0e-3
55 const Standard_Integer theNbParticles,
56 Standard_Real& theBestValue,
57 Standard_Real& theBestParameter);
58
59static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
60 const Handle(Geom2d_Curve)& theCurve2d,
61 const Standard_Real theFirst,
62 const Standard_Real theLast,
63 Standard_Integer &theNbParticles,
64 TColStd_Array1OfReal* const theSubIntervals = 0);
1b7ae951 65
66//=======================================================================
769fb6a4 67//class : BRepLib_CheckCurveOnSurface_TargetFunc
68//purpose : Target function (to be minimized)
1b7ae951 69//=======================================================================
769fb6a4 70class BRepLib_CheckCurveOnSurface_TargetFunc :
1b7ae951 71 public math_MultipleVarFunctionWithHessian
72{
73 public:
769fb6a4 74 BRepLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
75 const Adaptor3d_Curve& theAdCS,
76 const Standard_Real theFirst,
77 const Standard_Real theLast):
78 myCurve1(theC3D),
79 myCurve2(theAdCS),
80 myFirst(theFirst),
81 myLast(theLast)
1b7ae951 82 {
83 }
769fb6a4 84
85 //returns the number of parameters of the function
86 //(the function is one-dimension).
1b7ae951 87 virtual Standard_Integer NbVariables() const {
88 return 1;
89 }
769fb6a4 90
91 //returns value of the function when parameters are equal to theX
1b7ae951 92 virtual Standard_Boolean Value(const math_Vector& theX,
769fb6a4 93 Standard_Real& theFVal)
94 {
95 return Value(theX(1), theFVal);
96 }
97
98 //returns value of the one-dimension-function when parameter
99 //is equal to theX
100 Standard_Boolean Value( const Standard_Real theX,
101 Standard_Real& theFVal) const
102 {
103 try
104 {
105 OCC_CATCH_SIGNALS
106 if (!CheckParameter(theX))
1b7ae951 107 return Standard_False;
769fb6a4 108
109 const gp_Pnt aP1(myCurve1.Value(theX)),
110 aP2(myCurve2.Value(theX));
111
1b7ae951 112 theFVal = -1.0*aP1.SquareDistance(aP2);
113 }
114 catch(Standard_Failure) {
115 return Standard_False;
116 }
117 //
118 return Standard_True;
119 }
769fb6a4 120
121 //see analogical method for abstract owner class math_MultipleVarFunction
122 virtual Standard_Integer GetStateNumber()
123 {
1b7ae951 124 return 0;
125 }
769fb6a4 126
127 //returns the gradient of the function when parameters are
128 //equal to theX
1b7ae951 129 virtual Standard_Boolean Gradient(const math_Vector& theX,
769fb6a4 130 math_Vector& theGrad)
131 {
132 return Derive(theX(1), theGrad(1));
133 }
134
135 //returns 1st derivative of the the one-dimension-function when
136 //parameter is equal to theX
137 Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const
138 {
139 try
140 {
141 OCC_CATCH_SIGNALS
142 if (!CheckParameter(theX))
143 {
1b7ae951 144 return Standard_False;
145 }
146 //
147 gp_Pnt aP1, aP2;
769fb6a4 148 gp_Vec aDC1, aDC2;
1b7ae951 149 //
769fb6a4 150 myCurve1.D1(theX, aP1, aDC1);
151 myCurve2.D1(theX, aP2, aDC2);
152
153 const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
1b7ae951 154 //
769fb6a4 155 theDeriv = -2.0*aVec1.Dot(aVec2);
1b7ae951 156 }
769fb6a4 157 catch(Standard_Failure)
158 {
1b7ae951 159 return Standard_False;
160 }
769fb6a4 161
1b7ae951 162 return Standard_True;
163 }
769fb6a4 164
165 //returns value and gradient
1b7ae951 166 virtual Standard_Boolean Values(const math_Vector& theX,
167 Standard_Real& theVal,
769fb6a4 168 math_Vector& theGrad)
169 {
170 if (!Value(theX, theVal))
171 {
1b7ae951 172 return Standard_False;
173 }
174 //
175 if (!Gradient(theX, theGrad)) {
176 return Standard_False;
177 }
178 //
179 return Standard_True;
180 }
769fb6a4 181
182 //returns value, gradient and hessian
1b7ae951 183 virtual Standard_Boolean Values(const math_Vector& theX,
184 Standard_Real& theVal,
185 math_Vector& theGrad,
769fb6a4 186 math_Matrix& theHessian)
187 {
188 if (!Value(theX, theVal))
189 {
1b7ae951 190 return Standard_False;
191 }
769fb6a4 192 //
193 if (!Gradient(theX, theGrad))
194 {
1b7ae951 195 return Standard_False;
196 }
197 //
198 theHessian(1,1) = theGrad(1);
199 //
200 return Standard_True;
201 }
202 //
769fb6a4 203 Standard_Real FirstParameter() const
204 {
205 return myFirst;
206 }
1b7ae951 207
769fb6a4 208 //
209 Standard_Real LastParameter() const
210 {
211 return myLast;
1b7ae951 212 }
769fb6a4 213
214 private:
215 BRepLib_CheckCurveOnSurface_TargetFunc operator=(BRepLib_CheckCurveOnSurface_TargetFunc&);
216
217 //checks if the function can be computed when its parameter is
218 //equal to theParam
219 Standard_Boolean CheckParameter(const Standard_Real theParam) const
220 {
221 return ((myFirst <= theParam) && (theParam <= myLast));
222 }
1b7ae951 223
769fb6a4 224 const Adaptor3d_Curve& myCurve1;
225 const Adaptor3d_Curve& myCurve2;
226 const Standard_Real myFirst;
227 const Standard_Real myLast;
1b7ae951 228};
229
769fb6a4 230//=======================================================================
231//class : BRepLib_CheckCurveOnSurface_Local
232//purpose : Created for parallelization possibility only
233//=======================================================================
234class BRepLib_CheckCurveOnSurface_Local
235{
236public:
237 BRepLib_CheckCurveOnSurface_Local(
238 const Handle(Geom_Curve)& theCurve3D,
239 const Handle(Geom2d_Curve)& theCurve2D,
240 const Handle(Geom_Surface)& theSurface,
241 const TColStd_Array1OfReal& theIntervalsArr,
242 const Standard_Real theEpsilonRange,
243 const Standard_Integer theNbParticles):
244 myCurve3D(theCurve3D),
245 myCurve2D(theCurve2D),
246 mySurface(theSurface),
247 mySubIntervals(theIntervalsArr),
248 myEpsilonRange(theEpsilonRange),
249 myNbParticles(theNbParticles),
250 myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1),
251 myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1)
252 {
253 }
254
255 void operator()(const Standard_Integer& theIndex) const
256 {
257 //For every sub-interval (which is set by mySubIntervals array) this method
258 //computes optimal value of BRepLib_CheckCurveOnSurface_TargetFunc function.
259 //This optimal value will be put in corresponding (depending on theIndex - the
260 //identificator of the current interval in mySubIntervals array) cell of
261 //myArrOfDist and myArrOfParam arrays.
262 const GeomAdaptor_Curve anAC(myCurve3D);
263 const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D);
264 const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface);
265
266 const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
267
268 BRepLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
269 mySubIntervals.Value(theIndex),
270 mySubIntervals.Value(theIndex+1));
1b7ae951 271
769fb6a4 272 Standard_Real aMinDist = RealLast(), aPar = 0.0;
273 if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
274 {
275 myArrOfDist(theIndex) = RealLast();
276 myArrOfParam(theIndex) = aFunc.FirstParameter();
277 return;
278 }
279
280 myArrOfDist(theIndex) = aMinDist;
281 myArrOfParam(theIndex) = aPar;
282 }
283
284 //Returns optimal value (inverse of square of maximal distance)
285 void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const
286 {
287 //This method looks for the minimal value of myArrOfDist.
288
289 const Standard_Integer aStartInd = myArrOfDist.Lower();
290 theMinimalValue = myArrOfDist(aStartInd);
291 theParameter = myArrOfParam(aStartInd);
292 for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++)
293 {
294 if(myArrOfDist(i) < theMinimalValue)
295 {
296 theMinimalValue = myArrOfDist(i);
297 theParameter = myArrOfParam(i);
298 }
299 }
300 }
301
302private:
303 BRepLib_CheckCurveOnSurface_Local operator=(BRepLib_CheckCurveOnSurface_Local&);
304 const Handle(Geom_Curve)& myCurve3D;
305 const Handle(Geom2d_Curve)& myCurve2D;
306 const Handle(Geom_Surface)& mySurface;
307
308 const TColStd_Array1OfReal& mySubIntervals;
309 const Standard_Real myEpsilonRange;
310 const Standard_Integer myNbParticles;
311 mutable NCollection_Array1<Standard_Real> myArrOfDist;
312 mutable NCollection_Array1<Standard_Real> myArrOfParam;
313};
1b7ae951 314
315//=======================================================================
316//function : BRepLib_CheckCurveOnSurface
317//purpose :
318//=======================================================================
319BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface()
320:
321 myFirst(0.),
322 myLast(0.),
323 myErrorStatus(0),
769fb6a4 324 myMaxDistance(RealLast()),
1b7ae951 325 myMaxParameter(0.)
326{
327}
328
329//=======================================================================
330//function : BRepLib_CheckCurveOnSurface
331//purpose :
332//=======================================================================
333BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface
334 (const TopoDS_Edge& theEdge,
335 const TopoDS_Face& theFace)
336:
337 myErrorStatus(0),
769fb6a4 338 myMaxDistance(RealLast()),
1b7ae951 339 myMaxParameter(0.)
340{
341 Init(theEdge, theFace);
342}
343
344//=======================================================================
345//function : BRepLib_CheckCurveOnSurface
346//purpose :
347//=======================================================================
348BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface
349 (const Handle(Geom_Curve)& the3DCurve,
350 const Handle(Geom2d_Curve)& the2DCurve,
351 const Handle(Geom_Surface)& theSurface,
352 const Standard_Real theFirst,
353 const Standard_Real theLast)
354:
355 myErrorStatus(0),
769fb6a4 356 myMaxDistance(RealLast()),
1b7ae951 357 myMaxParameter(0.)
358{
359 Init(the3DCurve, the2DCurve, theSurface, theFirst, theLast);
360}
361
362//=======================================================================
363//function : Init
364//purpose :
365//=======================================================================
366void BRepLib_CheckCurveOnSurface::Init
367 (const TopoDS_Edge& theEdge,
368 const TopoDS_Face& theFace)
369{
769fb6a4 370 myCurve.Nullify();
371 myPCurve.Nullify();
372 myPCurve2.Nullify();
373 mySurface.Nullify();
374 myErrorStatus = 0;
375 myMaxDistance = RealLast();
376 myMaxParameter = 0.0;
377 myFirst = 0.0;
378 myLast = 0.0;
379
1b7ae951 380 if (theEdge.IsNull() || theFace.IsNull()) {
381 return;
382 }
383 //
384 if (BRep_Tool::Degenerated(theEdge) ||
385 !BRep_Tool::IsGeometric(theEdge)) {
386 return;
387 }
388 //
1b7ae951 389 TopLoc_Location aLocE, aLocF, aLocC2D;
390 //
391 // 3D curve initialization
769fb6a4 392 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(theEdge, aLocE, myFirst, myLast);
393 myCurve = Handle(Geom_Curve)::DownCast(aC->Transformed(aLocE.Transformation()));
394
1b7ae951 395 // Surface initialization
396 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLocF);
769fb6a4 397 mySurface = Handle(Geom_Surface)::DownCast(aS->Transformed(aLocF.Transformation()));
1b7ae951 398 //
399 // 2D curves initialization
769fb6a4 400 myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, myFirst, myLast);
401
402 if(BRep_Tool::IsClosed(theEdge, theFace))
403 myPCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()),
404 theFace, myFirst, myLast);
1b7ae951 405}
406
407//=======================================================================
408//function : Init
409//purpose :
410//=======================================================================
411void BRepLib_CheckCurveOnSurface::Init
412 (const Handle(Geom_Curve)& the3DCurve,
413 const Handle(Geom2d_Curve)& the2DCurve,
414 const Handle(Geom_Surface)& theSurface,
415 const Standard_Real theFirst,
416 const Standard_Real theLast)
417{
418 myCurve = the3DCurve;
419 myPCurve = the2DCurve;
769fb6a4 420 myPCurve2.Nullify();
1b7ae951 421 mySurface = theSurface;
422 myFirst = theFirst;
423 myLast = theLast;
769fb6a4 424 myErrorStatus = 0;
425 myMaxDistance = RealLast();
426 myMaxParameter = 0.0;
1b7ae951 427}
428
429//=======================================================================
430//function : Perform
769fb6a4 431//purpose : if isTheMTDisabled == TRUE parallelization is not used
1b7ae951 432//=======================================================================
769fb6a4 433#ifndef HAVE_TBB
434//After fixing bug # 26365, this fragment should be deleted
435//(together the text "#ifdef HAVE_TBB")
436
437void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean)
438{
439 const Standard_Boolean isTheMTDisabled = Standard_True;
440#else
441void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled)
1b7ae951 442{
769fb6a4 443#endif
1b7ae951 444 try {
769fb6a4 445 OCC_CATCH_SIGNALS
1b7ae951 446 //
447 // 1. Check data
448 CheckData();
449 if (myErrorStatus) {
450 return;
451 }
769fb6a4 452
1b7ae951 453 // 2. Compute the max distance
769fb6a4 454 Compute(myPCurve, isTheMTDisabled);
1b7ae951 455 //
456 if (!myPCurve2.IsNull()) {
457 // compute max distance for myPCurve2
458 // (for the second curve on closed surface)
769fb6a4 459 Compute(myPCurve2, isTheMTDisabled);
1b7ae951 460 }
461 }
462 catch (Standard_Failure) {
463 myErrorStatus = 3;
464 }
465}
466
467//=======================================================================
468//function : Compute
769fb6a4 469//purpose : if isTheMTDisabled == TRUE parallelization is not used
1b7ae951 470//=======================================================================
769fb6a4 471void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve,
472 const Standard_Boolean isTheMTDisabled)
1b7ae951 473{
769fb6a4 474 const Standard_Real anEpsilonRange = 1.e-3;
475
476 Standard_Integer aNbParticles = 3;
477
478 //Polynomial function with degree n has not more than n-1 maxima and
479 //minima (degree of 1st derivative is equal to n-1 => 1st derivative has
480 //no greater than n-1 roots). Consequently, this function has
481 //maximum n monotonicity intervals. That is a good idea to try to put
482 //at least one particle in every monotonicity interval. Therefore,
483 //number of particles should be equal to n.
484
485 const Standard_Integer aNbSubIntervals =
486 FillSubIntervals( myCurve, thePCurve,
487 myFirst, myLast, aNbParticles);
488
489 if(!aNbSubIntervals)
490 {
491 myErrorStatus = 3;
492 return;
493 }
494
495 TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
496 FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
497
498 BRepLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve,
499 mySurface, anIntervals, anEpsilonRange, aNbParticles);
500
501 OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled);
502
503 aComp.OptimalValues(myMaxDistance, myMaxParameter);
504
505 myMaxDistance = sqrt(Abs(myMaxDistance));
506}
507
508//=======================================================================
509// Function : FillSubIntervals
510// purpose : Divides [theFirst, theLast] interval on parts
511// in order to make searching-algorithm more precisely
512// (fills theSubIntervals array).
513// Returns number of subintervals.
514//=======================================================================
515Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
516 const Handle(Geom2d_Curve)& theCurve2d,
517 const Standard_Real theFirst,
518 const Standard_Real theLast,
519 Standard_Integer &theNbParticles,
520 TColStd_Array1OfReal* const theSubIntervals)
521{
522 const Standard_Real anArrTempC[2] = {theFirst, theLast};
523 const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2);
524
525 theNbParticles = 3;
526 Handle(Geom2d_BSplineCurve) aBS2DCurv;
527 Handle(Geom_BSplineCurve) aBS3DCurv;
528
1b7ae951 529 //
769fb6a4 530 if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
531 {
532 aBS3DCurv = Handle(Geom_BSplineCurve)::
533 DownCast(Handle(Geom_TrimmedCurve)::
534 DownCast(theCurve3d)->BasisCurve());
535 }
536 else
537 {
538 aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
539 }
e002f1ce 540
e002f1ce 541
769fb6a4 542 if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
543 {
544 aBS2DCurv = Handle(Geom2d_BSplineCurve)::
545 DownCast(Handle(Geom2d_TrimmedCurve)::
546 DownCast(theCurve2d)->BasisCurve());
547 }
548 else
549 {
550 aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
551 }
552
553 const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ?
554 aBS3DCurv->Knots() :
555 anArrTemp;
556 const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ?
557 aBS2DCurv->Knots() :
558 anArrTemp;
559
560 Standard_Integer aNbSubIntervals = 1;
561
562 try
563 {
564 OCC_CATCH_SIGNALS
565 const Standard_Integer anIndMax3D = anArrKnots3D.Upper(),
566 anIndMax2D = anArrKnots2D.Upper();
567
568 Standard_Integer anIndex3D = anArrKnots3D.Lower(),
569 anIndex2D = anArrKnots2D.Lower();
570
571 if(theSubIntervals)
572 theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst;
573
574 while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D))
575 {
576 const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D),
577 aVal2D = anArrKnots2D.Value(anIndex2D);
578 const Standard_Real aDelta = aVal3D - aVal2D;
579
580 if(aDelta < Precision::PConfusion())
581 {//aVal3D <= aVal2D
582 if((aVal3D > theFirst) && (aVal3D < theLast))
583 {
584 aNbSubIntervals++;
585
586 if(theSubIntervals)
587 theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D;
588 }
589
590 anIndex3D++;
591
592 if(-aDelta < Precision::PConfusion())
593 {//aVal3D == aVal2D
594 anIndex2D++;
595 }
1b7ae951 596 }
769fb6a4 597 else
598 {//aVal2D < aVal3D
599 if((aVal2D > theFirst) && (aVal2D < theLast))
600 {
601 aNbSubIntervals++;
602
603 if(theSubIntervals)
604 theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D;
605 }
606
607 anIndex2D++;
1b7ae951 608 }
609 }
769fb6a4 610
611 if(theSubIntervals)
612 theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast;
613
614 if(!aBS3DCurv.IsNull())
615 {
616 theNbParticles = Max(theNbParticles, aBS3DCurv->Degree());
617 }
618
619 if(!aBS2DCurv.IsNull())
620 {
621 theNbParticles = Max(theNbParticles, aBS2DCurv->Degree());
622 }
1b7ae951 623 }
769fb6a4 624 catch(Standard_Failure)
625 {
626#ifdef OCCT_DEBUG
627 cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, "
628 "FillSubIntervals(): Incorrect filling!" << endl;
629#endif
630
631 aNbSubIntervals = 0;
632 }
633
634 return aNbSubIntervals;
1b7ae951 635}
636
637//=======================================================================
769fb6a4 638//class : MinComputing
639//purpose : Performs computing minimal value
1b7ae951 640//=======================================================================
769fb6a4 641Standard_Boolean MinComputing (
642 BRepLib_CheckCurveOnSurface_TargetFunc& theFunction,
643 const Standard_Real theEpsilon, //1.0e-3
644 const Standard_Integer theNbParticles,
645 Standard_Real& theBestValue,
646 Standard_Real& theBestParameter)
1b7ae951 647{
769fb6a4 648 try
1b7ae951 649 {
769fb6a4 650 OCC_CATCH_SIGNALS
651
652 //They are used for finding a position of theNbParticles worst places
653 const Standard_Integer aNbControlPoints = 3*theNbParticles;
1b7ae951 654 //
769fb6a4 655 math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1);
656 aParInf(1) = theFunction.FirstParameter();
657 aParSup(1) = theFunction.LastParameter();
658 theBestParameter = aParInf(1);
659 theBestValue = RealLast();
660
661 const Standard_Real aDeltaParam = aParSup(1) - aParInf(1);
662 if(aDeltaParam < Precision::PConfusion())
663 return Standard_False;
664
665 aStepPar(1) = theEpsilon*aDeltaParam;
666
667 math_PSOParticlesPool aParticles(theNbParticles, 1);
668
669 const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1);
670 Standard_Integer aCount = 1;
671 for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++,
672 aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep)
673 {
674 Standard_Real aVal = RealLast();
675 theFunction.Value(aPrm, aVal);
676
677 PSO_Particle* aParticle = aParticles.GetWorstParticle();
678
679 if(aVal > aParticle->BestDistance)
680 continue;
681
682 aParticle->Position[0] = aPrm;
683 aParticle->BestPosition[0] = aPrm;
684 aParticle->Distance = aVal;
685 aParticle->BestDistance = aVal;
1b7ae951 686 }
769fb6a4 687
688 math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar);
689 aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam);
690
691 //Here, anOutputParam contains parameter, which is near to optimal.
692 //It needs to be more precise. Precision is made by math_NewtonMinimum.
693 math_NewtonMinimum anA(theFunction);
694 anA.Perform(theFunction, anOutputParam);
695
696 if(!anA.IsDone())
697 {
698#ifdef OCCT_DEBUG
699 cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl;
700#endif
701 return Standard_False;
702 }
703
704 anA.Location(anOutputParam);
705 theBestParameter = anOutputParam(1);
706 theBestValue = anA.Minimum();
1b7ae951 707 }
769fb6a4 708 catch(Standard_Failure)
709 {
710#ifdef OCCT_DEBUG
711 cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl;
712#endif
713 return Standard_False;
714 }
715
716 return Standard_True;
1b7ae951 717}