// Copyright (c) 1995-1999 Matra Datavision // Copyright (c) 1999-2014 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 #include #include #include #include #include #include #include #ifdef OCCT_DEBUG #include #include #include #include #include #include #include #endif static Standard_Boolean IsDegenerated(const Handle(Adaptor3d_CurveOnSurface)& theCurve); static Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric); static void FindVertex (const TheArc&, const Handle(TheTopolTool)&, TheFunction&, IntStart_SequenceOfPathPoint&, const Standard_Real); static void BoundedArc (const TheArc& A, const Handle(TheTopolTool)& Domain, const Standard_Real Pdeb, const Standard_Real Pfin, TheFunction& Func, IntStart_SequenceOfPathPoint& pnt, IntStart_SequenceOfSegment& seg, const Standard_Real TolBoundary, const Standard_Real TolTangency, Standard_Boolean& Arcsol, const Standard_Boolean RecheckOnRegularity); static void PointProcess (const gp_Pnt&, const Standard_Real, const TheArc&, const Handle(TheTopolTool)&, IntStart_SequenceOfPathPoint&, const Standard_Real, Standard_Integer&); static Standard_Integer TreatLC (const TheArc& A, const Handle(TheTopolTool)& aDomain, const IntSurf_Quadric& aQuadric, const Standard_Real TolBoundary, IntStart_SequenceOfPathPoint& pnt); static Standard_Boolean IsRegularity(const TheArc& A, const Handle(TheTopolTool)& aDomain); class MinFunction : public math_Function { public: MinFunction(TheFunction &theFunc) : myFunc(&theFunc) {}; //returns value of the one-dimension-function when parameter //is equal to theX virtual Standard_Boolean Value(const Standard_Real theX, Standard_Real& theFVal) { if(!myFunc->Value(theX, theFVal)) return Standard_False; theFVal *= theFVal; return Standard_True; } //see analogical method for abstract owner class math_Function virtual Standard_Integer GetStateNumber() { return 0; } private: TheFunction *myFunc; }; //======================================================================= //function : FindVertex //purpose : //======================================================================= void FindVertex (const TheArc& A, const Handle(TheTopolTool)& Domain, TheFunction& Func, IntStart_SequenceOfPathPoint& pnt, const Standard_Real Toler) { // Find the vertex of the arc A restriction solutions. It stores // Vertex in the list solutions pnt. TheVertex vtx; Standard_Real param,valf; Standard_Integer itemp; Domain->Initialize(A); Domain->InitVertexIterator(); while (Domain->MoreVertex()) { vtx = Domain->Vertex(); param = TheSOBTool::Parameter(vtx,A); // Evaluate the function and look compared to tolerance of the // Vertex. If distance <= tolerance then add a vertex to the list of solutions. // The arc is already assumed in the load function. Func.Value(param,valf); if (Abs(valf) <= Toler) { itemp = Func.GetStateNumber(); pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, vtx,A,param)); // Solution is added } Domain->NextVertex(); } } Standard_Boolean IsDegenerated(const Handle(Adaptor3d_CurveOnSurface)& theCurve) { if (theCurve->GetType() == GeomAbs_Circle) { gp_Circ aCirc = theCurve->Circle(); if (aCirc.Radius() <= Precision::Confusion()) return Standard_True; } return Standard_False; } Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric) { GeomAbs_SurfaceType TypeQuad = theQuadric.TypeQuadric(); if (TypeQuad == GeomAbs_Cone) { gp_Cone aCone = theQuadric.Cone(); Standard_Real aSemiAngle = Abs(aCone.SemiAngle()); if (aSemiAngle < 0.02 || aSemiAngle > 1.55) return Standard_True; } return Standard_False; } class SolInfo { public: SolInfo() : myMathIndex(-1), myValue(RealLast()) { } void Init(const math_FunctionAllRoots& theSolution, const Standard_Integer theIndex) { myMathIndex = theIndex; myValue = theSolution.GetPoint(theIndex); } void Init(const IntCurveSurface_HInter& theSolution, const Standard_Integer theIndex) { myMathIndex = theIndex; myValue = theSolution.Point(theIndex).W(); } Standard_Real Value() const { return myValue; } Standard_Integer Index() const { return myMathIndex; } bool operator>(const SolInfo& theOther) const { return myValue > theOther.myValue; } bool operator<(const SolInfo& theOther) const { return myValue < theOther.myValue; } bool operator==(const SolInfo& theOther) const { return myValue == theOther.myValue; } Standard_Real& ChangeValue() { return myValue; } private: Standard_Integer myMathIndex; Standard_Real myValue; }; static void BoundedArc (const TheArc& A, const Handle(TheTopolTool)& Domain, const Standard_Real Pdeb, const Standard_Real Pfin, TheFunction& Func, IntStart_SequenceOfPathPoint& pnt, IntStart_SequenceOfSegment& seg, const Standard_Real TolBoundary, const Standard_Real TolTangency, Standard_Boolean& Arcsol, const Standard_Boolean RecheckOnRegularity) { // Recherche des points solutions et des bouts d arc solution sur un arc donne. // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour // des arcs ayant un point debut et un point de fin (intervalle ferme de // parametrage). Standard_Integer i, Nbi = 0, Nbp = 0; gp_Pnt ptdeb,ptfin; Standard_Real pardeb = 0., parfin = 0.; Standard_Integer ideb,ifin,range,ranged,rangef; // Creer l echantillonage (math_FunctionSample ou classe heritant) // Appel a math_FunctionAllRoots //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement ) //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 ) //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une //@@@ ligne de cheminement //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Standard_Real EpsX = 1.e-10; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); Standard_Integer NbEchant = Func.NbSamples(); if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 //-- Toujours des pbs //-- Modif 24 Aout 93 ----------------------------- Standard_Real nTolTangency = TolTangency; if((Pfin - Pdeb) < (TolTangency*10.0)) { nTolTangency=(Pfin-Pdeb)*0.1; } if(EpsX>(nTolTangency+nTolTangency)) { EpsX = nTolTangency * 0.1; } //-------------------------------------------------- //-- Plante avec un edge avec 2 Samples //-- dont les extremites son solutions (f=0) //-- et ou la derivee est nulle //-- Exemple : un segment diametre d une sphere //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95 //-------------------------------------------------- Standard_Real para=0,dist,maxdist; //-------------------------------------------------------------- REJECTIONS le 15 oct 98 Standard_Boolean Rejection=Standard_True; Standard_Real maxdr,maxr,minr,ur,dur; minr=RealLast(); maxr=-minr; maxdr=-minr; dur=(Pfin-Pdeb)*0.2; for(i=1,ur=Pdeb;i<=6;i++) { Standard_Real F,D; if(Func.Values(ur,F,D)) { Standard_Real lminr,lmaxr; if(D<0.0) D=-D; D*=dur+dur; if(D>maxdr) maxdr=D; lminr=F-D; lmaxr=F+D; if(lminrmaxr) maxr=lmaxr; if(minr<0.0 && maxr>0.0) { Rejection=Standard_False; break; } } ur+=dur; } if(Rejection) { dur=0.001+maxdr+(maxr-minr)*0.1; minr-=dur; maxr+=dur; if(minr<0.0 && maxr>0.0) { Rejection=Standard_False; } } Arcsol=Standard_False; if(Rejection==Standard_False) { const IntSurf_Quadric& aQuadric = Func.Quadric(); GeomAbs_SurfaceType TypeQuad = aQuadric.TypeQuadric(); GeomAbs_CurveType TypeConS = GeomAbs_OtherCurve; IntCurveSurface_HInter IntCS; Standard_Boolean IsIntCSdone = Standard_False; TColStd_SequenceOfReal Params; std::unique_ptr pSol; math_FunctionSample Echant(Pdeb,Pfin,NbEchant); Standard_Boolean aelargir=Standard_True; //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f // //maxdist = 100.0*TolBoundary; maxdist = TolBoundary+TolTangency; // //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t for(i=1; i<=NbEchant && aelargir;i++) { Standard_Real u = Echant.GetParameter(i); if(Func.Value(u,dist)) { if(dist>maxdist || -dist>maxdist) { aelargir=Standard_False; } } } if(!(aelargir && maxdist<0.01)) { maxdist = TolBoundary; } if (TypeQuad != GeomAbs_OtherSurface) //intersection of boundary curve and quadric surface { //Exact solution Handle(Adaptor3d_Surface) aSurf = Func.Surface(); Adaptor3d_CurveOnSurface ConS(A, aSurf); TypeConS = ConS.GetType(); #ifdef OCCT_DEBUG Handle(Geom_Curve) CurveConS; switch(TypeConS) { case GeomAbs_Line: { CurveConS = new Geom_Line(ConS.Line()); break; } case GeomAbs_Circle: { CurveConS = new Geom_Circle(ConS.Circle()); break; } case GeomAbs_Ellipse: { CurveConS = new Geom_Ellipse(ConS.Ellipse()); break; } case GeomAbs_Hyperbola: { CurveConS = new Geom_Hyperbola(ConS.Hyperbola()); break; } case GeomAbs_Parabola: { CurveConS = new Geom_Parabola(ConS.Parabola()); break; } case GeomAbs_BezierCurve: { CurveConS = ConS.Bezier(); break; } case GeomAbs_BSplineCurve: { CurveConS = ConS.BSpline(); break; } default: { Standard_Real MaxDeviation, AverageDeviation; GeomLib::BuildCurve3d(1.e-5, ConS, ConS.FirstParameter(), ConS.LastParameter(), CurveConS, MaxDeviation, AverageDeviation); break; } } #endif Handle(Adaptor3d_CurveOnSurface) HConS = new Adaptor3d_CurveOnSurface(ConS); Handle(Geom_Surface) QuadSurf; switch (TypeQuad) { case GeomAbs_Plane: { QuadSurf = new Geom_Plane(aQuadric.Plane()); break; } case GeomAbs_Cylinder: { QuadSurf = new Geom_CylindricalSurface(aQuadric.Cylinder()); break; } case GeomAbs_Cone: { QuadSurf = new Geom_ConicalSurface(aQuadric.Cone()); break; } case GeomAbs_Sphere: { QuadSurf = new Geom_SphericalSurface(aQuadric.Sphere()); break; } case GeomAbs_Torus: { QuadSurf = new Geom_ToroidalSurface(aQuadric.Torus()); break; } default: break; } Handle(GeomAdaptor_Surface) GAHsurf = new GeomAdaptor_Surface(QuadSurf); if ((TypeConS == GeomAbs_Line || TypeConS == GeomAbs_Circle || TypeConS == GeomAbs_Ellipse || TypeConS == GeomAbs_Parabola || TypeConS == GeomAbs_Hyperbola) && TypeQuad != GeomAbs_Torus && !IsDegenerated(HConS) && !IsDegenerated(aQuadric)) { //exact intersection for only canonic curves and real quadric surfaces IntCS.Perform(HConS, GAHsurf); } IsIntCSdone = IntCS.IsDone(); if (IsIntCSdone) { Nbp = IntCS.NbPoints(); Nbi = IntCS.NbSegments(); } //If we have not got intersection, it may be touch with some tolerance, //need to be checked if (Nbp == 0 && Nbi == 0) IsIntCSdone = Standard_False; } //if (TypeQuad != GeomAbs_OtherSurface) - intersection of boundary curve and quadric surface if (!IsIntCSdone) { pSol.reset(new math_FunctionAllRoots(Func,Echant,EpsX,maxdist,maxdist)); //-- TolBoundary,nTolTangency); if (!pSol->IsDone()) {throw Standard_Failure();} Nbp=pSol->NbPoints(); } // //jgv: build solution on the whole boundary if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain)) { //Standard_Real theTol = Domain->MaxTolerance(A); //theTol += theTol; Standard_Real theTol = 5.e-4; math_FunctionAllRoots SolAgain(Func,Echant,EpsX,theTol,theTol); //-- TolBoundary,nTolTangency); if (!SolAgain.IsDone()) {throw Standard_Failure();} Standard_Integer Nbi_again = SolAgain.NbIntervals(); if (Nbi_again > 0) { Standard_Integer NbSamples = 10; Standard_Real delta = (Pfin - Pdeb)/NbSamples; Standard_Real GlobalTol = theTol*10; Standard_Boolean SolOnBoundary = Standard_True; for (i = 0; i <= NbSamples; i++) { Standard_Real aParam = Pdeb + i*delta; Standard_Real aValue; Func.Value(aParam, aValue); if (Abs(aValue) > GlobalTol) { SolOnBoundary = Standard_False; break; } } if (SolOnBoundary) { for (i = 1; i <= Nbi_again; i++) { IntStart_TheSegment newseg; newseg.SetValue(A); // Recuperer point debut et fin, et leur parametre. SolAgain.GetInterval(i,pardeb,parfin); if (Abs(pardeb - Pdeb) <= Precision::PConfusion()) pardeb = Pdeb; if (Abs(parfin - Pfin) <= Precision::PConfusion()) parfin = Pfin; SolAgain.GetIntervalState(i,ideb,ifin); //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "< 0 && IsRegularity(A, Domain)) //////////////////////////////////////////// //-- detection du cas ou la fonction est quasi tangente et que les //-- zeros sont quasi confondus. //-- Dans ce cas on prend le point "milieu" //-- On suppose que les solutions sont triees. if(Nbp) { NCollection_Array1 aSI(1, Nbp); for(i=1;i<=Nbp;i++) { if (IsIntCSdone) aSI(i).Init(IntCS, i); else aSI(i).Init(*pSol, i); } std::sort(aSI.begin(), aSI.end()); //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f ////////////////////////////////////////////////////////// // The treatment of the situation when line(arc) that is // tangent to cylinder(domain). // We should have only one solution i.e Nbp=1. Ok? // But we have 2,3,.. solutions. That is wrong ersult. // The TreatLC(...) function is dedicated to solve the pb. // PKV Fri Mar 23 12:17:29 2001 Standard_Integer ip = TreatLC (A, Domain, aQuadric, TolBoundary, pnt); if (ip) { ////////////////////////////////////////////////////////// //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t // // Using of old usual way proposed by Laurent // for(i=1;i 0.001) aTol = 0.001; // fix floating point exception 569, chl-922-e9 parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9); para = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9); Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol)); Standard_Real aVal = RealLast(); Standard_Real aValMax = 0.; //Standard_Integer aNbNodes = 23; Standard_Real aDelta = (parap1 - para)/(aNbNodes + 1.); Standard_Integer ii; Standard_Real aCurPar; Standard_Real aCurVal; for (ii = 0; ii <= aNbNodes + 1; ii++) { aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1; if (Func.Value(aCurPar, aCurVal)) { Standard_Real anAbsVal = Abs(aCurVal); if (anAbsVal < aVal) { aVal = anAbsVal; param = aCurPar; } if (anAbsVal > aValMax) { aValMax = anAbsVal; } } } // At last, interval got by exact intersection can be considered as tangent if // minimal distance is inside interval and // minimal and maximal values are almost the same if (IsIntCSdone && aNbNodes > 1) { aTang = Abs(param - para) > EpsX && Abs(parap1 - param) > EpsX && 0.01*aValMax <= aVal; } if (aTang) { aSI(i).ChangeValue() = Pdeb - 1; aSI(i + 1).ChangeValue() = param; } } } } for (i=1; i<=Nbp; i++) { para = aSI(i).Value(); if((para-Pdeb)GetPoint(aSI(i).Index()); const Standard_Real aParam = aSI(i).Value(); if (dist < maxdist) { if (!IsIntCSdone && (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion())) { anIndx = pSol->GetPointState(aSI(i).Index()); } } gp_Pnt aPnt(anIndx < 0 ? Func.LastComputedPoint() : Func.Valpoint(anIndx)); if (dist > 0.1*Precision::Confusion()) { //Precise found points. It results in following: // 1. Make the vertex nearer to the intersection line // (see description to issue #27252 in order to // understand necessity). // 2. Merge two near vertices to single point. //All members in TabSol array has already been sorted in increase order. //Now, we limit precise boundaries in order to avoid changing this order. const Standard_Real aFPar = (i == 1) ? Pdeb : (para + aSI(i - 1).Value()) / 2.0; const Standard_Real aLPar = (i == Nbp) ? Pfin : (para + aSI(i + 1).Value()) / 2.0; MinFunction aNewFunc(Func); math_BrentMinimum aMin(Precision::Confusion()); aMin.Perform(aNewFunc, aFPar, para, aLPar); if(aMin.IsDone()) { para = aMin.Location(); const gp_Pnt2d aP2d(A->Value(para)); aPnt = Func.Surface()->Value(aP2d.X(), aP2d.Y()); } } PointProcess(aPnt, para, A, Domain, pnt, TolBoundary, range); } }// end of if(ip) } // end of if(Nbp) // Pour chaque intervalle trouve faire // Traiter les extremites comme des points // Ajouter intervalle dans la liste des segments if (!IsIntCSdone) Nbi = pSol->NbIntervals(); if (!RecheckOnRegularity && Nbp) { //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0 0 <- Nbi "<GetInterval(i,pardeb,parfin); pSol->GetIntervalState(i,ideb,ifin); //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<U0) { Umin=U0-10.0; } if(UmaxInitialize(A); Domain->InitVertexIterator(); found = Standard_False; goon = Domain->MoreVertex(); while (goon) { vtx = Domain->Vertex(); dist= Abs(Para-TheSOBTool::Parameter(vtx,A)); toler = TheSOBTool::Tolerance(vtx,A); #ifdef OCCT_DEBUG if(toler>0.1) { std::cout<<"IntStart_SearchOnBoundaries_1.gxx : ** WARNING ** Tol Vertex="<10000) toler=1e-7; } #endif if (dist <= toler) { // Locate the vertex in the list of solutions k=1; found = (k>Nbsol); while (!found) { ptsol = pnt.Value(k); if (!ptsol.IsNew()) { //jag 940608 if (ptsol.Vertex() == vtx && ptsol.Arc() == A) { if (Domain->Identical(ptsol.Vertex(),vtx) && ptsol.Arc() == A && Abs(ptsol.Parameter()-Para) <= toler) { found=Standard_True; } else { k=k+1; found=(k>Nbsol); } } else { k=k+1; found=(k>Nbsol); } } if (k<=Nbsol) { // We find the vertex Range = k; } else { // Otherwise ptsol.SetValue(Pt,Tol,vtx,A,Para); pnt.Append(ptsol); Range = pnt.Length(); } found = Standard_True; goon = Standard_False; } else { Domain->NextVertex(); goon = Domain->MoreVertex(); } } if (!found) { // No one is falling on a vertex //jgv: do not add segment's extremities if they already exist Standard_Boolean found_internal = Standard_False; for (k = 1; k <= pnt.Length(); k++) { ptsol = pnt.Value(k); if (ptsol.Arc() != A || !ptsol.IsNew()) //vertex continue; if (Abs(ptsol.Parameter()-Para) <= Precision::PConfusion()) { found_internal = Standard_True; Range = k; } } ///////////////////////////////////////////////////////////// if (!found_internal) { Standard_Real TOL=Tol; TOL*=1000.0; //if(TOL>0.001) TOL=0.001; if(TOL>0.005) TOL=0.005; //#24643 ptsol.SetValue(Pt,TOL,A,Para); pnt.Append(ptsol); Range = pnt.Length(); } } } //======================================================================= //function : IsRegularity //purpose : //======================================================================= Standard_Boolean IsRegularity(const TheArc& /*A*/, const Handle(TheTopolTool)& aDomain) { Standard_Address anEAddress=aDomain->Edge(); if (anEAddress==NULL) { return Standard_False; } TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; return (BRep_Tool::HasContinuity(*anE)); } //======================================================================= //function : TreatLC //purpose : //======================================================================= Standard_Integer TreatLC (const TheArc& A, const Handle(TheTopolTool)& aDomain, const IntSurf_Quadric& aQuadric, const Standard_Real TolBoundary, IntStart_SequenceOfPathPoint& pnt) { Standard_Integer anExitCode=1, aNbExt; Standard_Address anEAddress=aDomain->Edge(); if (anEAddress==NULL) { return anExitCode; } TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; if (BRep_Tool::Degenerated(*anE)) { return anExitCode; } GeomAbs_CurveType aTypeE; BRepAdaptor_Curve aBAC(*anE); aTypeE=aBAC.GetType(); if (aTypeE!=GeomAbs_Line) { return anExitCode; } GeomAbs_SurfaceType aTypeS; aTypeS=aQuadric.TypeQuadric(); if (aTypeS!=GeomAbs_Cylinder) { return anExitCode; } Standard_Real f, l, U1f, U1l, U2f, U2l, UEgde, TOL, aDist, aR, aRRel, Tol; Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l); gp_Cylinder aCyl=aQuadric.Cylinder(); const gp_Ax1& anAx1=aCyl.Axis(); gp_Lin aLin(anAx1); Handle(Geom_Line) aCAxis=new Geom_Line (aLin); aR=aCyl.Radius(); U1f = aCAxis->FirstParameter(); U1l = aCAxis->LastParameter(); U2f = aCEdge->FirstParameter(); U2l = aCEdge->LastParameter(); GeomAdaptor_Curve C1, C2; C1.Load(aCAxis); C2.Load(aCEdge); Tol = Precision::PConfusion(); Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol); aNbExt=anExtCC.NbExt(); if (aNbExt!=1) { return anExitCode; } gp_Pnt P1,PEdge; Extrema_POnCurv PC1, PC2; anExtCC.Points(1, PC1, PC2); P1 =PC1.Value(); PEdge=PC2.Value(); UEgde=PC2.Parameter(); aDist=PEdge.Distance(P1); aRRel=fabs(aDist-aR)/aR; if (aRRel > TolBoundary) { return anExitCode; } if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) { return anExitCode; } // // Do not wonder ! // It was done as into PointProcess(...) function //printf("TreatLC()=> tangent line is found\n"); TOL=1000.*TolBoundary; if(TOL>0.001) TOL=0.001; IntStart_ThePathPoint ptsol; ptsol.SetValue(PEdge, TOL, A, UEgde); pnt.Append(ptsol); anExitCode=0; return anExitCode; } //======================================================================= //function : IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries //purpose : //======================================================================= IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries () : done(Standard_False), all(Standard_False) { } //======================================================================= //function : Perform //purpose : //======================================================================= void IntStart_SearchOnBoundaries::Perform (TheFunction& Func, const Handle(TheTopolTool)& Domain, const Standard_Real TolBoundary, const Standard_Real TolTangency, const Standard_Boolean RecheckOnRegularity) { done = Standard_False; spnt.Clear(); sseg.Clear(); Standard_Boolean Arcsol; Standard_Real PDeb,PFin, prm, tol; Standard_Integer i, nbknown, nbfound,index; gp_Pnt pt; Domain->Init(); if (Domain->More()) { all = Standard_True; } else { all = Standard_False; } while (Domain->More()) { TheArc A = Domain->Value(); if (!TheSOBTool::HasBeenSeen(A)) { Func.Set(A); FindVertex(A,Domain,Func,spnt,TolBoundary); TheSOBTool::Bounds(A,PDeb,PFin); if(Precision::IsNegativeInfinite(PDeb) || Precision::IsPositiveInfinite(PFin)) { Standard_Integer NbEchant; ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant); } BoundedArc(A,Domain,PDeb,PFin,Func,spnt,sseg,TolBoundary,TolTangency,Arcsol,RecheckOnRegularity); all = (all && Arcsol); } else { // as it seems we'll never be here, because // TheSOBTool::HasBeenSeen(A) always returns FALSE nbfound = spnt.Length(); // On recupere les points connus nbknown = TheSOBTool::NbPoints(A); for (i=1; i<=nbknown; i++) { TheSOBTool::Value(A,i,pt,tol,prm); if (TheSOBTool::IsVertex(A,i)) { TheVertex vtx; TheSOBTool::Vertex(A,i,vtx); spnt.Append(IntStart_ThePathPoint(pt,tol,vtx,A,prm)); } else { spnt.Append(IntStart_ThePathPoint(pt,tol,A,prm)); } } // On recupere les arcs solutions nbknown = TheSOBTool::NbSegments(A); for (i=1; i<=nbknown; i++) { IntStart_TheSegment newseg; newseg.SetValue(A); if (TheSOBTool::HasFirstPoint(A,i,index)) { newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_True); } if (TheSOBTool::HasLastPoint(A,i,index)) { newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_False); } sseg.Append(newseg); } all = (all& TheSOBTool::IsAllSolution(A)); } Domain->Next(); } done = Standard_True; }