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 <Adaptor3d_HSurface.hxx>
17 #include <Adaptor3d_HSurfaceTool.hxx>
18 #include <Extrema_GenLocateExtPS.hxx>
19 #include <Geom_Surface.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <IntImp_ComputeTangence.hxx>
24 #include <IntSurf_LineOn2S.hxx>
25 #include <IntSurf_PntOn2S.hxx>
26 #include <IntWalk_PWalking.hxx>
27 #include <IntWalk_StatusDeflection.hxx>
28 #include <math_FunctionSetRoot.hxx>
29 #include <Precision.hxx>
30 #include <Standard_Failure.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <StdFail_NotDone.hxx>
33 #include <TColgp_Array1OfPnt.hxx>
34 #include <TColStd_Array1OfReal.hxx>
36 //==================================================================================
37 // function : IntWalk_PWalking::IntWalk_PWalking
39 // estimate of max step : To avoid abrupt changes
40 // during change of isos
41 //==================================================================================
42 void ComputePasInit(Standard_Real *pasuv,
43 Standard_Real Um1,Standard_Real UM1,
44 Standard_Real Vm1,Standard_Real VM1,
45 Standard_Real Um2,Standard_Real UM2,
46 Standard_Real Vm2,Standard_Real VM2,
47 Standard_Real _Um1,Standard_Real _UM1,
48 Standard_Real _Vm1,Standard_Real _VM1,
49 Standard_Real _Um2,Standard_Real _UM2,
50 Standard_Real _Vm2,Standard_Real _VM2,
51 const Handle(Adaptor3d_HSurface)& Caro1,
52 const Handle(Adaptor3d_HSurface)& Caro2,
53 const Standard_Real Increment,
54 const Standard_Real tolconf)
56 Standard_Real du1=Abs(UM1-Um1);
57 Standard_Real dv1=Abs(VM1-Vm1);
58 Standard_Real du2=Abs(UM2-Um2);
59 Standard_Real dv2=Abs(VM2-Vm2);
61 Standard_Real _du1=Abs(_UM1-_Um1);
62 Standard_Real _dv1=Abs(_VM1-_Vm1);
63 Standard_Real _du2=Abs(_UM2-_Um2);
64 Standard_Real _dv2=Abs(_VM2-_Vm2);
66 //-- limit the reduction of uv box estimate to 0.01 natural box
67 //-- du1 : On box of Inter
68 //-- _du1 : On parametric space
69 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
70 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
71 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
72 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
74 pasuv[0]=Increment*du1;
75 pasuv[1]=Increment*dv1;
76 pasuv[2]=Increment*du2;
77 pasuv[3]=Increment*dv2;
79 Standard_Real ResoU1tol = Adaptor3d_HSurfaceTool::UResolution(Caro1, tolconf);
80 Standard_Real ResoV1tol = Adaptor3d_HSurfaceTool::VResolution(Caro1, tolconf);
81 Standard_Real ResoU2tol = Adaptor3d_HSurfaceTool::UResolution(Caro2, tolconf);
82 Standard_Real ResoV2tol = Adaptor3d_HSurfaceTool::VResolution(Caro2, tolconf);
84 if (pasuv[0] < 2*ResoU1tol)
85 pasuv[0] = 2*ResoU1tol;
86 if (pasuv[1] < 2*ResoV1tol)
87 pasuv[1] = 2*ResoV1tol;
88 if (pasuv[2] < 2*ResoU2tol)
89 pasuv[2] = 2*ResoU2tol;
90 if (pasuv[3] < 2*ResoV2tol)
91 pasuv[3] = 2*ResoV2tol;
94 //=======================================================================
95 //function : IsParallel
96 //purpose : Checks if theLine is parallel of some boundary of given
97 // surface (it is determined by theCheckSurf1 flag).
98 // Parallelism assumes small oscillations (swing is less or
99 // equal than theToler).
100 // Small lines (if first and last parameters in the Surface
101 // are almost equal) are classified as parallel (as same as
102 // any point can be considered as parallel of any line).
103 //=======================================================================
104 static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
105 const Standard_Boolean theCheckSurf1,
106 const Standard_Real theToler,
107 Standard_Boolean& theIsUparallel,
108 Standard_Boolean& theIsVparallel)
110 const Standard_Integer aNbPointsMAX = 23;
112 theIsUparallel = theIsVparallel = Standard_True;
114 Standard_Integer aNbPoints = theLine->NbPoints();
115 if(aNbPoints > aNbPointsMAX)
117 aNbPoints = aNbPointsMAX;
119 else if(aNbPoints < 3)
121 //Here we cannot estimate parallelism.
122 //Do all same as for small lines
126 Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
127 Standard_Real aNPoint = 1.0;
129 Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
130 for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
132 if(aNPoint > aNbPoints)
139 theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
141 theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
156 theIsVparallel = ((aUmax - aUmin) < theToler);
157 theIsUparallel = ((aVmax - aVmin) < theToler);
160 //=======================================================================
161 //function : Checking
162 //purpose : Check, if given point is in surface's boundaries.
163 // If "yes" then theFactTol = 0.0, else theFactTol is
164 // equal maximal deviation.
165 //=======================================================================
166 static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
167 const Handle(Adaptor3d_HSurface)& theASurf2,
168 Standard_Real& theU1,
169 Standard_Real& theV1,
170 Standard_Real& theU2,
171 Standard_Real& theV2,
172 Standard_Real& theFactTol)
174 const Standard_Real aTol = Precision::PConfusion();
175 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
176 const Standard_Real aU1bLast = theASurf1->LastUParameter();
177 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
178 const Standard_Real aU2bLast = theASurf2->LastUParameter();
179 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
180 const Standard_Real aV1bLast = theASurf1->LastVParameter();
181 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
182 const Standard_Real aV2bLast = theASurf2->LastVParameter();
184 Standard_Boolean isOnOrIn = Standard_True;
187 Standard_Real aDelta = aU1bFirst - theU1;
191 theFactTol = Max(theFactTol, aDelta);
192 isOnOrIn = Standard_False;
195 aDelta = theU1 - aU1bLast;
199 theFactTol = Max(theFactTol, aDelta);
200 isOnOrIn = Standard_False;
203 aDelta = aV1bFirst - theV1;
207 theFactTol = Max(theFactTol, aDelta);
208 isOnOrIn = Standard_False;
211 aDelta = theV1 - aV1bLast;
215 theFactTol = Max(theFactTol, aDelta);
216 isOnOrIn = Standard_False;
219 aDelta = aU2bFirst - theU2;
223 theFactTol = Max(theFactTol, aDelta);
224 isOnOrIn = Standard_False;
227 aDelta = theU2 - aU2bLast;
231 theFactTol = Max(theFactTol, aDelta);
232 isOnOrIn = Standard_False;
235 aDelta = aV2bFirst - theV2;
239 theFactTol = Max(theFactTol, aDelta);
240 isOnOrIn = Standard_False;
243 aDelta = theV2 - aV2bLast;
247 theFactTol = Max(theFactTol, aDelta);
248 isOnOrIn = Standard_False;
254 //==================================================================================
255 // function : IntWalk_PWalking::IntWalk_PWalking
257 //==================================================================================
258 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
259 const Handle(Adaptor3d_HSurface)& Caro2,
260 const Standard_Real TolTangency,
261 const Standard_Real Epsilon,
262 const Standard_Real Deflection,
263 const Standard_Real Increment )
267 close(Standard_False),
271 myIntersectionOn2S(Caro1,Caro2,TolTangency),
272 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
273 STATIC_PRECEDENT_INFLEXION(0)
275 Standard_Real KELARG=20.;
277 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
278 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
279 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
280 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
281 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
283 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
284 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
285 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
286 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
288 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
289 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
291 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
292 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
294 Standard_Real NEWRESO;
295 Standard_Real MAXVAL;
296 Standard_Real MAXVAL2;
298 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
299 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
300 NEWRESO = ResoU1 * MAXVAL ;
301 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
304 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
305 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
306 NEWRESO = ResoU2 * MAXVAL ;
307 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
310 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
311 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
312 NEWRESO = ResoV1 * MAXVAL ;
313 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
316 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
317 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
318 NEWRESO = ResoV2 * MAXVAL ;
319 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
321 pasuv[0]=pasMax*Abs(UM1-Um1);
322 pasuv[1]=pasMax*Abs(VM1-Vm1);
323 pasuv[2]=pasMax*Abs(UM2-Um2);
324 pasuv[3]=pasMax*Abs(VM2-Vm2);
326 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
327 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
328 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
329 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
332 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
333 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
336 Standard_Real t = UM1-Um1;
337 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
338 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
339 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
344 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
345 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
348 Standard_Real t = VM1-Vm1;
349 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
350 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
351 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
356 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
357 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
360 Standard_Real t = UM2-Um2;
361 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
362 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
363 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
368 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
369 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
372 Standard_Real t = VM2-Vm2;
373 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
374 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
375 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
380 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
382 for (Standard_Integer i = 0; i<=3;i++) {
385 pasInit[i] = pasSav[i] = pasuv[i];
390 //==================================================================================
391 // function : IntWalk_PWalking
393 //==================================================================================
394 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
395 const Handle(Adaptor3d_HSurface)& Caro2,
396 const Standard_Real TolTangency,
397 const Standard_Real Epsilon,
398 const Standard_Real Deflection,
399 const Standard_Real Increment,
400 const Standard_Real U1,
401 const Standard_Real V1,
402 const Standard_Real U2,
403 const Standard_Real V2)
407 close(Standard_False),
411 myIntersectionOn2S(Caro1,Caro2,TolTangency),
412 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
413 STATIC_PRECEDENT_INFLEXION(0)
415 Standard_Real KELARG=20.;
417 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
419 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
420 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
421 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
422 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
424 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
425 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
426 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
427 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
429 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
430 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
432 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
433 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
435 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
439 if(MAXVAL2 > MAXVAL) {
442 NEWRESO = ResoU1 * MAXVAL ;
443 if(NEWRESO > ResoU1) {
449 if(MAXVAL2 > MAXVAL){
452 NEWRESO = ResoU2 * MAXVAL ;
453 if(NEWRESO > ResoU2) {
459 if(MAXVAL2 > MAXVAL) {
462 NEWRESO = ResoV1 * MAXVAL ;
463 if(NEWRESO > ResoV1) {
469 if(MAXVAL2 > MAXVAL){
472 NEWRESO = ResoV2 * MAXVAL ;
473 if(NEWRESO > ResoV2) {
477 pasuv[0]=pasMax*Abs(UM1-Um1);
478 pasuv[1]=pasMax*Abs(VM1-Vm1);
479 pasuv[2]=pasMax*Abs(UM2-Um2);
480 pasuv[3]=pasMax*Abs(VM2-Vm2);
482 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
483 UM1+=KELARG*pasuv[0];
484 Um1-=KELARG*pasuv[0];
487 Standard_Real t = UM1-Um1;
488 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
489 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
490 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
496 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
497 VM1+=KELARG*pasuv[1];
498 Vm1-=KELARG*pasuv[1];
501 Standard_Real t = VM1-Vm1;
502 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
503 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
504 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
509 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
510 UM2+=KELARG*pasuv[2];
511 Um2-=KELARG*pasuv[2];
514 Standard_Real t = UM2-Um2;
515 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
516 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
517 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
523 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
524 VM2+=KELARG*pasuv[3];
525 Vm2-=KELARG*pasuv[3];
528 Standard_Real t = VM2-Vm2;
529 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
530 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
531 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
536 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
538 for (Standard_Integer i = 0; i<=3;i++) {
539 pasInit[i] = pasSav[i] = pasuv[i];
542 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
543 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
544 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
545 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
547 TColStd_Array1OfReal Par(1,4);
555 //==================================================================================
556 // function : PerformFirstPoint
558 //==================================================================================
559 Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
560 IntSurf_PntOn2S& FirstPoint)
563 close = Standard_False;
566 TColStd_Array1OfReal Param(1,4);
568 for (i=1; i<=4; ++i) {
569 Param(i) = ParDep(i);
571 //-- calculate the first solution point
572 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
574 myIntersectionOn2S.Perform(Param,Rsnld);
575 if (!myIntersectionOn2S.IsDone()) {
576 return Standard_False;
579 if (myIntersectionOn2S.IsEmpty()) {
580 return Standard_False;
583 FirstPoint = myIntersectionOn2S.Point();
584 return Standard_True;
586 //==================================================================================
587 // function : Perform
589 //==================================================================================
590 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
592 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
595 //=======================================================================
596 //function : SQDistPointSurface
597 //purpose : Returns square distance between thePnt and theSurf.
598 // (theU0, theV0) is initial point for extrema
599 //=======================================================================
600 static Standard_Real SQDistPointSurface(const gp_Pnt &thePnt,
601 const Adaptor3d_Surface& theSurf,
602 const Standard_Real theU0,
603 const Standard_Real theV0)
605 const Extrema_GenLocateExtPS aExtPS(thePnt, theSurf, theU0, theV0,
606 Precision::PConfusion(), Precision::PConfusion());
610 return aExtPS.SquareDistance();
613 //==================================================================================
614 // function : IsTangentExtCheck
615 // purpose : Additional check if the surfaces are tangent.
616 // Checks if any point in one surface lie in another surface
617 // (with given tolerance)
618 //==================================================================================
619 static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theSurf1,
620 const Handle(Adaptor3d_HSurface)& theSurf2,
621 const Standard_Real theU10,
622 const Standard_Real theV10,
623 const Standard_Real theU20,
624 const Standard_Real theV20,
625 const Standard_Real theArrStep[])
629 gp_Vec aDu1, aDv1, aDu2, aDv2;
630 theSurf1->D1(theU10, theV10, aPt, aDu1, aDv1);
631 theSurf2->D1(theU20, theV20, aPt, aDu2, aDv2);
633 const gp_Vec aN1(aDu1.Crossed(aDv1)),
634 aN2(aDu2.Crossed(aDv2));
635 const Standard_Real aDP = aN1.Dot(aN2),
636 aSQ1 = aN1.SquareMagnitude(),
637 aSQ2 = aN2.SquareMagnitude();
639 if((aSQ1 < RealSmall()) || (aSQ2 < RealSmall()))
640 return Standard_True; //Tangent
642 if(aDP*aDP < 0.9998*aSQ1*aSQ2)
643 {//cos(ang N1<->N2) < 0.9999
644 return Standard_False; //Not tangent
648 const Standard_Real aSQToler = 4.0e-14;
649 const Standard_Integer aNbItems = 4;
650 const Standard_Real aParUS1[aNbItems] = { theU10 + theArrStep[0],
651 theU10 - theArrStep[0],
653 const Standard_Real aParVS1[aNbItems] = { theV10, theV10,
654 theV10 + theArrStep[1],
655 theV10 - theArrStep[1]};
656 const Standard_Real aParUS2[aNbItems] = { theU20 + theArrStep[2],
657 theU20 - theArrStep[2],
659 const Standard_Real aParVS2[aNbItems] = { theV20, theV20,
660 theV20 + theArrStep[3],
661 theV20 - theArrStep[3]};
663 for(Standard_Integer i = 0; i < aNbItems; i++)
665 gp_Pnt aP(theSurf1->Value(aParUS1[i], aParVS1[i]));
666 const Standard_Real aSqDist = SQDistPointSurface(aP, theSurf2->Surface(), theU20, theV20);
667 if(aSqDist > aSQToler)
668 return Standard_False;
671 for(Standard_Integer i = 0; i < aNbItems; i++)
673 gp_Pnt aP(theSurf2->Value(aParUS2[i], aParVS2[i]));
674 const Standard_Real aSqDist = SQDistPointSurface(aP, theSurf1->Surface(), theU10, theV10);
675 if(aSqDist > aSQToler)
676 return Standard_False;
679 return Standard_True;
682 //==================================================================================
683 // function : Perform
685 //==================================================================================
686 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
687 const Standard_Real u1min,
688 const Standard_Real v1min,
689 const Standard_Real u2min,
690 const Standard_Real v2min,
691 const Standard_Real u1max,
692 const Standard_Real v1max,
693 const Standard_Real u2max,
694 const Standard_Real v2max)
696 const Standard_Real aSQDistMax = 1.0e-14;
699 Standard_Integer NbPasOKConseq=0;
700 TColStd_Array1OfReal Param(1,4);
701 IntImp_ConstIsoparametric ChoixIso;
704 done = Standard_False;
707 const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
708 const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
710 const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
711 const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
712 const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
713 const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
715 const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
716 const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
717 const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
718 const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
720 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
721 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax,tolconf);
723 if(pasuv[0]<100.0*ResoU1) {
724 pasuv[0]=100.0*ResoU1;
726 if(pasuv[1]<100.0*ResoV1) {
727 pasuv[1]=100.0*ResoV1;
729 if(pasuv[2]<100.0*ResoU2) {
730 pasuv[2]=100.0*ResoU2;
732 if(pasuv[3]<100.0*ResoV2) {
733 pasuv[3]=100.0*ResoV2;
736 for (Standard_Integer i=0; i<4; ++i)
743 pasInit[i] = pasSav[i] = pasuv[i];
746 line = new IntSurf_LineOn2S ();
748 for (Standard_Integer i=1; i<=4; ++i)
752 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
753 //-- pasuv[] and pasSav[] are modified during the marching
754 for(Standard_Integer i = 0; i < 4; ++i)
756 pasSav[i] = pasuv[i] = pasInit[i];
759 //-- calculate the first solution point
760 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
762 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
763 if (!myIntersectionOn2S.IsDone())
769 if (myIntersectionOn2S.IsEmpty())
774 if(myIntersectionOn2S.IsTangent())
779 Standard_Boolean Arrive, DejaReparti;
780 const Standard_Integer RejectIndexMAX = 250000;
781 Standard_Integer IncKey, RejectIndex;
784 DejaReparti = Standard_False;
788 previousPoint = myIntersectionOn2S.Point();
789 previoustg = Standard_False;
790 previousd = myIntersectionOn2S.Direction();
791 previousd1 = myIntersectionOn2S.DirectionOnS1();
792 previousd2 = myIntersectionOn2S.DirectionOnS2();
795 firstd1 = previousd1;
796 firstd2 = previousd2;
797 tgfirst = tglast = Standard_False;
798 choixIsoSav = ChoixIso;
799 //------------------------------------------------------------
800 //-- Test if the first point of marching corresponds
801 //-- to a point on borders.
802 //-- In this case, DejaReparti is initialized as True
804 pf = previousPoint.Value();
805 Standard_Boolean bTestFirstPoint = Standard_True;
807 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
809 if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), pasuv))
812 AddAPoint(line,previousPoint);
814 IntWalk_StatusDeflection Status = IntWalk_OK;
815 Standard_Boolean NoTestDeflection = Standard_False;
816 Standard_Real SvParam[4], f;
817 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
818 Standard_Integer LevelOfPointConfondu = 0;
819 Standard_Integer LevelOfIterWithoutAppend = -1;
822 const Standard_Real aTol[4] = { Epsilon(u1max - u1min),
823 Epsilon(v1max - v1min),
824 Epsilon(u2max - u2min),
825 Epsilon(v2max - v2min)};
826 Arrive = Standard_False;
829 LevelOfIterWithoutAppend++;
830 if(LevelOfIterWithoutAppend>20)
832 Arrive = Standard_True;
836 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
837 LevelOfIterWithoutAppend = 0;
843 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
844 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
845 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
846 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
854 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
857 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
859 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
860 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
861 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
862 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
864 aIncKey=5.*(Standard_Real)IncKey;
866 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
871 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
876 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
881 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
891 //==========================
897 Standard_Integer aTryNumber = 0;
898 Standard_Real isBadPoint = Standard_False;
899 IntImp_ConstIsoparametric aBestIso = ChoixIso;
902 isBadPoint = Standard_False;
904 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
906 if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
908 //If we go along any surface boundary then it is possible
909 //to find "outboundaried" point.
910 //Nevertheless, if this deflection is quite small, we will be
911 //able to adjust this point to the boundary.
913 Standard_Real aNewPnt[4], anAbsParamDist[4];
914 myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
915 const Standard_Real aParMin[4] = {u1min, v1min, u2min, v2min};
916 const Standard_Real aParMax[4] = {u1max, v1max, u2max, v2max};
918 for(Standard_Integer i = 0; i < 4; i++)
920 if(Abs(aNewPnt[i] - aParMin[i]) < aTol[i])
921 aNewPnt[i] = aParMin[i];
922 else if(Abs(aNewPnt[i] - aParMax[i]) < aTol[i])
923 aNewPnt[i] = aParMax[i];
926 if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
927 aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
928 aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
929 aNewPnt[3] < v2min || aNewPnt[3] > v2max)
931 break; // Out of borders, handle this later.
934 myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
939 anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
940 anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
941 anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
942 anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
943 if (anAbsParamDist[0] < ResoU1 &&
944 anAbsParamDist[1] < ResoV1 &&
945 anAbsParamDist[2] < ResoU2 &&
946 anAbsParamDist[3] < ResoV2 &&
947 Status != IntWalk_PasTropGrand)
949 isBadPoint = Standard_True;
950 aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
953 } while (isBadPoint && ++aTryNumber <= 4);
955 if (!myIntersectionOn2S.IsDone())
957 //end of line, division
958 Arrive = Standard_False;
963 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
967 //== Calculation of exact point from Param(.) is possible
968 if (myIntersectionOn2S.IsEmpty())
970 Standard_Real u1,v1,u2,v2;
971 previousPoint.Parameters(u1,v1,u2,v2);
973 Arrive = Standard_False;
974 if(u1<UFirst1 || u1>ULast1)
976 Arrive=Standard_True;
979 if(u2<UFirst2 || u2>ULast2)
981 Arrive=Standard_True;
984 if(v1<VFirst1 || v1>VLast1)
986 Arrive=Standard_True;
989 if(v2<VFirst2 || v2>VLast2)
991 Arrive=Standard_True;
994 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
995 LevelOfEmptyInmyIntersectionOn2S++;
997 if(LevelOfEmptyInmyIntersectionOn2S>10)
1007 //============================================================
1008 //== A point has been found : T E S T D E F L E C T I O N
1009 //============================================================
1010 if(NoTestDeflection)
1012 NoTestDeflection = Standard_False;
1016 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
1018 LevelOfEmptyInmyIntersectionOn2S=0;
1019 if(LevelOfIterWithoutAppend < 10)
1021 Status = TestDeflection();
1033 //============================================================
1034 //== T r a i t e m e n t s u r S t a t u s ==
1035 //============================================================
1036 if(LevelOfPointConfondu > 5)
1038 Status = IntWalk_ArretSurPoint;
1039 LevelOfPointConfondu = 0;
1042 if(Status==IntWalk_OK)
1045 if(NbPasOKConseq >= 5)
1048 Standard_Boolean pastroppetit;
1053 pastroppetit=Standard_True;
1055 if(pasuv[0]<pasInit[0])
1057 t = (pasInit[0]-pasuv[0])*0.25;
1058 if(t>0.1*pasInit[0])
1064 pastroppetit=Standard_False;
1067 if(pasuv[1]<pasInit[1])
1069 t = (pasInit[1]-pasuv[1])*0.25;
1070 if(t>0.1*pasInit[1]) {
1075 pastroppetit=Standard_False;
1078 if(pasuv[2]<pasInit[2])
1080 t = (pasInit[2]-pasuv[2])*0.25;
1081 if(t>0.1*pasInit[2])
1087 pastroppetit=Standard_False;
1090 if(pasuv[3]<pasInit[3])
1092 t = (pasInit[3]-pasuv[3])*0.25;
1093 if(t>0.1*pasInit[3]) {
1097 pastroppetit=Standard_False;
1111 pastroppetit=Standard_False;
1115 while(pastroppetit);
1117 }//Status==IntWalk_OK
1124 case IntWalk_ArretSurPointPrecedent:
1126 Arrive = Standard_False;
1127 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
1130 case IntWalk_PasTropGrand:
1132 Param(1)=SvParam[0];
1133 Param(2)=SvParam[1];
1134 Param(3)=SvParam[2];
1135 Param(4)=SvParam[3];
1137 if(LevelOfIterWithoutAppend > 5)
1139 for (Standard_Integer i = 0; i < 4; i++)
1141 if (pasSav[i] > pasInit[i])
1144 const Standard_Real aDelta = (pasInit[i]-pasSav[i])*0.25;
1146 if(aDelta > Epsilon(pasInit[i]))
1148 pasInit[i] -= aDelta;
1149 LevelOfIterWithoutAppend=0;
1156 case IntWalk_PointConfondu:
1158 LevelOfPointConfondu++;
1160 if(LevelOfPointConfondu>5)
1162 Standard_Boolean pastroppetit;
1166 pastroppetit=Standard_True;
1168 if(pasuv[0]<pasInit[0])
1170 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1171 pastroppetit=Standard_False;
1174 if(pasuv[1]<pasInit[1])
1176 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1177 pastroppetit=Standard_False;
1180 if(pasuv[2]<pasInit[2])
1182 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1183 pastroppetit=Standard_False;
1186 if(pasuv[3]<pasInit[3])
1188 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1189 pastroppetit=Standard_False;
1204 pastroppetit=Standard_False;
1208 while(pastroppetit);
1214 case IntWalk_ArretSurPoint://006
1216 //=======================================================
1217 //== Stop Test t : Frame on Param(.) ==
1218 //=======================================================
1220 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1221 // JMB 30th December 1999.
1222 // Some statement below should not be put in comment because they are useful.
1223 // See grid CTO 909 A1 which infinitely loops
1224 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1226 Arrive=Standard_True;
1228 cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
1234 NbPasOKConseq = -10;
1239 //=====================================================
1240 //== Param(.) is in the limits ==
1241 //== and does not end a closed line ==
1242 //=====================================================
1243 //== Check on the current point of myInters
1244 Standard_Boolean pointisvalid = Standard_False;
1246 Standard_Real u1,v1,u2,v2;
1247 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1250 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1251 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1252 v1 >= Vm1 && v2 >= Vm2)
1254 pointisvalid=Standard_True;
1261 previousPoint = myIntersectionOn2S.Point();
1262 previoustg = myIntersectionOn2S.IsTangent();
1266 previousd = myIntersectionOn2S.Direction();
1267 previousd1 = myIntersectionOn2S.DirectionOnS1();
1268 previousd2 = myIntersectionOn2S.DirectionOnS2();
1270 //=====================================================
1271 //== Check on the previous Point
1273 Standard_Real u1,v1,u2,v2;
1274 previousPoint.Parameters(u1,v1,u2,v2);
1275 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1276 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1277 v1 >= Vm1 && v2 >= Vm2)
1279 pl = previousPoint.Value();
1282 if(pf.SquareDistance(pl) < aSQDistMax)
1292 bTestFirstPoint = Standard_False;
1296 AddAPoint(line,previousPoint);
1299 if(RejectIndex >= RejectIndexMAX)
1305 LevelOfIterWithoutAppend = 0;
1309 //====================================================
1311 if(Status == IntWalk_ArretSurPoint)
1313 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1317 if (line->NbPoints() == 2)
1319 pasSav[0] = pasuv[0];
1320 pasSav[1] = pasuv[1];
1321 pasSav[2] = pasuv[2];
1322 pasSav[3] = pasuv[3];
1330 //================= la ligne est fermee ===============
1331 AddAPoint(line,line->Value(1)); //ligne fermee
1332 LevelOfIterWithoutAppend=0;
1336 //====================================================
1337 //== Param was not in the limits (was reframed)
1338 //====================================================
1339 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1341 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1342 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1344 if(!myIntersectionOn2S.IsEmpty()) //002
1346 // mutially outpasses in the square or intersection in corner
1348 if(TestArret(Standard_True,Param,ChoixIso))
1350 NbPasOKConseq = -10;
1351 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1353 if(!myIntersectionOn2S.IsEmpty())
1355 previousPoint = myIntersectionOn2S.Point();
1356 previoustg = myIntersectionOn2S.IsTangent();
1360 previousd = myIntersectionOn2S.Direction();
1361 previousd1 = myIntersectionOn2S.DirectionOnS1();
1362 previousd2 = myIntersectionOn2S.DirectionOnS2();
1365 pl = previousPoint.Value();
1369 if(pf.SquareDistance(pl) < aSQDistMax)
1379 bTestFirstPoint = Standard_False;
1383 AddAPoint(line,previousPoint);
1386 if(RejectIndex >= RejectIndexMAX)
1392 LevelOfIterWithoutAppend=0;
1393 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1397 //fail framing divides the step
1398 Arrive = Standard_False;
1399 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1400 NoTestDeflection = Standard_True;
1401 ChoixIso = SauvChoixIso;
1406 // save the last point
1407 // to revert to it if the current point is out of bounds
1409 IntSurf_PntOn2S previousPointSave = previousPoint;
1410 Standard_Boolean previoustgSave = previoustg;
1411 gp_Dir previousdSave = previousd;
1412 gp_Dir2d previousd1Save = previousd1;
1413 gp_Dir2d previousd2Save = previousd2;
1415 previousPoint = myIntersectionOn2S.Point();
1416 previoustg = myIntersectionOn2S.IsTangent();
1417 Arrive = Standard_False;
1421 previousd = myIntersectionOn2S.Direction();
1422 previousd1 = myIntersectionOn2S.DirectionOnS1();
1423 previousd2 = myIntersectionOn2S.DirectionOnS2();
1426 //========================================
1427 //== Check on PreviousPoint @@
1430 Standard_Real u1,v1,u2,v2;
1431 previousPoint.Parameters(u1,v1,u2,v2);
1433 //To save initial 2d points
1434 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1435 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1437 ///////////////////////////
1445 Standard_Boolean bFlag1, bFlag2;
1446 Standard_Real aTol2D=1.e-11;
1448 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1449 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1450 if (bFlag1 && bFlag2)
1452 if (line->NbPoints() > 1)
1454 IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1455 Standard_Real ppU1, ppV1, ppU2, ppV2;
1456 prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1457 Standard_Real pU1, pV1, pU2, pV2;
1458 previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1459 gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1460 gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1461 gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1462 gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1464 const Standard_Real aDot1 = V1onS1 * V2onS1;
1465 const Standard_Real aDot2 = V1onS2 * V2onS2;
1467 if ((aDot1 < 0.0) || (aDot2 < 0.0))
1469 Arrive = Standard_True;
1474 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1475 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1476 v1 >= Vm1 && v2 >= Vm2) {
1479 pl = previousPoint.Value();
1483 if(pf.SquareDistance(pl) < aSQDistMax)
1494 bTestFirstPoint = Standard_False;
1498 //To avoid walking around the same point
1499 //in the tangent zone near a border
1503 //There are three consecutive points:
1504 //previousPointSave -> ParamPnt -> curPnt.
1506 Standard_Real prevU1, prevV1, prevU2, prevV2;
1507 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1508 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1509 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1510 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1511 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1512 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1513 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1514 Standard_Real MaxAngle = 3*M_PI/4;
1515 Standard_Real anAngleS1 = 0.0, anAngleS2 = 0.0;
1516 const Standard_Real aSQMParS1 = PrevToParamOnS1.SquareMagnitude();
1517 const Standard_Real aSQMParS2 = PrevToParamOnS2.SquareMagnitude();
1518 const Standard_Real aSQMCurS1 = PrevToCurOnS1.SquareMagnitude();
1519 const Standard_Real aSQMCurS2 = PrevToCurOnS2.SquareMagnitude();
1521 if(aSQMCurS1 < gp::Resolution())
1523 //We came back to the one of previos point.
1524 //Therefore, we must break;
1528 else if(aSQMParS1 < gp::Resolution())
1530 //We are walking along tangent zone.
1531 //It should be continued.
1536 anAngleS1 = Abs(PrevToParamOnS1.Angle(PrevToCurOnS1));
1539 if(aSQMCurS2 < gp::Resolution())
1541 //We came back to the one of previos point.
1542 //Therefore, we must break;
1546 else if(aSQMParS2 < gp::Resolution())
1548 //We are walking along tangent zone.
1549 //It should be continued;
1554 anAngleS2 = Abs(PrevToParamOnS2.Angle(PrevToCurOnS2));
1557 if ((anAngleS1 > MaxAngle) && (anAngleS2 > MaxAngle))
1559 Arrive = Standard_True;
1564 //Check singularity.
1565 //I.e. check if we are walking along direction, which does not
1566 //result in comming to any point (i.e. derivative
1567 //3D-intersection curve along this direction is equal to 0).
1568 //A sphere with direction {dU=1, dV=0} from point
1569 //(U=0, V=M_PI/2) can be considered as example for
1570 //this case (we cannot find another 3D-point if we go thus).
1572 //Direction chosen along 1st and 2nd surface correspondingly
1573 const gp_Vec2d aDirS1(prevPntOnS1, curPntOnS1),
1574 aDirS2(prevPntOnS2, curPntOnS2);
1577 gp_Vec aDuS1, aDvS1, aDuS2, aDvS2;
1579 myIntersectionOn2S.Function().AuxillarSurface1()->
1580 D1(curPntOnS1.X(), curPntOnS1.Y(), aPtemp, aDuS1, aDvS1);
1581 myIntersectionOn2S.Function().AuxillarSurface2()->
1582 D1(curPntOnS2.X(), curPntOnS2.Y(), aPtemp, aDuS2, aDvS2);
1584 //Derivative WLine along (it is vector-function indeed)
1586 //(https://en.wikipedia.org/wiki/Directional_derivative#Variation_using_only_direction_of_vector).
1587 //F1 - on the 1st surface, F2 - on the 2nd surface.
1588 //x, y, z - coordinates of derivative vector.
1589 const Standard_Real aF1x = aDuS1.X()*aDirS1.X() +
1590 aDvS1.X()*aDirS1.Y();
1591 const Standard_Real aF1y = aDuS1.Y()*aDirS1.X() +
1592 aDvS1.Y()*aDirS1.Y();
1593 const Standard_Real aF1z = aDuS1.Z()*aDirS1.X() +
1594 aDvS1.Z()*aDirS1.Y();
1595 const Standard_Real aF2x = aDuS2.X()*aDirS2.X() +
1596 aDvS2.X()*aDirS2.Y();
1597 const Standard_Real aF2y = aDuS2.Y()*aDirS2.X() +
1598 aDvS2.Y()*aDirS2.Y();
1599 const Standard_Real aF2z = aDuS2.Z()*aDirS2.X() +
1600 aDvS2.Z()*aDirS2.Y();
1602 const Standard_Real aF1 = aF1x*aF1x + aF1y*aF1y + aF1z*aF1z;
1603 const Standard_Real aF2 = aF2x*aF2x + aF2y*aF2y + aF2z*aF2z;
1605 if((aF1 < gp::Resolution()) && (aF2 < gp::Resolution()))
1607 //All derivative are equal to 0. Therefore, there is
1608 //no point in going along direction chosen.
1609 Arrive = Standard_True;
1613 }//if (previoustg) cond.
1615 ////////////////////////////////////////
1616 AddAPoint(line,previousPoint);
1619 if(RejectIndex >= RejectIndexMAX)
1626 LevelOfIterWithoutAppend=0;
1627 Arrive = Standard_True;
1631 // revert to the last correctly calculated point
1632 previousPoint = previousPointSave;
1633 previoustg = previoustgSave;
1634 previousd = previousdSave;
1635 previousd1 = previousd1Save;
1636 previousd2 = previousd2Save;
1641 Standard_Boolean wasExtended = Standard_False;
1643 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1645 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1647 wasExtended = Standard_True;
1648 Arrive = Standard_False;
1649 ChoixIso = SauvChoixIso;
1653 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1656 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1657 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1660 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1662 wasExtended = Standard_True;
1663 Arrive = Standard_False;
1664 ChoixIso = SauvChoixIso;
1667 }//else !TestArret() $
1668 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1671 //echec framing on border; division of step
1672 Arrive = Standard_False;
1673 NoTestDeflection = Standard_True;
1674 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1676 }//$$$ end framing on border (!close)
1677 }//004 fin TestArret return Arrive = True
1678 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1679 } //007 switch(Status)
1680 } //008 end processing point (TEST DEFLECTION)
1681 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1682 } //010 end if first departure point allows marching while (!Arrive)
1684 done = Standard_True;
1686 // ===========================================================================================================
1687 // function: ExtendLineInCommonZone
1688 // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1689 // Returns Standard_True if the line was extended through tangent zone and the last computed point
1690 // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1691 // ===========================================================================================================
1692 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1693 const Standard_Boolean theDirectionFlag)
1695 Standard_Boolean bOutOfTangentZone = Standard_False;
1696 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1697 Standard_Integer dIncKey = 1;
1698 TColStd_Array1OfReal Param(1,4);
1699 IntWalk_StatusDeflection Status = IntWalk_OK;
1700 Standard_Integer nbIterWithoutAppend = 0;
1701 Standard_Integer nbEqualPoints = 0;
1702 Standard_Integer parit = 0;
1703 Standard_Integer uvit = 0;
1704 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1707 nbIterWithoutAppend++;
1709 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1711 cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1713 bStop = Standard_True;
1716 Standard_Real f = 0.;
1718 switch (theChoixIso)
1720 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1721 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1722 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1723 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1728 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1730 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1731 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1732 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1733 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1735 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1736 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1737 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1738 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1744 Standard_Real SvParam[4];
1745 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1747 for(parit = 0; parit < 4; parit++) {
1748 SvParam[parit] = Param(parit+1);
1750 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1751 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1753 if (!myIntersectionOn2S.IsDone()) {
1754 return bOutOfTangentZone;
1757 if (myIntersectionOn2S.IsEmpty()) {
1758 return bOutOfTangentZone;
1761 Status = TestDeflection();
1763 if(Status == IntWalk_OK) {
1765 for(uvit = 0; uvit < 4; uvit++) {
1766 if(pasuv[uvit] < pasInit[uvit]) {
1767 pasuv[uvit] = pasInit[uvit];
1773 case IntWalk_ArretSurPointPrecedent:
1775 bStop = Standard_True;
1776 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1779 case IntWalk_PasTropGrand:
1781 for(parit = 0; parit < 4; parit++) {
1782 Param(parit+1) = SvParam[parit];
1784 Standard_Boolean bDecrease = Standard_False;
1786 for(uvit = 0; uvit < 4; uvit++) {
1787 if(pasSav[uvit] < pasInit[uvit]) {
1788 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1789 bDecrease = Standard_True;
1793 if(bDecrease) nbIterWithoutAppend--;
1796 case IntWalk_PointConfondu:
1798 for(uvit = 0; uvit < 4; uvit++) {
1799 if(pasuv[uvit] < pasInit[uvit]) {
1800 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1806 case IntWalk_ArretSurPoint:
1809 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1814 Standard_Real u11,v11,u12,v12;
1815 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1816 Standard_Real u21,v21,u22,v22;
1817 previousPoint.Parameters(u21,v21,u22,v22);
1819 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1820 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1829 bStop = bStop || !myIntersectionOn2S.IsTangent();
1830 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1833 Standard_Boolean pointisvalid = Standard_False;
1834 Standard_Real u1,v1,u2,v2;
1835 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1837 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1838 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1839 v1 >= Vm1 && v2 >= Vm2)
1840 pointisvalid = Standard_True;
1843 previousPoint = myIntersectionOn2S.Point();
1844 previoustg = myIntersectionOn2S.IsTangent();
1847 previousd = myIntersectionOn2S.Direction();
1848 previousd1 = myIntersectionOn2S.DirectionOnS1();
1849 previousd2 = myIntersectionOn2S.DirectionOnS2();
1851 Standard_Boolean bAddPoint = Standard_True;
1853 if(line->NbPoints() >= 1) {
1854 gp_Pnt pf = line->Value(1).Value();
1855 gp_Pnt pl = previousPoint.Value();
1857 if(pf.Distance(pl) < Precision::Confusion()) {
1859 if(dIncKey == 5000) return bOutOfTangentZone;
1860 else bAddPoint = Standard_False;
1865 aSeqOfNewPoint.Append(previousPoint);
1866 nbIterWithoutAppend = 0;
1870 if (line->NbPoints() == 2) {
1871 for(uvit = 0; uvit < 4; uvit++) {
1872 pasSav[uvit] = pasuv[uvit];
1876 if ( !pointisvalid ) {
1877 // decrease step if out of bounds
1878 // otherwise the same calculations will be
1879 // repeated several times
1880 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1883 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1886 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1889 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1894 if(close && (line->NbPoints() >= 1)) {
1896 if(!bOutOfTangentZone) {
1897 aSeqOfNewPoint.Append(line->Value(1)); // line end
1899 nbIterWithoutAppend = 0;
1902 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1904 if(myIntersectionOn2S.IsEmpty()) {
1905 bStop = !myIntersectionOn2S.IsTangent();
1906 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1909 Standard_Boolean bAddPoint = Standard_True;
1910 Standard_Boolean pointisvalid = Standard_False;
1912 previousPoint = myIntersectionOn2S.Point();
1913 Standard_Real u1,v1,u2,v2;
1914 previousPoint.Parameters(u1,v1,u2,v2);
1916 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1917 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1918 v1 >= Vm1 && v2 >= Vm2)
1919 pointisvalid = Standard_True;
1923 if(line->NbPoints() >= 1) {
1924 gp_Pnt pf = line->Value(1).Value();
1925 gp_Pnt pl = previousPoint.Value();
1927 if(pf.Distance(pl) < Precision::Confusion()) {
1929 if(dIncKey == 5000) return bOutOfTangentZone;
1930 else bAddPoint = Standard_False;
1934 if(bAddPoint && !bOutOfTangentZone) {
1935 aSeqOfNewPoint.Append(previousPoint);
1936 nbIterWithoutAppend = 0;
1951 Standard_Boolean bExtendLine = Standard_False;
1952 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1954 Standard_Integer pit = 0;
1956 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1958 previousPoint.Parameters(u1,v1,u2,v2);
1960 if(aSeqOfNewPoint.Length() > 0)
1961 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1966 if(((u1 - Um1) < ResoU1) ||
1967 ((UM1 - u1) < ResoU1) ||
1968 ((u2 - Um2) < ResoU2) ||
1969 ((UM2 - u2) < ResoU2) ||
1970 ((v1 - Vm1) < ResoV1) ||
1971 ((VM1 - v1) < ResoV1) ||
1972 ((v2 - Vm2) < ResoV2) ||
1973 ((VM2 - v2) < ResoV2))
1974 bExtendLine = Standard_True;
1978 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1979 if(Status == IntWalk_OK) {
1980 bExtendLine = Standard_True;
1982 if(aSeqOfNewPoint.Length() > 1) {
1983 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1984 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1986 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1987 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1988 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1989 LastParams.ChangeValue(1),
1990 LastParams.ChangeValue(2),
1991 LastParams.ChangeValue(3));
1992 Standard_Integer indexofiso = 0;
1994 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1995 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1996 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1997 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1999 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
2000 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
2001 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
2003 gp_Dir2d anIsoDir(0, 1);
2005 if((indexofiso == 1) || (indexofiso == 3))
2006 anIsoDir = gp_Dir2d(1, 0);
2008 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
2009 Standard_Real piquota = M_PI*0.25;
2011 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
2012 Standard_Integer ii = 1, nextii = 2;
2014 Standard_Real asqresol = gp::Resolution();
2015 asqresol *= asqresol;
2018 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2019 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2020 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2021 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2022 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2023 FirstParams.Value(afirstindex + 1)),
2024 gp_Pnt2d(LastParams.Value(afirstindex),
2025 LastParams.Value(afirstindex + 1)));
2028 while((d1.SquareMagnitude() < asqresol) &&
2029 (ii < aSeqOfNewPoint.Length()));
2033 while(nextii < aSeqOfNewPoint.Length()) {
2035 gp_Vec2d nextd1(0, 0);
2036 Standard_Integer jj = nextii;
2039 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2040 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2041 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2042 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2043 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2044 FirstParams.Value(afirstindex + 1)),
2045 gp_Pnt2d(LastParams.Value(afirstindex),
2046 LastParams.Value(afirstindex + 1)));
2050 while((nextd1.SquareMagnitude() < asqresol) &&
2051 (jj < aSeqOfNewPoint.Length()));
2054 if(fabs(d1.Angle(nextd1)) > piquota) {
2055 bExtendLine = Standard_False;
2061 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
2068 return Standard_False;
2070 Standard_Integer i = 0;
2072 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
2073 AddAPoint(line, aSeqOfNewPoint.Value(i));
2076 return bOutOfTangentZone;
2079 //=======================================================================
2080 //function : DistanceMinimizeByGradient
2082 //=======================================================================
2083 Standard_Boolean IntWalk_PWalking::
2084 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
2085 const Handle(Adaptor3d_HSurface)& theASurf2,
2086 Standard_Real& theU1,
2087 Standard_Real& theV1,
2088 Standard_Real& theU2,
2089 Standard_Real& theV2,
2090 const Standard_Real theStep0U1V1,
2091 const Standard_Real theStep0U2V2)
2093 const Standard_Integer aNbIterMAX = 60;
2094 const Standard_Real aTol = 1.0e-14;
2095 Handle(Geom_Surface) aS1, aS2;
2097 if (theASurf1->GetType() != GeomAbs_BezierSurface &&
2098 theASurf1->GetType() != GeomAbs_BSplineSurface)
2099 return Standard_True;
2100 if (theASurf2->GetType() != GeomAbs_BezierSurface &&
2101 theASurf2->GetType() != GeomAbs_BSplineSurface)
2102 return Standard_True;
2104 Standard_Boolean aStatus = Standard_False;
2107 gp_Vec aD1u, aD1v, aD2U, aD2V;
2109 theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v);
2110 theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V);
2112 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
2114 gp_Vec aP12(aP1, aP2);
2116 Standard_Real aGradFu(-aP12.Dot(aD1u));
2117 Standard_Real aGradFv(-aP12.Dot(aD1v));
2118 Standard_Real aGradFU( aP12.Dot(aD2U));
2119 Standard_Real aGradFV( aP12.Dot(aD2V));
2121 Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
2123 Standard_Boolean flRepeat = Standard_True;
2124 Standard_Integer aNbIter = aNbIterMAX;
2128 Standard_Real anAdd = aGradFu*aSTEPuv;
2129 Standard_Real aPARu = (anAdd >= 0.0)?
2130 (theU1 - Max(anAdd, Epsilon(theU1))) :
2131 (theU1 + Max(-anAdd, Epsilon(theU1)));
2132 anAdd = aGradFv*aSTEPuv;
2133 Standard_Real aPARv = (anAdd >= 0.0)?
2134 (theV1 - Max(anAdd, Epsilon(theV1))) :
2135 (theV1 + Max(-anAdd, Epsilon(theV1)));
2136 anAdd = aGradFU*aStepUV;
2137 Standard_Real aParU = (anAdd >= 0.0)?
2138 (theU2 - Max(anAdd, Epsilon(theU2))) :
2139 (theU2 + Max(-anAdd, Epsilon(theU2)));
2140 anAdd = aGradFV*aStepUV;
2141 Standard_Real aParV = (anAdd >= 0.0)?
2142 (theV2 - Max(anAdd, Epsilon(theV2))) :
2143 (theV2 + Max(-anAdd, Epsilon(theV2)));
2147 theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
2148 theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
2150 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
2152 if(aSQDist < aSQDistPrev)
2154 aSQDistPrev = aSQDist;
2160 aStatus = aSQDistPrev < aTol;
2168 flRepeat = Standard_False;
2172 theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v);
2173 theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V);
2175 gp_Vec aPt12(aPt1, aPt2);
2176 aGradFu = -aPt12.Dot(aD1u);
2177 aGradFv = -aPt12.Dot(aD1v);
2178 aGradFU = aPt12.Dot(aD2U);
2179 aGradFV = aPt12.Dot(aD2V);
2180 aSTEPuv = theStep0U1V1;
2181 aStepUV = theStep0U2V2;
2189 //=======================================================================
2190 //function : DistanceMinimizeByExtrema
2192 //=======================================================================
2193 Standard_Boolean IntWalk_PWalking::
2194 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
2195 const gp_Pnt& theP0,
2196 Standard_Real& theU0,
2197 Standard_Real& theV0,
2198 const Standard_Real theStep0U,
2199 const Standard_Real theStep0V)
2201 const Standard_Real aTol = 1.0e-14;
2203 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2204 Standard_Real aSQDistPrev = RealLast();
2205 Standard_Real aU = theU0, aV = theV0;
2207 Standard_Integer aNbIter = 10;
2210 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2212 gp_Vec aVec(theP0, aPS);
2214 Standard_Real aSQDist = aVec.SquareMagnitude();
2216 if(aSQDist >= aSQDistPrev)
2219 aSQDistPrev = aSQDist;
2224 if(aSQDistPrev < aTol)
2228 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2231 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2232 aDf1v = aD2Su.Dot(aD1Sv),
2234 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2236 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2237 aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
2238 aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
2242 return (aSQDistPrev < aTol);
2245 //=======================================================================
2246 //function : SeekPointOnBoundary
2248 //=======================================================================
2249 Standard_Boolean IntWalk_PWalking::
2250 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2251 const Handle(Adaptor3d_HSurface)& theASurf2,
2252 const Standard_Real theU1,
2253 const Standard_Real theV1,
2254 const Standard_Real theU2,
2255 const Standard_Real theV2,
2256 const Standard_Boolean isTheFirst)
2258 const Standard_Real aTol = 1.0e-14;
2259 Standard_Boolean isOK = Standard_False;
2260 Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
2262 Standard_Boolean flFinish = Standard_False;
2264 Standard_Integer aNbIter = 20;
2267 flFinish = Standard_False;
2268 Standard_Boolean aStatus = Standard_False;
2273 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2279 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2285 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2291 while(!aStatus && (aNbIter > 0));
2295 const Standard_Real aTolMax = 1.0e-8;
2296 Standard_Real aTolF = 0.0;
2298 Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2300 flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2302 if(aTolF <= aTolMax)
2304 gp_Pnt aP1 = theASurf1->Value(u1, v1),
2305 aP2 = theASurf2->Value(u2, v2);
2306 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2308 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2309 aSQDist2 = aPInt.SquareDistance(aP2);
2310 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2312 IntSurf_PntOn2S anIP;
2313 anIP.SetValue(aPInt, u1, v1, u2, v2);
2316 line->InsertBefore(1,anIP);
2320 isOK = Standard_True;
2336 //=======================================================================
2337 //function : PutToBoundary
2339 //=======================================================================
2340 Standard_Boolean IntWalk_PWalking::
2341 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2342 const Handle(Adaptor3d_HSurface)& theASurf2)
2344 const Standard_Real aTolMin = Precision::Confusion();
2346 Standard_Boolean hasBeenAdded = Standard_False;
2348 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2349 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2350 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2351 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2352 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2353 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2354 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2355 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2357 Standard_Real aTol = 1.0;
2358 aTol = Min(aTol, aU1bLast - aU1bFirst);
2359 aTol = Min(aTol, aU2bLast - aU2bFirst);
2360 aTol = Min(aTol, aV1bLast - aV1bFirst);
2361 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2363 if(aTol <= 2.0*aTolMin)
2364 return hasBeenAdded;
2366 Standard_Boolean isNeedAdding = Standard_False;
2367 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2368 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2369 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2370 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2372 Standard_Real u1, v1, u2, v2;
2373 line->Value(1).Parameters(u1, v1, u2, v2);
2374 Standard_Real aDelta = 0.0;
2378 aDelta = u1 - aU1bFirst;
2379 if((aTolMin < aDelta) && (aDelta < aTol))
2381 u1 = aU1bFirst - aDelta;
2382 isNeedAdding = Standard_True;
2386 aDelta = aU1bLast - u1;
2387 if((aTolMin < aDelta) && (aDelta < aTol))
2389 u1 = aU1bLast + aDelta;
2390 isNeedAdding = Standard_True;
2397 aDelta = u2 - aU2bFirst;
2398 if((aTolMin < aDelta) && (aDelta < aTol))
2400 u2 = aU2bFirst - aDelta;
2401 isNeedAdding = Standard_True;
2405 aDelta = aU2bLast - u2;
2406 if((aTolMin < aDelta) && (aDelta < aTol))
2408 u2 = aU2bLast + aDelta;
2409 isNeedAdding = Standard_True;
2416 aDelta = v1 - aV1bFirst;
2417 if((aTolMin < aDelta) && (aDelta < aTol))
2419 v1 = aV1bFirst - aDelta;
2420 isNeedAdding = Standard_True;
2424 aDelta = aV1bLast - v1;
2425 if((aTolMin < aDelta) && (aDelta < aTol))
2427 v1 = aV1bLast + aDelta;
2428 isNeedAdding = Standard_True;
2435 aDelta = v2 - aV2bFirst;
2436 if((aTolMin < aDelta) && (aDelta < aTol))
2438 v2 = aV2bFirst - aDelta;
2439 isNeedAdding = Standard_True;
2443 aDelta = aV2bLast - v2;
2444 if((aTolMin < aDelta) && (aDelta < aTol))
2446 v2 = aV2bLast + aDelta;
2447 isNeedAdding = Standard_True;
2455 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2456 v1, u2, v2, Standard_True);
2459 const Standard_Integer aNbPnts = line->NbPoints();
2460 isNeedAdding = Standard_False;
2461 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2465 aDelta = u1 - aU1bFirst;
2466 if((aTolMin < aDelta) && (aDelta < aTol))
2468 u1 = aU1bFirst - aDelta;
2469 isNeedAdding = Standard_True;
2473 aDelta = aU1bLast - u1;
2474 if((aTolMin < aDelta) && (aDelta < aTol))
2476 u1 = aU1bLast + aDelta;
2477 isNeedAdding = Standard_True;
2484 aDelta = u2 - aU2bFirst;
2485 if((aTolMin < aDelta) && (aDelta < aTol))
2487 u2 = aU2bFirst - aDelta;
2488 isNeedAdding = Standard_True;
2492 aDelta = aU2bLast - u2;
2493 if((aTolMin < aDelta) && (aDelta < aTol))
2495 u2 = aU2bLast + aDelta;
2496 isNeedAdding = Standard_True;
2503 aDelta = v1 - aV1bFirst;
2504 if((aTolMin < aDelta) && (aDelta < aTol))
2506 v1 = aV1bFirst - aDelta;
2507 isNeedAdding = Standard_True;
2511 aDelta = aV1bLast - v1;
2512 if((aTolMin < aDelta) && (aDelta < aTol))
2514 v1 = aV1bLast + aDelta;
2515 isNeedAdding = Standard_True;
2522 aDelta = v2 - aV2bFirst;
2523 if((aTolMin < aDelta) && (aDelta < aTol))
2525 v2 = aV2bFirst - aDelta;
2526 isNeedAdding = Standard_True;
2530 aDelta = aV2bLast - v2;
2531 if((aTolMin < aDelta) && (aDelta < aTol))
2533 v2 = aV2bLast + aDelta;
2534 isNeedAdding = Standard_True;
2542 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2543 v1, u2, v2, Standard_False);
2546 return hasBeenAdded;
2549 //=======================================================================
2550 //function : SeekAdditionalPoints
2552 //=======================================================================
2553 Standard_Boolean IntWalk_PWalking::
2554 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2555 const Handle(Adaptor3d_HSurface)& theASurf2,
2556 const Standard_Integer theMinNbPoints)
2558 const Standard_Real aTol = 1.0e-14;
2559 Standard_Integer aNbPoints = line->NbPoints();
2560 if(aNbPoints > theMinNbPoints)
2561 return Standard_True;
2563 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2564 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2565 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2566 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2567 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2568 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2569 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2570 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2573 Standard_Boolean isPrecise = Standard_False;
2575 Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2577 Standard_Integer aNbPointsPrev = 0;
2578 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2580 aNbPointsPrev = aNbPoints;
2581 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2583 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2584 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2587 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2588 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2590 U1prec = 0.5*(U1f+U1l);
2591 if(U1prec < aU1bFirst)
2593 if(U1prec > aU1bLast)
2596 V1prec = 0.5*(V1f+V1l);
2597 if(V1prec < aV1bFirst)
2599 if(V1prec > aV1bLast)
2602 U2prec = 0.5*(U2f+U2l);
2603 if(U2prec < aU2bFirst)
2605 if(U2prec > aU2bLast)
2608 V2prec = 0.5*(V2f+V2l);
2609 if(V2prec < aV2bFirst)
2611 if(V2prec > aV2bLast)
2614 Standard_Boolean aStatus = Standard_False;
2615 Standard_Integer aNbIter = 5;
2618 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2624 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2630 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2636 while(!aStatus && (--aNbIter > 0));
2640 gp_Pnt aP1 = theASurf1->Value(U1prec, V1prec),
2641 aP2 = theASurf2->Value(U2prec, V2prec);
2642 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2644 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2645 aSQDist2 = aPInt.SquareDistance(aP2);
2647 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2649 IntSurf_PntOn2S anIP;
2650 anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2651 line->InsertBefore(lp, anIP);
2653 isPrecise = Standard_True;
2655 if(++aNbPoints >= theMinNbPoints)
2669 void IntWalk_PWalking::
2670 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2671 IntImp_ConstIsoparametric& ChoixIso,
2672 Standard_Boolean& Arrive)
2674 // at the neighborhood of a point, there is a fail of marching
2675 // it is required to divide the steps to try to continue
2676 // if the step is too small if we are on border
2677 // restart in another direction if it was not done, otherwise stop
2680 // Standard_Integer i;
2681 if (Arrive) { //restart in the other direction
2682 if (!DejaReparti ) {
2683 Arrive = Standard_False;
2684 DejaReparti = Standard_True;
2685 previousPoint = line->Value(1);
2686 previoustg = Standard_False;
2687 previousd1 = firstd1;
2688 previousd2 = firstd2;
2690 indextg = line->NbPoints();
2694 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2695 sensCheminement = -1;
2697 tglast = Standard_False;
2698 ChoixIso = choixIsoSav;
2705 Standard_Real u1,v1,u2,v2;
2706 Standard_Real U1,V1,U2,V2;
2707 Standard_Integer nn=line->NbPoints();
2709 line->Value(nn).Parameters(u1,v1,u2,v2);
2710 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2711 pasuv[0]=Abs(u1-U1);
2712 pasuv[1]=Abs(v1-V1);
2713 pasuv[2]=Abs(u2-U2);
2714 pasuv[3]=Abs(v2-V2);
2721 if ( pasuv[0]*0.5 < ResoU1
2722 && pasuv[1]*0.5 < ResoV1
2723 && pasuv[2]*0.5 < ResoU2
2724 && pasuv[3]*0.5 < ResoV2
2727 tglast = Standard_True; // IS IT ENOUGH ????
2730 if (!DejaReparti) { //restart in the other direction
2731 DejaReparti = Standard_True;
2732 previousPoint = line->Value(1);
2733 previoustg = Standard_False;
2734 previousd1 = firstd1;
2735 previousd2 = firstd2;
2737 indextg = line->NbPoints();
2741 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2743 sensCheminement = -1;
2745 tglast = Standard_False;
2746 ChoixIso = choixIsoSav;
2754 Standard_Real u1,v1,u2,v2;
2755 Standard_Real U1,V1,U2,V2;
2756 Standard_Integer nn=line->NbPoints();
2758 line->Value(nn).Parameters(u1,v1,u2,v2);
2759 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2760 pasuv[0]=Abs(u1-U1);
2761 pasuv[1]=Abs(v1-V1);
2762 pasuv[2]=Abs(u2-U2);
2763 pasuv[3]=Abs(v2-V2);
2767 else Arrive = Standard_True;
2779 //OCC431(apo): modified ->
2780 static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
2782 static const Standard_Real d = 7.0;
2785 IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
2787 // test if vector is observed by calculating an increase of vector
2788 // or the previous point and its tangent, the new calculated point and its
2789 // tangent; it is possible to find a cube passing by the 2 points and having as a
2790 // derivative the tangents of the intersection
2791 // calculate the point with parameter 0.5 on cube=p1
2792 // calculate the medium point of 2 points of intersection=p2
2793 // if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2794 // otherwise adjust the step depending on the ratio ||p1p2||/vector
2795 // and the previous step
2796 // test if in 2 tangent planes of surfaces there is no too great angle2d
2797 // grand : if yes divide the step
2798 // test if there is no change of side
2801 if(line->NbPoints() ==1 ) {
2802 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
2805 IntWalk_StatusDeflection Status = IntWalk_OK;
2806 Standard_Real FlecheCourante ,Ratio;
2809 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
2810 //==================================================================================
2811 //========= S t o p o n p o i n t ============
2812 //==================================================================================
2813 if (myIntersectionOn2S.IsTangent()) {
2814 return IntWalk_ArretSurPoint;
2817 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
2819 //==================================================================================
2820 //========= R i s k o f i n f l e x i o n p o i n t ============
2821 //==================================================================================
2822 if (TgCourante.Dot(previousd)<0) {
2823 //------------------------------------------------------------
2824 //-- Risk of inflexion point : Divide the step by 2
2825 //-- Initialize STATIC_PRECEDENT_INFLEXION so that
2826 //-- at the next call to return Pas_OK if there is no
2827 //-- more risk of the point of inflexion
2828 //------------------------------------------------------------
2834 STATIC_PRECEDENT_INFLEXION+=3;
2835 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
2836 return IntWalk_ArretSurPointPrecedent;
2838 return IntWalk_PasTropGrand;
2842 if(STATIC_PRECEDENT_INFLEXION > 0) {
2843 STATIC_PRECEDENT_INFLEXION -- ;
2848 //==================================================================================
2849 //========= D e t e c t c o n f u s e d P o in t s ===========
2850 //==================================================================================
2852 Standard_Real Dist = previousPoint.Value().
2853 SquareDistance(CurrentPoint.Value());
2856 if (Dist < tolconf*tolconf ) {
2857 pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
2858 pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
2859 pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
2860 pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
2861 Status = IntWalk_PointConfondu;
2864 //==================================================================================
2865 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
2866 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
2868 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
2869 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
2871 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
2872 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
2878 //=================================================================================
2879 //==== S t e p o f p r o g r e s s i o n (between previous and Current) =======
2880 //=================================================================================
2881 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
2882 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
2883 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
2884 return(IntWalk_ArretSurPointPrecedent);
2886 //==================================================================================
2888 Standard_Real tolArea = 100.0;
2889 if (ResoU1 < Precision::PConfusion() ||
2890 ResoV1 < Precision::PConfusion() ||
2891 ResoU2 < Precision::PConfusion() ||
2892 ResoV2 < Precision::PConfusion() )
2893 tolArea = tolArea*2.0;
2895 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
2896 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
2897 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
2898 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
2899 Duv1 = Du1*Du1 + Dv1*Dv1;
2900 Duv2 = Du2*Du2 + Dv2*Dv2;
2901 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
2902 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
2904 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
2906 Standard_Real aMinDiv2=Precision::Confusion();
2907 aMinDiv2=aMinDiv2*aMinDiv2;
2910 if (Duv1>aMinDiv2) {
2911 d1 = Abs(ResoUV1/Duv1);
2912 d1 = Min(Sqrt(d1)*tolArea, d);
2914 //d1 = Abs(ResoUV1/Duv1);
2915 //d1 = Min(Sqrt(d1)*tolArea,d);
2916 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
2917 tolCoeff1 = Exp(d1);
2919 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
2921 if (Duv2>aMinDiv2) {
2922 d2 = Abs(ResoUV2/Duv2);
2923 d2 = Min(Sqrt(d2)*tolArea,d);
2925 //d2 = Abs(ResoUV2/Duv2);
2926 //d2 = Min(Sqrt(d2)*tolArea,d);
2927 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
2928 tolCoeff2 = Exp(d2);
2929 CosRef1 = CosRef2D/tolCoeff1;
2930 CosRef2 = CosRef2D/tolCoeff2;
2932 //==================================================================================
2933 //== The points are not confused : ==
2934 //== 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 ==
2935 //== N o t T o o G r e a t (angle in space UV) ==
2936 //== C h a n g e o f s i d e ==
2937 //==================================================================================
2938 if (Status != IntWalk_PointConfondu) {
2939 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
2940 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2941 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
2942 return(IntWalk_ArretSurPointPrecedent);
2945 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2946 return(IntWalk_PasTropGrand);
2949 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
2950 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
2951 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
2952 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
2953 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
2954 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
2955 AngRef1 = AngRef2D*tolCoeff1;
2956 AngRef2 = AngRef2D*tolCoeff2;
2957 //-------------------------------------------------------
2958 //-- Test : Angle too great in space UV -----
2959 //-- Change of side -----
2960 //-------------------------------------------------------
2961 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
2962 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2963 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
2964 return(IntWalk_ArretSurPoint);
2966 return(IntWalk_PasTropGrand);
2970 //==================================================================================
2971 //== D e t e c t i o n o f : Step Too Small
2973 //==================================================================================
2975 //---------------------------------------
2976 //-- Estimate of the vector --
2977 //---------------------------------------
2979 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
2981 if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
2982 if(FlecheCourante>1e-16) {
2983 Ratio = 0.5*(fleche/FlecheCourante);
2988 Standard_Real pasSu1 = pasuv[0];
2989 Standard_Real pasSv1 = pasuv[1];
2990 Standard_Real pasSu2 = pasuv[2];
2991 Standard_Real pasSv2 = pasuv[3];
2994 //-- a point at U+DeltaU is required, ....
2995 //-- return a point at U + Epsilon
2996 //-- Epsilon << DeltaU.
2998 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
2999 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
3000 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
3001 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
3003 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
3004 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
3005 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
3006 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
3007 //-- if(Ratio>10.0 ) { Ratio=10.0; }
3008 Standard_Real R1,R = pasInit[0]/pasuv[0];
3009 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
3010 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
3011 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
3012 if(Ratio > R) Ratio=R;
3013 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
3014 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
3015 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
3016 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
3017 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
3018 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
3019 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3020 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3021 return IntWalk_PasTropGrand;
3024 if(Status == IntWalk_OK) {
3025 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3026 //-- Try to increase the step
3030 else { //-- CurrentVector > vector*0.5
3031 if (FlecheCourante > fleche) { //-- Current step too Great
3032 Ratio = fleche/FlecheCourante;
3033 pasuv[0] = Ratio*pasuv[0];
3034 pasuv[1] = Ratio*pasuv[1];
3035 pasuv[2] = Ratio*pasuv[2];
3036 pasuv[3] = Ratio*pasuv[3];
3037 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3038 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3039 return IntWalk_PasTropGrand;
3042 else { //-- vector/2 < CurrentVector <= vector
3043 Ratio = 0.75 * (fleche / FlecheCourante);
3046 pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
3047 pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
3048 pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
3049 pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
3050 if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3054 Standard_Boolean IntWalk_PWalking::
3055 TestArret(const Standard_Boolean DejaReparti,
3056 TColStd_Array1OfReal& Param,
3057 IntImp_ConstIsoparametric& ChoixIso)
3060 // test if the point of intersection set by these parameters remains in the
3061 // natural domain of each square.
3062 // if the point outpasses reframe to find the best iso (border)
3063 // that intersects easiest the other square
3064 // otherwise test if closed line is present
3067 Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
3068 Standard_Real DPc,DPb;
3069 Standard_Integer i = 0, k = 0;
3074 previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
3076 Standard_Real SolParam[4];
3077 myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
3079 Standard_Boolean Trouve = Standard_False;
3081 Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1;
3082 Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2;
3084 Standard_Integer im1;
3085 for ( i = 1,im1 = 0;i<=4;i++,im1++) {
3092 if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
3093 SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous
3095 Trouve = Standard_True; //--
3096 DPc = Uvp[im1]-Param(i); //-- Previous - Current
3097 DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf
3098 ParC[im1] = Uvd[im1]; //-- ParamCorrige
3099 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3101 if(dv2>RealEpsilon()) { //-- Progress at the other Direction ?
3102 Duv[im1] = DPc*DPb + dv2;
3103 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3106 Duv[im1]=-1.0; //-- If no progress, do not change
3107 } //-- the choice of iso
3109 else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
3110 SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current
3112 Trouve = Standard_True; //--
3113 DPc = Param(i)-Uvp[im1]; //-- Current - Previous
3114 DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous
3115 ParC[im1] = Uvf[im1]; //-- Param Corrige
3116 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3118 if(dv2>RealEpsilon()) { //-- Progress in other Direction ?
3119 Duv[im1] = DPc*DPb + dv2;
3120 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3123 Duv[im1]=-1.0; //-- If no progress, do not change
3124 } //-- the choice of iso
3133 //--------------------------------------------------
3134 //-- One of Parameters u1,v1,u2,v2 is outside of --
3135 //-- the natural limits. --
3136 //-- Find the best direction of --
3137 //-- progress and reframe the parameters. --
3138 //--------------------------------------------------
3139 Standard_Real ddv = -1.0;
3141 for (i=0;i<=3;i++) {
3142 Param(i+1) = ParC[i];
3149 ChoixIso = ChoixRef[k];
3152 if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
3153 ChoixIso = IntImp_UIsoparametricOnCaro1;
3155 else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
3156 ChoixIso = IntImp_VIsoparametricOnCaro1;
3158 else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
3159 ChoixIso = IntImp_UIsoparametricOnCaro2;
3161 else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
3162 ChoixIso = IntImp_VIsoparametricOnCaro2;
3165 close = Standard_False;
3166 return Standard_True;
3170 if (!DejaReparti) { // find if line closed
3173 const IntSurf_PntOn2S& POn2S1=line->Value(1);
3175 POn2S1.ParametersOnS1(u,v);
3176 gp_Pnt2d P1uvS1(u,v);
3177 previousPoint.ParametersOnS1(u,v);
3178 gp_Pnt2d PrevuvS1(u,v);
3179 myIntersectionOn2S.Point().ParametersOnS1(u,v);
3180 gp_Pnt2d myIntersuvS1(u,v);
3181 Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
3182 (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
3184 POn2S1.ParametersOnS2(u,v);
3185 gp_Pnt2d P1uvS2(u,v);
3186 previousPoint.ParametersOnS2(u,v);
3187 gp_Pnt2d PrevuvS2(u,v);
3188 myIntersectionOn2S.Point().ParametersOnS2(u,v);
3189 gp_Pnt2d myIntersuvS2(u,v);
3190 Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
3191 (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
3193 close = close2dS1 && close2dS2;
3196 else return Standard_False;