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 : ComputePasInit
38 // purpose : estimate of max step : To avoid abrupt changes during change of isos
39 //==================================================================================
40 void IntWalk_PWalking::ComputePasInit(const Standard_Real theDeltaU1,
41 const Standard_Real theDeltaV1,
42 const Standard_Real theDeltaU2,
43 const Standard_Real theDeltaV2)
45 const Standard_Real aRangePart = 0.01;
46 const Standard_Real Increment = 2.0*pasMax;
47 const Handle(Adaptor3d_HSurface)&
48 Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
49 const Handle(Adaptor3d_HSurface)&
50 Caro2 = myIntersectionOn2S.Function().AuxillarSurface2();
52 const Standard_Real aDeltaU1=Abs(UM1-Um1);
53 const Standard_Real aDeltaV1=Abs(VM1-Vm1);
54 const Standard_Real aDeltaU2=Abs(UM2-Um2);
55 const Standard_Real aDeltaV2=Abs(VM2-Vm2);
57 //-- limit the reduction of uv box estimate to 0.01 natural box
58 //-- theDeltaU1 : On box of Inter
59 //-- aDeltaU1 : On parametric space
60 if(!Precision::IsInfinite(aDeltaU1))
61 pasuv[0]=Max(Increment*Max(theDeltaU1, aRangePart*aDeltaU1), pasuv[0]);
63 pasuv[0]=Max(Increment*theDeltaU1, pasuv[0]);
65 if(!Precision::IsInfinite(aDeltaV1))
66 pasuv[1]=Max(Increment*Max(theDeltaV1, aRangePart*aDeltaV1), pasuv[1]);
68 pasuv[1]=Max(Increment*theDeltaV1, pasuv[1]);
70 if(!Precision::IsInfinite(aDeltaU2))
71 pasuv[2]=Max(Increment*Max(theDeltaU2, aRangePart*aDeltaU2), pasuv[2]);
73 pasuv[2]=Max(Increment*theDeltaU2, pasuv[2]);
75 if(!Precision::IsInfinite(aDeltaV2))
76 pasuv[3]=Max(Increment*Max(theDeltaV2, aRangePart*aDeltaV2), pasuv[3]);
78 pasuv[3]=Max(Increment*theDeltaV2, pasuv[3]);
80 const Standard_Real ResoU1tol = Adaptor3d_HSurfaceTool::UResolution(Caro1, tolconf);
81 const Standard_Real ResoV1tol = Adaptor3d_HSurfaceTool::VResolution(Caro1, tolconf);
82 const Standard_Real ResoU2tol = Adaptor3d_HSurfaceTool::UResolution(Caro2, tolconf);
83 const Standard_Real ResoV2tol = Adaptor3d_HSurfaceTool::VResolution(Caro2, tolconf);
85 myStepMin[0] = Max(myStepMin[0], 2.0*ResoU1tol);
86 myStepMin[1] = Max(myStepMin[1], 2.0*ResoV1tol);
87 myStepMin[2] = Max(myStepMin[2], 2.0*ResoU2tol);
88 myStepMin[3] = Max(myStepMin[3], 2.0*ResoV2tol);
90 for(Standard_Integer i = 0; i < 4; i++)
92 pasuv[i]=Max(myStepMin[i], pasuv[i]);
96 //=======================================================================
97 //function : IsParallel
98 //purpose : Checks if theLine is parallel of some boundary of given
99 // surface (it is determined by theCheckSurf1 flag).
100 // Parallelism assumes small oscillations (swing is less or
101 // equal than theToler).
102 // Small lines (if first and last parameters in the Surface
103 // are almost equal) are classified as parallel (as same as
104 // any point can be considered as parallel of any line).
105 //=======================================================================
106 static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
107 const Standard_Boolean theCheckSurf1,
108 const Standard_Real theToler,
109 Standard_Boolean& theIsUparallel,
110 Standard_Boolean& theIsVparallel)
112 const Standard_Integer aNbPointsMAX = 23;
114 theIsUparallel = theIsVparallel = Standard_True;
116 const Standard_Integer aNbLinePnts = theLine->NbPoints();
117 Standard_Integer aNbPoints = aNbLinePnts;
118 if(aNbPoints > aNbPointsMAX)
120 aNbPoints = aNbPointsMAX;
122 else if(aNbPoints < 3)
124 //Here we cannot estimate parallelism.
125 //Do all same as for small lines
129 Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints;
130 Standard_Real aNPoint = 1.0;
132 Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
133 for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
135 // Fix possible "out of parameter" case.
136 if (aNPoint > aNbLinePnts)
137 aNPoint = aNbLinePnts;
141 theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v);
143 theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v);
158 theIsVparallel = ((aUmax - aUmin) < theToler);
159 theIsUparallel = ((aVmax - aVmin) < theToler);
162 //=======================================================================
163 //function : AdjustToDomain
164 //purpose : Returns TRUE if theP has been changed (i.e. initial value
165 // was out of the domain)
166 //=======================================================================
167 static Standard_Boolean AdjustToDomain(const Standard_Integer theNbElem,
168 Standard_Real* theParam,
169 const Standard_Real* const theLowBorder,
170 const Standard_Real* const theUppBorder)
172 Standard_Boolean aRetVal = Standard_False;
173 for (Standard_Integer i = 0; i < theNbElem; i++)
175 if ((theParam[i] - theLowBorder[i]) < -Precision::PConfusion())
177 theParam[i] = theLowBorder[i];
178 aRetVal = Standard_True;
181 if ((theParam[i] - theUppBorder[i]) > Precision::PConfusion())
183 theParam[i] = theUppBorder[i];
184 aRetVal = Standard_True;
191 //==================================================================================
192 // function : IntWalk_PWalking::IntWalk_PWalking
194 //==================================================================================
195 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
196 const Handle(Adaptor3d_HSurface)& Caro2,
197 const Standard_Real TolTangency,
198 const Standard_Real Epsilon,
199 const Standard_Real Deflection,
200 const Standard_Real Increment )
204 close(Standard_False),
207 myTolTang(TolTangency),
209 myIntersectionOn2S(Caro1,Caro2,TolTangency),
210 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
211 STATIC_PRECEDENT_INFLEXION(0)
213 Standard_Real KELARG=20.;
215 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
216 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
217 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
218 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
219 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
221 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
222 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
223 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
224 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
226 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
227 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
229 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
230 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
232 Standard_Real NEWRESO;
233 Standard_Real MAXVAL;
234 Standard_Real MAXVAL2;
236 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
237 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
238 NEWRESO = ResoU1 * MAXVAL ;
239 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
242 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
243 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
244 NEWRESO = ResoU2 * MAXVAL ;
245 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
248 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
249 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
250 NEWRESO = ResoV1 * MAXVAL ;
251 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
254 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
255 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
256 NEWRESO = ResoV2 * MAXVAL ;
257 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
259 pasuv[0]=pasMax*Abs(UM1-Um1);
260 pasuv[1]=pasMax*Abs(VM1-Vm1);
261 pasuv[2]=pasMax*Abs(UM2-Um2);
262 pasuv[3]=pasMax*Abs(VM2-Vm2);
264 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
265 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
266 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
267 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
270 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
271 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
274 Standard_Real t = UM1-Um1;
275 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
276 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
277 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
282 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
283 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
286 Standard_Real t = VM1-Vm1;
287 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
288 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
289 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
294 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
295 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
298 Standard_Real t = UM2-Um2;
299 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
300 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
301 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
306 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
307 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
310 Standard_Real t = VM2-Vm2;
311 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
312 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
313 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
318 myStepMin[0] = 100.0*ResoU1;
319 myStepMin[1] = 100.0*ResoV1;
320 myStepMin[2] = 100.0*ResoU2;
321 myStepMin[3] = 100.0*ResoV2;
323 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
325 for (Standard_Integer i = 0; i<=3;i++) {
328 pasInit[i] = pasSav[i] = pasuv[i];
333 //==================================================================================
334 // function : IntWalk_PWalking
336 //==================================================================================
337 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
338 const Handle(Adaptor3d_HSurface)& Caro2,
339 const Standard_Real TolTangency,
340 const Standard_Real Epsilon,
341 const Standard_Real Deflection,
342 const Standard_Real Increment,
343 const Standard_Real U1,
344 const Standard_Real V1,
345 const Standard_Real U2,
346 const Standard_Real V2)
350 close(Standard_False),
353 myTolTang(TolTangency),
355 myIntersectionOn2S(Caro1,Caro2,TolTangency),
356 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
357 STATIC_PRECEDENT_INFLEXION(0)
359 Standard_Real KELARG=20.;
361 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
363 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
364 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
365 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
366 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
368 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
369 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
370 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
371 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
373 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
374 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
376 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
377 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
379 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
383 if(MAXVAL2 > MAXVAL) {
386 NEWRESO = ResoU1 * MAXVAL ;
387 if(NEWRESO > ResoU1) {
393 if(MAXVAL2 > MAXVAL){
396 NEWRESO = ResoU2 * MAXVAL ;
397 if(NEWRESO > ResoU2) {
403 if(MAXVAL2 > MAXVAL) {
406 NEWRESO = ResoV1 * MAXVAL ;
407 if(NEWRESO > ResoV1) {
413 if(MAXVAL2 > MAXVAL){
416 NEWRESO = ResoV2 * MAXVAL ;
417 if(NEWRESO > ResoV2) {
421 pasuv[0]=pasMax*Abs(UM1-Um1);
422 pasuv[1]=pasMax*Abs(VM1-Vm1);
423 pasuv[2]=pasMax*Abs(UM2-Um2);
424 pasuv[3]=pasMax*Abs(VM2-Vm2);
426 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
427 UM1+=KELARG*pasuv[0];
428 Um1-=KELARG*pasuv[0];
431 Standard_Real t = UM1-Um1;
432 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
433 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
434 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
440 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
441 VM1+=KELARG*pasuv[1];
442 Vm1-=KELARG*pasuv[1];
445 Standard_Real t = VM1-Vm1;
446 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
447 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
448 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
453 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
454 UM2+=KELARG*pasuv[2];
455 Um2-=KELARG*pasuv[2];
458 Standard_Real t = UM2-Um2;
459 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
460 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
461 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
467 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
468 VM2+=KELARG*pasuv[3];
469 Vm2-=KELARG*pasuv[3];
472 Standard_Real t = VM2-Vm2;
473 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
474 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
475 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
480 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
482 for (Standard_Integer i = 0; i<=3;i++) {
483 pasInit[i] = pasSav[i] = pasuv[i];
486 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
487 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
488 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
489 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
491 myStepMin[0] = 100.0*ResoU1;
492 myStepMin[1] = 100.0*ResoV1;
493 myStepMin[2] = 100.0*ResoU2;
494 myStepMin[3] = 100.0*ResoV2;
497 TColStd_Array1OfReal Par(1,4);
505 //==================================================================================
506 // function : PerformFirstPoint
508 //==================================================================================
509 Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
510 IntSurf_PntOn2S& FirstPoint)
513 close = Standard_False;
516 TColStd_Array1OfReal Param(1,4);
518 for (i=1; i<=4; ++i) {
519 Param(i) = ParDep(i);
521 //-- calculate the first solution point
522 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
524 myIntersectionOn2S.Perform(Param,Rsnld);
525 if (!myIntersectionOn2S.IsDone()) {
526 return Standard_False;
529 if (myIntersectionOn2S.IsEmpty()) {
530 return Standard_False;
533 FirstPoint = myIntersectionOn2S.Point();
534 return Standard_True;
536 //==================================================================================
537 // function : Perform
539 //==================================================================================
540 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
542 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
545 //=======================================================================
546 //function : SQDistPointSurface
547 //purpose : Returns square distance between thePnt and theSurf.
548 // (theU0, theV0) is initial point for extrema
549 //=======================================================================
550 static Standard_Real SQDistPointSurface(const gp_Pnt &thePnt,
551 const Adaptor3d_Surface& theSurf,
552 const Standard_Real theU0,
553 const Standard_Real theV0)
555 Extrema_GenLocateExtPS aExtPS(theSurf);
556 aExtPS.Perform(thePnt, theU0, theV0);
561 return aExtPS.SquareDistance();
564 //==================================================================================
565 // function : IsTangentExtCheck
566 // purpose : Additional check if the surfaces are tangent.
567 // Checks if any point in one surface lie in another surface
568 // (with given tolerance)
569 //==================================================================================
570 static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theSurf1,
571 const Handle(Adaptor3d_HSurface)& theSurf2,
572 const Standard_Real theU10,
573 const Standard_Real theV10,
574 const Standard_Real theU20,
575 const Standard_Real theV20,
576 const Standard_Real theToler,
577 const Standard_Real theArrStep[])
581 gp_Vec aDu1, aDv1, aDu2, aDv2;
582 theSurf1->D1(theU10, theV10, aPt, aDu1, aDv1);
583 theSurf2->D1(theU20, theV20, aPt, aDu2, aDv2);
585 const gp_Vec aN1(aDu1.Crossed(aDv1)),
586 aN2(aDu2.Crossed(aDv2));
587 const Standard_Real aDP = aN1.Dot(aN2),
588 aSQ1 = aN1.SquareMagnitude(),
589 aSQ2 = aN2.SquareMagnitude();
591 if((aSQ1 < RealSmall()) || (aSQ2 < RealSmall()))
592 return Standard_True; //Tangent
594 if(aDP*aDP < 0.9998*aSQ1*aSQ2)
595 {//cos(ang N1<->N2) < 0.9999
596 return Standard_False; //Not tangent
600 //For two faces (2^2 = 4)
601 const Standard_Real aSQToler = 4.0*theToler*theToler;
602 const Standard_Integer aNbItems = 4;
603 const Standard_Real aParUS1[aNbItems] = { theU10 + theArrStep[0],
604 theU10 - theArrStep[0],
606 const Standard_Real aParVS1[aNbItems] = { theV10, theV10,
607 theV10 + theArrStep[1],
608 theV10 - theArrStep[1]};
609 const Standard_Real aParUS2[aNbItems] = { theU20 + theArrStep[2],
610 theU20 - theArrStep[2],
612 const Standard_Real aParVS2[aNbItems] = { theV20, theV20,
613 theV20 + theArrStep[3],
614 theV20 - theArrStep[3]};
616 for(Standard_Integer i = 0; i < aNbItems; i++)
618 gp_Pnt aP(theSurf1->Value(aParUS1[i], aParVS1[i]));
619 const Standard_Real aSqDist = SQDistPointSurface(aP, theSurf2->Surface(), theU20, theV20);
620 if(aSqDist > aSQToler)
621 return Standard_False;
624 for(Standard_Integer i = 0; i < aNbItems; i++)
626 gp_Pnt aP(theSurf2->Value(aParUS2[i], aParVS2[i]));
627 const Standard_Real aSqDist = SQDistPointSurface(aP, theSurf1->Surface(), theU10, theV10);
628 if(aSqDist > aSQToler)
629 return Standard_False;
632 return Standard_True;
635 //==================================================================================
636 // function : Perform
638 //==================================================================================
639 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
640 const Standard_Real u1min,
641 const Standard_Real v1min,
642 const Standard_Real u2min,
643 const Standard_Real v2min,
644 const Standard_Real u1max,
645 const Standard_Real v1max,
646 const Standard_Real u2max,
647 const Standard_Real v2max)
649 const Standard_Real aSQDistMax = 1.0e-14;
652 Standard_Integer NbPasOKConseq=0;
653 TColStd_Array1OfReal Param(1,4);
654 IntImp_ConstIsoparametric ChoixIso;
657 done = Standard_False;
660 const Handle(Adaptor3d_HSurface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
661 const Handle(Adaptor3d_HSurface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
663 const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
664 const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
665 const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
666 const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
668 const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
669 const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
670 const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
671 const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
673 ComputePasInit(u1max - u1min,v1max - v1min,u2max - u2min,v2max - v2min);
675 for (Standard_Integer i=0; i<4; ++i)
682 pasInit[i] = pasSav[i] = pasuv[i];
685 line = new IntSurf_LineOn2S ();
687 for (Standard_Integer i=1; i<=4; ++i)
691 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
692 //-- pasuv[] and pasSav[] are modified during the marching
693 for(Standard_Integer i = 0; i < 4; ++i)
695 pasSav[i] = pasuv[i] = pasInit[i];
698 //-- calculate the first solution point
699 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
701 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
702 if (!myIntersectionOn2S.IsDone())
708 if (myIntersectionOn2S.IsEmpty())
713 if(myIntersectionOn2S.IsTangent())
718 Standard_Boolean Arrive, DejaReparti;
719 const Standard_Integer RejectIndexMAX = 250000;
720 Standard_Integer IncKey, RejectIndex;
723 DejaReparti = Standard_False;
727 previousPoint = myIntersectionOn2S.Point();
728 previoustg = Standard_False;
729 previousd = myIntersectionOn2S.Direction();
730 previousd1 = myIntersectionOn2S.DirectionOnS1();
731 previousd2 = myIntersectionOn2S.DirectionOnS2();
734 firstd1 = previousd1;
735 firstd2 = previousd2;
736 tgfirst = tglast = Standard_False;
737 choixIsoSav = ChoixIso;
738 //------------------------------------------------------------
739 //-- Test if the first point of marching corresponds
740 //-- to a point on borders.
741 //-- In this case, DejaReparti is initialized as True
743 pf = previousPoint.Value();
744 Standard_Boolean bTestFirstPoint = Standard_True;
746 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
748 if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), myTolTang, pasuv))
751 AddAPoint(previousPoint);
753 IntWalk_StatusDeflection aStatus = IntWalk_OK, aPrevStatus = IntWalk_OK;
754 Standard_Boolean NoTestDeflection = Standard_False;
755 Standard_Real SvParam[4], f;
756 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
757 Standard_Integer LevelOfPointConfondu = 0;
758 Standard_Integer LevelOfIterWithoutAppend = -1;
761 const Standard_Real aTol[4] = { Epsilon(UM1 - Um1),
765 Arrive = Standard_False;
768 aPrevStatus = aStatus;
770 LevelOfIterWithoutAppend++;
771 if(LevelOfIterWithoutAppend>20)
773 Arrive = Standard_True;
777 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
778 LevelOfIterWithoutAppend = 0;
784 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
785 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
786 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
787 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
795 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
798 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
800 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
801 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
802 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
803 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
805 aIncKey=5.*(Standard_Real)IncKey;
807 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
812 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
817 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
822 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
832 //==========================
838 Standard_Integer aTryNumber = 0;
839 Standard_Boolean isBadPoint = Standard_False;
840 IntImp_ConstIsoparametric aBestIso = ChoixIso;
843 isBadPoint = Standard_False;
845 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
847 if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
849 //If we go along any surface boundary then it is possible
850 //to find "outboundaried" point.
851 //Nevertheless, if this deflection is quite small, we will be
852 //able to adjust this point to the boundary.
854 Standard_Real aNewPnt[4], anAbsParamDist[4];
855 myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
856 const Standard_Real aParMin[4] = {Um1, Vm1, Um2, Vm2};
857 const Standard_Real aParMax[4] = {UM1, VM1, UM2, VM2};
859 for(Standard_Integer i = 0; i < 4; i++)
861 if(Abs(aNewPnt[i] - aParMin[i]) < aTol[i])
862 aNewPnt[i] = aParMin[i];
863 else if(Abs(aNewPnt[i] - aParMax[i]) < aTol[i])
864 aNewPnt[i] = aParMax[i];
867 if (aNewPnt[0] < Um1 || aNewPnt[0] > UM1 ||
868 aNewPnt[1] < Vm1 || aNewPnt[1] > VM1 ||
869 aNewPnt[2] < Um2 || aNewPnt[2] > UM2 ||
870 aNewPnt[3] < Vm2 || aNewPnt[3] > VM2)
872 // Out of borders, process it later.
876 myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
881 anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
882 anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
883 anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
884 anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
885 if (anAbsParamDist[0] < ResoU1 &&
886 anAbsParamDist[1] < ResoV1 &&
887 anAbsParamDist[2] < ResoU2 &&
888 anAbsParamDist[3] < ResoV2 &&
889 aStatus != IntWalk_PasTropGrand)
891 isBadPoint = Standard_True;
892 aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
895 } while (isBadPoint && ++aTryNumber <= 4);
897 if (!myIntersectionOn2S.IsDone())
899 //end of line, division
900 Arrive = Standard_False;
905 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
909 //== Calculation of exact point from Param(.) is possible
910 if (myIntersectionOn2S.IsEmpty())
912 Standard_Real u1,v1,u2,v2;
913 previousPoint.Parameters(u1,v1,u2,v2);
915 Arrive = Standard_False;
916 if(u1<UFirst1 || u1>ULast1)
918 Arrive=Standard_True;
921 if(u2<UFirst2 || u2>ULast2)
923 Arrive=Standard_True;
926 if(v1<VFirst1 || v1>VLast1)
928 Arrive=Standard_True;
931 if(v2<VFirst2 || v2>VLast2)
933 Arrive=Standard_True;
936 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
937 LevelOfEmptyInmyIntersectionOn2S++;
939 if(LevelOfEmptyInmyIntersectionOn2S>10)
949 //============================================================
950 //== A point has been found : T E S T D E F L E C T I O N
951 //============================================================
954 NoTestDeflection = Standard_False;
958 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
960 LevelOfEmptyInmyIntersectionOn2S=0;
961 if(LevelOfIterWithoutAppend < 10)
963 aStatus = TestDeflection(ChoixIso);
967 if (aStatus != IntWalk_StepTooSmall)
969 // Bug #0029682 (Boolean intersection with
970 // fuzzy-option hangs).
971 // If aStatus == IntWalk_StepTooSmall then
972 // the counter "LevelOfIterWithoutAppend" will
973 // be nulified in the future if the step is smaller
974 // (see "case IntWalk_StepTooSmall:" below).
975 // Here, we forbid this nulification and thereby provide out from
986 //============================================================
987 //== T r a i t e m e n t s u r S t a t u s ==
988 //============================================================
989 if(LevelOfPointConfondu > 5)
991 aStatus = IntWalk_ArretSurPoint;
992 LevelOfPointConfondu = 0;
995 if(aStatus==IntWalk_OK)
998 if(NbPasOKConseq >= 5)
1001 Standard_Boolean pastroppetit;
1006 pastroppetit=Standard_True;
1008 if(pasuv[0]<pasInit[0])
1010 t = (pasInit[0]-pasuv[0])*0.25;
1011 if(t>0.1*pasInit[0])
1017 pastroppetit=Standard_False;
1020 if(pasuv[1]<pasInit[1])
1022 t = (pasInit[1]-pasuv[1])*0.25;
1023 if(t>0.1*pasInit[1]) {
1028 pastroppetit=Standard_False;
1031 if(pasuv[2]<pasInit[2])
1033 t = (pasInit[2]-pasuv[2])*0.25;
1034 if(t>0.1*pasInit[2])
1040 pastroppetit=Standard_False;
1043 if(pasuv[3]<pasInit[3])
1045 t = (pasInit[3]-pasuv[3])*0.25;
1046 if(t>0.1*pasInit[3]) {
1050 pastroppetit=Standard_False;
1064 pastroppetit=Standard_False;
1068 while(pastroppetit);
1070 }//aStatus==IntWalk_OK
1075 switch(aStatus)//007
1077 case IntWalk_ArretSurPointPrecedent:
1079 Arrive = Standard_False;
1080 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
1083 case IntWalk_PasTropGrand:
1085 Param(1)=SvParam[0];
1086 Param(2)=SvParam[1];
1087 Param(3)=SvParam[2];
1088 Param(4)=SvParam[3];
1090 if(LevelOfIterWithoutAppend > 5)
1092 for (Standard_Integer i = 0; i < 4; i++)
1094 if (pasSav[i] > pasInit[i])
1097 const Standard_Real aDelta = (pasInit[i]-pasSav[i])*0.25;
1099 if(aDelta > Epsilon(pasInit[i]))
1101 pasInit[i] -= aDelta;
1102 LevelOfIterWithoutAppend=0;
1109 case IntWalk_PointConfondu:
1111 LevelOfPointConfondu++;
1113 if(LevelOfPointConfondu>5)
1115 Standard_Boolean pastroppetit;
1119 pastroppetit=Standard_True;
1121 for(Standard_Integer i = 0; i < 4; i++)
1123 if(pasuv[i]<pasInit[i])
1125 pasuv[i]+=(pasInit[i]-pasuv[i])*0.25;
1126 pastroppetit=Standard_False;
1142 pastroppetit=Standard_False;
1146 while(pastroppetit);
1151 case IntWalk_StepTooSmall:
1153 Standard_Boolean hasStepBeenIncreased = Standard_False;
1155 for(Standard_Integer i = 0; i < 4; i++)
1157 const Standard_Real aNewStep = Min(1.5*pasuv[i], pasInit[i]);
1158 if(aNewStep > pasuv[i])
1160 pasuv[i] = aNewStep;
1161 hasStepBeenIncreased = Standard_True;
1165 if(hasStepBeenIncreased)
1167 Param(1)=SvParam[0];
1168 Param(2)=SvParam[1];
1169 Param(3)=SvParam[2];
1170 Param(4)=SvParam[3];
1172 // In order to avoid cyclic changes
1173 // (PasTropGrand --> Decrease step -->
1174 // StepTooSmall --> Increase step --> PasTropGrand...)
1175 // nullify LevelOfIterWithoutAppend only if the condition
1177 if (aPrevStatus != IntWalk_PasTropGrand)
1178 LevelOfIterWithoutAppend = 0;
1183 Standard_FALLTHROUGH
1185 case IntWalk_ArretSurPoint://006
1187 //=======================================================
1188 //== Stop Test t : Frame on Param(.) ==
1189 //=======================================================
1191 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1192 // JMB 30th December 1999.
1193 // Some statement below should not be put in comment because they are useful.
1194 // See grid CTO 909 A1 which infinitely loops
1195 if(Arrive==Standard_False && aStatus==IntWalk_ArretSurPoint)
1197 Arrive=Standard_True;
1199 cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
1205 NbPasOKConseq = -10;
1210 //=====================================================
1211 //== Param(.) is in the limits ==
1212 //== and does not end a closed line ==
1213 //=====================================================
1214 //== Check on the current point of myInters
1215 Standard_Boolean pointisvalid = Standard_False;
1217 Standard_Real u1,v1,u2,v2;
1218 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1221 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1222 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1223 v1 >= Vm1 && v2 >= Vm2)
1225 pointisvalid=Standard_True;
1232 previousPoint = myIntersectionOn2S.Point();
1233 previoustg = myIntersectionOn2S.IsTangent();
1237 previousd = myIntersectionOn2S.Direction();
1238 previousd1 = myIntersectionOn2S.DirectionOnS1();
1239 previousd2 = myIntersectionOn2S.DirectionOnS2();
1241 //=====================================================
1242 //== Check on the previous Point
1244 Standard_Real u1,v1,u2,v2;
1245 previousPoint.Parameters(u1,v1,u2,v2);
1246 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1247 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1248 v1 >= Vm1 && v2 >= Vm2)
1250 pl = previousPoint.Value();
1253 if(pf.SquareDistance(pl) < aSQDistMax)
1263 bTestFirstPoint = Standard_False;
1267 AddAPoint(previousPoint);
1270 if(RejectIndex >= RejectIndexMAX)
1272 Arrive = Standard_True;
1277 LevelOfIterWithoutAppend = 0;
1281 //====================================================
1283 if (aStatus == IntWalk_ArretSurPoint)
1285 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1289 if (line->NbPoints() == 2)
1291 pasSav[0] = pasuv[0];
1292 pasSav[1] = pasuv[1];
1293 pasSav[2] = pasuv[2];
1294 pasSav[3] = pasuv[3];
1296 if ((aPrevStatus == IntWalk_PasTropGrand) &&
1297 (LevelOfIterWithoutAppend > 0))
1299 pasInit[0] = pasuv[0];
1300 pasInit[1] = pasuv[1];
1301 pasInit[2] = pasuv[2];
1302 pasInit[3] = pasuv[3];
1311 //================= la ligne est fermee ===============
1312 AddAPoint(line->Value(1)); //ligne fermee
1313 LevelOfIterWithoutAppend=0;
1317 //====================================================
1318 //== Param was not in the limits (was reframed)
1319 //====================================================
1320 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1322 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1323 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1325 if(!myIntersectionOn2S.IsEmpty()) //002
1327 // mutially outpasses in the square or intersection in corner
1329 if(TestArret(Standard_True,Param,ChoixIso))
1331 NbPasOKConseq = -10;
1332 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1334 if(!myIntersectionOn2S.IsEmpty())
1336 previousPoint = myIntersectionOn2S.Point();
1337 previoustg = myIntersectionOn2S.IsTangent();
1341 previousd = myIntersectionOn2S.Direction();
1342 previousd1 = myIntersectionOn2S.DirectionOnS1();
1343 previousd2 = myIntersectionOn2S.DirectionOnS2();
1346 pl = previousPoint.Value();
1350 if(pf.SquareDistance(pl) < aSQDistMax)
1360 bTestFirstPoint = Standard_False;
1364 AddAPoint(previousPoint);
1367 if(RejectIndex >= RejectIndexMAX)
1369 Arrive = Standard_True;
1374 LevelOfIterWithoutAppend=0;
1375 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1379 //fail framing divides the step
1380 Arrive = Standard_False;
1381 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1382 NoTestDeflection = Standard_True;
1383 ChoixIso = SauvChoixIso;
1388 // save the last point
1389 // to revert to it if the current point is out of bounds
1391 IntSurf_PntOn2S previousPointSave = previousPoint;
1392 Standard_Boolean previoustgSave = previoustg;
1393 gp_Dir previousdSave = previousd;
1394 gp_Dir2d previousd1Save = previousd1;
1395 gp_Dir2d previousd2Save = previousd2;
1397 previousPoint = myIntersectionOn2S.Point();
1398 previoustg = myIntersectionOn2S.IsTangent();
1399 Arrive = Standard_False;
1403 previousd = myIntersectionOn2S.Direction();
1404 previousd1 = myIntersectionOn2S.DirectionOnS1();
1405 previousd2 = myIntersectionOn2S.DirectionOnS2();
1408 //========================================
1409 //== Check on PreviousPoint @@
1412 Standard_Real u1,v1,u2,v2;
1413 previousPoint.Parameters(u1,v1,u2,v2);
1415 //To save initial 2d points
1416 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1417 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1419 ///////////////////////////
1427 Standard_Boolean bFlag1, bFlag2;
1428 Standard_Real aTol2D=1.e-11;
1430 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1431 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1432 if (bFlag1 && bFlag2)
1434 if (line->NbPoints() > 1)
1436 IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1437 Standard_Real ppU1, ppV1, ppU2, ppV2;
1438 prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1439 Standard_Real pU1, pV1, pU2, pV2;
1440 previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1441 gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1442 gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1443 gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1444 gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1446 const Standard_Real aDot1 = V1onS1 * V2onS1;
1447 const Standard_Real aDot2 = V1onS2 * V2onS2;
1449 if ((aDot1 < 0.0) || (aDot2 < 0.0))
1451 Arrive = Standard_True;
1456 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1457 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1458 v1 >= Vm1 && v2 >= Vm2) {
1461 pl = previousPoint.Value();
1465 if(pf.SquareDistance(pl) < aSQDistMax)
1476 bTestFirstPoint = Standard_False;
1480 //To avoid walking around the same point
1481 //in the tangent zone near a border
1485 //There are three consecutive points:
1486 //previousPointSave -> ParamPnt -> curPnt.
1488 Standard_Real prevU1, prevV1, prevU2, prevV2;
1489 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1490 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1491 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1492 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1493 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1494 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1495 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1496 Standard_Real MaxAngle = 3*M_PI/4;
1497 Standard_Real anAngleS1 = 0.0, anAngleS2 = 0.0;
1498 const Standard_Real aSQMParS1 = PrevToParamOnS1.SquareMagnitude();
1499 const Standard_Real aSQMParS2 = PrevToParamOnS2.SquareMagnitude();
1500 const Standard_Real aSQMCurS1 = PrevToCurOnS1.SquareMagnitude();
1501 const Standard_Real aSQMCurS2 = PrevToCurOnS2.SquareMagnitude();
1503 if(aSQMCurS1 < gp::Resolution())
1505 //We came back to the one of previos point.
1506 //Therefore, we must break;
1510 else if(aSQMParS1 < gp::Resolution())
1512 //We are walking along tangent zone.
1513 //It should be continued.
1518 anAngleS1 = Abs(PrevToParamOnS1.Angle(PrevToCurOnS1));
1521 if(aSQMCurS2 < gp::Resolution())
1523 //We came back to the one of previos point.
1524 //Therefore, we must break;
1528 else if(aSQMParS2 < gp::Resolution())
1530 //We are walking along tangent zone.
1531 //It should be continued;
1536 anAngleS2 = Abs(PrevToParamOnS2.Angle(PrevToCurOnS2));
1539 if ((anAngleS1 > MaxAngle) && (anAngleS2 > MaxAngle))
1541 Arrive = Standard_True;
1546 //Check singularity.
1547 //I.e. check if we are walking along direction, which does not
1548 //result in comming to any point (i.e. derivative
1549 //3D-intersection curve along this direction is equal to 0).
1550 //A sphere with direction {dU=1, dV=0} from point
1551 //(U=0, V=M_PI/2) can be considered as example for
1552 //this case (we cannot find another 3D-point if we go thus).
1554 //Direction chosen along 1st and 2nd surface correspondingly
1555 const gp_Vec2d aDirS1(prevPntOnS1, curPntOnS1),
1556 aDirS2(prevPntOnS2, curPntOnS2);
1559 gp_Vec aDuS1, aDvS1, aDuS2, aDvS2;
1561 myIntersectionOn2S.Function().AuxillarSurface1()->
1562 D1(curPntOnS1.X(), curPntOnS1.Y(), aPtemp, aDuS1, aDvS1);
1563 myIntersectionOn2S.Function().AuxillarSurface2()->
1564 D1(curPntOnS2.X(), curPntOnS2.Y(), aPtemp, aDuS2, aDvS2);
1566 //Derivative WLine along (it is vector-function indeed)
1568 //(https://en.wikipedia.org/wiki/Directional_derivative#Variation_using_only_direction_of_vector).
1569 //F1 - on the 1st surface, F2 - on the 2nd surface.
1570 //x, y, z - coordinates of derivative vector.
1571 const Standard_Real aF1x = aDuS1.X()*aDirS1.X() +
1572 aDvS1.X()*aDirS1.Y();
1573 const Standard_Real aF1y = aDuS1.Y()*aDirS1.X() +
1574 aDvS1.Y()*aDirS1.Y();
1575 const Standard_Real aF1z = aDuS1.Z()*aDirS1.X() +
1576 aDvS1.Z()*aDirS1.Y();
1577 const Standard_Real aF2x = aDuS2.X()*aDirS2.X() +
1578 aDvS2.X()*aDirS2.Y();
1579 const Standard_Real aF2y = aDuS2.Y()*aDirS2.X() +
1580 aDvS2.Y()*aDirS2.Y();
1581 const Standard_Real aF2z = aDuS2.Z()*aDirS2.X() +
1582 aDvS2.Z()*aDirS2.Y();
1584 const Standard_Real aF1 = aF1x*aF1x + aF1y*aF1y + aF1z*aF1z;
1585 const Standard_Real aF2 = aF2x*aF2x + aF2y*aF2y + aF2z*aF2z;
1587 if((aF1 < gp::Resolution()) && (aF2 < gp::Resolution()))
1589 //All derivative are equal to 0. Therefore, there is
1590 //no point in going along direction chosen.
1591 Arrive = Standard_True;
1595 }//if (previoustg) cond.
1597 ////////////////////////////////////////
1598 AddAPoint(previousPoint);
1601 if(RejectIndex >= RejectIndexMAX)
1603 Arrive = Standard_True;
1609 LevelOfIterWithoutAppend=0;
1610 Arrive = Standard_True;
1614 // revert to the last correctly calculated point
1615 previousPoint = previousPointSave;
1616 previoustg = previoustgSave;
1617 previousd = previousdSave;
1618 previousd1 = previousd1Save;
1619 previousd2 = previousd2Save;
1624 Standard_Boolean wasExtended = Standard_False;
1626 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1628 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1630 wasExtended = Standard_True;
1631 Arrive = Standard_False;
1632 ChoixIso = SauvChoixIso;
1636 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1639 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1640 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1643 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1645 wasExtended = Standard_True;
1646 Arrive = Standard_False;
1647 ChoixIso = SauvChoixIso;
1650 }//else !TestArret() $
1651 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1654 //echec framing on border; division of step
1655 Arrive = Standard_False;
1656 NoTestDeflection = Standard_True;
1657 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1659 }//$$$ end framing on border (!close)
1660 }//004 fin TestArret return Arrive = True
1661 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1662 } //007 switch(aStatus)
1663 } //008 end processing point (TEST DEFLECTION)
1664 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1665 } //010 end if first departure point allows marching while (!Arrive)
1667 done = Standard_True;
1669 // ===========================================================================================================
1670 // function: ExtendLineInCommonZone
1671 // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1672 // Returns Standard_True if the line was extended through tangent zone and the last computed point
1673 // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1674 // ===========================================================================================================
1675 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1676 const Standard_Boolean theDirectionFlag)
1678 Standard_Boolean bOutOfTangentZone = Standard_False;
1679 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1680 Standard_Integer dIncKey = 1;
1681 TColStd_Array1OfReal Param(1,4);
1682 IntWalk_StatusDeflection aStatus = IntWalk_OK;
1683 Standard_Integer nbIterWithoutAppend = 0;
1684 Standard_Integer nbEqualPoints = 0;
1685 Standard_Integer parit = 0;
1686 Standard_Integer uvit = 0;
1687 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1690 nbIterWithoutAppend++;
1692 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1694 cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
1696 bStop = Standard_True;
1699 Standard_Real f = 0.;
1701 switch (theChoixIso)
1703 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1704 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1705 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1706 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1711 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1713 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1714 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1715 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1716 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1718 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1719 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1720 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1721 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1727 Standard_Real SvParam[4];
1728 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1730 for(parit = 0; parit < 4; parit++) {
1731 SvParam[parit] = Param(parit+1);
1733 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1734 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1736 if (!myIntersectionOn2S.IsDone()) {
1737 return bOutOfTangentZone;
1740 if (myIntersectionOn2S.IsEmpty()) {
1741 return bOutOfTangentZone;
1744 aStatus = TestDeflection(ChoixIso);
1746 if(aStatus == IntWalk_OK) {
1748 for(uvit = 0; uvit < 4; uvit++) {
1749 if(pasuv[uvit] < pasInit[uvit]) {
1750 pasuv[uvit] = pasInit[uvit];
1756 case IntWalk_ArretSurPointPrecedent:
1758 bStop = Standard_True;
1759 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1762 case IntWalk_PasTropGrand:
1764 for(parit = 0; parit < 4; parit++) {
1765 Param(parit+1) = SvParam[parit];
1767 Standard_Boolean bDecrease = Standard_False;
1769 for(uvit = 0; uvit < 4; uvit++) {
1770 if(pasSav[uvit] < pasInit[uvit]) {
1771 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1772 bDecrease = Standard_True;
1776 if(bDecrease) nbIterWithoutAppend--;
1779 case IntWalk_PointConfondu:
1781 for(uvit = 0; uvit < 4; uvit++) {
1782 if(pasuv[uvit] < pasInit[uvit]) {
1783 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1789 case IntWalk_ArretSurPoint:
1792 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1797 Standard_Real u11,v11,u12,v12;
1798 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1799 Standard_Real u21,v21,u22,v22;
1800 previousPoint.Parameters(u21,v21,u22,v22);
1802 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1803 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1812 bStop = bStop || !myIntersectionOn2S.IsTangent();
1813 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1816 Standard_Boolean pointisvalid = Standard_False;
1817 Standard_Real u1,v1,u2,v2;
1818 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1820 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1821 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1822 v1 >= Vm1 && v2 >= Vm2)
1823 pointisvalid = Standard_True;
1826 previousPoint = myIntersectionOn2S.Point();
1827 previoustg = myIntersectionOn2S.IsTangent();
1830 previousd = myIntersectionOn2S.Direction();
1831 previousd1 = myIntersectionOn2S.DirectionOnS1();
1832 previousd2 = myIntersectionOn2S.DirectionOnS2();
1834 Standard_Boolean bAddPoint = Standard_True;
1836 if(line->NbPoints() >= 1) {
1837 gp_Pnt pf = line->Value(1).Value();
1838 gp_Pnt pl = previousPoint.Value();
1840 if(pf.Distance(pl) < Precision::Confusion()) {
1842 if(dIncKey == 5000) return bOutOfTangentZone;
1843 else bAddPoint = Standard_False;
1848 aSeqOfNewPoint.Append(previousPoint);
1849 nbIterWithoutAppend = 0;
1853 if (line->NbPoints() == 2) {
1854 for(uvit = 0; uvit < 4; uvit++) {
1855 pasSav[uvit] = pasuv[uvit];
1859 if ( !pointisvalid ) {
1860 // decrease step if out of bounds
1861 // otherwise the same calculations will be
1862 // repeated several times
1863 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1866 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1869 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1872 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1877 if(close && (line->NbPoints() >= 1)) {
1879 if(!bOutOfTangentZone) {
1880 aSeqOfNewPoint.Append(line->Value(1)); // line end
1882 nbIterWithoutAppend = 0;
1885 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1887 if(myIntersectionOn2S.IsEmpty()) {
1888 bStop = Standard_True;// !myIntersectionOn2S.IsTangent();
1889 bOutOfTangentZone = Standard_False; // !myIntersectionOn2S.IsTangent();
1892 Standard_Boolean bAddPoint = Standard_True;
1893 Standard_Boolean pointisvalid = Standard_False;
1895 previousPoint = myIntersectionOn2S.Point();
1896 Standard_Real u1,v1,u2,v2;
1897 previousPoint.Parameters(u1,v1,u2,v2);
1899 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1900 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1901 v1 >= Vm1 && v2 >= Vm2)
1902 pointisvalid = Standard_True;
1906 if(line->NbPoints() >= 1) {
1907 gp_Pnt pf = line->Value(1).Value();
1908 gp_Pnt pl = previousPoint.Value();
1910 if(pf.Distance(pl) < Precision::Confusion()) {
1912 if(dIncKey == 5000) return bOutOfTangentZone;
1913 else bAddPoint = Standard_False;
1917 if(bAddPoint && !bOutOfTangentZone) {
1918 aSeqOfNewPoint.Append(previousPoint);
1919 nbIterWithoutAppend = 0;
1934 Standard_Boolean bExtendLine = Standard_False;
1935 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1937 Standard_Integer pit = 0;
1939 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1941 previousPoint.Parameters(u1,v1,u2,v2);
1943 if(aSeqOfNewPoint.Length() > 0)
1944 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1949 if(((u1 - Um1) < ResoU1) ||
1950 ((UM1 - u1) < ResoU1) ||
1951 ((u2 - Um2) < ResoU2) ||
1952 ((UM2 - u2) < ResoU2) ||
1953 ((v1 - Vm1) < ResoV1) ||
1954 ((VM1 - v1) < ResoV1) ||
1955 ((v2 - Vm2) < ResoV2) ||
1956 ((VM2 - v2) < ResoV2))
1957 bExtendLine = Standard_True;
1961 // if(aStatus == IntWalk_OK || aStatus == IntWalk_ArretSurPoint) {
1962 if(aStatus == IntWalk_OK) {
1963 bExtendLine = Standard_True;
1965 if(aSeqOfNewPoint.Length() > 1) {
1966 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1967 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1969 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1970 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1971 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1972 LastParams.ChangeValue(1),
1973 LastParams.ChangeValue(2),
1974 LastParams.ChangeValue(3));
1975 Standard_Integer indexofiso = 0;
1977 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1978 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1979 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1980 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
1982 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
1983 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
1984 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
1986 gp_Dir2d anIsoDir(0, 1);
1988 if((indexofiso == 1) || (indexofiso == 3))
1989 anIsoDir = gp_Dir2d(1, 0);
1991 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
1992 Standard_Real piquota = M_PI*0.25;
1994 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
1995 Standard_Integer ii = 1, nextii = 2;
1997 Standard_Real asqresol = gp::Resolution();
1998 asqresol *= asqresol;
2001 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2002 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2003 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2004 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2005 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2006 FirstParams.Value(afirstindex + 1)),
2007 gp_Pnt2d(LastParams.Value(afirstindex),
2008 LastParams.Value(afirstindex + 1)));
2011 while((d1.SquareMagnitude() < asqresol) &&
2012 (ii < aSeqOfNewPoint.Length()));
2016 while(nextii < aSeqOfNewPoint.Length()) {
2018 gp_Vec2d nextd1(0, 0);
2019 Standard_Integer jj = nextii;
2022 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2023 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2024 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2025 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2026 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2027 FirstParams.Value(afirstindex + 1)),
2028 gp_Pnt2d(LastParams.Value(afirstindex),
2029 LastParams.Value(afirstindex + 1)));
2033 while((nextd1.SquareMagnitude() < asqresol) &&
2034 (jj < aSeqOfNewPoint.Length()));
2037 if(fabs(d1.Angle(nextd1)) > piquota) {
2038 bExtendLine = Standard_False;
2044 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
2051 return Standard_False;
2053 Standard_Integer i = 0;
2055 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
2056 AddAPoint(aSeqOfNewPoint.Value(i));
2059 return bOutOfTangentZone;
2062 //=======================================================================
2063 //function : DistanceMinimizeByGradient
2067 // theInit should be initialized before function calling.
2068 //=======================================================================
2069 Standard_Boolean IntWalk_PWalking::
2070 DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
2071 const Handle(Adaptor3d_HSurface)& theASurf2,
2072 TColStd_Array1OfReal& theInit,
2073 const Standard_Real* theStep0)
2075 const Standard_Integer aNbIterMAX = 60;
2076 const Standard_Real aTol = 1.0e-14;
2077 const Standard_Real aTolNul = 1.0 / Precision::Infinite();
2079 // I.e. if theU1 = 0.0 then Epsilon(theU1) = DBL_MIN (~1.0e-308).
2080 // Work with this number is impossible: there is a dangerous to
2081 // obtain Floating-point-overflow. Therefore, we limit this value.
2082 const Standard_Real aMinAddValU1 = Max(Epsilon(theInit(1)), aTolNul);
2083 const Standard_Real aMinAddValV1 = Max(Epsilon(theInit(2)), aTolNul);
2084 const Standard_Real aMinAddValU2 = Max(Epsilon(theInit(3)), aTolNul);
2085 const Standard_Real aMinAddValV2 = Max(Epsilon(theInit(4)), aTolNul);
2087 Handle(Geom_Surface) aS1, aS2;
2089 if (theASurf1->GetType() != GeomAbs_BezierSurface &&
2090 theASurf1->GetType() != GeomAbs_BSplineSurface)
2091 return Standard_True;
2092 if (theASurf2->GetType() != GeomAbs_BezierSurface &&
2093 theASurf2->GetType() != GeomAbs_BSplineSurface)
2094 return Standard_True;
2096 Standard_Boolean aStatus = Standard_False;
2099 gp_Vec aD1u, aD1v, aD2U, aD2V;
2101 theASurf1->D1(theInit(1), theInit(2), aP1, aD1u, aD1v);
2102 theASurf2->D1(theInit(3), theInit(4), aP2, aD2U, aD2V);
2104 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
2106 gp_Vec aP12(aP1, aP2);
2108 Standard_Real aGradFu(-aP12.Dot(aD1u));
2109 Standard_Real aGradFv(-aP12.Dot(aD1v));
2110 Standard_Real aGradFU( aP12.Dot(aD2U));
2111 Standard_Real aGradFV( aP12.Dot(aD2V));
2113 Standard_Real aStepU1 = 1.0e-6, aStepV1 = 1.0e-6,
2114 aStepU2 = 1.0e-6, aStepV2 = 1.0e-6;
2118 aStepU1 = theStep0[0];
2119 aStepV1 = theStep0[1];
2120 aStepU2 = theStep0[2];
2121 aStepV2 = theStep0[3];
2124 Standard_Boolean flRepeat = Standard_True;
2125 Standard_Integer aNbIter = aNbIterMAX;
2129 Standard_Real anAdd = aGradFu*aStepU1;
2130 const Standard_Real aPARu = theInit(1) - Sign(Max(Abs(anAdd), aMinAddValU1), anAdd);
2132 anAdd = aGradFv*aStepV1;
2133 const Standard_Real aPARv = theInit(2) - Sign(Max(Abs(anAdd), aMinAddValV1), anAdd);
2135 anAdd = aGradFU*aStepU2;
2136 const Standard_Real aParU = theInit(3) - Sign(Max(Abs(anAdd), aMinAddValU2), anAdd);
2138 anAdd = aGradFV*aStepV2;
2139 const Standard_Real aParV = theInit(4) - Sign(Max(Abs(anAdd), aMinAddValV2), anAdd);
2143 theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
2144 theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
2146 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
2148 if(aSQDist < aSQDistPrev)
2150 aSQDistPrev = aSQDist;
2156 aStatus = aSQDistPrev < aTol;
2166 flRepeat = Standard_False;
2170 theASurf1->D1(theInit(1), theInit(2), aPt1, aD1u, aD1v);
2171 theASurf2->D1(theInit(3), theInit(4), aPt2, aD2U, aD2V);
2173 gp_Vec aPt12(aPt1, aPt2);
2174 aGradFu = -aPt12.Dot(aD1u);
2175 aGradFv = -aPt12.Dot(aD1v);
2176 aGradFU = aPt12.Dot(aD2U);
2177 aGradFV = aPt12.Dot(aD2V);
2181 aStepU1 = theStep0[0];
2182 aStepV1 = theStep0[1];
2183 aStepU2 = theStep0[2];
2184 aStepV2 = theStep0[3];
2188 aStepU1 = aStepV1 = aStepU2 = aStepV2 = 1.0e-6;
2197 //=======================================================================
2198 //function : DistanceMinimizeByExtrema
2202 // theP0, theU0 and theV0 parameters should be initialized
2203 // before the function calling.
2204 //=======================================================================
2205 Standard_Boolean IntWalk_PWalking::
2206 DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
2207 const gp_Pnt& theP0,
2208 Standard_Real& theU0,
2209 Standard_Real& theV0,
2210 const Standard_Real* theStep0)
2212 const Standard_Real aTol = 1.0e-14;
2214 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2215 Standard_Real aSQDistPrev = RealLast();
2216 Standard_Real aU = theU0, aV = theV0;
2218 const Standard_Real aStep0[2] = { theStep0 ? theStep0[0] : 1.0,
2219 theStep0 ? theStep0[1] : 1.0 };
2221 Standard_Integer aNbIter = 10;
2224 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2226 gp_Vec aVec(theP0, aPS);
2228 Standard_Real aSQDist = aVec.SquareMagnitude();
2230 if(aSQDist >= aSQDistPrev)
2233 aSQDistPrev = aSQDist;
2238 if(aSQDistPrev < aTol)
2242 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2245 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2246 aDf1v = aD2Su.Dot(aD1Sv),
2248 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2250 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2251 aU -= aStep0[0]*(aDf2v*aF1 - aDf1v*aF2) / aDet;
2252 aV += aStep0[1]*(aDf2u*aF1 - aDf1u*aF2) / aDet;
2256 return (aSQDistPrev < aTol);
2259 //=======================================================================
2260 //function : HandleSingleSingularPoint
2262 //=======================================================================
2263 Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adaptor3d_HSurface)& theASurf1,
2264 const Handle(Adaptor3d_HSurface)& theASurf2,
2265 const Standard_Real the3DTol,
2266 TColStd_Array1OfReal &thePnt)
2268 // u1, v1, u2, v2 order is used.
2269 Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
2270 theASurf1->FirstVParameter(),
2271 theASurf2->FirstUParameter(),
2272 theASurf2->FirstVParameter()};
2273 Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
2274 theASurf1->LastVParameter(),
2275 theASurf2->LastUParameter(),
2276 theASurf2->LastVParameter()};
2277 IntImp_ConstIsoparametric aLockedDir[4] = {IntImp_UIsoparametricOnCaro1,
2278 IntImp_VIsoparametricOnCaro1,
2279 IntImp_UIsoparametricOnCaro2,
2280 IntImp_VIsoparametricOnCaro2};
2282 // Create new intersector with new tolerance.
2283 IntWalk_TheInt2S anInt(theASurf1, theASurf2, the3DTol);
2284 math_FunctionSetRoot aRsnld(anInt.Function());
2286 for (Standard_Integer i = 1; i <= 4; ++i)
2288 if ( Abs(thePnt(i) - aLowBorder[i - 1]) < Precision::PConfusion() ||
2289 Abs(thePnt(i) - aUppBorder[i - 1]) < Precision::PConfusion())
2292 anInt.Perform(thePnt,aRsnld, aLockedDir[i - 1]);
2294 if (!anInt.IsDone())
2297 if (anInt.IsEmpty())
2300 anInt.Point().Parameters(thePnt(1), thePnt(2), thePnt(3), thePnt(4));
2302 Standard_Boolean isInDomain = Standard_True;
2303 for (Standard_Integer j = 1; isInDomain && (j <= 4); ++j)
2305 if ((thePnt(j) - aLowBorder[j - 1] + Precision::PConfusion())*
2306 (thePnt(j) - aUppBorder[j - 1] - Precision::PConfusion()) > 0.0)
2308 isInDomain = Standard_False;
2313 return Standard_True;
2317 return Standard_False;
2320 //=======================================================================
2321 //function : SeekPointOnBoundary
2323 //=======================================================================
2324 Standard_Boolean IntWalk_PWalking::
2325 SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2326 const Handle(Adaptor3d_HSurface)& theASurf2,
2327 const Standard_Real theU1,
2328 const Standard_Real theV1,
2329 const Standard_Real theU2,
2330 const Standard_Real theV2,
2331 const Standard_Boolean isTheFirst)
2333 Standard_Boolean isOK = Standard_False;
2335 // u1, v1, u2, v2 order is used.
2336 const Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
2337 theASurf1->FirstVParameter(),
2338 theASurf2->FirstUParameter(),
2339 theASurf2->FirstVParameter()};
2340 const Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
2341 theASurf1->LastVParameter(),
2342 theASurf2->LastUParameter(),
2343 theASurf2->LastVParameter()};
2345 // Tune solution tolerance according with object size.
2346 const Standard_Real aRes1 = Max(Precision::PConfusion() / theASurf1->UResolution(1.0),
2347 Precision::PConfusion() / theASurf1->VResolution(1.0));
2348 const Standard_Real aRes2 = Max(Precision::PConfusion() / theASurf2->UResolution(1.0),
2349 Precision::PConfusion() / theASurf2->VResolution(1.0));
2350 const Standard_Real a3DTol = Max(aRes1, aRes2);
2351 const Standard_Real aTol = Max(Precision::Confusion(), a3DTol);
2353 // u1, v1, u2, v2 order is used.
2354 TColStd_Array1OfReal aPnt(1,4);
2355 aPnt(1) = theU1; aPnt(2) = theV1; aPnt(3) = theU2; aPnt(4) = theV2;
2356 TColStd_Array1OfReal aSingularPnt(aPnt);
2358 Standard_Integer aNbIter = 20;
2359 Standard_Boolean aStatus = Standard_False;
2363 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt);
2364 if (aStatus && !AdjustToDomain(4, &aPnt(1), &aLowBorder[0], &aUppBorder[0]))
2367 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)),
2369 if (aStatus && !AdjustToDomain(2, &aPnt(1), &aLowBorder[0], &aUppBorder[0]))
2372 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)),
2374 if (aStatus && !AdjustToDomain(2, &aPnt(3), &aLowBorder[2], &aUppBorder[2]))
2377 while(!aStatus && (aNbIter > 0));
2379 // Handle singular points.
2380 Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1,
2384 if (aSingularStatus)
2385 aPnt = aSingularPnt;
2387 if (!aStatus && !aSingularStatus)
2392 gp_Pnt aP1 = theASurf1->Value(aPnt(1), aPnt(2));
2393 gp_Pnt aP2 = theASurf2->Value(aPnt(3), aPnt(4));
2394 const gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2396 const Standard_Real aSQDist = aPInt.SquareDistance(aP1);
2397 if (aSQDist > aTol * aTol)
2402 //Found point is true intersection point
2403 IntSurf_PntOn2S anIP;
2404 anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
2406 //The main idea of checks below is to define if insertion of
2407 //addition point (on the boundary) does not lead to invalid
2408 //intersection curve (e.g. having a loop).
2410 //Loops are detected with rotation angle of the Walking-line (WL).
2411 //If there is hairpin bend then insertion is forbidden.
2413 //There are at least two possible problems:
2414 // 1. There are some cases when two neighbor points of the WL
2415 // are almost coincident (the distance between them is less
2416 // than Precision::Confusion). It is impossible to define
2417 // rotation angle in these cases. Therefore, points with
2418 // "good" distances should be selected.
2420 // 2. Intersection point on the surface boundary has highest
2421 // priority in compare with other "middle" points. Therefore,
2422 // if insertion of new point will result in a bend then some
2423 // "middle" points should be deleted in order to provide
2424 // correct insertion.
2426 //Problem test cases:
2427 // test bugs modalg_5 bug24585_1
2428 // test boolean bcut_complex G7
2429 // test bugs moddata_2 bug469
2433 while (line->NbPoints() > 1)
2435 const Standard_Integer aNbPnts = line->NbPoints();
2437 Standard_Integer aPInd = 1;
2438 for (; aPInd <= aNbPnts; aPInd++)
2440 aP1.SetXYZ(line->Value(aPInd).Value().XYZ());
2441 if (aP1.SquareDistance(aPInt) > Precision::SquareConfusion())
2445 else if (aPInd == 1)
2447 // After insertion, we will obtain
2448 // two coincident points in the line.
2449 // Therefore, insertion is forbidden.
2454 for (++aPInd; aPInd <= aNbPnts; aPInd++)
2456 aP2.SetXYZ(line->Value(aPInd).Value().XYZ());
2457 if (aP1.SquareDistance(aP2) > Precision::SquareConfusion())
2461 if (aPInd > aNbPnts)
2466 const gp_XYZ aDir01(aP1.XYZ() - aPInt.XYZ());
2467 const gp_XYZ aDir12(aP2.XYZ() - aP1.XYZ());
2469 if (aDir01.Dot(aDir12) > 0.0)
2477 line->InsertBefore(1, anIP);
2478 isOK = Standard_True;
2482 while (line->NbPoints() > 1)
2484 const Standard_Integer aNbPnts = line->NbPoints();
2486 gp_Pnt aPPrev, aPCurr;
2487 Standard_Integer aPInd = aNbPnts;
2488 for (; aPInd > 0; aPInd--)
2490 aPCurr.SetXYZ(line->Value(aPInd).Value().XYZ());
2491 if (aPCurr.SquareDistance(aPInt) > Precision::SquareConfusion())
2495 else if (aPInd == aNbPnts)
2497 // After insertion, we will obtain
2498 // two coincident points in the line.
2499 // Therefore, insertion is forbidden.
2504 for (--aPInd; aPInd > 0; aPInd--)
2506 aPPrev.SetXYZ(line->Value(aPInd).Value().XYZ());
2507 if (aPCurr.SquareDistance(aPPrev) > Precision::SquareConfusion())
2516 const gp_XYZ aDirPC(aPCurr.XYZ() - aPPrev.XYZ());
2517 const gp_XYZ aDirCN(aPInt.XYZ() - aPCurr.XYZ());
2519 if (aDirPC.Dot(aDirCN) > 0.0)
2524 RemoveAPoint(aNbPnts);
2528 isOK = Standard_True;
2534 //=======================================================================
2535 //function : PutToBoundary
2537 //=======================================================================
2538 Standard_Boolean IntWalk_PWalking::
2539 PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
2540 const Handle(Adaptor3d_HSurface)& theASurf2)
2542 const Standard_Real aTolMin = Precision::Confusion();
2544 Standard_Boolean hasBeenAdded = Standard_False;
2546 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2547 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2548 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2549 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2550 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2551 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2552 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2553 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2555 Standard_Real aTol = 1.0;
2556 aTol = Min(aTol, aU1bLast - aU1bFirst);
2557 aTol = Min(aTol, aU2bLast - aU2bFirst);
2558 aTol = Min(aTol, aV1bLast - aV1bFirst);
2559 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2561 if(aTol <= 2.0*aTolMin)
2562 return hasBeenAdded;
2564 Standard_Boolean isNeedAdding = Standard_False;
2565 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2566 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2567 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2568 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2570 Standard_Real u1, v1, u2, v2;
2571 line->Value(1).Parameters(u1, v1, u2, v2);
2572 Standard_Real aDelta = 0.0;
2576 aDelta = u1 - aU1bFirst;
2577 if((aTolMin < aDelta) && (aDelta < aTol))
2580 isNeedAdding = Standard_True;
2584 aDelta = aU1bLast - u1;
2585 if((aTolMin < aDelta) && (aDelta < aTol))
2588 isNeedAdding = Standard_True;
2595 aDelta = u2 - aU2bFirst;
2596 if((aTolMin < aDelta) && (aDelta < aTol))
2599 isNeedAdding = Standard_True;
2603 aDelta = aU2bLast - u2;
2604 if((aTolMin < aDelta) && (aDelta < aTol))
2607 isNeedAdding = Standard_True;
2614 aDelta = v1 - aV1bFirst;
2615 if((aTolMin < aDelta) && (aDelta < aTol))
2618 isNeedAdding = Standard_True;
2622 aDelta = aV1bLast - v1;
2623 if((aTolMin < aDelta) && (aDelta < aTol))
2626 isNeedAdding = Standard_True;
2633 aDelta = v2 - aV2bFirst;
2634 if((aTolMin < aDelta) && (aDelta < aTol))
2637 isNeedAdding = Standard_True;
2641 aDelta = aV2bLast - v2;
2642 if((aTolMin < aDelta) && (aDelta < aTol))
2645 isNeedAdding = Standard_True;
2653 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2654 v1, u2, v2, Standard_True);
2657 const Standard_Integer aNbPnts = line->NbPoints();
2658 isNeedAdding = Standard_False;
2659 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2663 aDelta = u1 - aU1bFirst;
2664 if((aTolMin < aDelta) && (aDelta < aTol))
2667 isNeedAdding = Standard_True;
2671 aDelta = aU1bLast - u1;
2672 if((aTolMin < aDelta) && (aDelta < aTol))
2675 isNeedAdding = Standard_True;
2682 aDelta = u2 - aU2bFirst;
2683 if((aTolMin < aDelta) && (aDelta < aTol))
2686 isNeedAdding = Standard_True;
2690 aDelta = aU2bLast - u2;
2691 if((aTolMin < aDelta) && (aDelta < aTol))
2694 isNeedAdding = Standard_True;
2701 aDelta = v1 - aV1bFirst;
2702 if((aTolMin < aDelta) && (aDelta < aTol))
2705 isNeedAdding = Standard_True;
2709 aDelta = aV1bLast - v1;
2710 if((aTolMin < aDelta) && (aDelta < aTol))
2713 isNeedAdding = Standard_True;
2720 aDelta = v2 - aV2bFirst;
2721 if((aTolMin < aDelta) && (aDelta < aTol))
2724 isNeedAdding = Standard_True;
2728 aDelta = aV2bLast - v2;
2729 if((aTolMin < aDelta) && (aDelta < aTol))
2732 isNeedAdding = Standard_True;
2740 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2741 v1, u2, v2, Standard_False);
2744 return hasBeenAdded;
2747 //=======================================================================
2748 //function : SeekAdditionalPoints
2750 //=======================================================================
2751 Standard_Boolean IntWalk_PWalking::
2752 SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
2753 const Handle(Adaptor3d_HSurface)& theASurf2,
2754 const Standard_Integer theMinNbPoints)
2756 const Standard_Real aTol = 1.0e-14;
2757 Standard_Integer aNbPoints = line->NbPoints();
2758 if(aNbPoints > theMinNbPoints)
2759 return Standard_True;
2761 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2762 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2763 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2764 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2765 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2766 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2767 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2768 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2771 Standard_Boolean isPrecise = Standard_False;
2773 TColStd_Array1OfReal aPnt(1, 4);
2776 Standard_Integer aNbPointsPrev = 0;
2777 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2779 aNbPointsPrev = aNbPoints;
2780 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2782 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2783 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2786 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2787 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2789 aPnt(1) = 0.5*(U1f + U1l);
2790 if(aPnt(1) < aU1bFirst)
2791 aPnt(1) = aU1bFirst;
2792 if(aPnt(1) > aU1bLast)
2795 aPnt(2) = 0.5*(V1f+V1l);
2796 if(aPnt(2) < aV1bFirst)
2797 aPnt(2) = aV1bFirst;
2798 if(aPnt(2) > aV1bLast)
2801 aPnt(3) = 0.5*(U2f+U2l);
2802 if(aPnt(3) < aU2bFirst)
2803 aPnt(3) = aU2bFirst;
2804 if(aPnt(3) > aU2bLast)
2807 aPnt(4) = 0.5*(V2f+V2l);
2808 if(aPnt(4) < aV2bFirst)
2809 aPnt(4) = aV2bFirst;
2810 if(aPnt(4) > aV2bLast)
2813 Standard_Boolean aStatus = Standard_False;
2814 Standard_Integer aNbIter = 5;
2817 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt);
2823 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), aPnt(1), aPnt(2));
2829 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), aPnt(3), aPnt(4));
2835 while(!aStatus && (--aNbIter > 0));
2839 gp_Pnt aP1 = theASurf1->Value(aPnt(1), aPnt(2)),
2840 aP2 = theASurf2->Value(aPnt(3), aPnt(4));
2841 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2843 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2844 aSQDist2 = aPInt.SquareDistance(aP2);
2846 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2848 IntSurf_PntOn2S anIP;
2849 anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
2850 line->InsertBefore(lp, anIP);
2852 isPrecise = Standard_True;
2854 if(++aNbPoints >= theMinNbPoints)
2868 void IntWalk_PWalking::
2869 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2870 IntImp_ConstIsoparametric& ChoixIso,
2871 Standard_Boolean& Arrive)
2873 // at the neighborhood of a point, there is a fail of marching
2874 // it is required to divide the steps to try to continue
2875 // if the step is too small if we are on border
2876 // restart in another direction if it was not done, otherwise stop
2879 // Standard_Integer i;
2880 if (Arrive) { //restart in the other direction
2881 if (!DejaReparti ) {
2882 Arrive = Standard_False;
2883 DejaReparti = Standard_True;
2884 previousPoint = line->Value(1);
2885 previoustg = Standard_False;
2886 previousd1 = firstd1;
2887 previousd2 = firstd2;
2889 myTangentIdx = line->NbPoints();
2893 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2894 sensCheminement = -1;
2896 tglast = Standard_False;
2897 ChoixIso = choixIsoSav;
2904 Standard_Real u1,v1,u2,v2;
2905 Standard_Real U1,V1,U2,V2;
2906 Standard_Integer nn=line->NbPoints();
2908 line->Value(nn).Parameters(u1,v1,u2,v2);
2909 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2910 pasuv[0]=Abs(u1-U1);
2911 pasuv[1]=Abs(v1-V1);
2912 pasuv[2]=Abs(u2-U2);
2913 pasuv[3]=Abs(v2-V2);
2920 if ( pasuv[0]*0.5 < ResoU1
2921 && pasuv[1]*0.5 < ResoV1
2922 && pasuv[2]*0.5 < ResoU2
2923 && pasuv[3]*0.5 < ResoV2
2926 tglast = Standard_True; // IS IT ENOUGH ????
2930 { //restart in the other direction
2931 DejaReparti = Standard_True;
2932 previousPoint = line->Value(1);
2933 previoustg = Standard_False;
2934 previousd1 = firstd1;
2935 previousd2 = firstd2;
2937 myTangentIdx = line->NbPoints();
2941 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2943 sensCheminement = -1;
2945 tglast = Standard_False;
2946 ChoixIso = choixIsoSav;
2954 Standard_Real u1,v1,u2,v2;
2955 Standard_Real U1,V1,U2,V2;
2956 Standard_Integer nn=line->NbPoints();
2958 line->Value(nn).Parameters(u1,v1,u2,v2);
2959 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2960 pasuv[0]=Abs(u1-U1);
2961 pasuv[1]=Abs(v1-V1);
2962 pasuv[2]=Abs(u2-U2);
2963 pasuv[3]=Abs(v2-V2);
2967 else Arrive = Standard_True;
2979 //OCC431(apo): modified ->
2980 static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
2982 static const Standard_Real d = 7.0;
2985 IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso)
2987 // test if vector is observed by calculating an increase of vector
2988 // or the previous point and its tangent, the new calculated point and its
2989 // tangent; it is possible to find a cube passing by the 2 points and having as a
2990 // derivative the tangents of the intersection
2991 // calculate the point with parameter 0.5 on cube=p1
2992 // calculate the medium point of 2 points of intersection=p2
2993 // if arrow/2<=||p1p2||<= arrow consider that the vector is observed
2994 // otherwise adjust the step depending on the ratio ||p1p2||/vector
2995 // and the previous step
2996 // test if in 2 tangent planes of surfaces there is no too great angle2d
2997 // grand : if yes divide the step
2998 // test if there is no change of side
3001 if(line->NbPoints() ==1 ) {
3002 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
3005 IntWalk_StatusDeflection aStatus = IntWalk_OK;
3006 Standard_Real FlecheCourante , Ratio = 1.0;
3009 const Handle(Adaptor3d_HSurface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
3010 const Handle(Adaptor3d_HSurface)& Caro2 = myIntersectionOn2S.Function().AuxillarSurface2();
3012 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
3013 //==================================================================================
3014 //========= S t o p o n p o i n t ============
3015 //==================================================================================
3016 if (myIntersectionOn2S.IsTangent()) {
3017 return IntWalk_ArretSurPoint;
3020 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
3022 const Standard_Real aCosBetweenTangent = TgCourante.Dot(previousd);
3024 //==================================================================================
3025 //========= R i s k o f i n f l e x i o n p o i n t ============
3026 //==================================================================================
3027 if (aCosBetweenTangent < 0) {
3028 //------------------------------------------------------------
3029 //-- Risk of inflexion point : Divide the step by 2
3030 //-- Initialize STATIC_PRECEDENT_INFLEXION so that
3031 //-- at the next call to return Pas_OK if there is no
3032 //-- more risk of the point of inflexion
3033 //------------------------------------------------------------
3039 STATIC_PRECEDENT_INFLEXION+=3;
3040 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
3041 return IntWalk_ArretSurPointPrecedent;
3043 return IntWalk_PasTropGrand;
3046 if(STATIC_PRECEDENT_INFLEXION > 0) {
3047 STATIC_PRECEDENT_INFLEXION -- ;
3052 //==================================================================================
3053 //========= D e t e c t c o n f u s e d P o in t s ===========
3054 //==================================================================================
3056 const Standard_Real aSqDist = previousPoint.Value().
3057 SquareDistance(CurrentPoint.Value());
3060 if (aSqDist < Precision::SquareConfusion()) {
3061 pasInit[0] = Max(pasInit[0], 5.0*ResoU1);
3062 pasInit[1] = Max(pasInit[1], 5.0*ResoV1);
3063 pasInit[2] = Max(pasInit[2], 5.0*ResoU2);
3064 pasInit[3] = Max(pasInit[3], 5.0*ResoV2);
3066 for(Standard_Integer i = 0; i < 4; i++)
3068 pasuv[i] = Max(pasuv[i], Min(1.5*pasuv[i], pasInit[i]));
3070 //Compute local resolution: for OCC26717
3071 if (Abs(pasuv[choixIso] - pasInit[choixIso]) <= Precision::Confusion())
3073 Standard_Real CurU, CurV;
3074 if (choixIso == IntImp_UIsoparametricOnCaro1 ||
3075 choixIso == IntImp_VIsoparametricOnCaro1)
3076 previousPoint.ParametersOnS1(CurU, CurV);
3078 previousPoint.ParametersOnS2(CurU, CurV);
3079 gp_Pnt CurPnt = (choixIso == IntImp_UIsoparametricOnCaro1 ||
3080 choixIso == IntImp_VIsoparametricOnCaro1)?
3081 Adaptor3d_HSurfaceTool::Value(Caro1, CurU, CurV) :
3082 Adaptor3d_HSurfaceTool::Value(Caro2, CurU, CurV);
3086 case IntImp_UIsoparametricOnCaro1:
3088 Adaptor3d_HSurfaceTool::Value(Caro1,
3089 CurU + sensCheminement*pasuv[0],
3092 case IntImp_VIsoparametricOnCaro1:
3094 Adaptor3d_HSurfaceTool::Value(Caro1,
3096 CurV + sensCheminement*pasuv[1]);
3098 case IntImp_UIsoparametricOnCaro2:
3100 Adaptor3d_HSurfaceTool::Value(Caro2,
3101 CurU + sensCheminement*pasuv[2],
3104 case IntImp_VIsoparametricOnCaro2:
3106 Adaptor3d_HSurfaceTool::Value(Caro2,
3108 CurV + sensCheminement*pasuv[3]);
3112 Standard_Real RefDist = CurPnt.Distance(OffsetPnt);
3113 Standard_Real LocalResol = 0.;
3114 if (RefDist > gp::Resolution())
3115 LocalResol = pasuv[choixIso] * tolconf / RefDist;
3116 if (pasuv[choixIso] < 2*LocalResol)
3117 pasuv[choixIso] = pasInit[choixIso] = 2*LocalResol;
3119 ////////////////////////////////////////
3120 aStatus = IntWalk_PointConfondu;
3123 //==================================================================================
3124 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
3125 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
3127 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
3128 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
3130 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
3131 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
3137 //=================================================================================
3138 //==== S t e p o f p r o g r e s s i o n (between previous and Current) =======
3139 //=================================================================================
3140 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
3141 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
3142 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
3143 return(IntWalk_ArretSurPointPrecedent);
3145 //==================================================================================
3147 Standard_Real tolArea = 100.0;
3148 if (ResoU1 < Precision::PConfusion() ||
3149 ResoV1 < Precision::PConfusion() ||
3150 ResoU2 < Precision::PConfusion() ||
3151 ResoV2 < Precision::PConfusion() )
3152 tolArea = tolArea*2.0;
3154 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
3155 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
3156 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
3157 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
3158 Duv1 = Du1*Du1 + Dv1*Dv1;
3159 Duv2 = Du2*Du2 + Dv2*Dv2;
3160 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
3161 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
3163 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
3165 Standard_Real aMinDiv2=Precision::Confusion();
3166 aMinDiv2=aMinDiv2*aMinDiv2;
3169 if (Duv1>aMinDiv2) {
3170 d1 = Abs(ResoUV1/Duv1);
3171 d1 = Min(Sqrt(d1)*tolArea, d);
3173 //d1 = Abs(ResoUV1/Duv1);
3174 //d1 = Min(Sqrt(d1)*tolArea,d);
3175 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
3176 tolCoeff1 = Exp(d1);
3178 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
3180 if (Duv2>aMinDiv2) {
3181 d2 = Abs(ResoUV2/Duv2);
3182 d2 = Min(Sqrt(d2)*tolArea,d);
3184 //d2 = Abs(ResoUV2/Duv2);
3185 //d2 = Min(Sqrt(d2)*tolArea,d);
3186 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
3187 tolCoeff2 = Exp(d2);
3188 CosRef1 = CosRef2D/tolCoeff1;
3189 CosRef2 = CosRef2D/tolCoeff2;
3191 //==================================================================================
3192 //== The points are not confused : ==
3193 //== 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 ==
3194 //== N o t T o o G r e a t (angle in space UV) ==
3195 //== C h a n g e o f s i d e ==
3196 //==================================================================================
3197 if (aStatus != IntWalk_PointConfondu) {
3198 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
3199 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3200 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
3201 return(IntWalk_ArretSurPointPrecedent);
3204 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3205 return(IntWalk_PasTropGrand);
3208 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
3209 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
3210 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
3211 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
3212 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
3213 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
3214 AngRef1 = AngRef2D*tolCoeff1;
3215 AngRef2 = AngRef2D*tolCoeff2;
3216 //-------------------------------------------------------
3217 //-- Test : Angle too great in space UV -----
3218 //-- Change of side -----
3219 //-------------------------------------------------------
3220 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
3221 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3222 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
3223 return(IntWalk_ArretSurPoint);
3225 return(IntWalk_PasTropGrand);
3229 //==================================================================================
3230 //== D e t e c t i o n o f : Step Too Small
3232 //==================================================================================
3234 //---------------------------------------
3235 //-- Estimate of the vector --
3236 //---------------------------------------
3238 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*aSqDist))/8.;
3240 if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
3241 if(FlecheCourante>1e-16) {
3242 Ratio = 0.5*(fleche/FlecheCourante);
3247 Standard_Real pasSu1 = pasuv[0];
3248 Standard_Real pasSv1 = pasuv[1];
3249 Standard_Real pasSu2 = pasuv[2];
3250 Standard_Real pasSv2 = pasuv[3];
3253 //-- a point at U+DeltaU is required, ....
3254 //-- return a point at U + Epsilon
3255 //-- Epsilon << DeltaU.
3257 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
3258 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
3259 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
3260 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
3262 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
3263 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
3264 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
3265 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
3266 //-- if(Ratio>10.0 ) { Ratio=10.0; }
3267 Standard_Real R1,R = pasInit[0]/pasuv[0];
3268 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
3269 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
3270 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
3271 if(Ratio > R) Ratio=R;
3272 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
3273 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
3274 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
3275 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
3276 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
3277 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
3278 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3279 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3280 return IntWalk_PasTropGrand;
3283 if(aStatus == IntWalk_OK) {
3284 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3285 //-- Try to increase the step
3289 else { //-- CurrentVector > vector*0.5
3290 if (FlecheCourante > fleche) { //-- Current step too Great
3291 Ratio = fleche/FlecheCourante;
3292 pasuv[0] = Ratio*pasuv[0];
3293 pasuv[1] = Ratio*pasuv[1];
3294 pasuv[2] = Ratio*pasuv[2];
3295 pasuv[3] = Ratio*pasuv[3];
3296 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3297 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3298 return IntWalk_PasTropGrand;
3301 else { //-- vector/2 < CurrentVector <= vector
3302 Ratio = 0.75 * (fleche / FlecheCourante);
3306 if(aStatus != IntWalk_PointConfondu)
3308 //Here, aCosBetweenTangent >= 0.0 definitely.
3311 Brief algorithm description.
3312 We have two (not-coincindent) intersection point (P1 and P2). In every point,
3313 vector of tangent (to the intersection curve) is known (vectors T1 and T2).
3314 Basing on these data, we create osculating circle.
3316 * - arc of osculating circle
3323 Let me draw your attention to the following facts:
3324 1. Vectors T1 and T2 direct FROM (not TO) points P1 and P2. Therefore,
3325 one of previously computed vector should be reversed.
3327 In this case, the absolute (!) value of the deflection between the arc of
3328 the osculating circle and the P1P2 segment can be computed as follows:
3329 e = d*(1-sin(B/2))/(2*cos(B/2)), (1)
3330 where d is the length of P1P2 segment, B is the angle between vectors T1 and T2.
3338 Later, the normal state of algorithm work is (as we apply)
3339 tolconf/2 <= e <= tolconf.
3340 In this case, we keep previous step.
3342 If e < tolconf/2 then the local curvature of the intersection curve is small.
3343 As result, the step should be increased.
3345 If e > tolconf then the step is too big. Therefore, we should decrease one.
3347 Condition (1) is equivalent to
3348 sin(B/2) = 1 - 2/(1+(d/(2*e))^2) = Fs(e),
3349 cos(B) = 1 - 2*Fs(e)^2 = Fd(e),
3350 where Fs(e)and Fd(e) are some function with parameter "deflection".
3352 Let mean that Fs(e) is decreasing function. Fd(e) is increasing function,
3353 in the range, where Fs(e) > 0.0 (i.e. when e < d/2).
3355 Now, let substitute required deflection (tolconf or tolconf/2) to z. Then
3356 it is necessary to check if e < z or if e > z.
3358 In this case, it is enough to comapare Fs(e) and Fs(z).
3359 At that Fs(e) > 0 because sin(B/2) > 0 always.
3361 Therefore, if Fs(z) < 0.0 then Fs(e) > Fs(z) ==> e < z definitely.
3362 If Fs(z) > 0.0 then we can compare Fs(z)^2 and Fs(e)^2 or, in substance,
3363 values Fd(e) and Fd(z). If Fd(e) > Fd(z) then e > z and vice versa.
3366 //Fd(e) is already known (Fd(e) == -aCosBetweenTangent)
3368 const Standard_Real anInvSqAbsArcDeflMax = 0.25*aSqDist/(tolconf*tolconf);
3369 const Standard_Real aSinB2Max = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMax);
3371 if(aSinB2Max >= 0.0 && (aCosBetweenTangent <= 2.0 * aSinB2Max * aSinB2Max - 1.0))
3372 {//Real deflection is greater or equal than tolconf
3373 aStatus = IntWalk_PasTropGrand;
3376 {//Real deflection is less than tolconf
3377 const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax;
3378 const Standard_Real aSinB2Min = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin);
3380 if((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0))
3381 {//Real deflection is less than tolconf/2.0
3382 aStatus = IntWalk_StepTooSmall;
3386 if(aStatus == IntWalk_PasTropGrand)
3388 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3392 if(aStatus == IntWalk_StepTooSmall)
3394 pasuv[0] = Max(pasuv[0], AbsDu1);
3395 pasuv[1] = Max(pasuv[1], AbsDv1);
3396 pasuv[2] = Max(pasuv[2], AbsDu2);
3397 pasuv[3] = Max(pasuv[3], AbsDv2);
3399 pasInit[0] = Max(pasInit[0], AbsDu1);
3400 pasInit[1] = Max(pasInit[1], AbsDv1);
3401 pasInit[2] = Max(pasInit[2], AbsDu2);
3402 pasInit[3] = Max(pasInit[3], AbsDv2);
3408 pasuv[0] = Max(myStepMin[0],Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
3409 pasuv[1] = Max(myStepMin[1],Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
3410 pasuv[2] = Max(myStepMin[2],Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
3411 pasuv[3] = Max(myStepMin[3],Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
3413 if(aStatus == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3417 Standard_Boolean IntWalk_PWalking::
3418 TestArret(const Standard_Boolean DejaReparti,
3419 TColStd_Array1OfReal& Param,
3420 IntImp_ConstIsoparametric& ChoixIso)
3423 // test if the point of intersection set by these parameters remains in the
3424 // natural domain of each square.
3425 // if the point outpasses reframe to find the best iso (border)
3426 // that intersects easiest the other square
3427 // otherwise test if closed line is present
3430 Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
3431 Standard_Real DPc,DPb;
3432 Standard_Integer i = 0, k = 0;
3437 previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
3439 Standard_Real SolParam[4];
3440 myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
3442 Standard_Boolean Trouve = Standard_False;
3444 Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1;
3445 Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2;
3447 Standard_Integer im1;
3448 for ( i = 1,im1 = 0;i<=4;i++,im1++) {
3455 if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
3456 SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous
3458 Trouve = Standard_True; //--
3459 DPc = Uvp[im1]-Param(i); //-- Previous - Current
3460 DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf
3461 ParC[im1] = Uvd[im1]; //-- ParamCorrige
3462 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3464 if(dv2>RealEpsilon()) { //-- Progress at the other Direction ?
3465 Duv[im1] = DPc*DPb + dv2;
3466 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3469 Duv[im1]=-1.0; //-- If no progress, do not change
3470 } //-- the choice of iso
3472 else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
3473 SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current
3475 Trouve = Standard_True; //--
3476 DPc = Param(i)-Uvp[im1]; //-- Current - Previous
3477 DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous
3478 ParC[im1] = Uvf[im1]; //-- Param Corrige
3479 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3481 if(dv2>RealEpsilon()) { //-- Progress in other Direction ?
3482 Duv[im1] = DPc*DPb + dv2;
3483 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3486 Duv[im1]=-1.0; //-- If no progress, do not change
3487 } //-- the choice of iso
3496 //--------------------------------------------------
3497 //-- One of Parameters u1,v1,u2,v2 is outside of --
3498 //-- the natural limits. --
3499 //-- Find the best direction of --
3500 //-- progress and reframe the parameters. --
3501 //--------------------------------------------------
3502 Standard_Real ddv = -1.0;
3504 for (i=0;i<=3;i++) {
3505 Param(i+1) = ParC[i];
3512 ChoixIso = ChoixRef(k);
3515 if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
3516 ChoixIso = IntImp_UIsoparametricOnCaro1;
3518 else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
3519 ChoixIso = IntImp_VIsoparametricOnCaro1;
3521 else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
3522 ChoixIso = IntImp_UIsoparametricOnCaro2;
3524 else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
3525 ChoixIso = IntImp_VIsoparametricOnCaro2;
3528 close = Standard_False;
3529 return Standard_True;
3533 if (!DejaReparti) { // find if line closed
3536 const IntSurf_PntOn2S& POn2S1=line->Value(1);
3538 POn2S1.ParametersOnS1(u,v);
3539 gp_Pnt2d P1uvS1(u,v);
3540 previousPoint.ParametersOnS1(u,v);
3541 gp_Pnt2d PrevuvS1(u,v);
3542 myIntersectionOn2S.Point().ParametersOnS1(u,v);
3543 gp_Pnt2d myIntersuvS1(u,v);
3544 Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
3545 (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
3547 POn2S1.ParametersOnS2(u,v);
3548 gp_Pnt2d P1uvS2(u,v);
3549 previousPoint.ParametersOnS2(u,v);
3550 gp_Pnt2d PrevuvS2(u,v);
3551 myIntersectionOn2S.Point().ParametersOnS2(u,v);
3552 gp_Pnt2d myIntersuvS2(u,v);
3553 Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
3554 (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
3556 close = close2dS1 && close2dS2;
3559 else return Standard_False;