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.
15 #include <IntWalk_PWalking.ixx>
17 #include <IntWalk_StatusDeflection.hxx>
19 #include <TColgp_Array1OfPnt.hxx>
20 #include <TColStd_Array1OfReal.hxx>
22 #include <IntImp_ComputeTangence.hxx>
24 #include <Adaptor3d_HSurface.hxx>
25 #include <Adaptor3d_HSurfaceTool.hxx>
27 #include <Precision.hxx>
29 #include <math_FunctionSetRoot.hxx>
30 #include <Geom_Surface.hxx>
32 #include <Standard_Failure.hxx>
33 #include <gp_Pnt2d.hxx>
35 //==================================================================================
36 // function : IntWalk_PWalking::IntWalk_PWalking
38 // estimate of max step : To avoid abrupt changes
39 // during change of isos
40 //==================================================================================
41 void ComputePasInit(Standard_Real *pasuv,
42 Standard_Real Um1,Standard_Real UM1,
43 Standard_Real Vm1,Standard_Real VM1,
44 Standard_Real Um2,Standard_Real UM2,
45 Standard_Real Vm2,Standard_Real VM2,
46 Standard_Real _Um1,Standard_Real _UM1,
47 Standard_Real _Vm1,Standard_Real _VM1,
48 Standard_Real _Um2,Standard_Real _UM2,
49 Standard_Real _Vm2,Standard_Real _VM2,
50 const Handle(Adaptor3d_HSurface)& ,
51 const Handle(Adaptor3d_HSurface)& ,
52 const Standard_Real Increment)
54 Standard_Real du1=Abs(UM1-Um1);
55 Standard_Real dv1=Abs(VM1-Vm1);
56 Standard_Real du2=Abs(UM2-Um2);
57 Standard_Real dv2=Abs(VM2-Vm2);
59 Standard_Real _du1=Abs(_UM1-_Um1);
60 Standard_Real _dv1=Abs(_VM1-_Vm1);
61 Standard_Real _du2=Abs(_UM2-_Um2);
62 Standard_Real _dv2=Abs(_VM2-_Vm2);
64 //-- limit the reduction of uv box estimate to 0.01 natural box
65 //-- du1 : On box of Inter
66 //-- _du1 : On parametric space
67 if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1;
68 if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1;
69 if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
70 if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
72 pasuv[0]=Increment*du1;
73 pasuv[1]=Increment*dv1;
74 pasuv[2]=Increment*du2;
75 pasuv[3]=Increment*dv2;
78 //=======================================================================
79 //function : IsParallel
80 //purpose : Checks if theLine is parallel of some boundary of given
81 // surface (it is determined by theCheckSurf1 flag).
82 // Parallelism assumes small oscillations (swing is less or
83 // equal than theToler).
84 // Small lines (if first and last parameters in the Surface
85 // are almost equal) are classified as parallel (as same as
86 // any point can be considered as parallel of any line).
87 //=======================================================================
88 static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
89 const Standard_Boolean theCheckSurf1,
90 const Standard_Real theToler,
91 Standard_Boolean& theIsUparallel,
92 Standard_Boolean& theIsVparallel)
94 const Standard_Integer aNbPointsMAX = 23;
96 theIsUparallel = theIsVparallel = Standard_True;
98 Standard_Integer aNbPoints = theLine->NbPoints();
99 if(aNbPoints > aNbPointsMAX)
101 aNbPoints = aNbPointsMAX;
103 else if(aNbPoints < 3)
105 //Here we cannot estimate parallelism.
106 //Do all same as for small lines
110 Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
111 Standard_Real aNPoint = 1.0;
113 Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
114 for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
116 if(aNPoint > aNbPoints)
123 theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
125 theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
140 theIsVparallel = ((aUmax - aUmin) < theToler);
141 theIsUparallel = ((aVmax - aVmin) < theToler);
144 //=======================================================================
145 //function : Checking
146 //purpose : Check, if given point is in surface's boundaries.
147 // If "yes" then theFactTol = 0.0, else theFactTol is
148 // equal maximal deviation.
149 //=======================================================================
150 static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
151 const Handle(Adaptor3d_HSurface)& theASurf2,
152 Standard_Real& theU1,
153 Standard_Real& theV1,
154 Standard_Real& theU2,
155 Standard_Real& theV2,
156 Standard_Real& theFactTol)
158 const Standard_Real aTol = Precision::PConfusion();
159 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
160 const Standard_Real aU1bLast = theASurf1->LastUParameter();
161 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
162 const Standard_Real aU2bLast = theASurf2->LastUParameter();
163 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
164 const Standard_Real aV1bLast = theASurf1->LastVParameter();
165 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
166 const Standard_Real aV2bLast = theASurf2->LastVParameter();
168 Standard_Boolean isOnOrIn = Standard_True;
171 Standard_Real aDelta = aU1bFirst - theU1;
175 theFactTol = Max(theFactTol, aDelta);
176 isOnOrIn = Standard_False;
179 aDelta = theU1 - aU1bLast;
183 theFactTol = Max(theFactTol, aDelta);
184 isOnOrIn = Standard_False;
187 aDelta = aV1bFirst - theV1;
191 theFactTol = Max(theFactTol, aDelta);
192 isOnOrIn = Standard_False;
195 aDelta = theV1 - aV1bLast;
199 theFactTol = Max(theFactTol, aDelta);
200 isOnOrIn = Standard_False;
203 aDelta = aU2bFirst - theU2;
207 theFactTol = Max(theFactTol, aDelta);
208 isOnOrIn = Standard_False;
211 aDelta = theU2 - aU2bLast;
215 theFactTol = Max(theFactTol, aDelta);
216 isOnOrIn = Standard_False;
219 aDelta = aV2bFirst - theV2;
223 theFactTol = Max(theFactTol, aDelta);
224 isOnOrIn = Standard_False;
227 aDelta = theV2 - aV2bLast;
231 theFactTol = Max(theFactTol, aDelta);
232 isOnOrIn = Standard_False;
238 //==================================================================================
239 // function : IntWalk_PWalking::IntWalk_PWalking
241 //==================================================================================
242 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
243 const Handle(Adaptor3d_HSurface)& Caro2,
244 const Standard_Real TolTangency,
245 const Standard_Real Epsilon,
246 const Standard_Real Deflection,
247 const Standard_Real Increment )
251 close(Standard_False),
255 myIntersectionOn2S(Caro1,Caro2,TolTangency),
256 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
257 STATIC_PRECEDENT_INFLEXION(0)
259 Standard_Real KELARG=20.;
261 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
262 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
263 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
264 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
265 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
267 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
268 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
269 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
270 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
272 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
273 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
275 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
276 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
278 Standard_Real NEWRESO;
279 Standard_Real MAXVAL;
280 Standard_Real MAXVAL2;
282 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
283 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
284 NEWRESO = ResoU1 * MAXVAL ;
285 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
288 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
289 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
290 NEWRESO = ResoU2 * MAXVAL ;
291 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
294 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
295 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
296 NEWRESO = ResoV1 * MAXVAL ;
297 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
300 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
301 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
302 NEWRESO = ResoV2 * MAXVAL ;
303 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
305 pasuv[0]=pasMax*Abs(UM1-Um1);
306 pasuv[1]=pasMax*Abs(VM1-Vm1);
307 pasuv[2]=pasMax*Abs(UM2-Um2);
308 pasuv[3]=pasMax*Abs(VM2-Vm2);
310 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
311 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
312 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
313 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
316 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
317 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
320 Standard_Real t = UM1-Um1;
321 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
322 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
323 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
328 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
329 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
332 Standard_Real t = VM1-Vm1;
333 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
334 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
335 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
340 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
341 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
344 Standard_Real t = UM2-Um2;
345 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
346 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
347 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
352 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
353 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
356 Standard_Real t = VM2-Vm2;
357 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
358 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
359 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
364 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
366 for (Standard_Integer i = 0; i<=3;i++) {
369 pasInit[i] = pasSav[i] = pasuv[i];
374 //==================================================================================
375 // function : IntWalk_PWalking
377 //==================================================================================
378 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
379 const Handle(Adaptor3d_HSurface)& Caro2,
380 const Standard_Real TolTangency,
381 const Standard_Real Epsilon,
382 const Standard_Real Deflection,
383 const Standard_Real Increment,
384 const Standard_Real U1,
385 const Standard_Real V1,
386 const Standard_Real U2,
387 const Standard_Real V2)
391 close(Standard_False),
395 myIntersectionOn2S(Caro1,Caro2,TolTangency),
396 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
397 STATIC_PRECEDENT_INFLEXION(0)
399 Standard_Real KELARG=20.;
401 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
403 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
404 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
405 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
406 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
408 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
409 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
410 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
411 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
413 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
414 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
416 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
417 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
419 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
423 if(MAXVAL2 > MAXVAL) {
426 NEWRESO = ResoU1 * MAXVAL ;
427 if(NEWRESO > ResoU1) {
433 if(MAXVAL2 > MAXVAL){
436 NEWRESO = ResoU2 * MAXVAL ;
437 if(NEWRESO > ResoU2) {
443 if(MAXVAL2 > MAXVAL) {
446 NEWRESO = ResoV1 * MAXVAL ;
447 if(NEWRESO > ResoV1) {
453 if(MAXVAL2 > MAXVAL){
456 NEWRESO = ResoV2 * MAXVAL ;
457 if(NEWRESO > ResoV2) {
461 pasuv[0]=pasMax*Abs(UM1-Um1);
462 pasuv[1]=pasMax*Abs(VM1-Vm1);
463 pasuv[2]=pasMax*Abs(UM2-Um2);
464 pasuv[3]=pasMax*Abs(VM2-Vm2);
466 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
467 UM1+=KELARG*pasuv[0];
468 Um1-=KELARG*pasuv[0];
471 Standard_Real t = UM1-Um1;
472 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
473 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
474 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
480 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
481 VM1+=KELARG*pasuv[1];
482 Vm1-=KELARG*pasuv[1];
485 Standard_Real t = VM1-Vm1;
486 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
487 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
488 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
493 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
494 UM2+=KELARG*pasuv[2];
495 Um2-=KELARG*pasuv[2];
498 Standard_Real t = UM2-Um2;
499 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
500 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
501 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
507 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
508 VM2+=KELARG*pasuv[3];
509 Vm2-=KELARG*pasuv[3];
512 Standard_Real t = VM2-Vm2;
513 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
514 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
515 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
520 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
522 for (Standard_Integer i = 0; i<=3;i++) {
523 pasInit[i] = pasSav[i] = pasuv[i];
526 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
527 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
528 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
529 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
531 TColStd_Array1OfReal Par(1,4);
539 //==================================================================================
540 // function : PerformFirstPoint
542 //==================================================================================
543 Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
544 IntSurf_PntOn2S& FirstPoint)
547 close = Standard_False;
550 TColStd_Array1OfReal Param(1,4);
552 for (i=1; i<=4; ++i) {
553 Param(i) = ParDep(i);
555 //-- calculate the first solution point
556 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
558 myIntersectionOn2S.Perform(Param,Rsnld);
559 if (!myIntersectionOn2S.IsDone()) {
560 return Standard_False;
563 if (myIntersectionOn2S.IsEmpty()) {
564 return Standard_False;
567 FirstPoint = myIntersectionOn2S.Point();
568 return Standard_True;
570 //==================================================================================
571 // function : Perform
573 //==================================================================================
574 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
576 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
578 //==================================================================================
579 // function : Perform
581 //==================================================================================
582 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
583 const Standard_Real u1min,
584 const Standard_Real v1min,
585 const Standard_Real u2min,
586 const Standard_Real v2min,
587 const Standard_Real u1max,
588 const Standard_Real v1max,
589 const Standard_Real u2max,
590 const Standard_Real v2max)
592 const Standard_Real aSQDistMax = 1.0e-14;
595 Standard_Integer NbPasOKConseq=0;
596 Standard_Real pasMaxSV[4], aTmp;
597 TColStd_Array1OfReal Param(1,4);
598 IntImp_ConstIsoparametric ChoixIso;
601 done = Standard_False;
604 const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
605 const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
607 const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
608 const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
609 const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
610 const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
612 const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
613 const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
614 const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
615 const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
617 ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
618 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
620 if(pasuv[0]<100.0*ResoU1) {
621 pasuv[0]=100.0*ResoU1;
623 if(pasuv[1]<100.0*ResoV1) {
624 pasuv[1]=100.0*ResoV1;
626 if(pasuv[2]<100.0*ResoU2) {
627 pasuv[2]=100.0*ResoU2;
629 if(pasuv[3]<100.0*ResoV2) {
630 pasuv[3]=100.0*ResoV2;
633 for (Standard_Integer i=0; i<4; ++i)
640 pasInit[i] = pasSav[i] = pasuv[i];
643 line = new IntSurf_LineOn2S ();
645 for (Standard_Integer i=1; i<=4; ++i)
650 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
651 //-- pasuv[] and pasSav[] are modified during the marching
652 for(Standard_Integer i = 0; i < 4; ++i)
654 pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i];
657 //-- calculate the first solution point
658 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
660 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
661 if (!myIntersectionOn2S.IsDone())
667 if (myIntersectionOn2S.IsEmpty())
672 if(myIntersectionOn2S.IsTangent())
677 Standard_Boolean Arrive, DejaReparti;
678 const Standard_Integer RejectIndexMAX = 250000;
679 Standard_Integer IncKey, RejectIndex;
682 DejaReparti = Standard_False;
686 previousPoint = myIntersectionOn2S.Point();
687 previoustg = Standard_False;
688 previousd = myIntersectionOn2S.Direction();
689 previousd1 = myIntersectionOn2S.DirectionOnS1();
690 previousd2 = myIntersectionOn2S.DirectionOnS2();
693 firstd1 = previousd1;
694 firstd2 = previousd2;
695 tgfirst = tglast = Standard_False;
696 choixIsoSav = ChoixIso;
697 //------------------------------------------------------------
698 //-- Test if the first point of marching corresponds
699 //-- to a point on borders.
700 //-- In this case, DejaReparti is initialized as True
702 pf = previousPoint.Value();
703 Standard_Boolean bTestFirstPoint = Standard_True;
705 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
706 AddAPoint(line,previousPoint);
708 IntWalk_StatusDeflection Status = IntWalk_OK;
709 Standard_Boolean NoTestDeflection = Standard_False;
710 Standard_Real SvParam[4], f;
711 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
712 Standard_Integer LevelOfPointConfondu = 0;
713 Standard_Integer LevelOfIterWithoutAppend = -1;
715 Arrive = Standard_False;
718 LevelOfIterWithoutAppend++;
719 if(LevelOfIterWithoutAppend>20)
721 Arrive = Standard_True;
725 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
726 LevelOfIterWithoutAppend = 0;
732 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
733 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
734 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
735 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
743 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
746 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
748 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
749 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
750 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
751 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
753 aIncKey=5.*(Standard_Real)IncKey;
755 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
760 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
765 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
770 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
780 //==========================
786 Standard_Integer aTryNumber = 0;
787 Standard_Real isBadPoint = Standard_False;
788 IntImp_ConstIsoparametric aBestIso = ChoixIso;
791 isBadPoint = Standard_False;
793 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
795 if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
797 Standard_Real aNewPnt[4], anAbsParamDist[4];
798 myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
800 if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
801 aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
802 aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
803 aNewPnt[3] < v2min || aNewPnt[3] > v2max)
805 break; // Out of borders, handle this later.
808 anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
809 anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
810 anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
811 anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
812 if (anAbsParamDist[0] < ResoU1 &&
813 anAbsParamDist[1] < ResoV1 &&
814 anAbsParamDist[2] < ResoU2 &&
815 anAbsParamDist[3] < ResoV2 &&
816 Status != IntWalk_PasTropGrand)
818 isBadPoint = Standard_True;
819 aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
822 } while (isBadPoint && ++aTryNumber <= 4);
824 if (!myIntersectionOn2S.IsDone())
826 //end of line, division
827 Arrive = Standard_False;
832 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
836 //== Calculation of exact point from Param(.) is possible
837 if (myIntersectionOn2S.IsEmpty())
839 Standard_Real u1,v1,u2,v2;
840 previousPoint.Parameters(u1,v1,u2,v2);
842 Arrive = Standard_False;
843 if(u1<UFirst1 || u1>ULast1)
845 Arrive=Standard_True;
848 if(u2<UFirst2 || u2>ULast2)
850 Arrive=Standard_True;
853 if(v1<VFirst1 || v1>VLast1)
855 Arrive=Standard_True;
858 if(v2<VFirst2 || v2>VLast2)
860 Arrive=Standard_True;
863 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
864 LevelOfEmptyInmyIntersectionOn2S++;
866 if(LevelOfEmptyInmyIntersectionOn2S>10)
876 //============================================================
877 //== A point has been found : T E S T D E F L E C T I O N
878 //============================================================
881 NoTestDeflection = Standard_False;
885 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
887 LevelOfEmptyInmyIntersectionOn2S=0;
888 if(LevelOfIterWithoutAppend < 10)
890 Status = TestDeflection();
902 //============================================================
903 //== T r a i t e m e n t s u r S t a t u s ==
904 //============================================================
905 if(LevelOfPointConfondu > 5)
907 Status = IntWalk_ArretSurPoint;
908 LevelOfPointConfondu = 0;
911 if(Status==IntWalk_OK)
914 if(NbPasOKConseq >= 5)
917 Standard_Boolean pastroppetit;
922 pastroppetit=Standard_True;
924 if(pasuv[0]<pasInit[0])
926 t = (pasInit[0]-pasuv[0])*0.25;
933 pastroppetit=Standard_False;
936 if(pasuv[1]<pasInit[1])
938 t = (pasInit[1]-pasuv[1])*0.25;
939 if(t>0.1*pasInit[1]) {
944 pastroppetit=Standard_False;
947 if(pasuv[2]<pasInit[2])
949 t = (pasInit[2]-pasuv[2])*0.25;
956 pastroppetit=Standard_False;
959 if(pasuv[3]<pasInit[3])
961 t = (pasInit[3]-pasuv[3])*0.25;
962 if(t>0.1*pasInit[3]) {
966 pastroppetit=Standard_False;
980 pastroppetit=Standard_False;
986 }//Status==IntWalk_OK
993 case IntWalk_ArretSurPointPrecedent:
995 Arrive = Standard_False;
996 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
999 case IntWalk_PasTropGrand:
1001 Param(1)=SvParam[0];
1002 Param(2)=SvParam[1];
1003 Param(3)=SvParam[2];
1004 Param(4)=SvParam[3];
1006 if(LevelOfIterWithoutAppend > 5)
1008 if(pasSav[0]<pasInit[0])
1010 pasInit[0]-=(pasInit[0]-pasSav[0])*0.25;
1011 LevelOfIterWithoutAppend=0;
1014 if(pasSav[1]<pasInit[1])
1016 pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;
1017 LevelOfIterWithoutAppend=0;
1020 if(pasSav[2]<pasInit[2])
1022 pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;
1023 LevelOfIterWithoutAppend=0;
1026 if(pasSav[3]<pasInit[3])
1028 pasInit[3]-=(pasInit[3]-pasSav[3])*0.25;
1029 LevelOfIterWithoutAppend=0;
1035 case IntWalk_PointConfondu:
1037 LevelOfPointConfondu++;
1039 if(LevelOfPointConfondu>5)
1041 Standard_Boolean pastroppetit;
1045 pastroppetit=Standard_True;
1047 if(pasuv[0]<pasInit[0])
1049 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
1050 pastroppetit=Standard_False;
1053 if(pasuv[1]<pasInit[1])
1055 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
1056 pastroppetit=Standard_False;
1059 if(pasuv[2]<pasInit[2])
1061 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
1062 pastroppetit=Standard_False;
1065 if(pasuv[3]<pasInit[3])
1067 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
1068 pastroppetit=Standard_False;
1083 pastroppetit=Standard_False;
1087 while(pastroppetit);
1093 case IntWalk_ArretSurPoint://006
1095 //=======================================================
1096 //== Stop Test t : Frame on Param(.) ==
1097 //=======================================================
1099 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1100 // JMB 30th December 1999.
1101 // Some statement below should not be put in comment because they are useful.
1102 // See grid CTO 909 A1 which infinitely loops
1103 if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint)
1105 Arrive=Standard_True;
1107 cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
1113 NbPasOKConseq = -10;
1118 //=====================================================
1119 //== Param(.) is in the limits ==
1120 //== and does not end a closed line ==
1121 //=====================================================
1122 //== Check on the current point of myInters
1123 Standard_Boolean pointisvalid = Standard_False;
1125 Standard_Real u1,v1,u2,v2;
1126 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1129 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1130 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1131 v1 >= Vm1 && v2 >= Vm2)
1133 pointisvalid=Standard_True;
1140 previousPoint = myIntersectionOn2S.Point();
1141 previoustg = myIntersectionOn2S.IsTangent();
1145 previousd = myIntersectionOn2S.Direction();
1146 previousd1 = myIntersectionOn2S.DirectionOnS1();
1147 previousd2 = myIntersectionOn2S.DirectionOnS2();
1149 //=====================================================
1150 //== Check on the previous Point
1152 Standard_Real u1,v1,u2,v2;
1153 previousPoint.Parameters(u1,v1,u2,v2);
1154 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1155 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1156 v1 >= Vm1 && v2 >= Vm2)
1158 pl = previousPoint.Value();
1161 if(pf.SquareDistance(pl) < aSQDistMax)
1171 bTestFirstPoint = Standard_False;
1175 AddAPoint(line,previousPoint);
1178 if(RejectIndex >= RejectIndexMAX)
1184 LevelOfIterWithoutAppend = 0;
1188 //====================================================
1190 if(Status == IntWalk_ArretSurPoint)
1192 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1196 if (line->NbPoints() == 2)
1198 pasSav[0] = pasuv[0];
1199 pasSav[1] = pasuv[1];
1200 pasSav[2] = pasuv[2];
1201 pasSav[3] = pasuv[3];
1209 //================= la ligne est fermee ===============
1210 AddAPoint(line,line->Value(1)); //ligne fermee
1211 LevelOfIterWithoutAppend=0;
1215 //====================================================
1216 //== Param was not in the limits (was reframed)
1217 //====================================================
1218 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1220 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1221 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1223 if(!myIntersectionOn2S.IsEmpty()) //002
1225 // mutially outpasses in the square or intersection in corner
1227 if(TestArret(Standard_True,Param,ChoixIso))
1229 NbPasOKConseq = -10;
1230 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1232 if(!myIntersectionOn2S.IsEmpty())
1234 previousPoint = myIntersectionOn2S.Point();
1235 previoustg = myIntersectionOn2S.IsTangent();
1239 previousd = myIntersectionOn2S.Direction();
1240 previousd1 = myIntersectionOn2S.DirectionOnS1();
1241 previousd2 = myIntersectionOn2S.DirectionOnS2();
1244 pl = previousPoint.Value();
1248 if(pf.SquareDistance(pl) < aSQDistMax)
1258 bTestFirstPoint = Standard_False;
1262 AddAPoint(line,previousPoint);
1265 if(RejectIndex >= RejectIndexMAX)
1271 LevelOfIterWithoutAppend=0;
1272 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1276 //fail framing divides the step
1277 Arrive = Standard_False;
1278 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1279 NoTestDeflection = Standard_True;
1280 ChoixIso = SauvChoixIso;
1285 // save the last point
1286 // to revert to it if the current point is out of bounds
1288 IntSurf_PntOn2S previousPointSave = previousPoint;
1289 Standard_Boolean previoustgSave = previoustg;
1290 gp_Dir previousdSave = previousd;
1291 gp_Dir2d previousd1Save = previousd1;
1292 gp_Dir2d previousd2Save = previousd2;
1294 previousPoint = myIntersectionOn2S.Point();
1295 previoustg = myIntersectionOn2S.IsTangent();
1296 Arrive = Standard_False;
1300 previousd = myIntersectionOn2S.Direction();
1301 previousd1 = myIntersectionOn2S.DirectionOnS1();
1302 previousd2 = myIntersectionOn2S.DirectionOnS2();
1305 //========================================
1306 //== Check on PreviousPoint @@
1309 Standard_Real u1,v1,u2,v2;
1310 previousPoint.Parameters(u1,v1,u2,v2);
1312 //To save initial 2d points
1313 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1314 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1316 ///////////////////////////
1324 Standard_Boolean bFlag1, bFlag2;
1325 Standard_Real aTol2D=1.e-11;
1327 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1328 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1329 if (bFlag1 && bFlag2)
1331 if (line->NbPoints() > 1)
1333 IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1334 Standard_Real ppU1, ppV1, ppU2, ppV2;
1335 prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1336 Standard_Real pU1, pV1, pU2, pV2;
1337 previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1338 gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1339 gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1340 gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1341 gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1342 if (V1onS1 * V2onS1 < 0. ||
1343 V1onS2 * V2onS2 < 0.)
1345 Arrive = Standard_True;
1350 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1351 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1352 v1 >= Vm1 && v2 >= Vm2) {
1355 pl = previousPoint.Value();
1359 if(pf.SquareDistance(pl) < aSQDistMax)
1370 bTestFirstPoint = Standard_False;
1374 //To avoid walking around the same point
1375 //in the tangent zone near a border
1379 Standard_Real prevU1, prevV1, prevU2, prevV2;
1380 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1381 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1382 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1383 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1384 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1385 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1386 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1387 Standard_Real MaxAngle = 3*M_PI/4;
1389 if (Abs(PrevToParamOnS1.Angle(PrevToCurOnS1)) > MaxAngle &&
1390 Abs(PrevToParamOnS2.Angle(PrevToCurOnS2)) > MaxAngle)
1392 Arrive = Standard_True;
1397 ////////////////////////////////////////
1398 AddAPoint(line,previousPoint);
1401 if(RejectIndex >= RejectIndexMAX)
1408 LevelOfIterWithoutAppend=0;
1409 Arrive = Standard_True;
1413 // revert to the last correctly calculated point
1414 previousPoint = previousPointSave;
1415 previoustg = previoustgSave;
1416 previousd = previousdSave;
1417 previousd1 = previousd1Save;
1418 previousd2 = previousd2Save;
1423 Standard_Boolean wasExtended = Standard_False;
1425 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1427 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1429 wasExtended = Standard_True;
1430 Arrive = Standard_False;
1431 ChoixIso = SauvChoixIso;
1435 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1438 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1439 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1442 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1444 wasExtended = Standard_True;
1445 Arrive = Standard_False;
1446 ChoixIso = SauvChoixIso;
1449 }//else !TestArret() $
1450 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1453 //echec framing on border; division of step
1454 Arrive = Standard_False;
1455 NoTestDeflection = Standard_True;
1456 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1458 }//$$$ end framing on border (!close)
1459 }//004 fin TestArret return Arrive = True
1460 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1461 } //007 switch(Status)
1462 } //008 end processing point (TEST DEFLECTION)
1463 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1464 } //010 end if first departure point allows marching while (!Arrive)
1466 done = Standard_True;
1468 // ===========================================================================================================
1469 // function: ExtendLineInCommonZone
1470 // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1471 // Returns Standard_True if the line was extended through tangent zone and the last computed point
1472 // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1473 // ===========================================================================================================
1474 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1475 const Standard_Boolean theDirectionFlag)
1477 Standard_Boolean bOutOfTangentZone = Standard_False;
1478 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1479 Standard_Integer dIncKey = 1;
1480 TColStd_Array1OfReal Param(1,4);
1481 IntWalk_StatusDeflection Status = IntWalk_OK;
1482 Standard_Integer nbIterWithoutAppend = 0;
1483 Standard_Integer nbEqualPoints = 0;
1484 Standard_Integer parit = 0;
1485 Standard_Integer uvit = 0;
1486 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1489 nbIterWithoutAppend++;
1491 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1493 cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1495 bStop = Standard_True;
1498 Standard_Real f = 0.;
1500 switch (theChoixIso)
1502 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1503 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1504 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1505 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1510 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1512 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1513 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1514 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1515 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1517 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1518 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1519 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1520 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1526 Standard_Real SvParam[4];
1527 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1529 for(parit = 0; parit < 4; parit++) {
1530 SvParam[parit] = Param(parit+1);
1532 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1533 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1535 if (!myIntersectionOn2S.IsDone()) {
1536 return bOutOfTangentZone;
1539 if (myIntersectionOn2S.IsEmpty()) {
1540 return bOutOfTangentZone;
1543 Status = TestDeflection();
1545 if(Status == IntWalk_OK) {
1547 for(uvit = 0; uvit < 4; uvit++) {
1548 if(pasuv[uvit] < pasInit[uvit]) {
1549 pasuv[uvit] = pasInit[uvit];
1555 case IntWalk_ArretSurPointPrecedent:
1557 bStop = Standard_True;
1558 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1561 case IntWalk_PasTropGrand:
1563 for(parit = 0; parit < 4; parit++) {
1564 Param(parit+1) = SvParam[parit];
1566 Standard_Boolean bDecrease = Standard_False;
1568 for(uvit = 0; uvit < 4; uvit++) {
1569 if(pasSav[uvit] < pasInit[uvit]) {
1570 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1571 bDecrease = Standard_True;
1575 if(bDecrease) nbIterWithoutAppend--;
1578 case IntWalk_PointConfondu:
1580 for(uvit = 0; uvit < 4; uvit++) {
1581 if(pasuv[uvit] < pasInit[uvit]) {
1582 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1588 case IntWalk_ArretSurPoint:
1591 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1596 Standard_Real u11,v11,u12,v12;
1597 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1598 Standard_Real u21,v21,u22,v22;
1599 previousPoint.Parameters(u21,v21,u22,v22);
1601 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1602 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1611 bStop = bStop || !myIntersectionOn2S.IsTangent();
1612 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1615 Standard_Boolean pointisvalid = Standard_False;
1616 Standard_Real u1,v1,u2,v2;
1617 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1619 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1620 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1621 v1 >= Vm1 && v2 >= Vm2)
1622 pointisvalid = Standard_True;
1625 previousPoint = myIntersectionOn2S.Point();
1626 previoustg = myIntersectionOn2S.IsTangent();
1629 previousd = myIntersectionOn2S.Direction();
1630 previousd1 = myIntersectionOn2S.DirectionOnS1();
1631 previousd2 = myIntersectionOn2S.DirectionOnS2();
1633 Standard_Boolean bAddPoint = Standard_True;
1635 if(line->NbPoints() >= 1) {
1636 gp_Pnt pf = line->Value(1).Value();
1637 gp_Pnt pl = previousPoint.Value();
1639 if(pf.Distance(pl) < Precision::Confusion()) {
1641 if(dIncKey == 5000) return bOutOfTangentZone;
1642 else bAddPoint = Standard_False;
1647 aSeqOfNewPoint.Append(previousPoint);
1648 nbIterWithoutAppend = 0;
1652 if (line->NbPoints() == 2) {
1653 for(uvit = 0; uvit < 4; uvit++) {
1654 pasSav[uvit] = pasuv[uvit];
1658 if ( !pointisvalid ) {
1659 // decrease step if out of bounds
1660 // otherwise the same calculations will be
1661 // repeated several times
1662 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1665 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1668 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1671 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1676 if(close && (line->NbPoints() >= 1)) {
1678 if(!bOutOfTangentZone) {
1679 aSeqOfNewPoint.Append(line->Value(1)); // line end
1681 nbIterWithoutAppend = 0;
1684 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1686 if(myIntersectionOn2S.IsEmpty()) {
1687 bStop = !myIntersectionOn2S.IsTangent();
1688 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1691 Standard_Boolean bAddPoint = Standard_True;
1692 Standard_Boolean pointisvalid = Standard_False;
1694 previousPoint = myIntersectionOn2S.Point();
1695 Standard_Real u1,v1,u2,v2;
1696 previousPoint.Parameters(u1,v1,u2,v2);
1698 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1699 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1700 v1 >= Vm1 && v2 >= Vm2)
1701 pointisvalid = Standard_True;
1705 if(line->NbPoints() >= 1) {
1706 gp_Pnt pf = line->Value(1).Value();
1707 gp_Pnt pl = previousPoint.Value();
1709 if(pf.Distance(pl) < Precision::Confusion()) {
1711 if(dIncKey == 5000) return bOutOfTangentZone;
1712 else bAddPoint = Standard_False;
1716 if(bAddPoint && !bOutOfTangentZone) {
1717 aSeqOfNewPoint.Append(previousPoint);
1718 nbIterWithoutAppend = 0;
1733 Standard_Boolean bExtendLine = Standard_False;
1734 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1736 Standard_Integer pit = 0;
1738 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1740 previousPoint.Parameters(u1,v1,u2,v2);
1742 if(aSeqOfNewPoint.Length() > 0)
1743 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1748 if(((u1 - Um1) < ResoU1) ||
1749 ((UM1 - u1) < ResoU1) ||
1750 ((u2 - Um2) < ResoU2) ||
1751 ((UM2 - u2) < ResoU2) ||
1752 ((v1 - Vm1) < ResoV1) ||
1753 ((VM1 - v1) < ResoV1) ||
1754 ((v2 - Vm2) < ResoV2) ||
1755 ((VM2 - v2) < ResoV2))
1756 bExtendLine = Standard_True;
1760 // if(Status == IntWalk_OK || Status == IntWalk_ArretSurPoint) {
1761 if(Status == IntWalk_OK) {
1762 bExtendLine = Standard_True;
1764 if(aSeqOfNewPoint.Length() > 1) {
1765 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1766 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1768 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1769 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1770 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1771 LastParams.ChangeValue(1),
1772 LastParams.ChangeValue(2),
1773 LastParams.ChangeValue(3));
1774 Standard_Integer indexofiso = 0;
1776 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1777 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1778 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1779 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1781 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1782 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1783 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1785 gp_Dir2d anIsoDir(0, 1);
1787 if((indexofiso == 1) || (indexofiso == 3))
1788 anIsoDir = gp_Dir2d(1, 0);
1790 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1791 Standard_Real piquota = M_PI*0.25;
1793 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1794 Standard_Integer ii = 1, nextii = 2;
1796 Standard_Real asqresol = gp::Resolution();
1797 asqresol *= asqresol;
1800 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1801 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1802 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1803 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1804 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1805 FirstParams.Value(afirstindex + 1)),
1806 gp_Pnt2d(LastParams.Value(afirstindex),
1807 LastParams.Value(afirstindex + 1)));
1810 while((d1.SquareMagnitude() < asqresol) &&
1811 (ii < aSeqOfNewPoint.Length()));
1815 while(nextii < aSeqOfNewPoint.Length()) {
1817 gp_Vec2d nextd1(0, 0);
1818 Standard_Integer jj = nextii;
1821 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1822 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1823 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
1824 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
1825 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
1826 FirstParams.Value(afirstindex + 1)),
1827 gp_Pnt2d(LastParams.Value(afirstindex),
1828 LastParams.Value(afirstindex + 1)));
1832 while((nextd1.SquareMagnitude() < asqresol) &&
1833 (jj < aSeqOfNewPoint.Length()));
1836 if(fabs(d1.Angle(nextd1)) > piquota) {
1837 bExtendLine = Standard_False;
1843 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
1850 return Standard_False;
1852 Standard_Integer i = 0;
1854 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
1855 AddAPoint(line, aSeqOfNewPoint.Value(i));
1858 return bOutOfTangentZone;
1861 //=======================================================================
1862 //function : DistanceMinimizeByGradient
1864 //=======================================================================
1865 Standard_Boolean IntWalk_PWalking::
1866 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
1867 const Handle(Adaptor3d_HSurface)& theASurf2,
1868 Standard_Real& theU1,
1869 Standard_Real& theV1,
1870 Standard_Real& theU2,
1871 Standard_Real& theV2,
1872 const Standard_Real theStep0U1V1,
1873 const Standard_Real theStep0U2V2)
1875 const Standard_Integer aNbIterMAX = 60;
1876 const Standard_Real aTol = 1.0e-14;
1877 Handle(Geom_Surface) aS1, aS2;
1879 switch(theASurf1->GetType())
1881 case GeomAbs_BezierSurface:
1882 aS1 = theASurf1->Surface().Bezier();
1884 case GeomAbs_BSplineSurface:
1885 aS1 = theASurf1->Surface().BSpline();
1888 return Standard_True;
1891 switch(theASurf2->GetType())
1893 case GeomAbs_BezierSurface:
1894 aS2 = theASurf2->Surface().Bezier();
1896 case GeomAbs_BSplineSurface:
1897 aS2 = theASurf2->Surface().BSpline();
1900 return Standard_True;
1903 Standard_Boolean aStatus = Standard_False;
1906 gp_Vec aD1u, aD1v, aD2U, aD2V;
1908 aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
1909 aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
1911 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
1913 gp_Vec aP12(aP1, aP2);
1915 Standard_Real aGradFu(-aP12.Dot(aD1u));
1916 Standard_Real aGradFv(-aP12.Dot(aD1v));
1917 Standard_Real aGradFU( aP12.Dot(aD2U));
1918 Standard_Real aGradFV( aP12.Dot(aD2V));
1920 Standard_Real aSTEPuv = theStep0U1V1, aStepUV = theStep0U2V2;
1922 Standard_Boolean flRepeat = Standard_True;
1923 Standard_Integer aNbIter = aNbIterMAX;
1927 Standard_Real anAdd = aGradFu*aSTEPuv;
1928 Standard_Real aPARu = (anAdd >= 0.0)?
1929 (theU1 - Max(anAdd, Epsilon(theU1))) :
1930 (theU1 + Max(-anAdd, Epsilon(theU1)));
1931 anAdd = aGradFv*aSTEPuv;
1932 Standard_Real aPARv = (anAdd >= 0.0)?
1933 (theV1 - Max(anAdd, Epsilon(theV1))) :
1934 (theV1 + Max(-anAdd, Epsilon(theV1)));
1935 anAdd = aGradFU*aStepUV;
1936 Standard_Real aParU = (anAdd >= 0.0)?
1937 (theU2 - Max(anAdd, Epsilon(theU2))) :
1938 (theU2 + Max(-anAdd, Epsilon(theU2)));
1939 anAdd = aGradFV*aStepUV;
1940 Standard_Real aParV = (anAdd >= 0.0)?
1941 (theV2 - Max(anAdd, Epsilon(theV2))) :
1942 (theV2 + Max(-anAdd, Epsilon(theV2)));
1946 aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
1947 aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
1949 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
1951 if(aSQDist < aSQDistPrev)
1953 aSQDistPrev = aSQDist;
1959 aStatus = aSQDistPrev < aTol;
1967 flRepeat = Standard_False;
1971 aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
1972 aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
1974 gp_Vec aP12(aPt1, aPt2);
1975 aGradFu = -aP12.Dot(aD1u);
1976 aGradFv = -aP12.Dot(aD1v);
1977 aGradFU = aP12.Dot(aD2U);
1978 aGradFV = aP12.Dot(aD2V);
1979 aSTEPuv = theStep0U1V1;
1980 aStepUV = theStep0U2V2;
1988 //=======================================================================
1989 //function : DistanceMinimizeByExtrema
1991 //=======================================================================
1992 Standard_Boolean IntWalk_PWalking::
1993 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
1994 const gp_Pnt& theP0,
1995 Standard_Real& theU0,
1996 Standard_Real& theV0,
1997 const Standard_Real theStep0U,
1998 const Standard_Real theStep0V)
2000 const Standard_Real aTol = 1.0e-14;
2002 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2003 Standard_Real aSQDistPrev = RealLast();
2004 Standard_Real aU = theU0, aV = theV0;
2006 Standard_Integer aNbIter = 10;
2009 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2011 gp_Vec aVec(theP0, aPS);
2013 Standard_Real aSQDist = aVec.SquareMagnitude();
2015 if(aSQDist >= aSQDistPrev)
2018 aSQDistPrev = aSQDist;
2023 if(aSQDistPrev < aTol)
2027 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2030 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2031 aDf1v = aD2Su.Dot(aD1Sv),
2033 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2035 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2036 aU -= theStep0U*(aDf2v*aF1 - aDf1v*aF2)/aDet;
2037 aV += theStep0V*(aDf2u*aF1 - aDf1u*aF2)/aDet;
2041 return (aSQDistPrev < aTol);
2044 //=======================================================================
2045 //function : SeekPointOnBoundary
2047 //=======================================================================
2048 Standard_Boolean IntWalk_PWalking::
2049 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2050 const Handle(Adaptor3d_HSurface)& theASurf2,
2051 const Standard_Real theU1,
2052 const Standard_Real theV1,
2053 const Standard_Real theU2,
2054 const Standard_Real theV2,
2055 const Standard_Boolean isTheFirst)
2057 const Standard_Real aTol = 1.0e-14;
2058 Standard_Boolean isOK = Standard_False;
2059 Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
2061 Standard_Boolean flFinish = Standard_False;
2063 Standard_Integer aNbIter = 20;
2066 flFinish = Standard_False;
2067 Standard_Boolean aStatus = Standard_False;
2072 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2078 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2084 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2090 while(!aStatus && (aNbIter > 0));
2094 const Standard_Real aTolMax = 1.0e-8;
2095 Standard_Real aTolF = 0.0;
2097 Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
2099 flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
2101 if(aTolF <= aTolMax)
2103 gp_Pnt aP1 = theASurf1->Value(u1, v1),
2104 aP2 = theASurf2->Value(u2, v2);
2105 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2107 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2108 aSQDist2 = aPInt.SquareDistance(aP2);
2109 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2111 IntSurf_PntOn2S anIP;
2112 anIP.SetValue(aPInt, u1, v1, u2, v2);
2115 line->InsertBefore(1,anIP);
2119 isOK = Standard_True;
2135 //=======================================================================
2136 //function : PutToBoundary
2138 //=======================================================================
2139 Standard_Boolean IntWalk_PWalking::
2140 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2141 const Handle(Adaptor3d_HSurface)& theASurf2)
2143 const Standard_Real aTolMin = Precision::Confusion();
2145 Standard_Boolean hasBeenAdded = Standard_False;
2147 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2148 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2149 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2150 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2151 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2152 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2153 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2154 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2156 Standard_Real aTol = 1.0;
2157 aTol = Min(aTol, aU1bLast - aU1bFirst);
2158 aTol = Min(aTol, aU2bLast - aU2bFirst);
2159 aTol = Min(aTol, aV1bLast - aV1bFirst);
2160 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2162 if(aTol <= 2.0*aTolMin)
2163 return hasBeenAdded;
2165 Standard_Boolean isNeedAdding = Standard_False;
2166 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2167 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2168 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2169 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2171 const Standard_Integer aNbPnts = line->NbPoints();
2172 Standard_Real u1, v1, u2, v2;
2173 line->Value(1).Parameters(u1, v1, u2, v2);
2174 Standard_Real aDelta = 0.0;
2178 aDelta = u1 - aU1bFirst;
2179 if((aTolMin < aDelta) && (aDelta < aTol))
2181 u1 = aU1bFirst - aDelta;
2182 isNeedAdding = Standard_True;
2186 aDelta = aU1bLast - u1;
2187 if((aTolMin < aDelta) && (aDelta < aTol))
2189 u1 = aU1bLast + aDelta;
2190 isNeedAdding = Standard_True;
2197 aDelta = u2 - aU2bFirst;
2198 if((aTolMin < aDelta) && (aDelta < aTol))
2200 u2 = aU2bFirst - aDelta;
2201 isNeedAdding = Standard_True;
2205 aDelta = aU2bLast - u2;
2206 if((aTolMin < aDelta) && (aDelta < aTol))
2208 u2 = aU2bLast + aDelta;
2209 isNeedAdding = Standard_True;
2216 aDelta = v1 - aV1bFirst;
2217 if((aTolMin < aDelta) && (aDelta < aTol))
2219 v1 = aV1bFirst - aDelta;
2220 isNeedAdding = Standard_True;
2224 aDelta = aV1bLast - v1;
2225 if((aTolMin < aDelta) && (aDelta < aTol))
2227 v1 = aV1bLast + aDelta;
2228 isNeedAdding = Standard_True;
2235 aDelta = v2 - aV2bFirst;
2236 if((aTolMin < aDelta) && (aDelta < aTol))
2238 v2 = aV2bFirst - aDelta;
2239 isNeedAdding = Standard_True;
2243 aDelta = aV2bLast - v2;
2244 if((aTolMin < aDelta) && (aDelta < aTol))
2246 v2 = aV2bLast + aDelta;
2247 isNeedAdding = Standard_True;
2255 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2256 v1, u2, v2, Standard_True);
2259 isNeedAdding = Standard_False;
2260 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2264 aDelta = u1 - aU1bFirst;
2265 if((aTolMin < aDelta) && (aDelta < aTol))
2267 u1 = aU1bFirst - aDelta;
2268 isNeedAdding = Standard_True;
2272 aDelta = aU1bLast - u1;
2273 if((aTolMin < aDelta) && (aDelta < aTol))
2275 u1 = aU1bLast + aDelta;
2276 isNeedAdding = Standard_True;
2283 aDelta = u2 - aU2bFirst;
2284 if((aTolMin < aDelta) && (aDelta < aTol))
2286 u2 = aU2bFirst - aDelta;
2287 isNeedAdding = Standard_True;
2291 aDelta = aU2bLast - u2;
2292 if((aTolMin < aDelta) && (aDelta < aTol))
2294 u2 = aU2bLast + aDelta;
2295 isNeedAdding = Standard_True;
2302 aDelta = v1 - aV1bFirst;
2303 if((aTolMin < aDelta) && (aDelta < aTol))
2305 v1 = aV1bFirst - aDelta;
2306 isNeedAdding = Standard_True;
2310 aDelta = aV1bLast - v1;
2311 if((aTolMin < aDelta) && (aDelta < aTol))
2313 v1 = aV1bLast + aDelta;
2314 isNeedAdding = Standard_True;
2321 aDelta = v2 - aV2bFirst;
2322 if((aTolMin < aDelta) && (aDelta < aTol))
2324 v2 = aV2bFirst - aDelta;
2325 isNeedAdding = Standard_True;
2329 aDelta = aV2bLast - v2;
2330 if((aTolMin < aDelta) && (aDelta < aTol))
2332 v2 = aV2bLast + aDelta;
2333 isNeedAdding = Standard_True;
2341 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2342 v1, u2, v2, Standard_False);
2345 return hasBeenAdded;
2348 //=======================================================================
2349 //function : SeekAdditionalPoints
2351 //=======================================================================
2352 Standard_Boolean IntWalk_PWalking::
2353 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2354 const Handle(Adaptor3d_HSurface)& theASurf2,
2355 const Standard_Integer theMinNbPoints)
2357 const Standard_Real aTol = 1.0e-14;
2358 Standard_Integer aNbPoints = line->NbPoints();
2359 if(aNbPoints > theMinNbPoints)
2360 return Standard_True;
2362 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2363 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2364 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2365 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2366 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2367 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2368 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2369 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2372 Standard_Boolean isPrecise = Standard_False;
2374 Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
2376 Standard_Integer aNbPointsPrev = 0;
2377 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2379 aNbPointsPrev = aNbPoints;
2380 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2382 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2383 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2386 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2387 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2389 U1prec = 0.5*(U1f+U1l);
2390 if(U1prec < aU1bFirst)
2392 if(U1prec > aU1bLast)
2395 V1prec = 0.5*(V1f+V1l);
2396 if(V1prec < aV1bFirst)
2398 if(V1prec > aV1bLast)
2401 U2prec = 0.5*(U2f+U2l);
2402 if(U2prec < aU2bFirst)
2404 if(U2prec > aU2bLast)
2407 V2prec = 0.5*(V2f+V2l);
2408 if(V2prec < aV2bFirst)
2410 if(V2prec > aV2bLast)
2413 Standard_Boolean aStatus = Standard_False;
2414 Standard_Integer aNbIter = 5;
2417 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
2423 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
2429 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
2435 while(!aStatus && (--aNbIter > 0));
2439 gp_Pnt aP1 = theASurf1->Value(U1prec, V1prec),
2440 aP2 = theASurf2->Value(U2prec, V2prec);
2441 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2443 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2444 aSQDist2 = aPInt.SquareDistance(aP2);
2446 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2448 IntSurf_PntOn2S anIP;
2449 anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
2450 line->InsertBefore(lp, anIP);
2452 isPrecise = Standard_True;
2454 if(++aNbPoints >= theMinNbPoints)
2468 void IntWalk_PWalking::
2469 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2470 IntImp_ConstIsoparametric& ChoixIso,
2471 Standard_Boolean& Arrive)
2473 // at the neighborhood of a point, there is a fail of marching
2474 // it is required to divide the steps to try to continue
2475 // if the step is too small if we are on border
2476 // restart in another direction if it was not done, otherwise stop
2479 // Standard_Integer i;
2480 if (Arrive) { //restart in the other direction
2481 if (!DejaReparti ) {
2482 Arrive = Standard_False;
2483 DejaReparti = Standard_True;
2484 previousPoint = line->Value(1);
2485 previoustg = Standard_False;
2486 previousd1 = firstd1;
2487 previousd2 = firstd2;
2489 indextg = line->NbPoints();
2493 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2494 sensCheminement = -1;
2496 tglast = Standard_False;
2497 ChoixIso = choixIsoSav;
2504 Standard_Real u1,v1,u2,v2;
2505 Standard_Real U1,V1,U2,V2;
2506 Standard_Integer nn=line->NbPoints();
2508 line->Value(nn).Parameters(u1,v1,u2,v2);
2509 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2510 pasuv[0]=Abs(u1-U1);
2511 pasuv[1]=Abs(v1-V1);
2512 pasuv[2]=Abs(u2-U2);
2513 pasuv[3]=Abs(v2-V2);
2520 if ( pasuv[0]*0.5 < ResoU1
2521 && pasuv[1]*0.5 < ResoV1
2522 && pasuv[2]*0.5 < ResoU2
2523 && pasuv[3]*0.5 < ResoV2
2526 tglast = Standard_True; // IS IT ENOUGH ????
2529 if (!DejaReparti) { //restart in the other direction
2530 DejaReparti = Standard_True;
2531 previousPoint = line->Value(1);
2532 previoustg = Standard_False;
2533 previousd1 = firstd1;
2534 previousd2 = firstd2;
2536 indextg = line->NbPoints();
2540 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2542 sensCheminement = -1;
2544 tglast = Standard_False;
2545 ChoixIso = choixIsoSav;
2553 Standard_Real u1,v1,u2,v2;
2554 Standard_Real U1,V1,U2,V2;
2555 Standard_Integer nn=line->NbPoints();
2557 line->Value(nn).Parameters(u1,v1,u2,v2);
2558 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2559 pasuv[0]=Abs(u1-U1);
2560 pasuv[1]=Abs(v1-V1);
2561 pasuv[2]=Abs(u2-U2);
2562 pasuv[3]=Abs(v2-V2);
2566 else Arrive = Standard_True;
2578 //OCC431(apo): modified ->
2579 static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
2581 static const Standard_Real d = 7.0;
2584 IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
2586 // test if vector is observed by calculating an increase of vector
2587 // or the previous point and its tangent, the new calculated point and its
2588 // tangent; it is possible to find a cube passing by the 2 points and having as a
2589 // derivative the tangents of the intersection
2590 // calculate the point with parameter 0.5 on cube=p1
2591 // calculate the medium point of 2 points of intersection=p2
2592 // if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2593 // otherwise adjust the step depending on the ratio ||p1p2||/vector
2594 // and the previous step
2595 // test if in 2 tangent planes of surfaces there is no too great angle2d
2596 // grand : if yes divide the step
2597 // test if there is no change of side
2600 if(line->NbPoints() ==1 ) {
2601 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
2604 IntWalk_StatusDeflection Status = IntWalk_OK;
2605 Standard_Real FlecheCourante ,Ratio;
2608 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
2609 //==================================================================================
2610 //========= S t o p o n p o i n t ============
2611 //==================================================================================
2612 if (myIntersectionOn2S.IsTangent()) {
2613 return IntWalk_ArretSurPoint;
2616 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
2618 //==================================================================================
2619 //========= R i s k o f i n f l e x i o n p o i n t ============
2620 //==================================================================================
2621 if (TgCourante.Dot(previousd)<0) {
2622 //------------------------------------------------------------
2623 //-- Risk of inflexion point : Divide the step by 2
2624 //-- Initialize STATIC_PRECEDENT_INFLEXION so that
2625 //-- at the next call to return Pas_OK if there is no
2626 //-- more risk of the point of inflexion
2627 //------------------------------------------------------------
2633 STATIC_PRECEDENT_INFLEXION+=3;
2634 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
2635 return IntWalk_ArretSurPointPrecedent;
2637 return IntWalk_PasTropGrand;
2641 if(STATIC_PRECEDENT_INFLEXION > 0) {
2642 STATIC_PRECEDENT_INFLEXION -- ;
2647 //==================================================================================
2648 //========= D e t e c t c o n f u s e d P o in t s ===========
2649 //==================================================================================
2651 Standard_Real Dist = previousPoint.Value().
2652 SquareDistance(CurrentPoint.Value());
2655 if (Dist < tolconf*tolconf ) {
2656 pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
2657 pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
2658 pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
2659 pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3]));
2660 Status = IntWalk_PointConfondu;
2663 //==================================================================================
2664 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
2665 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
2667 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
2668 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
2670 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
2671 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
2677 //=================================================================================
2678 //==== S t e p o f p r o g r e s s i o n (between previous and Current) =======
2679 //=================================================================================
2680 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
2681 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
2682 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
2683 return(IntWalk_ArretSurPointPrecedent);
2685 //==================================================================================
2687 Standard_Real tolArea = 100.0;
2688 if (ResoU1 < Precision::PConfusion() ||
2689 ResoV1 < Precision::PConfusion() ||
2690 ResoU2 < Precision::PConfusion() ||
2691 ResoV2 < Precision::PConfusion() )
2692 tolArea = tolArea*2.0;
2694 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
2695 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
2696 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
2697 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
2698 Duv1 = Du1*Du1 + Dv1*Dv1;
2699 Duv2 = Du2*Du2 + Dv2*Dv2;
2700 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
2701 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
2703 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
2705 Standard_Real aMinDiv2=Precision::Confusion();
2706 aMinDiv2=aMinDiv2*aMinDiv2;
2709 if (Duv1>aMinDiv2) {
2710 d1 = Abs(ResoUV1/Duv1);
2711 d1 = Min(Sqrt(d1)*tolArea, d);
2713 //d1 = Abs(ResoUV1/Duv1);
2714 //d1 = Min(Sqrt(d1)*tolArea,d);
2715 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
2716 tolCoeff1 = Exp(d1);
2718 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
2720 if (Duv2>aMinDiv2) {
2721 d2 = Abs(ResoUV2/Duv2);
2722 d2 = Min(Sqrt(d2)*tolArea,d);
2724 //d2 = Abs(ResoUV2/Duv2);
2725 //d2 = Min(Sqrt(d2)*tolArea,d);
2726 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
2727 tolCoeff2 = Exp(d2);
2728 CosRef1 = CosRef2D/tolCoeff1;
2729 CosRef2 = CosRef2D/tolCoeff2;
2731 //==================================================================================
2732 //== The points are not confused : ==
2733 //== 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 ==
2734 //== N o t T o o G r e a t (angle in space UV) ==
2735 //== C h a n g e o f s i d e ==
2736 //==================================================================================
2737 if (Status != IntWalk_PointConfondu) {
2738 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
2739 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2740 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
2741 return(IntWalk_ArretSurPointPrecedent);
2744 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2745 return(IntWalk_PasTropGrand);
2748 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
2749 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
2750 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
2751 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
2752 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
2753 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
2754 AngRef1 = AngRef2D*tolCoeff1;
2755 AngRef2 = AngRef2D*tolCoeff2;
2756 //-------------------------------------------------------
2757 //-- Test : Angle too great in space UV -----
2758 //-- Change of side -----
2759 //-------------------------------------------------------
2760 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
2761 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
2762 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
2763 return(IntWalk_ArretSurPoint);
2765 return(IntWalk_PasTropGrand);
2769 //==================================================================================
2770 //== D e t e c t i o n o f : Step Too Small
2772 //==================================================================================
2774 //---------------------------------------
2775 //-- Estimate of the vector --
2776 //---------------------------------------
2778 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
2780 if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
2781 if(FlecheCourante>1e-16) {
2782 Ratio = 0.5*(fleche/FlecheCourante);
2787 Standard_Real pasSu1 = pasuv[0];
2788 Standard_Real pasSv1 = pasuv[1];
2789 Standard_Real pasSu2 = pasuv[2];
2790 Standard_Real pasSv2 = pasuv[3];
2793 //-- a point at U+DeltaU is required, ....
2794 //-- return a point at U + Epsilon
2795 //-- Epsilon << DeltaU.
2797 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
2798 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
2799 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
2800 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
2802 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
2803 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
2804 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
2805 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
2806 //-- if(Ratio>10.0 ) { Ratio=10.0; }
2807 Standard_Real R1,R = pasInit[0]/pasuv[0];
2808 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
2809 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
2810 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
2811 if(Ratio > R) Ratio=R;
2812 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
2813 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
2814 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
2815 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
2816 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
2817 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
2818 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2819 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2820 return IntWalk_PasTropGrand;
2823 if(Status == IntWalk_OK) {
2824 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2825 //-- Try to increase the step
2829 else { //-- CurrentVector > vector*0.5
2830 if (FlecheCourante > fleche) { //-- Current step too Great
2831 Ratio = fleche/FlecheCourante;
2832 pasuv[0] = Ratio*pasuv[0];
2833 pasuv[1] = Ratio*pasuv[1];
2834 pasuv[2] = Ratio*pasuv[2];
2835 pasuv[3] = Ratio*pasuv[3];
2836 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
2837 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
2838 return IntWalk_PasTropGrand;
2841 else { //-- vector/2 < CurrentVector <= vector
2842 Ratio = 0.75 * (fleche / FlecheCourante);
2845 pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
2846 pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
2847 pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
2848 pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
2849 if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
2853 Standard_Boolean IntWalk_PWalking::
2854 TestArret(const Standard_Boolean DejaReparti,
2855 TColStd_Array1OfReal& Param,
2856 IntImp_ConstIsoparametric& ChoixIso)
2859 // test if the point of intersection set by these parameters remains in the
2860 // natural domain of each square.
2861 // if the point outpasses reframe to find the best iso (border)
2862 // that intersects easiest the other square
2863 // otherwise test if closed line is present
2866 Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
2867 Standard_Real DPc,DPb;
2868 Standard_Integer i = 0, k = 0;
2873 previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
2875 Standard_Real SolParam[4];
2876 myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
2878 Standard_Boolean Trouve = Standard_False;
2880 Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1;
2881 Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2;
2883 Standard_Integer im1;
2884 for ( i = 1,im1 = 0;i<=4;i++,im1++) {
2891 if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
2892 SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous
2894 Trouve = Standard_True; //--
2895 DPc = Uvp[im1]-Param(i); //-- Previous - Current
2896 DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf
2897 ParC[im1] = Uvd[im1]; //-- ParamCorrige
2898 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
2900 if(dv2>RealEpsilon()) { //-- Progress at the other Direction ?
2901 Duv[im1] = DPc*DPb + dv2;
2902 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
2905 Duv[im1]=-1.0; //-- If no progress, do not change
2906 } //-- the choice of iso
2908 else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
2909 SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current
2911 Trouve = Standard_True; //--
2912 DPc = Param(i)-Uvp[im1]; //-- Current - Previous
2913 DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous
2914 ParC[im1] = Uvf[im1]; //-- Param Corrige
2915 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
2917 if(dv2>RealEpsilon()) { //-- Progress in other Direction ?
2918 Duv[im1] = DPc*DPb + dv2;
2919 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
2922 Duv[im1]=-1.0; //-- If no progress, do not change
2923 } //-- the choice of iso
2932 //--------------------------------------------------
2933 //-- One of Parameters u1,v1,u2,v2 is outside of --
2934 //-- the natural limits. --
2935 //-- Find the best direction of --
2936 //-- progress and reframe the parameters. --
2937 //--------------------------------------------------
2938 Standard_Real ddv = -1.0;
2940 for (i=0;i<=3;i++) {
2941 Param(i+1) = ParC[i];
2948 ChoixIso = ChoixRef[k];
2951 if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
2952 ChoixIso = IntImp_UIsoparametricOnCaro1;
2954 else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
2955 ChoixIso = IntImp_VIsoparametricOnCaro1;
2957 else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
2958 ChoixIso = IntImp_UIsoparametricOnCaro2;
2960 else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
2961 ChoixIso = IntImp_VIsoparametricOnCaro2;
2964 close = Standard_False;
2965 return Standard_True;
2969 if (!DejaReparti) { // find if line closed
2972 const IntSurf_PntOn2S& POn2S1=line->Value(1);
2974 POn2S1.ParametersOnS1(u,v);
2975 gp_Pnt2d P1uvS1(u,v);
2976 previousPoint.ParametersOnS1(u,v);
2977 gp_Pnt2d PrevuvS1(u,v);
2978 myIntersectionOn2S.Point().ParametersOnS1(u,v);
2979 gp_Pnt2d myIntersuvS1(u,v);
2980 Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
2981 (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
2983 POn2S1.ParametersOnS2(u,v);
2984 gp_Pnt2d P1uvS2(u,v);
2985 previousPoint.ParametersOnS2(u,v);
2986 gp_Pnt2d PrevuvS2(u,v);
2987 myIntersectionOn2S.Point().ParametersOnS2(u,v);
2988 gp_Pnt2d myIntersuvS2(u,v);
2989 Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
2990 (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
2992 close = close2dS1 && close2dS2;
2995 else return Standard_False;