// 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 //================================================================================== // function : IntWalk_PWalking::IntWalk_PWalking // purpose : // estimate of max step : To avoid abrupt changes // during change of isos //================================================================================== void ComputePasInit(Standard_Real *pasuv, Standard_Real Um1,Standard_Real UM1, Standard_Real Vm1,Standard_Real VM1, Standard_Real Um2,Standard_Real UM2, Standard_Real Vm2,Standard_Real VM2, Standard_Real _Um1,Standard_Real _UM1, Standard_Real _Vm1,Standard_Real _VM1, Standard_Real _Um2,Standard_Real _UM2, Standard_Real _Vm2,Standard_Real _VM2, const Handle(Adaptor3d_HSurface)& , const Handle(Adaptor3d_HSurface)& , const Standard_Real Increment) { Standard_Real du1=Abs(UM1-Um1); Standard_Real dv1=Abs(VM1-Vm1); Standard_Real du2=Abs(UM2-Um2); Standard_Real dv2=Abs(VM2-Vm2); Standard_Real _du1=Abs(_UM1-_Um1); Standard_Real _dv1=Abs(_VM1-_Vm1); Standard_Real _du2=Abs(_UM2-_Um2); Standard_Real _dv2=Abs(_VM2-_Vm2); //-- limit the reduction of uv box estimate to 0.01 natural box //-- du1 : On box of Inter //-- _du1 : On parametric space if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1; if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1; if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2; if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2; pasuv[0]=Increment*du1; pasuv[1]=Increment*dv1; pasuv[2]=Increment*du2; pasuv[3]=Increment*dv2; } //======================================================================= //function : IsParallel //purpose : Checks if theLine is parallel of some boundary of given // surface (it is determined by theCheckSurf1 flag). // Parallelism assumes small oscillations (swing is less or // equal than theToler). // Small lines (if first and last parameters in the Surface // are almost equal) are classified as parallel (as same as // any point can be considered as parallel of any line). //======================================================================= static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine, const Standard_Boolean theCheckSurf1, const Standard_Real theToler, Standard_Boolean& theIsUparallel, Standard_Boolean& theIsVparallel) { const Standard_Integer aNbPointsMAX = 23; theIsUparallel = theIsVparallel = Standard_True; Standard_Integer aNbPoints = theLine->NbPoints(); if(aNbPoints > aNbPointsMAX) { aNbPoints = aNbPointsMAX; } else if(aNbPoints < 3) { //Here we cannot estimate parallelism. //Do all same as for small lines return; } Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints; Standard_Real aNPoint = 1.0; Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst(); for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep) { if(aNPoint > aNbPoints) { aNPoint = aNbPoints; } Standard_Real u, v; if(theCheckSurf1) theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v); else theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v); if(u < aUmin) aUmin = u; if(u > aUmax) aUmax = u; if(v < aVmin) aVmin = v; if(v > aVmax) aVmax = v; } theIsVparallel = ((aUmax - aUmin) < theToler); theIsUparallel = ((aVmax - aVmin) < theToler); } //======================================================================= //function : Checking //purpose : Check, if given point is in surface's boundaries. // If "yes" then theFactTol = 0.0, else theFactTol is // equal maximal deviation. //======================================================================= static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, Standard_Real& theU1, Standard_Real& theV1, Standard_Real& theU2, Standard_Real& theV2, Standard_Real& theFactTol) { const Standard_Real aTol = Precision::PConfusion(); const Standard_Real aU1bFirst = theASurf1->FirstUParameter(); const Standard_Real aU1bLast = theASurf1->LastUParameter(); const Standard_Real aU2bFirst = theASurf2->FirstUParameter(); const Standard_Real aU2bLast = theASurf2->LastUParameter(); const Standard_Real aV1bFirst = theASurf1->FirstVParameter(); const Standard_Real aV1bLast = theASurf1->LastVParameter(); const Standard_Real aV2bFirst = theASurf2->FirstVParameter(); const Standard_Real aV2bLast = theASurf2->LastVParameter(); Standard_Boolean isOnOrIn = Standard_True; theFactTol = 0.0; Standard_Real aDelta = aU1bFirst - theU1; if(aDelta > aTol) { theU1 = aU1bFirst; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = theU1 - aU1bLast; if(aDelta > aTol) { theU1 = aU1bLast; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = aV1bFirst - theV1; if(aDelta > aTol) { theV1 = aV1bFirst; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = theV1 - aV1bLast; if(aDelta > aTol) { theV1 = aV1bLast; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = aU2bFirst - theU2; if(aDelta > aTol) { theU2 = aU2bFirst; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = theU2 - aU2bLast; if(aDelta > aTol) { theU2 = aU2bLast; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = aV2bFirst - theV2; if(aDelta > aTol) { theV2 = aV2bFirst; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } aDelta = theV2 - aV2bLast; if(aDelta > aTol) { theV2 = aV2bLast; theFactTol = Max(theFactTol, aDelta); isOnOrIn = Standard_False; } return isOnOrIn; } //================================================================================== // function : IntWalk_PWalking::IntWalk_PWalking // purpose : //================================================================================== IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment ) : done(Standard_True), close(Standard_False), fleche(Deflection), tolconf(Epsilon), sensCheminement(1), myIntersectionOn2S(Caro1,Caro2,TolTangency), STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0), STATIC_PRECEDENT_INFLEXION(0) { Standard_Real KELARG=20.; // pasMax=Increment*0.2; //-- June 25 99 after problems with precision Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1); Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1); UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1); VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1); Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2); Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2); UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2); VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2); ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion()); ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion()); ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion()); ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion()); Standard_Real NEWRESO; Standard_Real MAXVAL; Standard_Real MAXVAL2; // MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1); if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2; NEWRESO = ResoU1 * MAXVAL ; if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; } MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2); if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2; NEWRESO = ResoU2 * MAXVAL ; if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; } MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1); if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2; NEWRESO = ResoV1 * MAXVAL ; if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; } MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2); if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2; NEWRESO = ResoV2 * MAXVAL ; if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; } pasuv[0]=pasMax*Abs(UM1-Um1); pasuv[1]=pasMax*Abs(VM1-Vm1); pasuv[2]=pasMax*Abs(UM2-Um2); pasuv[3]=pasMax*Abs(VM2-Vm2); if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0]; if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1]; if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2]; if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3]; if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0]; } else { Standard_Real t = UM1-Um1; if(tKELARG*pasuv[0])? KELARG*pasuv[0] : t; UM1+=t; Um1-=t; } } if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1]; } else { Standard_Real t = VM1-Vm1; if(tKELARG*pasuv[1])? KELARG*pasuv[1] : t; VM1+=t; Vm1-=t; } } if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2]; } else { Standard_Real t = UM2-Um2; if(tKELARG*pasuv[2])? KELARG*pasuv[2] : t; UM2+=t; Um2-=t; } } if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) { //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3]; } else { Standard_Real t = VM2-Vm2; if(tKELARG*pasuv[3])? KELARG*pasuv[3] : t; VM2+=t; Vm2-=t; } } //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2); for (Standard_Integer i = 0; i<=3;i++) { if(pasuv[i]>10) pasuv[i] = 10; pasInit[i] = pasSav[i] = pasuv[i]; } } //================================================================================== // function : IntWalk_PWalking // purpose : //================================================================================== IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2) : done(Standard_True), close(Standard_False), fleche(Deflection), tolconf(Epsilon), sensCheminement(1), myIntersectionOn2S(Caro1,Caro2,TolTangency), STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0), STATIC_PRECEDENT_INFLEXION(0) { Standard_Real KELARG=20.; // pasMax=Increment*0.2; //-- June 25 99 after problems with precision // Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1); Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1); UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1); VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1); Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2); Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2); UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2); VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2); ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion()); ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion()); ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion()); ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion()); // Standard_Real NEWRESO, MAXVAL, MAXVAL2; // MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1); if(MAXVAL2 > MAXVAL) { MAXVAL = MAXVAL2; } NEWRESO = ResoU1 * MAXVAL ; if(NEWRESO > ResoU1) { ResoU1 = NEWRESO; } // MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2); if(MAXVAL2 > MAXVAL){ MAXVAL = MAXVAL2; } NEWRESO = ResoU2 * MAXVAL ; if(NEWRESO > ResoU2) { ResoU2 = NEWRESO; } // MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1); if(MAXVAL2 > MAXVAL) { MAXVAL = MAXVAL2; } NEWRESO = ResoV1 * MAXVAL ; if(NEWRESO > ResoV1) { ResoV1 = NEWRESO; } // MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2); if(MAXVAL2 > MAXVAL){ MAXVAL = MAXVAL2; } NEWRESO = ResoV2 * MAXVAL ; if(NEWRESO > ResoV2) { ResoV2 = NEWRESO; } // pasuv[0]=pasMax*Abs(UM1-Um1); pasuv[1]=pasMax*Abs(VM1-Vm1); pasuv[2]=pasMax*Abs(UM2-Um2); pasuv[3]=pasMax*Abs(VM2-Vm2); // if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) { UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0]; } else { Standard_Real t = UM1-Um1; if(tKELARG*pasuv[0])? KELARG*pasuv[0] : t; UM1+=t; Um1-=t; } } // if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) { VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1]; } else { Standard_Real t = VM1-Vm1; if(tKELARG*pasuv[1])? KELARG*pasuv[1] : t; VM1+=t; Vm1-=t; } } // if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) { UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2]; } else { Standard_Real t = UM2-Um2; if(tKELARG*pasuv[2])? KELARG*pasuv[2] : t; UM2+=t; Um2-=t; } } if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) { VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3]; } else { Standard_Real t = VM2-Vm2; if(tKELARG*pasuv[3])? KELARG*pasuv[3] : t; VM2+=t; Vm2-=t; } } //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2); for (Standard_Integer i = 0; i<=3;i++) { pasInit[i] = pasSav[i] = pasuv[i]; } if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0]; if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1]; if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2]; if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3]; // TColStd_Array1OfReal Par(1,4); Par(1) = U1; Par(2) = V1; Par(3) = U2; Par(4) = V2; Perform(Par); } //================================================================================== // function : PerformFirstPoint // purpose : //================================================================================== Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep, IntSurf_PntOn2S& FirstPoint) { sensCheminement = 1; close = Standard_False; // Standard_Integer i; TColStd_Array1OfReal Param(1,4); // for (i=1; i<=4; ++i) { Param(i) = ParDep(i); } //-- calculate the first solution point math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function()); // myIntersectionOn2S.Perform(Param,Rsnld); if (!myIntersectionOn2S.IsDone()) { return Standard_False; } if (myIntersectionOn2S.IsEmpty()) { return Standard_False; } FirstPoint = myIntersectionOn2S.Point(); return Standard_True; } //================================================================================== // function : Perform // purpose : //================================================================================== void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep) { Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2); } //================================================================================== // function : Perform // purpose : //================================================================================== void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, const Standard_Real u1min, const Standard_Real v1min, const Standard_Real u2min, const Standard_Real v2min, const Standard_Real u1max, const Standard_Real v1max, const Standard_Real u2max, const Standard_Real v2max) { const Standard_Real aSQDistMax = 1.0e-14; //xf Standard_Integer NbPasOKConseq=0; Standard_Real pasMaxSV[4], aTmp; TColStd_Array1OfReal Param(1,4); IntImp_ConstIsoparametric ChoixIso; //xt // done = Standard_False; // // Caro1 and Caro2 const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1(); const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2(); // const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1); const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1); const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1); const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1); const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2); const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2); const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2); const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2); // ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max, Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax); // if(pasuv[0]<100.0*ResoU1) { pasuv[0]=100.0*ResoU1; } if(pasuv[1]<100.0*ResoV1) { pasuv[1]=100.0*ResoV1; } if(pasuv[2]<100.0*ResoU2) { pasuv[2]=100.0*ResoU2; } if(pasuv[3]<100.0*ResoV2) { pasuv[3]=100.0*ResoV2; } // for (Standard_Integer i=0; i<4; ++i) { if(pasuv[i]>10) { pasuv[i] = 10; } pasInit[i] = pasSav[i] = pasuv[i]; } // line = new IntSurf_LineOn2S (); // for (Standard_Integer i=1; i<=4; ++i) { aTmp=ParDep(i); Param(i)=ParDep(i); } //-- reproduce steps uv connected to surfaces Caro1 and Caro2 //-- pasuv[] and pasSav[] are modified during the marching for(Standard_Integer i = 0; i < 4; ++i) { pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i]; } //-- calculate the first solution point math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function()); // ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld); if (!myIntersectionOn2S.IsDone()) { return; } // if (myIntersectionOn2S.IsEmpty()) { return; } // if(myIntersectionOn2S.IsTangent()) { return; } // Standard_Boolean Arrive, DejaReparti; const Standard_Integer RejectIndexMAX = 250000; Standard_Integer IncKey, RejectIndex; gp_Pnt pf,pl; // DejaReparti = Standard_False; IncKey = 0; RejectIndex = 0; // previousPoint = myIntersectionOn2S.Point(); previoustg = Standard_False; previousd = myIntersectionOn2S.Direction(); previousd1 = myIntersectionOn2S.DirectionOnS1(); previousd2 = myIntersectionOn2S.DirectionOnS2(); indextg = 1; tgdir = previousd; firstd1 = previousd1; firstd2 = previousd2; tgfirst = tglast = Standard_False; choixIsoSav = ChoixIso; //------------------------------------------------------------ //-- Test if the first point of marching corresponds //-- to a point on borders. //-- In this case, DejaReparti is initialized as True //-- pf = previousPoint.Value(); Standard_Boolean bTestFirstPoint = Standard_True; previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4)); AddAPoint(line,previousPoint); // IntWalk_StatusDeflection Status = IntWalk_OK; Standard_Boolean NoTestDeflection = Standard_False; Standard_Real SvParam[4], f; Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0; Standard_Integer LevelOfPointConfondu = 0; Standard_Integer LevelOfIterWithoutAppend = -1; // Arrive = Standard_False; while(!Arrive) //010 { LevelOfIterWithoutAppend++; if(LevelOfIterWithoutAppend>20) { Arrive = Standard_True; if(DejaReparti) { break; } RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); LevelOfIterWithoutAppend = 0; } // // compute f f = 0.; switch (ChoixIso) { case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break; case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break; case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break; case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break; default:break; } // if(f<0.1) { f=0.1; } // previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4)); // //--ofv.begin Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4; // dP1 = sensCheminement * pasuv[0] * previousd1.X() /f; dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f; dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f; // aIncKey=5.*(Standard_Real)IncKey; aEps=1.e-7; if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) { dP1 *= aIncKey; } if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) { dP2 *= aIncKey; } if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) { dP3 *= aIncKey; } if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) { dP4 *= aIncKey; } //--ofv.end // Param(1) += dP1; Param(2) += dP2; Param(3) += dP3; Param(4) += dP4; //========================== SvParam[0]=Param(1); SvParam[1]=Param(2); SvParam[2]=Param(3); SvParam[3]=Param(4); // Standard_Integer aTryNumber = 0; Standard_Real isBadPoint = Standard_False; IntImp_ConstIsoparametric aBestIso = ChoixIso; do { isBadPoint = Standard_False; ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso); if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty()) { Standard_Real aNewPnt[4], anAbsParamDist[4]; myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]); if (aNewPnt[0] < u1min || aNewPnt[0] > u1max || aNewPnt[1] < v1min || aNewPnt[1] > v1max || aNewPnt[2] < u2min || aNewPnt[2] > u2max || aNewPnt[3] < v2min || aNewPnt[3] > v2max) { break; // Out of borders, handle this later. } anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]); anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]); anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]); anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]); if (anAbsParamDist[0] < ResoU1 && anAbsParamDist[1] < ResoV1 && anAbsParamDist[2] < ResoU2 && anAbsParamDist[3] < ResoV2 && Status != IntWalk_PasTropGrand) { isBadPoint = Standard_True; aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4); } } } while (isBadPoint && ++aTryNumber <= 4); // if (!myIntersectionOn2S.IsDone()) { //end of line, division Arrive = Standard_False; Param(1)=SvParam[0]; Param(2)=SvParam[1]; Param(3)=SvParam[2]; Param(4)=SvParam[3]; RepartirOuDiviser(DejaReparti, ChoixIso, Arrive); } else //009 { //== Calculation of exact point from Param(.) is possible if (myIntersectionOn2S.IsEmpty()) { Standard_Real u1,v1,u2,v2; previousPoint.Parameters(u1,v1,u2,v2); // Arrive = Standard_False; if(u1ULast1) { Arrive=Standard_True; } if(u2ULast2) { Arrive=Standard_True; } if(v1VLast1) { Arrive=Standard_True; } if(v2VLast2) { Arrive=Standard_True; } RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); LevelOfEmptyInmyIntersectionOn2S++; // if(LevelOfEmptyInmyIntersectionOn2S>10) { pasuv[0]=pasSav[0]; pasuv[1]=pasSav[1]; pasuv[2]=pasSav[2]; pasuv[3]=pasSav[3]; } } else //008 { //============================================================ //== A point has been found : T E S T D E F L E C T I O N //============================================================ if(NoTestDeflection) { NoTestDeflection = Standard_False; } else { if(--LevelOfEmptyInmyIntersectionOn2S<=0) { LevelOfEmptyInmyIntersectionOn2S=0; if(LevelOfIterWithoutAppend < 10) { Status = TestDeflection(); } else { pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; } } } //============================================================ //== T r a i t e m e n t s u r S t a t u s == //============================================================ if(LevelOfPointConfondu > 5) { Status = IntWalk_ArretSurPoint; LevelOfPointConfondu = 0; } // if(Status==IntWalk_OK) { NbPasOKConseq++; if(NbPasOKConseq >= 5) { NbPasOKConseq=0; Standard_Boolean pastroppetit; Standard_Real t; // do { pastroppetit=Standard_True; // if(pasuv[0]0.1*pasInit[0]) { t=0.1*pasuv[0]; } pasuv[0]+=t; pastroppetit=Standard_False; } if(pasuv[1]0.1*pasInit[1]) { t=0.1*pasuv[1]; } pasuv[1]+=t; pastroppetit=Standard_False; } if(pasuv[2]0.1*pasInit[2]) { t=0.1*pasuv[2]; } pasuv[2]+=t; pastroppetit=Standard_False; } if(pasuv[3]0.1*pasInit[3]) { t=0.1*pasuv[3]; } pasuv[3]+=t; pastroppetit=Standard_False; } if(pastroppetit) { if(pasMax<0.1) { pasMax*=1.1; pasInit[0]*=1.1; pasInit[1]*=1.1; pasInit[2]*=1.1; pasInit[3]*=1.1; } else { pastroppetit=Standard_False; } } } while(pastroppetit); } }//Status==IntWalk_OK else NbPasOKConseq=0; // switch(Status)//007 { case IntWalk_ArretSurPointPrecedent: { Arrive = Standard_False; RepartirOuDiviser(DejaReparti, ChoixIso, Arrive); break; } case IntWalk_PasTropGrand: { Param(1)=SvParam[0]; Param(2)=SvParam[1]; Param(3)=SvParam[2]; Param(4)=SvParam[3]; if(LevelOfIterWithoutAppend > 5) { if(pasSav[0]5) { Standard_Boolean pastroppetit; // do { pastroppetit=Standard_True; if(pasuv[0]= Um1 && u2 >= Um2 && v1 >= Vm1 && v2 >= Vm2) { pointisvalid=Standard_True; } } // if(pointisvalid) { previousPoint = myIntersectionOn2S.Point(); previoustg = myIntersectionOn2S.IsTangent(); if(!previoustg) { previousd = myIntersectionOn2S.Direction(); previousd1 = myIntersectionOn2S.DirectionOnS1(); previousd2 = myIntersectionOn2S.DirectionOnS2(); } //===================================================== //== Check on the previous Point { Standard_Real u1,v1,u2,v2; previousPoint.Parameters(u1,v1,u2,v2); if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && v1 >= Vm1 && v2 >= Vm2) { pl = previousPoint.Value(); if(bTestFirstPoint) { if(pf.SquareDistance(pl) < aSQDistMax) { IncKey++; if(IncKey == 5000) return; else continue; } else { bTestFirstPoint = Standard_False; } } // AddAPoint(line,previousPoint); RejectIndex++; if(RejectIndex >= RejectIndexMAX) { break; } // LevelOfIterWithoutAppend = 0; } } }//pointisvalid //==================================================== if(Status == IntWalk_ArretSurPoint) { RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); } else { if (line->NbPoints() == 2) { pasSav[0] = pasuv[0]; pasSav[1] = pasuv[1]; pasSav[2] = pasuv[2]; pasSav[3] = pasuv[3]; } } }//005 if(!Arrive) else //004 { if(close) { //================= la ligne est fermee =============== AddAPoint(line,line->Value(1)); //ligne fermee LevelOfIterWithoutAppend=0; } else //$$$ { //==================================================== //== Param was not in the limits (was reframed) //==================================================== Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent(); IntImp_ConstIsoparametric SauvChoixIso = ChoixIso; ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); // if(!myIntersectionOn2S.IsEmpty()) //002 { // mutially outpasses in the square or intersection in corner if(TestArret(Standard_True,Param,ChoixIso)) { NbPasOKConseq = -10; ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); if(!myIntersectionOn2S.IsEmpty()) { previousPoint = myIntersectionOn2S.Point(); previoustg = myIntersectionOn2S.IsTangent(); if (!previoustg) { previousd = myIntersectionOn2S.Direction(); previousd1 = myIntersectionOn2S.DirectionOnS1(); previousd2 = myIntersectionOn2S.DirectionOnS2(); } pl = previousPoint.Value(); if(bTestFirstPoint) { if(pf.SquareDistance(pl) < aSQDistMax) { IncKey++; if(IncKey == 5000) return; else continue; } else { bTestFirstPoint = Standard_False; } } // AddAPoint(line,previousPoint); RejectIndex++; if(RejectIndex >= RejectIndexMAX) { break; } // LevelOfIterWithoutAppend=0; RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); } else { //fail framing divides the step Arrive = Standard_False; RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); NoTestDeflection = Standard_True; ChoixIso = SauvChoixIso; } }//if(TestArret()) else { // save the last point // to revert to it if the current point is out of bounds IntSurf_PntOn2S previousPointSave = previousPoint; Standard_Boolean previoustgSave = previoustg; gp_Dir previousdSave = previousd; gp_Dir2d previousd1Save = previousd1; gp_Dir2d previousd2Save = previousd2; previousPoint = myIntersectionOn2S.Point(); previoustg = myIntersectionOn2S.IsTangent(); Arrive = Standard_False; if(!previoustg) { previousd = myIntersectionOn2S.Direction(); previousd1 = myIntersectionOn2S.DirectionOnS1(); previousd2 = myIntersectionOn2S.DirectionOnS2(); } //======================================== //== Check on PreviousPoint @@ { Standard_Real u1,v1,u2,v2; previousPoint.Parameters(u1,v1,u2,v2); //To save initial 2d points gp_Pnt2d ParamPntOnS1(Param(1), Param(2)); gp_Pnt2d ParamPntOnS2(Param(3), Param(4)); /////////////////////////// Param(1) = u1; Param(2) = v1; Param(3) = u2; Param(4) = v2; // //xf Standard_Boolean bFlag1, bFlag2; Standard_Real aTol2D=1.e-11; // bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D; bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D; if (bFlag1 && bFlag2) { /* if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && v1 >= Vm1 && v2 >= Vm2) { */ //xt pl = previousPoint.Value(); if(bTestFirstPoint) { if(pf.SquareDistance(pl) < aSQDistMax) { IncKey++; if(IncKey == 5000) return; else continue; } else { bTestFirstPoint = Standard_False; } } //To avoid walking around the same point //in the tangent zone near a border if (previoustg) { Standard_Real prevU1, prevV1, prevU2, prevV2; previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2); gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2); gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2); gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1); gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1); gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2); gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2); Standard_Real MaxAngle = 3*M_PI/4; if (Abs(PrevToParamOnS1.Angle(PrevToCurOnS1)) > MaxAngle && Abs(PrevToParamOnS2.Angle(PrevToCurOnS2)) > MaxAngle) { Arrive = Standard_True; break; } } //////////////////////////////////////// AddAPoint(line,previousPoint); RejectIndex++; if(RejectIndex >= RejectIndexMAX) { break; } // LevelOfIterWithoutAppend=0; Arrive = Standard_True; } else { // revert to the last correctly calculated point previousPoint = previousPointSave; previoustg = previoustgSave; previousd = previousdSave; previousd1 = previousd1Save; previousd2 = previousd2Save; } } // Standard_Boolean wasExtended = Standard_False; if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) { if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) { wasExtended = Standard_True; Arrive = Standard_False; ChoixIso = SauvChoixIso; } } RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); if(Arrive && myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() && myIntersectionOn2S.IsTangent() && bPrevNotTangent && !wasExtended) { if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) { wasExtended = Standard_True; Arrive = Standard_False; ChoixIso = SauvChoixIso; } } }//else !TestArret() $ }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty()) else { //echec framing on border; division of step Arrive = Standard_False; NoTestDeflection = Standard_True; RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); } }//$$$ end framing on border (!close) }//004 fin TestArret return Arrive = True } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint } //007 switch(Status) } //008 end processing point (TEST DEFLECTION) } //009 end processing line (else if myIntersectionOn2S.IsDone()) } //010 end if first departure point allows marching while (!Arrive) done = Standard_True; } // =========================================================================================================== // function: ExtendLineInCommonZone // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso. // Returns Standard_True if the line was extended through tangent zone and the last computed point // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False. // =========================================================================================================== Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso, const Standard_Boolean theDirectionFlag) { Standard_Boolean bOutOfTangentZone = Standard_False; Standard_Boolean bStop = !myIntersectionOn2S.IsTangent(); Standard_Integer dIncKey = 1; TColStd_Array1OfReal Param(1,4); IntWalk_StatusDeflection Status = IntWalk_OK; Standard_Integer nbIterWithoutAppend = 0; Standard_Integer nbEqualPoints = 0; Standard_Integer parit = 0; Standard_Integer uvit = 0; IntSurf_SequenceOfPntOn2S aSeqOfNewPoint; while (!bStop) { nbIterWithoutAppend++; if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) { #ifdef OCCT_DEBUG cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl; #endif bStop = Standard_True; break; } Standard_Real f = 0.; switch (theChoixIso) { case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break; case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break; case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break; case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break; } if(f<0.1) f=0.1; previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4)); Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f; Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f; Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f; if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey); if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey); if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey); if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey); Param(1) += dP1; Param(2) += dP2; Param(3) += dP3; Param(4) += dP4; Standard_Real SvParam[4]; IntImp_ConstIsoparametric ChoixIso = theChoixIso; for(parit = 0; parit < 4; parit++) { SvParam[parit] = Param(parit+1); } math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function()); ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso); if (!myIntersectionOn2S.IsDone()) { return bOutOfTangentZone; } else { if (myIntersectionOn2S.IsEmpty()) { return bOutOfTangentZone; } Status = TestDeflection(); if(Status == IntWalk_OK) { for(uvit = 0; uvit < 4; uvit++) { if(pasuv[uvit] < pasInit[uvit]) { pasuv[uvit] = pasInit[uvit]; } } } switch(Status) { case IntWalk_ArretSurPointPrecedent: { bStop = Standard_True; bOutOfTangentZone = !myIntersectionOn2S.IsTangent(); break; } case IntWalk_PasTropGrand: { for(parit = 0; parit < 4; parit++) { Param(parit+1) = SvParam[parit]; } Standard_Boolean bDecrease = Standard_False; for(uvit = 0; uvit < 4; uvit++) { if(pasSav[uvit] < pasInit[uvit]) { pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1; bDecrease = Standard_True; } } if(bDecrease) nbIterWithoutAppend--; break; } case IntWalk_PointConfondu: { for(uvit = 0; uvit < 4; uvit++) { if(pasuv[uvit] < pasInit[uvit]) { pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1; } } break; } case IntWalk_OK: case IntWalk_ArretSurPoint: { // bStop = TestArret(theDirectionFlag, Param, ChoixIso); // // if(!bStop) { Standard_Real u11,v11,u12,v12; myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); Standard_Real u21,v21,u22,v22; previousPoint.Parameters(u21,v21,u22,v22); if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) || ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) { nbEqualPoints++; } else { nbEqualPoints = 0; } } // bStop = bStop || !myIntersectionOn2S.IsTangent(); bOutOfTangentZone = !myIntersectionOn2S.IsTangent(); if(!bStop) { Standard_Boolean pointisvalid = Standard_False; Standard_Real u1,v1,u2,v2; myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && v1 >= Vm1 && v2 >= Vm2) pointisvalid = Standard_True; if(pointisvalid) { previousPoint = myIntersectionOn2S.Point(); previoustg = myIntersectionOn2S.IsTangent(); if(!previoustg) { previousd = myIntersectionOn2S.Direction(); previousd1 = myIntersectionOn2S.DirectionOnS1(); previousd2 = myIntersectionOn2S.DirectionOnS2(); } Standard_Boolean bAddPoint = Standard_True; if(line->NbPoints() >= 1) { gp_Pnt pf = line->Value(1).Value(); gp_Pnt pl = previousPoint.Value(); if(pf.Distance(pl) < Precision::Confusion()) { dIncKey++; if(dIncKey == 5000) return bOutOfTangentZone; else bAddPoint = Standard_False; } } if(bAddPoint) { aSeqOfNewPoint.Append(previousPoint); nbIterWithoutAppend = 0; } } if (line->NbPoints() == 2) { for(uvit = 0; uvit < 4; uvit++) { pasSav[uvit] = pasuv[uvit]; } } if ( !pointisvalid ) { // decrease step if out of bounds // otherwise the same calculations will be // repeated several times if ( ( u1 > UM1 ) || ( u1 < Um1 ) ) pasuv[0] *= 0.5; if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) pasuv[1] *= 0.5; if ( ( u2 > UM2 ) || ( u2 < Um2 ) ) pasuv[2] *= 0.5; if ( ( v2 > VM2 ) || ( v2 < Vm2 ) ) pasuv[3] *= 0.5; } } // end if(!bStop) else { //if(bStop) if(close && (line->NbPoints() >= 1)) { if(!bOutOfTangentZone) { aSeqOfNewPoint.Append(line->Value(1)); // line end } nbIterWithoutAppend = 0; } else { ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso); if(myIntersectionOn2S.IsEmpty()) { bStop = !myIntersectionOn2S.IsTangent(); bOutOfTangentZone = !myIntersectionOn2S.IsTangent(); } else { Standard_Boolean bAddPoint = Standard_True; Standard_Boolean pointisvalid = Standard_False; previousPoint = myIntersectionOn2S.Point(); Standard_Real u1,v1,u2,v2; previousPoint.Parameters(u1,v1,u2,v2); if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && v1 >= Vm1 && v2 >= Vm2) pointisvalid = Standard_True; if(pointisvalid) { if(line->NbPoints() >= 1) { gp_Pnt pf = line->Value(1).Value(); gp_Pnt pl = previousPoint.Value(); if(pf.Distance(pl) < Precision::Confusion()) { dIncKey++; if(dIncKey == 5000) return bOutOfTangentZone; else bAddPoint = Standard_False; } } if(bAddPoint && !bOutOfTangentZone) { aSeqOfNewPoint.Append(previousPoint); nbIterWithoutAppend = 0; } } } } } break; } default: { break; } } } } Standard_Boolean bExtendLine = Standard_False; Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; Standard_Integer pit = 0; for(pit = 0; !bExtendLine && (pit < 2); pit++) { if(pit == 0) previousPoint.Parameters(u1,v1,u2,v2); else { if(aSeqOfNewPoint.Length() > 0) aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); else break; } if(((u1 - Um1) < ResoU1) || ((UM1 - u1) < ResoU1) || ((u2 - Um2) < ResoU2) || ((UM2 - u2) < ResoU2) || ((v1 - Vm1) < ResoV1) || ((VM1 - v1) < ResoV1) || ((v2 - Vm2) < ResoV2) || ((VM2 - v2) < ResoV2)) bExtendLine = Standard_True; } if(!bExtendLine) { // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) { if(Status == IntWalk_OK) { bExtendLine = Standard_True; if(aSeqOfNewPoint.Length() > 1) { TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3); Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2; aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1), LastParams.ChangeValue(2), LastParams.ChangeValue(3)); Standard_Integer indexofiso = 0; if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0; if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1; if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2; if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3; Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2; gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)), gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1))); gp_Dir2d anIsoDir(0, 1); if((indexofiso == 1) || (indexofiso == 3)) anIsoDir = gp_Dir2d(1, 0); if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) { Standard_Real piquota = M_PI*0.25; if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) { Standard_Integer ii = 1, nextii = 2; gp_Vec2d d1(0, 0); Standard_Real asqresol = gp::Resolution(); asqresol *= asqresol; do { aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1), LastParams.ChangeValue(2), LastParams.ChangeValue(3)); d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)), gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1))); ii++; } while((d1.SquareMagnitude() < asqresol) && (ii < aSeqOfNewPoint.Length())); nextii = ii; while(nextii < aSeqOfNewPoint.Length()) { gp_Vec2d nextd1(0, 0); Standard_Integer jj = nextii; do { aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1), LastParams.ChangeValue(2), LastParams.ChangeValue(3)); nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)), gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1))); jj++; } while((nextd1.SquareMagnitude() < asqresol) && (jj < aSeqOfNewPoint.Length())); nextii = jj; if(fabs(d1.Angle(nextd1)) > piquota) { bExtendLine = Standard_False; break; } d1 = nextd1; } } // end if(fabs(aTangentZoneDir.Angle(anIsoDir) } } } } if(!bExtendLine) { return Standard_False; } Standard_Integer i = 0; for(i = 1; i <= aSeqOfNewPoint.Length(); i++) { AddAPoint(line, aSeqOfNewPoint.Value(i)); } return bOutOfTangentZone; } //======================================================================= //function : DistanceMinimizeByGradient //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, Standard_Real& theU1, Standard_Real& theV1, Standard_Real& theU2, Standard_Real& theV2, const Standard_Real theStep0U1V1, const Standard_Real theStep0U2V2) { const Standard_Integer aNbIterMAX = 60; const Standard_Real aTol = 1.0e-14; Handle(Geom_Surface) aS1, aS2; switch(theASurf1->GetType()) { case GeomAbs_BezierSurface: aS1 = theASurf1->Surface().Bezier(); break; case GeomAbs_BSplineSurface: aS1 = theASurf1->Surface().BSpline(); break; default: return Standard_True; } switch(theASurf2->GetType()) { case GeomAbs_BezierSurface: aS2 = theASurf2->Surface().Bezier(); break; case GeomAbs_BSplineSurface: aS2 = theASurf2->Surface().BSpline(); break; default: return Standard_True; } Standard_Boolean aStatus = Standard_False; gp_Pnt aP1, aP2; gp_Vec aD1u, aD1v, aD2U, aD2V; aS1->D1(theU1, theV1, aP1, aD1u, aD1v); aS2->D1(theU2, theV2, aP2, aD2U, aD2V); Standard_Real aSQDistPrev = aP1.SquareDistance(aP2); gp_Vec aP12(aP1, aP2); Standard_Real aGradFu(-aP12.Dot(aD1u)); Standard_Real aGradFv(-aP12.Dot(aD1v)); Standard_Real aGradFU( aP12.Dot(aD2U)); Standard_Real aGradFV( aP12.Dot(aD2V)); Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2; Standard_Boolean flRepeat = Standard_True; Standard_Integer aNbIter = aNbIterMAX; while(flRepeat) { Standard_Real anAdd = aGradFu*aSTEPuv; Standard_Real aPARu = (anAdd >= 0.0)? (theU1 - Max(anAdd, Epsilon(theU1))) : (theU1 + Max(-anAdd, Epsilon(theU1))); anAdd = aGradFv*aSTEPuv; Standard_Real aPARv = (anAdd >= 0.0)? (theV1 - Max(anAdd, Epsilon(theV1))) : (theV1 + Max(-anAdd, Epsilon(theV1))); anAdd = aGradFU*aStepUV; Standard_Real aParU = (anAdd >= 0.0)? (theU2 - Max(anAdd, Epsilon(theU2))) : (theU2 + Max(-anAdd, Epsilon(theU2))); anAdd = aGradFV*aStepUV; Standard_Real aParV = (anAdd >= 0.0)? (theV2 - Max(anAdd, Epsilon(theV2))) : (theV2 + Max(-anAdd, Epsilon(theV2))); gp_Pnt aPt1, aPt2; aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v); aS2->D1(aParU, aParV, aPt2, aD2U, aD2V); Standard_Real aSQDist = aPt1.SquareDistance(aPt2); if(aSQDist < aSQDistPrev) { aSQDistPrev = aSQDist; theU1 = aPARu; theV1 = aPARv; theU2 = aParU; theV2 = aParV; aStatus = aSQDistPrev < aTol; aSTEPuv *= 1.2; aStepUV *= 1.2; } else { if(--aNbIter < 0) { flRepeat = Standard_False; } else { aS1->D1(theU1, theV1, aPt1, aD1u, aD1v); aS2->D1(theU2, theV2, aPt2, aD2U, aD2V); gp_Vec aP12(aPt1, aPt2); aGradFu = -aP12.Dot(aD1u); aGradFv = -aP12.Dot(aD1v); aGradFU = aP12.Dot(aD2U); aGradFV = aP12.Dot(aD2V); aSTEPuv = theStep0U1V1; aStepUV = theStep0U2V2; } } } return aStatus; } //======================================================================= //function : DistanceMinimizeByExtrema //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf, const gp_Pnt& theP0, Standard_Real& theU0, Standard_Real& theV0, const Standard_Real theStep0U, const Standard_Real theStep0V) { const Standard_Real aTol = 1.0e-14; gp_Pnt aPS; gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp; Standard_Real aSQDistPrev = RealLast(); Standard_Real aU = theU0, aV = theV0; Standard_Integer aNbIter = 10; do { theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp); gp_Vec aVec(theP0, aPS); Standard_Real aSQDist = aVec.SquareMagnitude(); if(aSQDist >= aSQDistPrev) break; aSQDistPrev = aSQDist; theU0 = aU; theV0 = aV; aNbIter--; if(aSQDistPrev < aTol) break; //Functions const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec); //Derivatives const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su), aDf1v = aD2Su.Dot(aD1Sv), aDf2u = aDf1v, aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv); const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u; aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet; aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet; } while(aNbIter > 0); return (aSQDistPrev < aTol); } //======================================================================= //function : SeekPointOnBoundary //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Real theU1, const Standard_Real theV1, const Standard_Real theU2, const Standard_Real theV2, const Standard_Boolean isTheFirst) { const Standard_Real aTol = 1.0e-14; Standard_Boolean isOK = Standard_False; Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2; Standard_Boolean flFinish = Standard_False; Standard_Integer aNbIter = 20; while(!flFinish) { flFinish = Standard_False; Standard_Boolean aStatus = Standard_False; do { aNbIter--; aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec); if(aStatus) { break; } aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec); if(aStatus) { break; } aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec); if(aStatus) { break; } } while(!aStatus && (aNbIter > 0)); if(aStatus) { const Standard_Real aTolMax = 1.0e-8; Standard_Real aTolF = 0.0; Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec; flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF); if(aTolF <= aTolMax) { gp_Pnt aP1 = theASurf1->Value(u1, v1), aP2 = theASurf2->Value(u2, v2); gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ())); const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1), aSQDist2 = aPInt.SquareDistance(aP2); if((aSQDist1 < aTol) && (aSQDist2 < aTol)) { IntSurf_PntOn2S anIP; anIP.SetValue(aPInt, u1, v1, u2, v2); if(isTheFirst) line->InsertBefore(1,anIP); else line->Add(anIP); isOK = Standard_True; } } } else { break; } if(aNbIter < 0) break; } return isOK; } //======================================================================= //function : PutToBoundary //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2) { const Standard_Real aTolMin = Precision::Confusion(); Standard_Boolean hasBeenAdded = Standard_False; const Standard_Real aU1bFirst = theASurf1->FirstUParameter(); const Standard_Real aU1bLast = theASurf1->LastUParameter(); const Standard_Real aU2bFirst = theASurf2->FirstUParameter(); const Standard_Real aU2bLast = theASurf2->LastUParameter(); const Standard_Real aV1bFirst = theASurf1->FirstVParameter(); const Standard_Real aV1bLast = theASurf1->LastVParameter(); const Standard_Real aV2bFirst = theASurf2->FirstVParameter(); const Standard_Real aV2bLast = theASurf2->LastVParameter(); Standard_Real aTol = 1.0; aTol = Min(aTol, aU1bLast - aU1bFirst); aTol = Min(aTol, aU2bLast - aU2bFirst); aTol = Min(aTol, aV1bLast - aV1bFirst); aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3; if(aTol <= 2.0*aTolMin) return hasBeenAdded; Standard_Boolean isNeedAdding = Standard_False; Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False; Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False; IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel); IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel); const Standard_Integer aNbPnts = line->NbPoints(); Standard_Real u1, v1, u2, v2; line->Value(1).Parameters(u1, v1, u2, v2); Standard_Real aDelta = 0.0; if(!isV1parallel) { aDelta = u1 - aU1bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { u1 = aU1bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aU1bLast - u1; if((aTolMin < aDelta) && (aDelta < aTol)) { u1 = aU1bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isV2parallel) { aDelta = u2 - aU2bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { u2 = aU2bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aU2bLast - u2; if((aTolMin < aDelta) && (aDelta < aTol)) { u2 = aU2bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isU1parallel) { aDelta = v1 - aV1bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { v1 = aV1bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aV1bLast - v1; if((aTolMin < aDelta) && (aDelta < aTol)) { v1 = aV1bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isU2parallel) { aDelta = v2 - aV2bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { v2 = aV2bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aV2bLast - v2; if((aTolMin < aDelta) && (aDelta < aTol)) { v2 = aV2bLast + aDelta; isNeedAdding = Standard_True; } } } if(isNeedAdding) { hasBeenAdded = SeekPointOnBoundary(theASurf1, theASurf2, u1, v1, u2, v2, Standard_True); } isNeedAdding = Standard_False; line->Value(aNbPnts).Parameters(u1, v1, u2, v2); if(!isV1parallel) { aDelta = u1 - aU1bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { u1 = aU1bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aU1bLast - u1; if((aTolMin < aDelta) && (aDelta < aTol)) { u1 = aU1bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isV2parallel) { aDelta = u2 - aU2bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { u2 = aU2bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aU2bLast - u2; if((aTolMin < aDelta) && (aDelta < aTol)) { u2 = aU2bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isU1parallel) { aDelta = v1 - aV1bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { v1 = aV1bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aV1bLast - v1; if((aTolMin < aDelta) && (aDelta < aTol)) { v1 = aV1bLast + aDelta; isNeedAdding = Standard_True; } } } if(!isU2parallel) { aDelta = v2 - aV2bFirst; if((aTolMin < aDelta) && (aDelta < aTol)) { v2 = aV2bFirst - aDelta; isNeedAdding = Standard_True; } else { aDelta = aV2bLast - v2; if((aTolMin < aDelta) && (aDelta < aTol)) { v2 = aV2bLast + aDelta; isNeedAdding = Standard_True; } } } if(isNeedAdding) { hasBeenAdded = SeekPointOnBoundary(theASurf1, theASurf2, u1, v1, u2, v2, Standard_False); } return hasBeenAdded; } //======================================================================= //function : SeekAdditionalPoints //purpose : //======================================================================= Standard_Boolean IntWalk_PWalking:: SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Integer theMinNbPoints) { const Standard_Real aTol = 1.0e-14; Standard_Integer aNbPoints = line->NbPoints(); if(aNbPoints > theMinNbPoints) return Standard_True; const Standard_Real aU1bFirst = theASurf1->FirstUParameter(); const Standard_Real aU1bLast = theASurf1->LastUParameter(); const Standard_Real aU2bFirst = theASurf2->FirstUParameter(); const Standard_Real aU2bLast = theASurf2->LastUParameter(); const Standard_Real aV1bFirst = theASurf1->FirstVParameter(); const Standard_Real aV1bLast = theASurf1->LastVParameter(); const Standard_Real aV2bFirst = theASurf2->FirstVParameter(); const Standard_Real aV2bLast = theASurf2->LastVParameter(); Standard_Boolean isPrecise = Standard_False; Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0; Standard_Integer aNbPointsPrev = 0; while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev)) { aNbPointsPrev = aNbPoints; for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1) { Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces lp = fp+1; line->Value(fp).Parameters(U1f, V1f, U2f, V2f); line->Value(lp).Parameters(U1l, V1l, U2l, V2l); U1prec = 0.5*(U1f+U1l); if(U1prec < aU1bFirst) U1prec = aU1bFirst; if(U1prec > aU1bLast) U1prec = aU1bLast; V1prec = 0.5*(V1f+V1l); if(V1prec < aV1bFirst) V1prec = aV1bFirst; if(V1prec > aV1bLast) V1prec = aV1bLast; U2prec = 0.5*(U2f+U2l); if(U2prec < aU2bFirst) U2prec = aU2bFirst; if(U2prec > aU2bLast) U2prec = aU2bLast; V2prec = 0.5*(V2f+V2l); if(V2prec < aV2bFirst) V2prec = aV2bFirst; if(V2prec > aV2bLast) V2prec = aV2bLast; Standard_Boolean aStatus = Standard_False; Standard_Integer aNbIter = 5; do { aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec); if(aStatus) { break; } aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec); if(aStatus) { break; } aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec); if(aStatus) { break; } } while(!aStatus && (--aNbIter > 0)); if(aStatus) { gp_Pnt aP1 = theASurf1->Value(U1prec, V1prec), aP2 = theASurf2->Value(U2prec, V2prec); gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ())); const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1), aSQDist2 = aPInt.SquareDistance(aP2); if((aSQDist1 < aTol) && (aSQDist2 < aTol)) { IntSurf_PntOn2S anIP; anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec); line->InsertBefore(lp, anIP); isPrecise = Standard_True; if(++aNbPoints >= theMinNbPoints) break; } else { lp--; } } } } return isPrecise; } void IntWalk_PWalking:: RepartirOuDiviser(Standard_Boolean& DejaReparti, IntImp_ConstIsoparametric& ChoixIso, Standard_Boolean& Arrive) // at the neighborhood of a point, there is a fail of marching // it is required to divide the steps to try to continue // if the step is too small if we are on border // restart in another direction if it was not done, otherwise stop { // Standard_Integer i; if (Arrive) { //restart in the other direction if (!DejaReparti ) { Arrive = Standard_False; DejaReparti = Standard_True; previousPoint = line->Value(1); previoustg = Standard_False; previousd1 = firstd1; previousd2 = firstd2; previousd = tgdir; indextg = line->NbPoints(); tgdir.Reverse(); line->Reverse(); //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg); sensCheminement = -1; tgfirst = tglast; tglast = Standard_False; ChoixIso = choixIsoSav; #if 0 pasuv[0]=pasSav[0]; pasuv[1]=pasSav[1]; pasuv[2]=pasSav[2]; pasuv[3]=pasSav[3]; #else Standard_Real u1,v1,u2,v2; Standard_Real U1,V1,U2,V2; Standard_Integer nn=line->NbPoints(); if(nn>2) { line->Value(nn).Parameters(u1,v1,u2,v2); line->Value(nn-1).Parameters(U1,V1,U2,V2); pasuv[0]=Abs(u1-U1); pasuv[1]=Abs(v1-V1); pasuv[2]=Abs(u2-U2); pasuv[3]=Abs(v2-V2); } #endif } } else { if ( pasuv[0]*0.5 < ResoU1 && pasuv[1]*0.5 < ResoV1 && pasuv[2]*0.5 < ResoU2 && pasuv[3]*0.5 < ResoV2 ) { if (!previoustg) { tglast = Standard_True; // IS IT ENOUGH ???? } if (!DejaReparti) { //restart in the other direction DejaReparti = Standard_True; previousPoint = line->Value(1); previoustg = Standard_False; previousd1 = firstd1; previousd2 = firstd2; previousd = tgdir; indextg = line->NbPoints(); tgdir.Reverse(); line->Reverse(); //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg); sensCheminement = -1; tgfirst = tglast; tglast = Standard_False; ChoixIso = choixIsoSav; #if 0 pasuv[0]=pasSav[0]; pasuv[1]=pasSav[1]; pasuv[2]=pasSav[2]; pasuv[3]=pasSav[3]; #else Standard_Real u1,v1,u2,v2; Standard_Real U1,V1,U2,V2; Standard_Integer nn=line->NbPoints(); if(nn>2) { line->Value(nn).Parameters(u1,v1,u2,v2); line->Value(nn-1).Parameters(U1,V1,U2,V2); pasuv[0]=Abs(u1-U1); pasuv[1]=Abs(v1-V1); pasuv[2]=Abs(u2-U2); pasuv[3]=Abs(v2-V2); } #endif } else Arrive = Standard_True; } else { pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; } } } namespace { //OCC431(apo): modified -> static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0; static const Standard_Real d = 7.0; } IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection() // test if vector is observed by calculating an increase of vector // or the previous point and its tangent, the new calculated point and its // tangent; it is possible to find a cube passing by the 2 points and having as a // derivative the tangents of the intersection // calculate the point with parameter 0.5 on cube=p1 // calculate the medium point of 2 points of intersection=p2 // if arrow/2<=||p1p2||<= arrow consider that the vector is observed // otherwise adjust the step depending on the ratio ||p1p2||/vector // and the previous step // test if in 2 tangent planes of surfaces there is no too great angle2d // grand : if yes divide the step // test if there is no change of side // { if(line->NbPoints() ==1 ) { STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0; } IntWalk_StatusDeflection Status = IntWalk_OK; Standard_Real FlecheCourante ,Ratio; const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); //================================================================================== //========= S t o p o n p o i n t ============ //================================================================================== if (myIntersectionOn2S.IsTangent()) { return IntWalk_ArretSurPoint; } const gp_Dir& TgCourante = myIntersectionOn2S.Direction(); //================================================================================== //========= R i s k o f i n f l e x i o n p o i n t ============ //================================================================================== if (TgCourante.Dot(previousd)<0) { //------------------------------------------------------------ //-- Risk of inflexion point : Divide the step by 2 //-- Initialize STATIC_PRECEDENT_INFLEXION so that //-- at the next call to return Pas_OK if there is no //-- more risk of the point of inflexion //------------------------------------------------------------ pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; STATIC_PRECEDENT_INFLEXION+=3; if (pasuv[0] < ResoU1 && pasuv[1] 0) { STATIC_PRECEDENT_INFLEXION -- ; return IntWalk_OK; } } //================================================================================== //========= D e t e c t c o n f u s e d P o in t s =========== //================================================================================== Standard_Real Dist = previousPoint.Value(). SquareDistance(CurrentPoint.Value()); if (Dist < tolconf*tolconf ) { pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0])); pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1])); pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2])); pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3])); Status = IntWalk_PointConfondu; } //================================================================================== Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2; Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2; previousPoint.Parameters(Up1,Vp1,Up2,Vp2); CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2); Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1; Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2; AbsDu1 = Abs(Du1); AbsDu2 = Abs(Du2); AbsDv1 = Abs(Dv1); AbsDv2 = Abs(Dv2); //================================================================================= //==== S t e p o f p r o g r e s s i o n (between previous and Current) ======= //================================================================================= if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) { pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2; return(IntWalk_ArretSurPointPrecedent); } //================================================================================== Standard_Real tolArea = 100.0; if (ResoU1 < Precision::PConfusion() || ResoV1 < Precision::PConfusion() || ResoU2 < Precision::PConfusion() || ResoV2 < Precision::PConfusion() ) tolArea = tolArea*2.0; Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1; Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2; Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y(); Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y(); Duv1 = Du1*Du1 + Dv1*Dv1; Duv2 = Du2*Du2 + Dv2*Dv2; ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1; ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2; // //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f // Standard_Real aMinDiv2=Precision::Confusion(); aMinDiv2=aMinDiv2*aMinDiv2; // d1=d; if (Duv1>aMinDiv2) { d1 = Abs(ResoUV1/Duv1); d1 = Min(Sqrt(d1)*tolArea, d); } //d1 = Abs(ResoUV1/Duv1); //d1 = Min(Sqrt(d1)*tolArea,d); //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t tolCoeff1 = Exp(d1); // //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f d2=d; if (Duv2>aMinDiv2) { d2 = Abs(ResoUV2/Duv2); d2 = Min(Sqrt(d2)*tolArea,d); } //d2 = Abs(ResoUV2/Duv2); //d2 = Min(Sqrt(d2)*tolArea,d); //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t tolCoeff2 = Exp(d2); CosRef1 = CosRef2D/tolCoeff1; CosRef2 = CosRef2D/tolCoeff2; // //================================================================================== //== The points are not confused : == //== D e t e c t t h e S t o p a t p r e v i o u s p o i n t == //== N o t T o o G r e a t (angle in space UV) == //== C h a n g e o f s i d e == //================================================================================== if (Status != IntWalk_PointConfondu) { if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) { pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; if (pasuv[0] AngRef1 || Ang2 > AngRef2) { pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; if (pasuv[0]1e-16) { Ratio = 0.5*(fleche/FlecheCourante); } else { Ratio = 10.0; } Standard_Real pasSu1 = pasuv[0]; Standard_Real pasSv1 = pasuv[1]; Standard_Real pasSu2 = pasuv[2]; Standard_Real pasSv2 = pasuv[3]; //-- In case if //-- a point at U+DeltaU is required, .... //-- return a point at U + Epsilon //-- Epsilon << DeltaU. if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1; if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1; if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2; if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2; if(pasuv[0]10.0 ) { Ratio=10.0; } Standard_Real R1,R = pasInit[0]/pasuv[0]; R1= pasInit[1]/pasuv[1]; if(R1 R) Ratio=R; pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]); pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]); pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]); pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]); if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2|| pasuv[1] != pasSv1 || pasuv[3] != pasSv2) { if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) { STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0; return IntWalk_PasTropGrand; } } if(Status == IntWalk_OK) { STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0; //-- Try to increase the step } return Status; } else { //-- CurrentVector > vector*0.5 if (FlecheCourante > fleche) { //-- Current step too Great Ratio = fleche/FlecheCourante; pasuv[0] = Ratio*pasuv[0]; pasuv[1] = Ratio*pasuv[1]; pasuv[2] = Ratio*pasuv[2]; pasuv[3] = Ratio*pasuv[3]; //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) { // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0; return IntWalk_PasTropGrand; //} } else { //-- vector/2 < CurrentVector <= vector Ratio = 0.75 * (fleche / FlecheCourante); } } pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0])); pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1])); pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2])); pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3])); if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0; return Status; } Standard_Boolean IntWalk_PWalking:: TestArret(const Standard_Boolean DejaReparti, TColStd_Array1OfReal& Param, IntImp_ConstIsoparametric& ChoixIso) // // test if the point of intersection set by these parameters remains in the // natural domain of each square. // if the point outpasses reframe to find the best iso (border) // that intersects easiest the other square // otherwise test if closed line is present // { Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4]; Standard_Real DPc,DPb; Standard_Integer i = 0, k = 0; Epsuv[0] = ResoU1; Epsuv[1] = ResoV1; Epsuv[2] = ResoU2; Epsuv[3] = ResoV2; previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]); Standard_Real SolParam[4]; myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]); Standard_Boolean Trouve = Standard_False; Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1; Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2; Standard_Integer im1; for ( i = 1,im1 = 0;i<=4;i++,im1++) { switch(i) { case 1: k=2; break; case 2: k=1; break; case 3: k=4; break; case 4: k=3; break; } if (Param(i) < (Uvd[im1]-Epsuv[im1]) || SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous { Trouve = Standard_True; //-- DPc = Uvp[im1]-Param(i); //-- Previous - Current DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf ParC[im1] = Uvd[im1]; //-- ParamCorrige dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction) dv2 = dv*dv; if(dv2>RealEpsilon()) { //-- Progress at the other Direction ? Duv[im1] = DPc*DPb + dv2; Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2); } else { Duv[im1]=-1.0; //-- If no progress, do not change } //-- the choice of iso } else if (Param(i) > (Uvf[im1] + Epsuv[im1]) || SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current { Trouve = Standard_True; //-- DPc = Param(i)-Uvp[im1]; //-- Current - Previous DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous ParC[im1] = Uvf[im1]; //-- Param Corrige dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction) dv2 = dv*dv; if(dv2>RealEpsilon()) { //-- Progress in other Direction ? Duv[im1] = DPc*DPb + dv2; Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2); } else { Duv[im1]=-1.0; //-- If no progress, do not change } //-- the choice of iso } else { Duv[im1]= -1.; ParC[im1]=Param(i); } } if (Trouve) { //-------------------------------------------------- //-- One of Parameters u1,v1,u2,v2 is outside of -- //-- the natural limits. -- //-- Find the best direction of -- //-- progress and reframe the parameters. -- //-------------------------------------------------- Standard_Real ddv = -1.0; k=-1; for (i=0;i<=3;i++) { Param(i+1) = ParC[i]; if(Duv[i]>ddv) { ddv = Duv[i]; k=i; } } if(k!=-1) { ChoixIso = ChoixRef[k]; } else { if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) { ChoixIso = IntImp_UIsoparametricOnCaro1; } else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) { ChoixIso = IntImp_VIsoparametricOnCaro1; } else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) { ChoixIso = IntImp_UIsoparametricOnCaro2; } else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) { ChoixIso = IntImp_VIsoparametricOnCaro2; } } close = Standard_False; return Standard_True; } else { if (!DejaReparti) { // find if line closed Standard_Real u,v; const IntSurf_PntOn2S& POn2S1=line->Value(1); //On S1 POn2S1.ParametersOnS1(u,v); gp_Pnt2d P1uvS1(u,v); previousPoint.ParametersOnS1(u,v); gp_Pnt2d PrevuvS1(u,v); myIntersectionOn2S.Point().ParametersOnS1(u,v); gp_Pnt2d myIntersuvS1(u,v); Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())* (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0; //On S2 POn2S1.ParametersOnS2(u,v); gp_Pnt2d P1uvS2(u,v); previousPoint.ParametersOnS2(u,v); gp_Pnt2d PrevuvS2(u,v); myIntersectionOn2S.Point().ParametersOnS2(u,v); gp_Pnt2d myIntersuvS2(u,v); Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())* (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0; close = close2dS1 && close2dS2; return close; } else return Standard_False; } }