1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
17 #include <TopoDS_Edge.hxx>
18 #include <Geom_Curve.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <Adaptor3d_Surface.hxx>
21 #include <Adaptor3d_CurveOnSurface.hxx>
22 #include <Adaptor3d_CurveOnSurface.hxx>
23 #include <GeomAbs_SurfaceType.hxx>
24 #include <BRep_Tool.hxx>
25 #include <Geom_Line.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_CylindricalSurface.hxx>
28 #include <Geom_ConicalSurface.hxx>
29 #include <Geom_SphericalSurface.hxx>
30 #include <Geom_ToroidalSurface.hxx>
34 #include <gp_Cylinder.hxx>
38 #include <GeomAdaptor_Curve.hxx>
39 #include <GeomAdaptor_Surface.hxx>
40 #include <Precision.hxx>
41 #include <Extrema_ExtCC.hxx>
42 //#include <Extrema_ExtCS.hxx>
43 #include <Extrema_POnCurv.hxx>
44 #include <IntCurveSurface_HInter.hxx>
46 #include <math_FunctionSample.hxx>
47 #include <math_FunctionAllRoots.hxx>
48 #include <TColgp_SequenceOfPnt.hxx>
50 // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569
52 #include <Precision.hxx>
53 #include <IntSurf_Quadric.hxx>
54 #include <math_Function.hxx>
55 #include <math_BrentMinimum.hxx>
56 #include <math_Matrix.hxx>
57 #include <math_Vector.hxx>
58 #include <NCollection_Array1.hxx>
61 #include <Geom_Circle.hxx>
62 #include <Geom_Ellipse.hxx>
63 #include <Geom_Hyperbola.hxx>
64 #include <Geom_Parabola.hxx>
65 #include <Geom_BezierCurve.hxx>
66 #include <Geom_BSplineCurve.hxx>
67 #include <GeomLib.hxx>
71 static Standard_Boolean IsDegenerated(const Handle(Adaptor3d_CurveOnSurface)& theCurve);
72 static Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric);
74 static void FindVertex (const TheArc&,
75 const Handle(TheTopolTool)&,
77 IntStart_SequenceOfPathPoint&,
81 static void BoundedArc (const TheArc& A,
82 const Handle(TheTopolTool)& Domain,
83 const Standard_Real Pdeb,
84 const Standard_Real Pfin,
86 IntStart_SequenceOfPathPoint& pnt,
87 IntStart_SequenceOfSegment& seg,
88 const Standard_Real TolBoundary,
89 const Standard_Real TolTangency,
90 Standard_Boolean& Arcsol,
91 const Standard_Boolean RecheckOnRegularity);
93 static void PointProcess (const gp_Pnt&,
96 const Handle(TheTopolTool)&,
97 IntStart_SequenceOfPathPoint&,
101 static Standard_Integer TreatLC (const TheArc& A,
102 const Handle(TheTopolTool)& aDomain,
103 const IntSurf_Quadric& aQuadric,
104 const Standard_Real TolBoundary,
105 IntStart_SequenceOfPathPoint& pnt);
107 static Standard_Boolean IsRegularity(const TheArc& A,
108 const Handle(TheTopolTool)& aDomain);
110 class MinFunction : public math_Function
113 MinFunction(TheFunction &theFunc) : myFunc(&theFunc) {};
115 //returns value of the one-dimension-function when parameter
117 virtual Standard_Boolean Value(const Standard_Real theX,
118 Standard_Real& theFVal)
120 if(!myFunc->Value(theX, theFVal))
121 return Standard_False;
124 return Standard_True;
127 //see analogical method for abstract owner class math_Function
128 virtual Standard_Integer GetStateNumber()
138 //=======================================================================
139 //function : FindVertex
141 //=======================================================================
142 void FindVertex (const TheArc& A,
143 const Handle(TheTopolTool)& Domain,
145 IntStart_SequenceOfPathPoint& pnt,
146 const Standard_Real Toler)
149 // Find the vertex of the arc A restriction solutions. It stores
150 // Vertex in the list solutions pnt.
154 Standard_Real param,valf;
155 Standard_Integer itemp;
157 Domain->Initialize(A);
158 Domain->InitVertexIterator();
159 while (Domain->MoreVertex()) {
160 vtx = Domain->Vertex();
161 param = TheSOBTool::Parameter(vtx,A);
163 // Evaluate the function and look compared to tolerance of the
164 // Vertex. If distance <= tolerance then add a vertex to the list of solutions.
165 // The arc is already assumed in the load function.
167 Func.Value(param,valf);
168 if (Abs(valf) <= Toler) {
169 itemp = Func.GetStateNumber();
170 pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, vtx,A,param));
173 Domain->NextVertex();
177 Standard_Boolean IsDegenerated(const Handle(Adaptor3d_CurveOnSurface)& theCurve)
179 if (theCurve->GetType() == GeomAbs_Circle)
181 gp_Circ aCirc = theCurve->Circle();
182 if (aCirc.Radius() <= Precision::Confusion())
183 return Standard_True;
185 return Standard_False;
188 Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric)
190 GeomAbs_SurfaceType TypeQuad = theQuadric.TypeQuadric();
191 if (TypeQuad == GeomAbs_Cone)
193 gp_Cone aCone = theQuadric.Cone();
194 Standard_Real aSemiAngle = Abs(aCone.SemiAngle());
195 if (aSemiAngle < 0.02 || aSemiAngle > 1.55)
196 return Standard_True;
198 return Standard_False;
204 SolInfo() : myMathIndex(-1), myValue(RealLast())
208 void Init(const math_FunctionAllRoots& theSolution, const Standard_Integer theIndex)
210 myMathIndex = theIndex;
211 myValue = theSolution.GetPoint(theIndex);
214 void Init(const IntCurveSurface_HInter& theSolution, const Standard_Integer theIndex)
216 myMathIndex = theIndex;
217 myValue = theSolution.Point(theIndex).W();
220 Standard_Real Value() const
225 Standard_Integer Index() const
230 bool operator>(const SolInfo& theOther) const
232 return myValue > theOther.myValue;
235 bool operator<(const SolInfo& theOther) const
237 return myValue < theOther.myValue;
240 bool operator==(const SolInfo& theOther) const
242 return myValue == theOther.myValue;
245 Standard_Real& ChangeValue()
251 Standard_Integer myMathIndex;
252 Standard_Real myValue;
256 void BoundedArc (const TheArc& A,
257 const Handle(TheTopolTool)& Domain,
258 const Standard_Real Pdeb,
259 const Standard_Real Pfin,
261 IntStart_SequenceOfPathPoint& pnt,
262 IntStart_SequenceOfSegment& seg,
263 const Standard_Real TolBoundary,
264 const Standard_Real TolTangency,
265 Standard_Boolean& Arcsol,
266 const Standard_Boolean RecheckOnRegularity)
268 // Recherche des points solutions et des bouts d arc solution sur un arc donne.
269 // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour
270 // des arcs ayant un point debut et un point de fin (intervalle ferme de
273 Standard_Integer i, Nbi = 0, Nbp = 0;
276 Standard_Real pardeb = 0., parfin = 0.;
277 Standard_Integer ideb,ifin,range,ranged,rangef;
279 // Creer l echantillonage (math_FunctionSample ou classe heritant)
280 // Appel a math_FunctionAllRoots
282 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
283 //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement )
284 //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 )
285 //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une
286 //@@@ ligne de cheminement
287 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
288 Standard_Real EpsX = 1.e-10;
289 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
290 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
291 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
293 // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A);
294 Standard_Integer NbEchant = Func.NbSamples();
295 if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96
296 //-- Toujours des pbs
298 //-- Modif 24 Aout 93 -----------------------------
299 Standard_Real nTolTangency = TolTangency;
300 if((Pfin - Pdeb) < (TolTangency*10.0)) {
301 nTolTangency=(Pfin-Pdeb)*0.1;
303 if(EpsX>(nTolTangency+nTolTangency)) {
304 EpsX = nTolTangency * 0.1;
307 //--------------------------------------------------
308 //-- Plante avec un edge avec 2 Samples
309 //-- dont les extremites son solutions (f=0)
310 //-- et ou la derivee est nulle
311 //-- Exemple : un segment diametre d une sphere
312 //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95
313 //--------------------------------------------------
314 Standard_Real para=0,dist,maxdist;
316 //-------------------------------------------------------------- REJECTIONS le 15 oct 98
317 Standard_Boolean Rejection=Standard_True;
318 Standard_Real maxdr,maxr,minr,ur,dur;
323 for(i=1,ur=Pdeb;i<=6;i++) {
325 if(Func.Values(ur,F,D)) {
326 Standard_Real lminr,lmaxr;
332 if(lminr<minr) minr=lminr;
333 if(lmaxr>maxr) maxr=lmaxr;
334 if(minr<0.0 && maxr>0.0) {
335 Rejection=Standard_False;
343 dur=0.001+maxdr+(maxr-minr)*0.1;
346 if(minr<0.0 && maxr>0.0) {
347 Rejection=Standard_False;
351 Arcsol=Standard_False;
353 if(Rejection==Standard_False)
355 const IntSurf_Quadric& aQuadric = Func.Quadric();
356 GeomAbs_SurfaceType TypeQuad = aQuadric.TypeQuadric();
357 GeomAbs_CurveType TypeConS = GeomAbs_OtherCurve;
359 IntCurveSurface_HInter IntCS;
360 Standard_Boolean IsIntCSdone = Standard_False;
361 TColStd_SequenceOfReal Params;
363 std::unique_ptr<math_FunctionAllRoots> pSol;
365 math_FunctionSample Echant(Pdeb,Pfin,NbEchant);
367 Standard_Boolean aelargir=Standard_True;
368 //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f
370 //maxdist = 100.0*TolBoundary;
371 maxdist = TolBoundary+TolTangency;
373 //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t
374 for(i=1; i<=NbEchant && aelargir;i++) {
375 Standard_Real u = Echant.GetParameter(i);
376 if(Func.Value(u,dist)) {
377 if(dist>maxdist || -dist>maxdist) {
378 aelargir=Standard_False;
382 if(!(aelargir && maxdist<0.01)) {
383 maxdist = TolBoundary;
386 if (TypeQuad != GeomAbs_OtherSurface) //intersection of boundary curve and quadric surface
389 Handle(Adaptor3d_Surface) aSurf = Func.Surface();
390 Adaptor3d_CurveOnSurface ConS(A, aSurf);
391 TypeConS = ConS.GetType();
393 Handle(Geom_Curve) CurveConS;
398 CurveConS = new Geom_Line(ConS.Line());
403 CurveConS = new Geom_Circle(ConS.Circle());
406 case GeomAbs_Ellipse:
408 CurveConS = new Geom_Ellipse(ConS.Ellipse());
411 case GeomAbs_Hyperbola:
413 CurveConS = new Geom_Hyperbola(ConS.Hyperbola());
416 case GeomAbs_Parabola:
418 CurveConS = new Geom_Parabola(ConS.Parabola());
421 case GeomAbs_BezierCurve:
423 CurveConS = ConS.Bezier();
426 case GeomAbs_BSplineCurve:
428 CurveConS = ConS.BSpline();
433 Standard_Real MaxDeviation, AverageDeviation;
434 GeomLib::BuildCurve3d(1.e-5, ConS, ConS.FirstParameter(), ConS.LastParameter(),
435 CurveConS, MaxDeviation, AverageDeviation);
440 Handle(Adaptor3d_CurveOnSurface) HConS = new Adaptor3d_CurveOnSurface(ConS);
441 Handle(Geom_Surface) QuadSurf;
446 QuadSurf = new Geom_Plane(aQuadric.Plane());
449 case GeomAbs_Cylinder:
451 QuadSurf = new Geom_CylindricalSurface(aQuadric.Cylinder());
456 QuadSurf = new Geom_ConicalSurface(aQuadric.Cone());
461 QuadSurf = new Geom_SphericalSurface(aQuadric.Sphere());
466 QuadSurf = new Geom_ToroidalSurface(aQuadric.Torus());
472 Handle(GeomAdaptor_Surface) GAHsurf = new GeomAdaptor_Surface(QuadSurf);
474 if ((TypeConS == GeomAbs_Line ||
475 TypeConS == GeomAbs_Circle ||
476 TypeConS == GeomAbs_Ellipse ||
477 TypeConS == GeomAbs_Parabola ||
478 TypeConS == GeomAbs_Hyperbola) &&
479 TypeQuad != GeomAbs_Torus &&
480 !IsDegenerated(HConS) &&
481 !IsDegenerated(aQuadric))
483 //exact intersection for only canonic curves and real quadric surfaces
484 IntCS.Perform(HConS, GAHsurf);
487 IsIntCSdone = IntCS.IsDone();
490 Nbp = IntCS.NbPoints();
491 Nbi = IntCS.NbSegments();
493 //If we have not got intersection, it may be touch with some tolerance,
495 if (Nbp == 0 && Nbi == 0)
496 IsIntCSdone = Standard_False;
498 } //if (TypeQuad != GeomAbs_OtherSurface) - intersection of boundary curve and quadric surface
502 pSol.reset(new math_FunctionAllRoots(Func,Echant,EpsX,maxdist,maxdist)); //-- TolBoundary,nTolTangency);
504 if (!pSol->IsDone()) {throw Standard_Failure();}
506 Nbp=pSol->NbPoints();
509 //jgv: build solution on the whole boundary
510 if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
512 //Standard_Real theTol = Domain->MaxTolerance(A);
514 Standard_Real theTol = 5.e-4;
515 math_FunctionAllRoots SolAgain(Func,Echant,EpsX,theTol,theTol); //-- TolBoundary,nTolTangency);
517 if (!SolAgain.IsDone()) {throw Standard_Failure();}
519 Standard_Integer Nbi_again = SolAgain.NbIntervals();
523 Standard_Integer NbSamples = 10;
524 Standard_Real delta = (Pfin - Pdeb)/NbSamples;
525 Standard_Real GlobalTol = theTol*10;
526 Standard_Boolean SolOnBoundary = Standard_True;
527 for (i = 0; i <= NbSamples; i++)
529 Standard_Real aParam = Pdeb + i*delta;
530 Standard_Real aValue;
531 Func.Value(aParam, aValue);
532 if (Abs(aValue) > GlobalTol)
534 SolOnBoundary = Standard_False;
541 for (i = 1; i <= Nbi_again; i++)
543 IntStart_TheSegment newseg;
545 // Recuperer point debut et fin, et leur parametre.
546 SolAgain.GetInterval(i,pardeb,parfin);
548 if (Abs(pardeb - Pdeb) <= Precision::PConfusion())
550 if (Abs(parfin - Pfin) <= Precision::PConfusion())
553 SolAgain.GetIntervalState(i,ideb,ifin);
555 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl;
557 ptdeb=Func.Valpoint(ideb);
558 ptfin=Func.Valpoint(ifin);
560 PointProcess(ptdeb,pardeb,A,Domain,pnt,theTol,ranged);
561 newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
562 PointProcess(ptfin,parfin,A,Domain,pnt,theTol,rangef);
563 newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
566 Arcsol=Standard_True;
570 } //if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
571 ////////////////////////////////////////////
573 //-- detection du cas ou la fonction est quasi tangente et que les
574 //-- zeros sont quasi confondus.
575 //-- Dans ce cas on prend le point "milieu"
576 //-- On suppose que les solutions sont triees.
579 NCollection_Array1<SolInfo> aSI(1, Nbp);
584 aSI(i).Init(IntCS, i);
586 aSI(i).Init(*pSol, i);
589 std::sort(aSI.begin(), aSI.end());
591 //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f
592 //////////////////////////////////////////////////////////
593 // The treatment of the situation when line(arc) that is
594 // tangent to cylinder(domain).
595 // We should have only one solution i.e Nbp=1. Ok?
596 // But we have 2,3,.. solutions. That is wrong ersult.
597 // The TreatLC(...) function is dedicated to solve the pb.
598 // PKV Fri Mar 23 12:17:29 2001
600 Standard_Integer ip = TreatLC (A, Domain, aQuadric, TolBoundary, pnt);
602 //////////////////////////////////////////////////////////
603 //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t
605 // Using of old usual way proposed by Laurent
608 Standard_Real parap1 = aSI(i + 1).Value();
609 para = aSI(i).Value();
611 Standard_Real param=(para+parap1)*0.5;
612 Standard_Real yf = 0.0;
613 Standard_Real ym = 0.0;
614 Standard_Real yl = 0.0;
615 if(Func.Value(param,ym) && Abs(ym) < maxdist) {
616 Standard_Real sm = Sign(1., ym);
617 Standard_Boolean aTang = Func.Value(para,yf) && Func.Value(parap1,yl);
619 //Line can be tangent surface if all distances less then maxdist
620 aTang = aTang && Abs(yf) < maxdist && Abs(yl) < maxdist;
622 if (aTang && IsIntCSdone && TypeConS == GeomAbs_Line) {
623 //Interval is got by exact intersection
624 //Line can be tangent if all points are on the same side of surface
625 //it means that signs of all distances are the same
626 Standard_Real sf = Sign(1., yf), sl = Sign(1., yl);
627 aTang = aTang && (sm == sf) && (sm == sl);
630 // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 Begin
631 // Consider this interval as tangent one. Treat it to find
632 // parameter with the lowest function value.
633 // Compute the number of nodes.
634 Standard_Real aTol = TolBoundary*1000.0;
638 // fix floating point exception 569, chl-922-e9
639 parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9);
640 para = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9);
642 Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol));
644 Standard_Real aVal = RealLast();
645 Standard_Real aValMax = 0.;
646 //Standard_Integer aNbNodes = 23;
647 Standard_Real aDelta = (parap1 - para)/(aNbNodes + 1.);
649 Standard_Real aCurPar;
650 Standard_Real aCurVal;
652 for (ii = 0; ii <= aNbNodes + 1; ii++) {
653 aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1;
655 if (Func.Value(aCurPar, aCurVal)) {
656 Standard_Real anAbsVal = Abs(aCurVal);
657 if (anAbsVal < aVal) {
661 if (anAbsVal > aValMax)
667 // At last, interval got by exact intersection can be considered as tangent if
668 // minimal distance is inside interval and
669 // minimal and maximal values are almost the same
670 if (IsIntCSdone && aNbNodes > 1) {
671 aTang = Abs(param - para) > EpsX && Abs(parap1 - param) > EpsX &&
672 0.01*aValMax <= aVal;
676 aSI(i).ChangeValue() = Pdeb - 1;
677 aSI(i + 1).ChangeValue() = param;
683 for (i=1; i<=Nbp; i++) {
684 para = aSI(i).Value();
685 if((para-Pdeb)<EpsX || (Pfin-para)<EpsX)
688 if(!Func.Value(para,dist))
693 Standard_Integer anIndx = -1;
694 //const Standard_Real aParam = Sol->GetPoint(aSI(i).Index());
695 const Standard_Real aParam = aSI(i).Value();
699 (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion()))
701 anIndx = pSol->GetPointState(aSI(i).Index());
705 gp_Pnt aPnt(anIndx < 0 ? Func.LastComputedPoint() : Func.Valpoint(anIndx));
707 if (dist > 0.1*Precision::Confusion())
709 //Precise found points. It results in following:
710 // 1. Make the vertex nearer to the intersection line
711 // (see description to issue #27252 in order to
712 // understand necessity).
713 // 2. Merge two near vertices to single point.
715 //All members in TabSol array has already been sorted in increase order.
716 //Now, we limit precise boundaries in order to avoid changing this order.
717 const Standard_Real aFPar = (i == 1) ? Pdeb : (para + aSI(i - 1).Value()) / 2.0;
718 const Standard_Real aLPar = (i == Nbp) ? Pfin : (para + aSI(i + 1).Value()) / 2.0;
720 MinFunction aNewFunc(Func);
721 math_BrentMinimum aMin(Precision::Confusion());
723 aMin.Perform(aNewFunc, aFPar, para, aLPar);
726 para = aMin.Location();
727 const gp_Pnt2d aP2d(A->Value(para));
728 aPnt = Func.Surface()->Value(aP2d.X(), aP2d.Y());
732 PointProcess(aPnt, para, A, Domain, pnt, TolBoundary, range);
737 // Pour chaque intervalle trouve faire
738 // Traiter les extremites comme des points
739 // Ajouter intervalle dans la liste des segments
742 Nbi = pSol->NbIntervals();
744 if (!RecheckOnRegularity && Nbp) {
745 //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0 0 <- Nbi "<<Nbi<<endl;
749 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : Nbi : "<<Nbi<<endl;
751 for (i=1; i<=Nbi; i++) {
752 IntStart_TheSegment newseg;
754 // Recuperer point debut et fin, et leur parametre.
757 IntCurveSurface_IntersectionSegment IntSeg = IntCS.Segment(i);
758 IntCurveSurface_IntersectionPoint End1 = IntSeg.FirstPoint();
759 IntCurveSurface_IntersectionPoint End2 = IntSeg.SecondPoint();
767 pSol->GetInterval(i,pardeb,parfin);
768 pSol->GetIntervalState(i,ideb,ifin);
770 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl;
772 ptdeb=Func.Valpoint(ideb);
773 ptfin=Func.Valpoint(ifin);
776 PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged);
777 newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
778 PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef);
779 newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
784 if((Abs(pardeb - Pdeb) < Precision::PConfusion()) &&
785 (Abs(parfin - Pfin) < Precision::PConfusion()))
787 Arcsol=Standard_True;
793 //=======================================================================
794 //function : ComputeBoundsfromInfinite
796 //=======================================================================
797 // - PROVISIONAL - TEMPORARY - NOT GOOD - NYI - TO DO
798 // - Temporary - temporary - not good - nyi - to do
799 void ComputeBoundsfromInfinite(TheFunction& Func,
802 Standard_Integer& NbEchant)
805 // - We are looking for parameters for start and end of the arc (2d curve)
806 // - Infinity, a way to intersect the quadric with a portion of arc
809 // - The quadric is a plane, a cylinder, a cone and a sphere.
810 // - Idea: We take any point on the arc and the fact grow
811 // - Terminals to the signed distance function values or is likely
814 // - WARNING: The following calculations provide a very estimated coarse parameters.
815 // - This avoids the raises and allows a case of Boxes
816 // - Inifinies walk. It will take this code
817 // - With curve surface intersections.
821 Standard_Real U0 = 0.0;
822 Standard_Real dU = 0.001;
823 Standard_Real Dist0,Dist1;
825 Func.Value(U0 , Dist0);
826 Func.Value(U0+dU, Dist1);
827 Standard_Real dDist = Dist1 - Dist0;
829 U0 -= dU*Dist0 / dDist;
831 Standard_Real Umin = U0 - 1e5;
832 Func.Value(Umin , Dist0);
833 Func.Value(Umin+dU, Dist1);
836 Umin -= dU*Dist0 / dDist;
841 Standard_Real Umax = U0 + 1e8;
842 Func.Value(Umax , Dist0);
843 Func.Value(Umax+dU, Dist1);
846 Umax -= dU*Dist0 / dDist;
851 if(Umin>U0) { Umin=U0-10.0; }
852 if(Umax<U0) { Umax=U0+10.0; }
854 PFin = Umax + 10. * (Umax - Umin);
855 PDeb = Umin - 10. * (Umax - Umin);
858 //-- Possibilite de Arc totalement inclu ds Quad
864 //=======================================================================
865 //function : PointProcess
867 //=======================================================================
868 void PointProcess (const gp_Pnt& Pt,
869 const Standard_Real Para,
871 const Handle(TheTopolTool)& Domain,
872 IntStart_SequenceOfPathPoint& pnt,
873 const Standard_Real Tol,
874 Standard_Integer& Range)
877 // Check to see if a solution point is coincident with a vertex.
878 // If confused, you should find this vertex in the list of
879 // Start. It then returns the position of this point in the list pnt.
880 // Otherwise, add the point in the list.
883 Standard_Boolean found,goon;
884 Standard_Real dist,toler;
886 Standard_Integer Nbsol = pnt.Length();
888 IntStart_ThePathPoint ptsol;
890 Domain->Initialize(A);
891 Domain->InitVertexIterator();
892 found = Standard_False;
893 goon = Domain->MoreVertex();
895 vtx = Domain->Vertex();
896 dist= Abs(Para-TheSOBTool::Parameter(vtx,A));
897 toler = TheSOBTool::Tolerance(vtx,A);
900 std::cout<<"IntStart_SearchOnBoundaries_1.gxx : ** WARNING ** Tol Vertex="<<toler<<std::endl;
901 std::cout<<" Ou Edge degenere Ou Kro pointu"<<std::endl;
902 if(toler>10000) toler=1e-7;
907 // Locate the vertex in the list of solutions
911 ptsol = pnt.Value(k);
912 if (!ptsol.IsNew()) {
913 //jag 940608 if (ptsol.Vertex() == vtx && ptsol.Arc() == A) {
914 if (Domain->Identical(ptsol.Vertex(),vtx) &&
916 Abs(ptsol.Parameter()-Para) <= toler) {
929 if (k<=Nbsol) { // We find the vertex
933 ptsol.SetValue(Pt,Tol,vtx,A,Para);
935 Range = pnt.Length();
937 found = Standard_True;
938 goon = Standard_False;
941 Domain->NextVertex();
942 goon = Domain->MoreVertex();
946 if (!found) { // No one is falling on a vertex
947 //jgv: do not add segment's extremities if they already exist
948 Standard_Boolean found_internal = Standard_False;
949 for (k = 1; k <= pnt.Length(); k++)
951 ptsol = pnt.Value(k);
952 if (ptsol.Arc() != A ||
953 !ptsol.IsNew()) //vertex
955 if (Abs(ptsol.Parameter()-Para) <= Precision::PConfusion())
957 found_internal = Standard_True;
961 /////////////////////////////////////////////////////////////
965 Standard_Real TOL=Tol;
967 //if(TOL>0.001) TOL=0.001;
968 if(TOL>0.005) TOL=0.005; //#24643
970 ptsol.SetValue(Pt,TOL,A,Para);
972 Range = pnt.Length();
977 //=======================================================================
978 //function : IsRegularity
980 //=======================================================================
981 Standard_Boolean IsRegularity(const TheArc& /*A*/,
982 const Handle(TheTopolTool)& aDomain)
984 Standard_Address anEAddress=aDomain->Edge();
985 if (anEAddress==NULL) {
986 return Standard_False;
989 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
991 return (BRep_Tool::HasContinuity(*anE));
994 //=======================================================================
997 //=======================================================================
998 Standard_Integer TreatLC (const TheArc& A,
999 const Handle(TheTopolTool)& aDomain,
1000 const IntSurf_Quadric& aQuadric,
1001 const Standard_Real TolBoundary,
1002 IntStart_SequenceOfPathPoint& pnt)
1004 Standard_Integer anExitCode=1, aNbExt;
1006 Standard_Address anEAddress=aDomain->Edge();
1007 if (anEAddress==NULL) {
1011 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1013 if (BRep_Tool::Degenerated(*anE)) {
1017 GeomAbs_CurveType aTypeE;
1018 BRepAdaptor_Curve aBAC(*anE);
1019 aTypeE=aBAC.GetType();
1021 if (aTypeE!=GeomAbs_Line) {
1025 GeomAbs_SurfaceType aTypeS;
1026 aTypeS=aQuadric.TypeQuadric();
1028 if (aTypeS!=GeomAbs_Cylinder) {
1032 Standard_Real f, l, U1f, U1l, U2f, U2l, UEgde, TOL, aDist, aR, aRRel, Tol;
1033 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l);
1035 gp_Cylinder aCyl=aQuadric.Cylinder();
1036 const gp_Ax1& anAx1=aCyl.Axis();
1038 Handle(Geom_Line) aCAxis=new Geom_Line (aLin);
1041 U1f = aCAxis->FirstParameter();
1042 U1l = aCAxis->LastParameter();
1044 U2f = aCEdge->FirstParameter();
1045 U2l = aCEdge->LastParameter();
1048 GeomAdaptor_Curve C1, C2;
1053 Tol = Precision::PConfusion();
1055 Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol);
1057 aNbExt=anExtCC.NbExt();
1063 Extrema_POnCurv PC1, PC2;
1065 anExtCC.Points(1, PC1, PC2);
1070 UEgde=PC2.Parameter();
1072 aDist=PEdge.Distance(P1);
1073 aRRel=fabs(aDist-aR)/aR;
1074 if (aRRel > TolBoundary) {
1078 if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) {
1083 // It was done as into PointProcess(...) function
1084 //printf("TreatLC()=> tangent line is found\n");
1085 TOL=1000.*TolBoundary;
1086 if(TOL>0.001) TOL=0.001;
1088 IntStart_ThePathPoint ptsol;
1089 ptsol.SetValue(PEdge, TOL, A, UEgde);
1098 //=======================================================================
1099 //function : IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries
1101 //=======================================================================
1102 IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries ()
1103 : done(Standard_False),
1108 //=======================================================================
1109 //function : Perform
1111 //=======================================================================
1112 void IntStart_SearchOnBoundaries::Perform (TheFunction& Func,
1113 const Handle(TheTopolTool)& Domain,
1114 const Standard_Real TolBoundary,
1115 const Standard_Real TolTangency,
1116 const Standard_Boolean RecheckOnRegularity)
1119 done = Standard_False;
1123 Standard_Boolean Arcsol;
1124 Standard_Real PDeb,PFin, prm, tol;
1125 Standard_Integer i, nbknown, nbfound,index;
1130 if (Domain->More()) {
1131 all = Standard_True;
1134 all = Standard_False;
1137 while (Domain->More()) {
1138 TheArc A = Domain->Value();
1139 if (!TheSOBTool::HasBeenSeen(A)) {
1141 FindVertex(A,Domain,Func,spnt,TolBoundary);
1142 TheSOBTool::Bounds(A,PDeb,PFin);
1143 if(Precision::IsNegativeInfinite(PDeb) ||
1144 Precision::IsPositiveInfinite(PFin)) {
1145 Standard_Integer NbEchant;
1146 ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant);
1148 BoundedArc(A,Domain,PDeb,PFin,Func,spnt,sseg,TolBoundary,TolTangency,Arcsol,RecheckOnRegularity);
1149 all = (all && Arcsol);
1153 // as it seems we'll never be here, because
1154 // TheSOBTool::HasBeenSeen(A) always returns FALSE
1155 nbfound = spnt.Length();
1157 // On recupere les points connus
1158 nbknown = TheSOBTool::NbPoints(A);
1159 for (i=1; i<=nbknown; i++) {
1160 TheSOBTool::Value(A,i,pt,tol,prm);
1161 if (TheSOBTool::IsVertex(A,i)) {
1163 TheSOBTool::Vertex(A,i,vtx);
1164 spnt.Append(IntStart_ThePathPoint(pt,tol,vtx,A,prm));
1167 spnt.Append(IntStart_ThePathPoint(pt,tol,A,prm));
1170 // On recupere les arcs solutions
1171 nbknown = TheSOBTool::NbSegments(A);
1172 for (i=1; i<=nbknown; i++) {
1173 IntStart_TheSegment newseg;
1175 if (TheSOBTool::HasFirstPoint(A,i,index)) {
1176 newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_True);
1178 if (TheSOBTool::HasLastPoint(A,i,index)) {
1179 newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_False);
1181 sseg.Append(newseg);
1183 all = (all& TheSOBTool::IsAllSolution(A));
1187 done = Standard_True;