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.
16 #include <TopoDS_Edge.hxx>
17 #include <Geom_Curve.hxx>
18 #include <BRepAdaptor_Curve.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <GeomAbs_SurfaceType.hxx>
21 #include <BRep_Tool.hxx>
22 #include <Geom_Line.hxx>
26 #include <gp_Cylinder.hxx>
30 #include <GeomAdaptor_Curve.hxx>
31 #include <Precision.hxx>
32 #include <Extrema_ExtCC.hxx>
33 #include <Extrema_POnCurv.hxx>
35 #include <math_FunctionSample.hxx>
36 #include <math_FunctionAllRoots.hxx>
37 #include <TColgp_SequenceOfPnt.hxx>
39 // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569
41 #include <Precision.hxx>
42 #include <IntSurf_Quadric.hxx>
43 #include <math_Function.hxx>
44 #include <math_BrentMinimum.hxx>
45 #include <math_Matrix.hxx>
46 #include <math_Vector.hxx>
47 #include <NCollection_Array1.hxx>
49 static void FindVertex (const TheArc&,
50 const Handle(TheTopolTool)&,
52 IntStart_SequenceOfPathPoint&,
56 static void BoundedArc (const TheArc& A,
57 const Handle(TheTopolTool)& Domain,
58 const Standard_Real Pdeb,
59 const Standard_Real Pfin,
61 IntStart_SequenceOfPathPoint& pnt,
62 IntStart_SequenceOfSegment& seg,
63 const Standard_Real TolBoundary,
64 const Standard_Real TolTangency,
65 Standard_Boolean& Arcsol,
66 const Standard_Boolean RecheckOnRegularity);
68 static void PointProcess (const gp_Pnt&,
71 const Handle(TheTopolTool)&,
72 IntStart_SequenceOfPathPoint&,
76 static Standard_Integer TreatLC (const TheArc& A,
77 const Handle(TheTopolTool)& aDomain,
78 const IntSurf_Quadric& aQuadric,
79 const Standard_Real TolBoundary,
80 IntStart_SequenceOfPathPoint& pnt);
82 static Standard_Boolean IsRegularity(const TheArc& A,
83 const Handle(TheTopolTool)& aDomain);
85 class MinFunction : public math_Function
88 MinFunction(TheFunction &theFunc) : myFunc(&theFunc) {};
90 //returns value of the one-dimension-function when parameter
92 virtual Standard_Boolean Value(const Standard_Real theX,
93 Standard_Real& theFVal)
95 if(!myFunc->Value(theX, theFVal))
96 return Standard_False;
102 //see analogical method for abstract owner class math_Function
103 virtual Standard_Integer GetStateNumber()
113 //=======================================================================
114 //function : FindVertex
116 //=======================================================================
117 void FindVertex (const TheArc& A,
118 const Handle(TheTopolTool)& Domain,
120 IntStart_SequenceOfPathPoint& pnt,
121 const Standard_Real Toler)
124 // Find the vertex of the arc A restriction solutions. It stores
125 // Vertex in the list solutions pnt.
129 Standard_Real param,valf;
130 Standard_Integer itemp;
132 Domain->Initialize(A);
133 Domain->InitVertexIterator();
134 while (Domain->MoreVertex()) {
135 vtx = Domain->Vertex();
136 param = TheSOBTool::Parameter(vtx,A);
138 // Evaluate the function and look compared to tolerance of the
139 // Vertex. If distance <= tolerance then add a vertex to the list of solutions.
140 // The arc is already assumed in the load function.
142 Func.Value(param,valf);
143 if (Abs(valf) <= Toler) {
144 itemp = Func.GetStateNumber();
145 pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, vtx,A,param));
148 Domain->NextVertex();
155 SolInfo() : myMathIndex(-1), myValue(RealLast())
159 void Init(const math_FunctionAllRoots& theSolution, const Standard_Integer theIndex)
161 myMathIndex = theIndex;
162 myValue = theSolution.GetPoint(theIndex);
165 Standard_Real Value() const
170 Standard_Integer Index() const
175 bool operator>(const SolInfo& theOther) const
177 return myValue > theOther.myValue;
180 bool operator<(const SolInfo& theOther) const
182 return myValue < theOther.myValue;
185 bool operator==(const SolInfo& theOther) const
187 return myValue == theOther.myValue;
190 Standard_Real& ChangeValue()
196 Standard_Integer myMathIndex;
197 Standard_Real myValue;
201 void BoundedArc (const TheArc& A,
202 const Handle(TheTopolTool)& Domain,
203 const Standard_Real Pdeb,
204 const Standard_Real Pfin,
206 IntStart_SequenceOfPathPoint& pnt,
207 IntStart_SequenceOfSegment& seg,
208 const Standard_Real TolBoundary,
209 const Standard_Real TolTangency,
210 Standard_Boolean& Arcsol,
211 const Standard_Boolean RecheckOnRegularity)
213 // Recherche des points solutions et des bouts d arc solution sur un arc donne.
214 // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour
215 // des arcs ayant un point debut et un point de fin (intervalle ferme de
218 Standard_Integer i,Nbi,Nbp;
221 Standard_Real pardeb = 0., parfin = 0.;
222 Standard_Integer ideb,ifin,range,ranged,rangef;
225 // Creer l echantillonage (math_FunctionSample ou classe heritant)
226 // Appel a math_FunctionAllRoots
228 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
229 //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement )
230 //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 )
231 //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une
232 //@@@ ligne de cheminement
233 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
234 Standard_Real EpsX = 1.e-10;
235 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
236 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
237 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
239 // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A);
240 Standard_Integer NbEchant = Func.NbSamples();
242 //-- Modif 24 Aout 93 -----------------------------
243 Standard_Real nTolTangency = TolTangency;
244 if((Pfin - Pdeb) < (TolTangency*10.0)) {
245 nTolTangency=(Pfin-Pdeb)*0.1;
247 if(EpsX>(nTolTangency+nTolTangency)) {
248 EpsX = nTolTangency * 0.1;
250 //--------------------------------------------------
251 //-- Plante avec un edge avec 2 Samples
252 //-- dont les extremites son solutions (f=0)
253 //-- et ou la derivee est nulle
254 //-- Exemple : un segment diametre d une sphere
255 //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95
256 //--------------------------------------------------
257 Standard_Real para=0,dist,maxdist;
258 /* if(NbEchant<20) NbEchant = 20; //-- lbr le 22 Avril 96
259 //-- Toujours des pbs
261 if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96
262 //-- Toujours des pbs
264 //-------------------------------------------------------------- REJECTIONS le 15 oct 98
265 Standard_Boolean Rejection=Standard_True;
266 Standard_Real maxdr,maxr,minr,ur,dur;
271 for(i=1,ur=Pdeb;i<=6;i++) {
273 if(Func.Values(ur,F,D)) {
274 Standard_Real lminr,lmaxr;
280 if(lminr<minr) minr=lminr;
281 if(lmaxr>maxr) maxr=lmaxr;
282 if(minr<0.0 && maxr>0.0) {
283 Rejection=Standard_False;
291 dur=0.001+maxdr+(maxr-minr)*0.1;
294 if(minr<0.0 && maxr>0.0) {
295 Rejection=Standard_False;
299 Arcsol=Standard_False;
301 if(Rejection==Standard_False) {
302 math_FunctionSample Echant(Pdeb,Pfin,NbEchant);
304 Standard_Boolean aelargir=Standard_True;
305 //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f
307 //maxdist = 100.0*TolBoundary;
308 maxdist = TolBoundary+TolTangency;
310 //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t
311 for(i=1; i<=NbEchant && aelargir;i++) {
312 Standard_Real u = Echant.GetParameter(i);
313 if(Func.Value(u,dist)) {
314 if(dist>maxdist || -dist>maxdist) {
315 aelargir=Standard_False;
319 if(!(aelargir && maxdist<0.01)) {
320 maxdist = TolBoundary;
323 math_FunctionAllRoots Sol(Func,Echant,EpsX,maxdist,maxdist); //-- TolBoundary,nTolTangency);
325 if (!Sol.IsDone()) {throw Standard_Failure();}
329 //jgv: build solution on the whole boundary
330 if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
332 //Standard_Real theTol = Domain->MaxTolerance(A);
334 Standard_Real theTol = 5.e-4;
335 math_FunctionAllRoots SolAgain(Func,Echant,EpsX,theTol,theTol); //-- TolBoundary,nTolTangency);
337 if (!SolAgain.IsDone()) {throw Standard_Failure();}
339 Standard_Integer Nbi_again = SolAgain.NbIntervals();
343 Standard_Integer NbSamples = 10;
344 Standard_Real delta = (Pfin - Pdeb)/NbSamples;
345 Standard_Real GlobalTol = theTol*10;
346 Standard_Boolean SolOnBoundary = Standard_True;
347 for (i = 0; i <= NbSamples; i++)
349 Standard_Real aParam = Pdeb + i*delta;
350 Standard_Real aValue;
351 Func.Value(aParam, aValue);
352 if (Abs(aValue) > GlobalTol)
354 SolOnBoundary = Standard_False;
361 for (i = 1; i <= Nbi_again; i++)
363 IntStart_TheSegment newseg;
365 // Recuperer point debut et fin, et leur parametre.
366 SolAgain.GetInterval(i,pardeb,parfin);
368 if (Abs(pardeb - Pdeb) <= Precision::PConfusion())
370 if (Abs(parfin - Pfin) <= Precision::PConfusion())
373 SolAgain.GetIntervalState(i,ideb,ifin);
375 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl;
377 ptdeb=Func.Valpoint(ideb);
378 ptfin=Func.Valpoint(ifin);
380 PointProcess(ptdeb,pardeb,A,Domain,pnt,theTol,ranged);
381 newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
382 PointProcess(ptfin,parfin,A,Domain,pnt,theTol,rangef);
383 newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
386 Arcsol=Standard_True;
391 ////////////////////////////////////////////
393 //-- detection du cas ou la fonction est quasi tangente et que les
394 //-- zeros sont quasi confondus.
395 //-- Dans ce cas on prend le point "milieu"
396 //-- On suppose que les solutions sont triees.
399 NCollection_Array1<SolInfo> aSI(1, Nbp);
406 std::sort(aSI.begin(), aSI.end());
408 //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f
409 //////////////////////////////////////////////////////////
410 // The treatment of the situation when line(arc) that is
411 // tangent to cylinder(domain).
412 // We should have only one solution i.e Nbp=1. Ok?
413 // But we have 2,3,.. solutions. That is wrong ersult.
414 // The TreatLC(...) function is dedicated to solve the pb.
415 // PKV Fri Mar 23 12:17:29 2001
417 const IntSurf_Quadric& aQuadric=Func.Quadric();
419 ip=TreatLC (A, Domain, aQuadric, TolBoundary, pnt);
421 //////////////////////////////////////////////////////////
422 //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t
424 // Using of old usual way proposed by Laurent
427 Standard_Real parap1 = aSI(i + 1).Value();
428 para = aSI(i).Value();
430 Standard_Real param=(para+parap1)*0.5;
432 if(Func.Value(param,ym)) {
433 if(Abs(ym)<maxdist) {
434 // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 Begin
435 // Consider this interval as tangent one. Treat it to find
436 // parameter with the lowest function value.
438 // Compute the number of nodes.
439 Standard_Real aTol = TolBoundary*1000.0;
443 // fix floating point exception 569, chl-922-e9
444 parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9);
445 para = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9);
447 Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol));
449 Standard_Real aVal = RealLast();
450 //Standard_Integer aNbNodes = 23;
451 Standard_Real aDelta = (parap1 - para)/(aNbNodes + 1.);
453 Standard_Real aCurPar;
454 Standard_Real aCurVal;
456 for (ii = 0; ii <= aNbNodes + 1; ii++) {
457 aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1;
459 if (Func.Value(aCurPar, aCurVal)) {
460 //if (aCurVal < aVal) {
461 if (Abs(aCurVal) < aVal) {
468 // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 End
469 aSI(i).ChangeValue() = Pdeb - 1;
470 aSI(i + 1).ChangeValue() = param;
475 for (i=1; i<=Nbp; i++) {
476 para = aSI(i).Value();
477 if((para-Pdeb)<EpsX || (Pfin-para)<EpsX)
480 if(!Func.Value(para,dist))
485 Standard_Integer anIndx = -1;
486 const Standard_Real aParam = Sol.GetPoint(aSI(i).Index());
489 if (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion())
491 Standard_Real aDistTemp = RealLast();
492 if (Func.Value(aParam, aDistTemp))
494 if (Abs(aDistTemp) < maxdist)
496 anIndx = Sol.GetPointState(aSI(i).Index());
502 gp_Pnt aPnt(anIndx < 0 ? Func.LastComputedPoint() : Func.Valpoint(anIndx));
504 if (dist > 0.1*Precision::Confusion())
506 //Precise found points. It results in following:
507 // 1. Make the vertex nearer to the intersection line
508 // (see description to issue #27252 in order to
509 // understand necessity).
510 // 2. Merge two near vertices to single point.
512 //All members in TabSol array has already been sorted in increase order.
513 //Now, we limit precise boundaries in order to avoid changing this order.
514 const Standard_Real aFPar = (i == 1) ? Pdeb : (para + aSI(i - 1).Value()) / 2.0;
515 const Standard_Real aLPar = (i == Nbp) ? Pfin : (para + aSI(i + 1).Value()) / 2.0;
517 MinFunction aNewFunc(Func);
518 math_BrentMinimum aMin(Precision::Confusion());
520 aMin.Perform(aNewFunc, aFPar, para, aLPar);
523 para = aMin.Location();
524 const gp_Pnt2d aP2d(A->Value(para));
525 aPnt = Func.Surface()->Value(aP2d.X(), aP2d.Y());
529 PointProcess(aPnt, para, A, Domain, pnt, TolBoundary, range);
534 // Pour chaque intervalle trouve faire
535 // Traiter les extremites comme des points
536 // Ajouter intervalle dans la liste des segments
538 Nbi=Sol.NbIntervals();
541 if (!RecheckOnRegularity && Nbp) {
542 //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0 0 <- Nbi "<<Nbi<<endl;
546 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : Nbi : "<<Nbi<<endl;
548 for (i=1; i<=Nbi; i++) {
549 IntStart_TheSegment newseg;
551 // Recuperer point debut et fin, et leur parametre.
552 Sol.GetInterval(i,pardeb,parfin);
553 Sol.GetIntervalState(i,ideb,ifin);
556 //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl;
558 ptdeb=Func.Valpoint(ideb);
559 ptfin=Func.Valpoint(ifin);
561 PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged);
562 newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
563 PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef);
564 newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
569 if((Abs(pardeb - Pdeb) < Precision::PConfusion()) &&
570 (Abs(parfin - Pfin) < Precision::PConfusion()))
572 Arcsol=Standard_True;
578 //=======================================================================
579 //function : ComputeBoundsfromInfinite
581 //=======================================================================
582 // - PROVISIONAL - TEMPORARY - NOT GOOD - NYI - TO DO
583 // - Temporary - temporary - not good - nyi - to do
584 void ComputeBoundsfromInfinite(TheFunction& Func,
587 Standard_Integer& NbEchant)
590 // - We are looking for parameters for start and end of the arc (2d curve)
591 // - Infinity, a way to intersect the quadric with a portion of arc
594 // - The quadric is a plane, a cylinder, a cone and a sphere.
595 // - Idea: We take any point on the arc and the fact grow
596 // - Terminals to the signed distance function values or is likely
599 // - WARNING: The following calculations provide a very estimated coarse parameters.
600 // - This avoids the raises and allows a case of Boxes
601 // - Inifinies walk. It will take this code
602 // - With curve surface intersections.
606 Standard_Real U0 = 0.0;
607 Standard_Real dU = 0.001;
608 Standard_Real Dist0,Dist1;
610 Func.Value(U0 , Dist0);
611 Func.Value(U0+dU, Dist1);
612 Standard_Real dDist = Dist1 - Dist0;
614 U0 -= dU*Dist0 / dDist;
616 Standard_Real Umin = U0 - 1e5;
617 Func.Value(Umin , Dist0);
618 Func.Value(Umin+dU, Dist1);
621 Umin -= dU*Dist0 / dDist;
626 Standard_Real Umax = U0 + 1e8;
627 Func.Value(Umax , Dist0);
628 Func.Value(Umax+dU, Dist1);
631 Umax -= dU*Dist0 / dDist;
636 if(Umin>U0) { Umin=U0-10.0; }
637 if(Umax<U0) { Umax=U0+10.0; }
639 PFin = Umax + 10. * (Umax - Umin);
640 PDeb = Umin - 10. * (Umax - Umin);
643 //-- Possibilite de Arc totalement inclu ds Quad
649 //=======================================================================
650 //function : PointProcess
652 //=======================================================================
653 void PointProcess (const gp_Pnt& Pt,
654 const Standard_Real Para,
656 const Handle(TheTopolTool)& Domain,
657 IntStart_SequenceOfPathPoint& pnt,
658 const Standard_Real Tol,
659 Standard_Integer& Range)
662 // Check to see if a solution point is coincident with a vertex.
663 // If confused, you should find this vertex in the list of
664 // Start. It then returns the position of this point in the list pnt.
665 // Otherwise, add the point in the list.
668 Standard_Boolean found,goon;
669 Standard_Real dist,toler;
671 Standard_Integer Nbsol = pnt.Length();
673 IntStart_ThePathPoint ptsol;
675 Domain->Initialize(A);
676 Domain->InitVertexIterator();
677 found = Standard_False;
678 goon = Domain->MoreVertex();
680 vtx = Domain->Vertex();
681 dist= Abs(Para-TheSOBTool::Parameter(vtx,A));
682 toler = TheSOBTool::Tolerance(vtx,A);
685 cout<<"IntStart_SearchOnBoundaries_1.gxx : ** WARNING ** Tol Vertex="<<toler<<endl;
686 cout<<" Ou Edge degenere Ou Kro pointu"<<endl;
687 if(toler>10000) toler=1e-7;
692 // Locate the vertex in the list of solutions
696 ptsol = pnt.Value(k);
697 if (!ptsol.IsNew()) {
698 //jag 940608 if (ptsol.Vertex() == vtx && ptsol.Arc() == A) {
699 if (Domain->Identical(ptsol.Vertex(),vtx) &&
701 Abs(ptsol.Parameter()-Para) <= toler) {
714 if (k<=Nbsol) { // We find the vertex
718 ptsol.SetValue(Pt,Tol,vtx,A,Para);
720 Range = pnt.Length();
722 found = Standard_True;
723 goon = Standard_False;
726 Domain->NextVertex();
727 goon = Domain->MoreVertex();
731 if (!found) { // No one is falling on a vertex
732 //jgv: do not add segment's extremities if they already exist
733 Standard_Boolean found_internal = Standard_False;
734 for (k = 1; k <= pnt.Length(); k++)
736 ptsol = pnt.Value(k);
737 if (ptsol.Arc() != A ||
738 !ptsol.IsNew()) //vertex
740 if (Abs(ptsol.Parameter()-Para) <= Precision::PConfusion())
742 found_internal = Standard_True;
746 /////////////////////////////////////////////////////////////
750 Standard_Real TOL=Tol;
752 //if(TOL>0.001) TOL=0.001;
753 if(TOL>0.005) TOL=0.005; //#24643
755 ptsol.SetValue(Pt,TOL,A,Para);
757 Range = pnt.Length();
762 //=======================================================================
763 //function : IsRegularity
765 //=======================================================================
766 Standard_Boolean IsRegularity(const TheArc& /*A*/,
767 const Handle(TheTopolTool)& aDomain)
769 Standard_Address anEAddress=aDomain->Edge();
770 if (anEAddress==NULL) {
771 return Standard_False;
774 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
776 return (BRep_Tool::HasContinuity(*anE));
779 //=======================================================================
782 //=======================================================================
783 Standard_Integer TreatLC (const TheArc& A,
784 const Handle(TheTopolTool)& aDomain,
785 const IntSurf_Quadric& aQuadric,
786 const Standard_Real TolBoundary,
787 IntStart_SequenceOfPathPoint& pnt)
789 Standard_Integer anExitCode=1, aNbExt;
791 Standard_Address anEAddress=aDomain->Edge();
792 if (anEAddress==NULL) {
796 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
798 if (BRep_Tool::Degenerated(*anE)) {
802 GeomAbs_CurveType aTypeE;
803 BRepAdaptor_Curve aBAC(*anE);
804 aTypeE=aBAC.GetType();
806 if (aTypeE!=GeomAbs_Line) {
810 GeomAbs_SurfaceType aTypeS;
811 aTypeS=aQuadric.TypeQuadric();
813 if (aTypeS!=GeomAbs_Cylinder) {
817 Standard_Real f, l, U1f, U1l, U2f, U2l, UEgde, TOL, aDist, aR, aRRel, Tol;
818 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l);
820 gp_Cylinder aCyl=aQuadric.Cylinder();
821 const gp_Ax1& anAx1=aCyl.Axis();
823 Handle(Geom_Line) aCAxis=new Geom_Line (aLin);
826 U1f = aCAxis->FirstParameter();
827 U1l = aCAxis->LastParameter();
829 U2f = aCEdge->FirstParameter();
830 U2l = aCEdge->LastParameter();
833 GeomAdaptor_Curve C1, C2;
838 Tol = Precision::PConfusion();
840 Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol);
842 aNbExt=anExtCC.NbExt();
848 Extrema_POnCurv PC1, PC2;
850 anExtCC.Points(1, PC1, PC2);
855 UEgde=PC2.Parameter();
857 aDist=PEdge.Distance(P1);
858 aRRel=fabs(aDist-aR)/aR;
859 if (aRRel > TolBoundary) {
863 if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) {
868 // It was done as into PointProcess(...) function
869 //printf("TreatLC()=> tangent line is found\n");
870 TOL=1000.*TolBoundary;
871 if(TOL>0.001) TOL=0.001;
873 IntStart_ThePathPoint ptsol;
874 ptsol.SetValue(PEdge, TOL, A, UEgde);
883 //=======================================================================
884 //function : IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries
886 //=======================================================================
887 IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries ()
888 : done(Standard_False)
892 //=======================================================================
895 //=======================================================================
896 void IntStart_SearchOnBoundaries::Perform (TheFunction& Func,
897 const Handle(TheTopolTool)& Domain,
898 const Standard_Real TolBoundary,
899 const Standard_Real TolTangency,
900 const Standard_Boolean RecheckOnRegularity)
903 done = Standard_False;
907 Standard_Boolean Arcsol;
908 Standard_Real PDeb,PFin, prm, tol;
909 Standard_Integer i, nbknown, nbfound,index;
914 if (Domain->More()) {
918 all = Standard_False;
921 while (Domain->More()) {
922 TheArc A = Domain->Value();
923 if (!TheSOBTool::HasBeenSeen(A)) {
925 FindVertex(A,Domain,Func,spnt,TolBoundary);
926 TheSOBTool::Bounds(A,PDeb,PFin);
927 if(Precision::IsNegativeInfinite(PDeb) ||
928 Precision::IsPositiveInfinite(PFin)) {
929 Standard_Integer NbEchant;
930 ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant);
932 BoundedArc(A,Domain,PDeb,PFin,Func,spnt,sseg,TolBoundary,TolTangency,Arcsol,RecheckOnRegularity);
933 all = (all && Arcsol);
937 // as it seems we'll never be here, because
938 // TheSOBTool::HasBeenSeen(A) always returns FALSE
939 nbfound = spnt.Length();
941 // On recupere les points connus
942 nbknown = TheSOBTool::NbPoints(A);
943 for (i=1; i<=nbknown; i++) {
944 TheSOBTool::Value(A,i,pt,tol,prm);
945 if (TheSOBTool::IsVertex(A,i)) {
947 TheSOBTool::Vertex(A,i,vtx);
948 spnt.Append(IntStart_ThePathPoint(pt,tol,vtx,A,prm));
951 spnt.Append(IntStart_ThePathPoint(pt,tol,A,prm));
954 // On recupere les arcs solutions
955 nbknown = TheSOBTool::NbSegments(A);
956 for (i=1; i<=nbknown; i++) {
957 IntStart_TheSegment newseg;
959 if (TheSOBTool::HasFirstPoint(A,i,index)) {
960 newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_True);
962 if (TheSOBTool::HasLastPoint(A,i,index)) {
963 newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_False);
967 all = (all& TheSOBTool::IsAllSolution(A));
971 done = Standard_True;