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_Surface.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_Surface)&
48 Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
49 const Handle(Adaptor3d_Surface)&
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_Surface)& Caro1,
196 const Handle(Adaptor3d_Surface)& 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),
205 tgfirst(Standard_False),
206 tglast(Standard_False),
211 myTolTang(TolTangency),
213 previoustg(Standard_False),
214 myIntersectionOn2S(Caro1,Caro2,TolTangency),
215 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
216 STATIC_PRECEDENT_INFLEXION(0)
218 Standard_Real KELARG=20.;
220 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
221 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
222 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
223 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
224 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
226 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
227 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
228 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
229 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
231 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
232 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
234 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
235 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
237 Standard_Real NEWRESO;
238 Standard_Real MAXVAL;
239 Standard_Real MAXVAL2;
241 MAXVAL = Abs(Um1); MAXVAL2 = Abs(UM1);
242 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
243 NEWRESO = ResoU1 * MAXVAL ;
244 if(NEWRESO > ResoU1 &&NEWRESO<10) { ResoU1 = NEWRESO; }
247 MAXVAL = Abs(Um2); MAXVAL2 = Abs(UM2);
248 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
249 NEWRESO = ResoU2 * MAXVAL ;
250 if(NEWRESO > ResoU2 && NEWRESO<10) { ResoU2 = NEWRESO; }
253 MAXVAL = Abs(Vm1); MAXVAL2 = Abs(VM1);
254 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
255 NEWRESO = ResoV1 * MAXVAL ;
256 if(NEWRESO > ResoV1 && NEWRESO<10) { ResoV1 = NEWRESO; }
259 MAXVAL = Abs(Vm2); MAXVAL2 = Abs(VM2);
260 if(MAXVAL2 > MAXVAL) MAXVAL = MAXVAL2;
261 NEWRESO = ResoV2 * MAXVAL ;
262 if(NEWRESO > ResoV2 && NEWRESO<10) { ResoV2 = NEWRESO; }
264 pasuv[0]=pasMax*Abs(UM1-Um1);
265 pasuv[1]=pasMax*Abs(VM1-Vm1);
266 pasuv[2]=pasMax*Abs(UM2-Um2);
267 pasuv[3]=pasMax*Abs(VM2-Vm2);
269 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
270 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
271 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
272 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
275 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
276 //UM1+=KELARG*pasuv[0]; Um1-=KELARG*pasuv[0];
279 Standard_Real t = UM1-Um1;
280 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
281 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
282 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
287 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
288 //VM1+=KELARG*pasuv[1]; Vm1-=KELARG*pasuv[1];
291 Standard_Real t = VM1-Vm1;
292 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
293 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
294 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
299 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
300 //UM2+=KELARG*pasuv[2]; Um2-=KELARG*pasuv[2];
303 Standard_Real t = UM2-Um2;
304 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
305 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
306 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
311 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
312 //VM2+=KELARG*pasuv[3]; Vm2-=KELARG*pasuv[3];
315 Standard_Real t = VM2-Vm2;
316 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
317 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
318 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
323 myStepMin[0] = 100.0*ResoU1;
324 myStepMin[1] = 100.0*ResoV1;
325 myStepMin[2] = 100.0*ResoU2;
326 myStepMin[3] = 100.0*ResoV2;
328 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
330 for (Standard_Integer i = 0; i<=3;i++) {
333 pasInit[i] = pasSav[i] = pasuv[i];
338 //==================================================================================
339 // function : IntWalk_PWalking
341 //==================================================================================
342 IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_Surface)& Caro1,
343 const Handle(Adaptor3d_Surface)& Caro2,
344 const Standard_Real TolTangency,
345 const Standard_Real Epsilon,
346 const Standard_Real Deflection,
347 const Standard_Real Increment,
348 const Standard_Real U1,
349 const Standard_Real V1,
350 const Standard_Real U2,
351 const Standard_Real V2)
355 close(Standard_False),
358 myTolTang(TolTangency),
360 myIntersectionOn2S(Caro1,Caro2,TolTangency),
361 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
362 STATIC_PRECEDENT_INFLEXION(0)
364 Standard_Real KELARG=20.;
366 pasMax=Increment*0.2; //-- June 25 99 after problems with precision
368 Um1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
369 Vm1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
370 UM1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1);
371 VM1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1);
373 Um2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
374 Vm2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
375 UM2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2);
376 VM2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2);
378 ResoU1 = Adaptor3d_HSurfaceTool::UResolution(Caro1,Precision::Confusion());
379 ResoV1 = Adaptor3d_HSurfaceTool::VResolution(Caro1,Precision::Confusion());
381 ResoU2 = Adaptor3d_HSurfaceTool::UResolution(Caro2,Precision::Confusion());
382 ResoV2 = Adaptor3d_HSurfaceTool::VResolution(Caro2,Precision::Confusion());
384 Standard_Real NEWRESO, MAXVAL, MAXVAL2;
388 if(MAXVAL2 > MAXVAL) {
391 NEWRESO = ResoU1 * MAXVAL ;
392 if(NEWRESO > ResoU1) {
398 if(MAXVAL2 > MAXVAL){
401 NEWRESO = ResoU2 * MAXVAL ;
402 if(NEWRESO > ResoU2) {
408 if(MAXVAL2 > MAXVAL) {
411 NEWRESO = ResoV1 * MAXVAL ;
412 if(NEWRESO > ResoV1) {
418 if(MAXVAL2 > MAXVAL){
421 NEWRESO = ResoV2 * MAXVAL ;
422 if(NEWRESO > ResoV2) {
426 pasuv[0]=pasMax*Abs(UM1-Um1);
427 pasuv[1]=pasMax*Abs(VM1-Vm1);
428 pasuv[2]=pasMax*Abs(UM2-Um2);
429 pasuv[3]=pasMax*Abs(VM2-Vm2);
431 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro1)==Standard_False) {
432 UM1+=KELARG*pasuv[0];
433 Um1-=KELARG*pasuv[0];
436 Standard_Real t = UM1-Um1;
437 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro1)) {
438 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro1)-t);
439 t=(t>KELARG*pasuv[0])? KELARG*pasuv[0] : t;
445 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro1)==Standard_False) {
446 VM1+=KELARG*pasuv[1];
447 Vm1-=KELARG*pasuv[1];
450 Standard_Real t = VM1-Vm1;
451 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro1)) {
452 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro1)-t);
453 t=(t>KELARG*pasuv[1])? KELARG*pasuv[1] : t;
458 if(Adaptor3d_HSurfaceTool::IsUPeriodic(Caro2)==Standard_False) {
459 UM2+=KELARG*pasuv[2];
460 Um2-=KELARG*pasuv[2];
463 Standard_Real t = UM2-Um2;
464 if(t<Adaptor3d_HSurfaceTool::UPeriod(Caro2)) {
465 t=0.5*(Adaptor3d_HSurfaceTool::UPeriod(Caro2)-t);
466 t=(t>KELARG*pasuv[2])? KELARG*pasuv[2] : t;
472 if(Adaptor3d_HSurfaceTool::IsVPeriodic(Caro2)==Standard_False) {
473 VM2+=KELARG*pasuv[3];
474 Vm2-=KELARG*pasuv[3];
477 Standard_Real t = VM2-Vm2;
478 if(t<Adaptor3d_HSurfaceTool::VPeriod(Caro2)) {
479 t=0.5*(Adaptor3d_HSurfaceTool::VPeriod(Caro2)-t);
480 t=(t>KELARG*pasuv[3])? KELARG*pasuv[3] : t;
485 //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
487 for (Standard_Integer i = 0; i<=3;i++) {
488 pasInit[i] = pasSav[i] = pasuv[i];
491 if(ResoU1>0.0001*pasuv[0]) ResoU1=0.00001*pasuv[0];
492 if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
493 if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
494 if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
496 myStepMin[0] = 100.0*ResoU1;
497 myStepMin[1] = 100.0*ResoV1;
498 myStepMin[2] = 100.0*ResoU2;
499 myStepMin[3] = 100.0*ResoV2;
502 TColStd_Array1OfReal Par(1,4);
510 //==================================================================================
511 // function : PerformFirstPoint
513 //==================================================================================
514 Standard_Boolean IntWalk_PWalking::PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
515 IntSurf_PntOn2S& FirstPoint)
518 close = Standard_False;
521 TColStd_Array1OfReal Param(1,4);
523 for (i=1; i<=4; ++i) {
524 Param(i) = ParDep(i);
526 //-- calculate the first solution point
527 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
529 myIntersectionOn2S.Perform(Param,Rsnld);
530 if (!myIntersectionOn2S.IsDone()) {
531 return Standard_False;
534 if (myIntersectionOn2S.IsEmpty()) {
535 return Standard_False;
538 FirstPoint = myIntersectionOn2S.Point();
539 return Standard_True;
541 //==================================================================================
542 // function : Perform
544 //==================================================================================
545 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep)
547 Perform(ParDep,Um1,Vm1,Um2,Vm2,UM1,VM1,UM2,VM2);
550 //=======================================================================
551 //function : SQDistPointSurface
552 //purpose : Returns square distance between thePnt and theSurf.
553 // (theU0, theV0) is initial point for extrema
554 //=======================================================================
555 static Standard_Real SQDistPointSurface(const gp_Pnt &thePnt,
556 const Adaptor3d_Surface& theSurf,
557 const Standard_Real theU0,
558 const Standard_Real theV0)
560 Extrema_GenLocateExtPS aExtPS(theSurf);
561 aExtPS.Perform(thePnt, theU0, theV0);
566 return aExtPS.SquareDistance();
569 //==================================================================================
570 // function : IsTangentExtCheck
571 // purpose : Additional check if the surfaces are tangent.
572 // Checks if any point in one surface lie in another surface
573 // (with given tolerance)
574 //==================================================================================
575 static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_Surface)& theSurf1,
576 const Handle(Adaptor3d_Surface)& theSurf2,
577 const Standard_Real theU10,
578 const Standard_Real theV10,
579 const Standard_Real theU20,
580 const Standard_Real theV20,
581 const Standard_Real theToler,
582 const Standard_Real theArrStep[])
586 gp_Vec aDu1, aDv1, aDu2, aDv2;
587 theSurf1->D1(theU10, theV10, aPt, aDu1, aDv1);
588 theSurf2->D1(theU20, theV20, aPt, aDu2, aDv2);
590 const gp_Vec aN1(aDu1.Crossed(aDv1)),
591 aN2(aDu2.Crossed(aDv2));
592 const Standard_Real aDP = aN1.Dot(aN2),
593 aSQ1 = aN1.SquareMagnitude(),
594 aSQ2 = aN2.SquareMagnitude();
596 if((aSQ1 < RealSmall()) || (aSQ2 < RealSmall()))
597 return Standard_True; //Tangent
599 if(aDP*aDP < 0.9998*aSQ1*aSQ2)
600 {//cos(ang N1<->N2) < 0.9999
601 return Standard_False; //Not tangent
605 //For two faces (2^2 = 4)
606 const Standard_Real aSQToler = 4.0*theToler*theToler;
607 const Standard_Integer aNbItems = 4;
608 const Standard_Real aParUS1[aNbItems] = { theU10 + theArrStep[0],
609 theU10 - theArrStep[0],
611 const Standard_Real aParVS1[aNbItems] = { theV10, theV10,
612 theV10 + theArrStep[1],
613 theV10 - theArrStep[1]};
614 const Standard_Real aParUS2[aNbItems] = { theU20 + theArrStep[2],
615 theU20 - theArrStep[2],
617 const Standard_Real aParVS2[aNbItems] = { theV20, theV20,
618 theV20 + theArrStep[3],
619 theV20 - theArrStep[3]};
621 for(Standard_Integer i = 0; i < aNbItems; i++)
623 gp_Pnt aP(theSurf1->Value(aParUS1[i], aParVS1[i]));
624 const Standard_Real aSqDist = SQDistPointSurface(aP, *theSurf2, theU20, theV20);
625 if(aSqDist > aSQToler)
626 return Standard_False;
629 for(Standard_Integer i = 0; i < aNbItems; i++)
631 gp_Pnt aP(theSurf2->Value(aParUS2[i], aParVS2[i]));
632 const Standard_Real aSqDist = SQDistPointSurface(aP, *theSurf1, theU10, theV10);
633 if(aSqDist > aSQToler)
634 return Standard_False;
637 return Standard_True;
640 //==================================================================================
641 // function : Perform
643 //==================================================================================
644 void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
645 const Standard_Real u1min,
646 const Standard_Real v1min,
647 const Standard_Real u2min,
648 const Standard_Real v2min,
649 const Standard_Real u1max,
650 const Standard_Real v1max,
651 const Standard_Real u2max,
652 const Standard_Real v2max)
654 const Standard_Real aSQDistMax = 1.0e-14;
657 Standard_Integer NbPasOKConseq=0;
658 TColStd_Array1OfReal Param(1,4);
659 IntImp_ConstIsoparametric ChoixIso;
662 done = Standard_False;
665 const Handle(Adaptor3d_Surface)& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
666 const Handle(Adaptor3d_Surface)& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
668 const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1);
669 const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1);
670 const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter (Caro1);
671 const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter (Caro1);
673 const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2);
674 const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2);
675 const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
676 const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
678 ComputePasInit(u1max - u1min,v1max - v1min,u2max - u2min,v2max - v2min);
680 for (Standard_Integer i=0; i<4; ++i)
687 pasInit[i] = pasSav[i] = pasuv[i];
690 line = new IntSurf_LineOn2S ();
692 for (Standard_Integer i=1; i<=4; ++i)
696 //-- reproduce steps uv connected to surfaces Caro1 and Caro2
697 //-- pasuv[] and pasSav[] are modified during the marching
698 for(Standard_Integer i = 0; i < 4; ++i)
700 pasSav[i] = pasuv[i] = pasInit[i];
703 //-- calculate the first solution point
704 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
706 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
707 if (!myIntersectionOn2S.IsDone())
713 if (myIntersectionOn2S.IsEmpty())
718 if(myIntersectionOn2S.IsTangent())
723 Standard_Boolean Arrive, DejaReparti;
724 const Standard_Integer RejectIndexMAX = 250000;
725 Standard_Integer IncKey, RejectIndex;
728 DejaReparti = Standard_False;
732 previousPoint = myIntersectionOn2S.Point();
733 previoustg = Standard_False;
734 previousd = myIntersectionOn2S.Direction();
735 previousd1 = myIntersectionOn2S.DirectionOnS1();
736 previousd2 = myIntersectionOn2S.DirectionOnS2();
739 firstd1 = previousd1;
740 firstd2 = previousd2;
741 tgfirst = tglast = Standard_False;
742 choixIsoSav = ChoixIso;
743 //------------------------------------------------------------
744 //-- Test if the first point of marching corresponds
745 //-- to a point on borders.
746 //-- In this case, DejaReparti is initialized as True
748 pf = previousPoint.Value();
749 Standard_Boolean bTestFirstPoint = Standard_True;
751 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
753 if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), myTolTang, pasuv))
756 AddAPoint(previousPoint);
758 IntWalk_StatusDeflection aStatus = IntWalk_OK, aPrevStatus = IntWalk_OK;
759 Standard_Boolean NoTestDeflection = Standard_False;
760 Standard_Real SvParam[4], f;
761 Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
762 Standard_Integer LevelOfPointConfondu = 0;
763 Standard_Integer LevelOfIterWithoutAppend = -1;
766 const Standard_Real aTol[4] = { Epsilon(UM1 - Um1),
771 Standard_Integer aPrevNbPoints = line->NbPoints();
773 Arrive = Standard_False;
776 aPrevStatus = aStatus;
778 LevelOfIterWithoutAppend++;
779 if(LevelOfIterWithoutAppend>20)
781 Arrive = Standard_True;
785 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
786 LevelOfIterWithoutAppend = 0;
792 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
793 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
794 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
795 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
803 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
806 Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
808 dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
809 dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
810 dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
811 dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
813 aIncKey=5.*(Standard_Real)IncKey;
815 if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps)
820 if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps)
825 if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps)
830 if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps)
840 //==========================
846 Standard_Integer aTryNumber = 0;
847 Standard_Boolean isBadPoint = Standard_False;
848 IntImp_ConstIsoparametric aBestIso = ChoixIso;
851 isBadPoint = Standard_False;
853 ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, aBestIso);
855 if (myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty())
857 //If we go along any surface boundary then it is possible
858 //to find "outboundaried" point.
859 //Nevertheless, if this deflection is quite small, we will be
860 //able to adjust this point to the boundary.
862 Standard_Real aNewPnt[4], anAbsParamDist[4];
863 myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
864 const Standard_Real aParMin[4] = {Um1, Vm1, Um2, Vm2};
865 const Standard_Real aParMax[4] = {UM1, VM1, UM2, VM2};
867 for(Standard_Integer i = 0; i < 4; i++)
869 if(Abs(aNewPnt[i] - aParMin[i]) < aTol[i])
870 aNewPnt[i] = aParMin[i];
871 else if(Abs(aNewPnt[i] - aParMax[i]) < aTol[i])
872 aNewPnt[i] = aParMax[i];
875 if (aNewPnt[0] < Um1 || aNewPnt[0] > UM1 ||
876 aNewPnt[1] < Vm1 || aNewPnt[1] > VM1 ||
877 aNewPnt[2] < Um2 || aNewPnt[2] > UM2 ||
878 aNewPnt[3] < Vm2 || aNewPnt[3] > VM2)
880 // Out of borders, process it later.
884 myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
889 anAbsParamDist[0] = Abs(Param(1) - dP1 - aNewPnt[0]);
890 anAbsParamDist[1] = Abs(Param(2) - dP2 - aNewPnt[1]);
891 anAbsParamDist[2] = Abs(Param(3) - dP3 - aNewPnt[2]);
892 anAbsParamDist[3] = Abs(Param(4) - dP4 - aNewPnt[3]);
893 if (anAbsParamDist[0] < ResoU1 &&
894 anAbsParamDist[1] < ResoV1 &&
895 anAbsParamDist[2] < ResoU2 &&
896 anAbsParamDist[3] < ResoV2 &&
897 aStatus != IntWalk_PasTropGrand)
899 isBadPoint = Standard_True;
900 aBestIso = IntImp_ConstIsoparametric((aBestIso + 1) % 4);
903 } while (isBadPoint && ++aTryNumber <= 4);
905 if (!myIntersectionOn2S.IsDone())
907 //end of line, division
908 Arrive = Standard_False;
913 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
917 //== Calculation of exact point from Param(.) is possible
918 if (myIntersectionOn2S.IsEmpty())
920 Standard_Real u1,v1,u2,v2;
921 previousPoint.Parameters(u1,v1,u2,v2);
923 Arrive = Standard_False;
924 if(u1<UFirst1 || u1>ULast1)
926 Arrive=Standard_True;
929 if(u2<UFirst2 || u2>ULast2)
931 Arrive=Standard_True;
934 if(v1<VFirst1 || v1>VLast1)
936 Arrive=Standard_True;
939 if(v2<VFirst2 || v2>VLast2)
941 Arrive=Standard_True;
944 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
945 LevelOfEmptyInmyIntersectionOn2S++;
947 if(LevelOfEmptyInmyIntersectionOn2S>10)
957 //============================================================
958 //== A point has been found : T E S T D E F L E C T I O N
959 //============================================================
962 NoTestDeflection = Standard_False;
966 if(--LevelOfEmptyInmyIntersectionOn2S<=0)
968 LevelOfEmptyInmyIntersectionOn2S=0;
969 if(LevelOfIterWithoutAppend < 10)
971 aStatus = TestDeflection(ChoixIso, aStatus);
975 if (aStatus != IntWalk_StepTooSmall)
977 // Bug #0029682 (Boolean intersection with
978 // fuzzy-option hangs).
979 // If aStatus == IntWalk_StepTooSmall then
980 // the counter "LevelOfIterWithoutAppend" will
981 // be nulified in the future if the step is smaller
982 // (see "case IntWalk_StepTooSmall:" below).
983 // Here, we forbid this nulification and thereby provide out from
994 //============================================================
995 //== T r a i t e m e n t s u r S t a t u s ==
996 //============================================================
997 if(LevelOfPointConfondu > 5)
999 aStatus = IntWalk_ArretSurPoint;
1000 LevelOfPointConfondu = 0;
1003 if(aStatus==IntWalk_OK)
1006 if(NbPasOKConseq >= 5)
1009 Standard_Boolean pastroppetit;
1014 pastroppetit=Standard_True;
1016 if(pasuv[0]<pasInit[0])
1018 t = (pasInit[0]-pasuv[0])*0.25;
1019 if(t>0.1*pasInit[0])
1025 pastroppetit=Standard_False;
1028 if(pasuv[1]<pasInit[1])
1030 t = (pasInit[1]-pasuv[1])*0.25;
1031 if(t>0.1*pasInit[1]) {
1036 pastroppetit=Standard_False;
1039 if(pasuv[2]<pasInit[2])
1041 t = (pasInit[2]-pasuv[2])*0.25;
1042 if(t>0.1*pasInit[2])
1048 pastroppetit=Standard_False;
1051 if(pasuv[3]<pasInit[3])
1053 t = (pasInit[3]-pasuv[3])*0.25;
1054 if(t>0.1*pasInit[3]) {
1058 pastroppetit=Standard_False;
1072 pastroppetit=Standard_False;
1076 while(pastroppetit);
1078 }//aStatus==IntWalk_OK
1083 switch(aStatus)//007
1085 case IntWalk_ArretSurPointPrecedent:
1087 Arrive = Standard_False;
1088 RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
1091 case IntWalk_PasTropGrand:
1093 Param(1)=SvParam[0];
1094 Param(2)=SvParam[1];
1095 Param(3)=SvParam[2];
1096 Param(4)=SvParam[3];
1098 if(LevelOfIterWithoutAppend > 5)
1100 for (Standard_Integer i = 0; i < 4; i++)
1102 if (pasSav[i] > pasInit[i])
1105 const Standard_Real aDelta = (pasInit[i]-pasSav[i])*0.25;
1107 if(aDelta > Epsilon(pasInit[i]))
1109 pasInit[i] -= aDelta;
1110 if ((aPrevStatus != IntWalk_StepTooSmall) &&
1111 (line->NbPoints() != aPrevNbPoints))
1113 LevelOfIterWithoutAppend = 0;
1116 aPrevNbPoints = line->NbPoints();
1123 case IntWalk_PointConfondu:
1125 LevelOfPointConfondu++;
1127 if(LevelOfPointConfondu>5)
1129 Standard_Boolean pastroppetit;
1133 pastroppetit=Standard_True;
1135 for(Standard_Integer i = 0; i < 4; i++)
1137 if(pasuv[i]<pasInit[i])
1139 pasuv[i]+=(pasInit[i]-pasuv[i])*0.25;
1140 pastroppetit=Standard_False;
1156 pastroppetit=Standard_False;
1160 while(pastroppetit);
1165 case IntWalk_StepTooSmall:
1167 Standard_Boolean hasStepBeenIncreased = Standard_False;
1169 for(Standard_Integer i = 0; i < 4; i++)
1171 const Standard_Real aNewStep = Min(1.5*pasuv[i], pasInit[i]);
1172 if(aNewStep > pasuv[i])
1174 pasuv[i] = aNewStep;
1175 hasStepBeenIncreased = Standard_True;
1179 if(hasStepBeenIncreased)
1181 Param(1)=SvParam[0];
1182 Param(2)=SvParam[1];
1183 Param(3)=SvParam[2];
1184 Param(4)=SvParam[3];
1186 // In order to avoid cyclic changes
1187 // (PasTropGrand --> Decrease step -->
1188 // StepTooSmall --> Increase step --> PasTropGrand...)
1189 // nullify LevelOfIterWithoutAppend only if the condition
1191 if ((aPrevStatus != IntWalk_PasTropGrand) &&
1192 (line->NbPoints() != aPrevNbPoints))
1194 LevelOfIterWithoutAppend = 0;
1197 aPrevNbPoints = line->NbPoints();
1202 Standard_FALLTHROUGH
1204 case IntWalk_ArretSurPoint://006
1206 //=======================================================
1207 //== Stop Test t : Frame on Param(.) ==
1208 //=======================================================
1210 Arrive = TestArret(DejaReparti,Param,ChoixIso);
1211 // JMB 30th December 1999.
1212 // Some statement below should not be put in comment because they are useful.
1213 // See grid CTO 909 A1 which infinitely loops
1214 if(Arrive==Standard_False && aStatus==IntWalk_ArretSurPoint)
1216 Arrive=Standard_True;
1218 std::cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<std::endl;
1224 NbPasOKConseq = -10;
1229 //=====================================================
1230 //== Param(.) is in the limits ==
1231 //== and does not end a closed line ==
1232 //=====================================================
1233 //== Check on the current point of myInters
1234 Standard_Boolean pointisvalid = Standard_False;
1236 Standard_Real u1,v1,u2,v2;
1237 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1240 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1241 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1242 v1 >= Vm1 && v2 >= Vm2)
1244 pointisvalid=Standard_True;
1251 previousPoint = myIntersectionOn2S.Point();
1252 previoustg = myIntersectionOn2S.IsTangent();
1256 previousd = myIntersectionOn2S.Direction();
1257 previousd1 = myIntersectionOn2S.DirectionOnS1();
1258 previousd2 = myIntersectionOn2S.DirectionOnS2();
1260 //=====================================================
1261 //== Check on the previous Point
1263 Standard_Real u1,v1,u2,v2;
1264 previousPoint.Parameters(u1,v1,u2,v2);
1265 if( u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1266 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1267 v1 >= Vm1 && v2 >= Vm2)
1269 pl = previousPoint.Value();
1272 if(pf.SquareDistance(pl) < aSQDistMax)
1282 bTestFirstPoint = Standard_False;
1286 AddAPoint(previousPoint);
1289 if(RejectIndex >= RejectIndexMAX)
1291 Arrive = Standard_True;
1296 LevelOfIterWithoutAppend = 0;
1300 //====================================================
1302 if (aStatus == IntWalk_ArretSurPoint)
1304 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1308 if (line->NbPoints() == 2)
1310 pasSav[0] = pasuv[0];
1311 pasSav[1] = pasuv[1];
1312 pasSav[2] = pasuv[2];
1313 pasSav[3] = pasuv[3];
1315 if ((aPrevStatus == IntWalk_PasTropGrand) &&
1316 (LevelOfIterWithoutAppend > 0))
1318 pasInit[0] = pasuv[0];
1319 pasInit[1] = pasuv[1];
1320 pasInit[2] = pasuv[2];
1321 pasInit[3] = pasuv[3];
1330 //================= la ligne est fermee ===============
1331 AddAPoint(line->Value(1)); //ligne fermee
1332 LevelOfIterWithoutAppend=0;
1336 //====================================================
1337 //== Param was not in the limits (was reframed)
1338 //====================================================
1339 Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
1341 IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
1342 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1344 if(!myIntersectionOn2S.IsEmpty()) //002
1346 // mutially outpasses in the square or intersection in corner
1348 if(TestArret(Standard_True,Param,ChoixIso))
1350 NbPasOKConseq = -10;
1351 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);
1353 if(!myIntersectionOn2S.IsEmpty())
1355 previousPoint = myIntersectionOn2S.Point();
1356 previoustg = myIntersectionOn2S.IsTangent();
1360 previousd = myIntersectionOn2S.Direction();
1361 previousd1 = myIntersectionOn2S.DirectionOnS1();
1362 previousd2 = myIntersectionOn2S.DirectionOnS2();
1365 pl = previousPoint.Value();
1369 if(pf.SquareDistance(pl) < aSQDistMax)
1379 bTestFirstPoint = Standard_False;
1383 AddAPoint(previousPoint);
1386 if(RejectIndex >= RejectIndexMAX)
1388 Arrive = Standard_True;
1393 LevelOfIterWithoutAppend=0;
1394 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1398 //fail framing divides the step
1399 Arrive = Standard_False;
1400 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1401 NoTestDeflection = Standard_True;
1402 ChoixIso = SauvChoixIso;
1407 // save the last point
1408 // to revert to it if the current point is out of bounds
1410 IntSurf_PntOn2S previousPointSave = previousPoint;
1411 Standard_Boolean previoustgSave = previoustg;
1412 gp_Dir previousdSave = previousd;
1413 gp_Dir2d previousd1Save = previousd1;
1414 gp_Dir2d previousd2Save = previousd2;
1416 previousPoint = myIntersectionOn2S.Point();
1417 previoustg = myIntersectionOn2S.IsTangent();
1418 Arrive = Standard_False;
1422 previousd = myIntersectionOn2S.Direction();
1423 previousd1 = myIntersectionOn2S.DirectionOnS1();
1424 previousd2 = myIntersectionOn2S.DirectionOnS2();
1427 //========================================
1428 //== Check on PreviousPoint @@
1431 Standard_Real u1,v1,u2,v2;
1432 previousPoint.Parameters(u1,v1,u2,v2);
1434 //To save initial 2d points
1435 gp_Pnt2d ParamPntOnS1(Param(1), Param(2));
1436 gp_Pnt2d ParamPntOnS2(Param(3), Param(4));
1438 ///////////////////////////
1446 Standard_Boolean bFlag1, bFlag2;
1447 Standard_Real aTol2D=1.e-11;
1449 bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
1450 bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
1451 if (bFlag1 && bFlag2)
1453 if (line->NbPoints() > 1)
1455 IntSurf_PntOn2S prevprevPoint = line->Value(line->NbPoints()-1);
1456 Standard_Real ppU1, ppV1, ppU2, ppV2;
1457 prevprevPoint.Parameters(ppU1, ppV1, ppU2, ppV2);
1458 Standard_Real pU1, pV1, pU2, pV2;
1459 previousPointSave.Parameters(pU1, pV1, pU2, pV2);
1460 gp_Vec2d V1onS1(gp_Pnt2d(ppU1, ppV1), gp_Pnt2d(pU1, pV1));
1461 gp_Vec2d V2onS1(gp_Pnt2d(pU1, pV1), gp_Pnt2d(u1, v1));
1462 gp_Vec2d V1onS2(gp_Pnt2d(ppU2, ppV2), gp_Pnt2d(pU2, pV2));
1463 gp_Vec2d V2onS2(gp_Pnt2d(pU2, pV2), gp_Pnt2d(u2, v2));
1465 const Standard_Real aDot1 = V1onS1 * V2onS1;
1466 const Standard_Real aDot2 = V1onS2 * V2onS2;
1468 if ((aDot1 < 0.0) || (aDot2 < 0.0))
1470 Arrive = Standard_True;
1475 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1476 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1477 v1 >= Vm1 && v2 >= Vm2) {
1480 pl = previousPoint.Value();
1484 if(pf.SquareDistance(pl) < aSQDistMax)
1495 bTestFirstPoint = Standard_False;
1499 //To avoid walking around the same point
1500 //in the tangent zone near a border
1504 //There are three consecutive points:
1505 //previousPointSave -> ParamPnt -> curPnt.
1507 Standard_Real prevU1, prevV1, prevU2, prevV2;
1508 previousPointSave.Parameters(prevU1, prevV1, prevU2, prevV2);
1509 gp_Pnt2d prevPntOnS1(prevU1, prevV1), prevPntOnS2(prevU2, prevV2);
1510 gp_Pnt2d curPntOnS1(u1, v1), curPntOnS2(u2, v2);
1511 gp_Vec2d PrevToParamOnS1(prevPntOnS1, ParamPntOnS1);
1512 gp_Vec2d PrevToCurOnS1(prevPntOnS1, curPntOnS1);
1513 gp_Vec2d PrevToParamOnS2(prevPntOnS2, ParamPntOnS2);
1514 gp_Vec2d PrevToCurOnS2(prevPntOnS2, curPntOnS2);
1515 Standard_Real MaxAngle = 3*M_PI/4;
1516 Standard_Real anAngleS1 = 0.0, anAngleS2 = 0.0;
1517 const Standard_Real aSQMParS1 = PrevToParamOnS1.SquareMagnitude();
1518 const Standard_Real aSQMParS2 = PrevToParamOnS2.SquareMagnitude();
1519 const Standard_Real aSQMCurS1 = PrevToCurOnS1.SquareMagnitude();
1520 const Standard_Real aSQMCurS2 = PrevToCurOnS2.SquareMagnitude();
1522 if(aSQMCurS1 < gp::Resolution())
1524 //We came back to the one of previous point.
1525 //Therefore, we must break;
1529 else if(aSQMParS1 < gp::Resolution())
1531 //We are walking along tangent zone.
1532 //It should be continued.
1537 anAngleS1 = Abs(PrevToParamOnS1.Angle(PrevToCurOnS1));
1540 if(aSQMCurS2 < gp::Resolution())
1542 //We came back to the one of previous point.
1543 //Therefore, we must break;
1547 else if(aSQMParS2 < gp::Resolution())
1549 //We are walking along tangent zone.
1550 //It should be continued;
1555 anAngleS2 = Abs(PrevToParamOnS2.Angle(PrevToCurOnS2));
1558 if ((anAngleS1 > MaxAngle) && (anAngleS2 > MaxAngle))
1560 Arrive = Standard_True;
1565 //Check singularity.
1566 //I.e. check if we are walking along direction, which does not
1567 //result in coming to any point (i.e. derivative
1568 //3D-intersection curve along this direction is equal to 0).
1569 //A sphere with direction {dU=1, dV=0} from point
1570 //(U=0, V=M_PI/2) can be considered as example for
1571 //this case (we cannot find another 3D-point if we go thus).
1573 //Direction chosen along 1st and 2nd surface correspondingly
1574 const gp_Vec2d aDirS1(prevPntOnS1, curPntOnS1),
1575 aDirS2(prevPntOnS2, curPntOnS2);
1578 gp_Vec aDuS1, aDvS1, aDuS2, aDvS2;
1580 myIntersectionOn2S.Function().AuxillarSurface1()->
1581 D1(curPntOnS1.X(), curPntOnS1.Y(), aPtemp, aDuS1, aDvS1);
1582 myIntersectionOn2S.Function().AuxillarSurface2()->
1583 D1(curPntOnS2.X(), curPntOnS2.Y(), aPtemp, aDuS2, aDvS2);
1585 //Derivative WLine along (it is vector-function indeed)
1587 //(https://en.wikipedia.org/wiki/Directional_derivative#Variation_using_only_direction_of_vector).
1588 //F1 - on the 1st surface, F2 - on the 2nd surface.
1589 //x, y, z - coordinates of derivative vector.
1590 const Standard_Real aF1x = aDuS1.X()*aDirS1.X() +
1591 aDvS1.X()*aDirS1.Y();
1592 const Standard_Real aF1y = aDuS1.Y()*aDirS1.X() +
1593 aDvS1.Y()*aDirS1.Y();
1594 const Standard_Real aF1z = aDuS1.Z()*aDirS1.X() +
1595 aDvS1.Z()*aDirS1.Y();
1596 const Standard_Real aF2x = aDuS2.X()*aDirS2.X() +
1597 aDvS2.X()*aDirS2.Y();
1598 const Standard_Real aF2y = aDuS2.Y()*aDirS2.X() +
1599 aDvS2.Y()*aDirS2.Y();
1600 const Standard_Real aF2z = aDuS2.Z()*aDirS2.X() +
1601 aDvS2.Z()*aDirS2.Y();
1603 const Standard_Real aF1 = aF1x*aF1x + aF1y*aF1y + aF1z*aF1z;
1604 const Standard_Real aF2 = aF2x*aF2x + aF2y*aF2y + aF2z*aF2z;
1606 if((aF1 < gp::Resolution()) && (aF2 < gp::Resolution()))
1608 //All derivative are equal to 0. Therefore, there is
1609 //no point in going along direction chosen.
1610 Arrive = Standard_True;
1614 }//if (previoustg) cond.
1616 ////////////////////////////////////////
1617 AddAPoint(previousPoint);
1620 if(RejectIndex >= RejectIndexMAX)
1622 Arrive = Standard_True;
1628 LevelOfIterWithoutAppend=0;
1629 Arrive = Standard_True;
1633 // revert to the last correctly calculated point
1634 previousPoint = previousPointSave;
1635 previoustg = previoustgSave;
1636 previousd = previousdSave;
1637 previousd1 = previousd1Save;
1638 previousd2 = previousd2Save;
1643 Standard_Boolean wasExtended = Standard_False;
1645 if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent)
1647 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1649 wasExtended = Standard_True;
1650 Arrive = Standard_False;
1651 ChoixIso = SauvChoixIso;
1655 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1658 myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
1659 myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
1662 if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti))
1664 wasExtended = Standard_True;
1665 Arrive = Standard_False;
1666 ChoixIso = SauvChoixIso;
1669 }//else !TestArret() $
1670 }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty())
1673 //echec framing on border; division of step
1674 Arrive = Standard_False;
1675 NoTestDeflection = Standard_True;
1676 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
1678 }//$$$ end framing on border (!close)
1679 }//004 fin TestArret return Arrive = True
1680 } // 006case IntWalk_ArretSurPoint: end Processing Status = OK or ArretSurPoint
1681 } //007 switch(aStatus)
1682 } //008 end processing point (TEST DEFLECTION)
1683 } //009 end processing line (else if myIntersectionOn2S.IsDone())
1684 } //010 end if first departure point allows marching while (!Arrive)
1686 done = Standard_True;
1688 // ===========================================================================================================
1689 // function: ExtendLineInCommonZone
1690 // purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso.
1691 // Returns Standard_True if the line was extended through tangent zone and the last computed point
1692 // is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False.
1693 // ===========================================================================================================
1694 Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso,
1695 const Standard_Boolean theDirectionFlag)
1697 Standard_Boolean bOutOfTangentZone = Standard_False;
1698 Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
1699 Standard_Integer dIncKey = 1;
1700 TColStd_Array1OfReal Param(1,4);
1701 IntWalk_StatusDeflection aStatus = IntWalk_OK;
1702 Standard_Integer nbIterWithoutAppend = 0;
1703 Standard_Integer nbEqualPoints = 0;
1704 Standard_Integer parit = 0;
1705 Standard_Integer uvit = 0;
1706 IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
1709 nbIterWithoutAppend++;
1711 if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
1713 std::cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << std::endl;
1715 bStop = Standard_True;
1718 Standard_Real f = 0.;
1720 switch (theChoixIso)
1722 case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
1723 case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
1724 case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
1725 case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
1730 previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
1732 Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
1733 Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
1734 Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f;
1735 Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
1737 if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey);
1738 if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey);
1739 if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey);
1740 if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey);
1746 Standard_Real SvParam[4];
1747 IntImp_ConstIsoparametric ChoixIso = theChoixIso;
1749 for(parit = 0; parit < 4; parit++) {
1750 SvParam[parit] = Param(parit+1);
1752 math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function());
1753 ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso);
1755 if (!myIntersectionOn2S.IsDone()) {
1756 return bOutOfTangentZone;
1759 if (myIntersectionOn2S.IsEmpty()) {
1760 return bOutOfTangentZone;
1763 aStatus = TestDeflection(ChoixIso, aStatus);
1765 if(aStatus == IntWalk_OK) {
1767 for(uvit = 0; uvit < 4; uvit++) {
1768 if(pasuv[uvit] < pasInit[uvit]) {
1769 pasuv[uvit] = pasInit[uvit];
1775 case IntWalk_ArretSurPointPrecedent:
1777 bStop = Standard_True;
1778 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1781 case IntWalk_PasTropGrand:
1783 for(parit = 0; parit < 4; parit++) {
1784 Param(parit+1) = SvParam[parit];
1786 Standard_Boolean bDecrease = Standard_False;
1788 for(uvit = 0; uvit < 4; uvit++) {
1789 if(pasSav[uvit] < pasInit[uvit]) {
1790 pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1;
1791 bDecrease = Standard_True;
1795 if(bDecrease) nbIterWithoutAppend--;
1798 case IntWalk_PointConfondu:
1800 for(uvit = 0; uvit < 4; uvit++) {
1801 if(pasuv[uvit] < pasInit[uvit]) {
1802 pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1;
1808 case IntWalk_ArretSurPoint:
1811 bStop = TestArret(theDirectionFlag, Param, ChoixIso);
1816 Standard_Real u11,v11,u12,v12;
1817 myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12);
1818 Standard_Real u21,v21,u22,v22;
1819 previousPoint.Parameters(u21,v21,u22,v22);
1821 if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) ||
1822 ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) {
1831 bStop = bStop || !myIntersectionOn2S.IsTangent();
1832 bOutOfTangentZone = !myIntersectionOn2S.IsTangent();
1835 Standard_Boolean pointisvalid = Standard_False;
1836 Standard_Real u1,v1,u2,v2;
1837 myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
1839 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1840 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1841 v1 >= Vm1 && v2 >= Vm2)
1842 pointisvalid = Standard_True;
1845 previousPoint = myIntersectionOn2S.Point();
1846 previoustg = myIntersectionOn2S.IsTangent();
1849 previousd = myIntersectionOn2S.Direction();
1850 previousd1 = myIntersectionOn2S.DirectionOnS1();
1851 previousd2 = myIntersectionOn2S.DirectionOnS2();
1853 Standard_Boolean bAddPoint = Standard_True;
1855 if(line->NbPoints() >= 1) {
1856 gp_Pnt pf = line->Value(1).Value();
1857 gp_Pnt pl = previousPoint.Value();
1859 if(pf.Distance(pl) < Precision::Confusion()) {
1861 if(dIncKey == 5000) return bOutOfTangentZone;
1862 else bAddPoint = Standard_False;
1867 aSeqOfNewPoint.Append(previousPoint);
1868 nbIterWithoutAppend = 0;
1872 if (line->NbPoints() == 2) {
1873 for(uvit = 0; uvit < 4; uvit++) {
1874 pasSav[uvit] = pasuv[uvit];
1878 if ( !pointisvalid ) {
1879 // decrease step if out of bounds
1880 // otherwise the same calculations will be
1881 // repeated several times
1882 if ( ( u1 > UM1 ) || ( u1 < Um1 ) )
1885 if ( ( v1 > VM1 ) || ( v1 < Vm1 ) )
1888 if ( ( u2 > UM2 ) || ( u2 < Um2 ) )
1891 if ( ( v2 > VM2 ) || ( v2 < Vm2 ) )
1896 if(close && (line->NbPoints() >= 1)) {
1898 if(!bOutOfTangentZone) {
1899 aSeqOfNewPoint.Append(line->Value(1)); // line end
1901 nbIterWithoutAppend = 0;
1904 ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso);
1906 if(myIntersectionOn2S.IsEmpty()) {
1907 bStop = Standard_True;// !myIntersectionOn2S.IsTangent();
1908 bOutOfTangentZone = Standard_False; // !myIntersectionOn2S.IsTangent();
1911 Standard_Boolean bAddPoint = Standard_True;
1912 Standard_Boolean pointisvalid = Standard_False;
1914 previousPoint = myIntersectionOn2S.Point();
1915 Standard_Real u1,v1,u2,v2;
1916 previousPoint.Parameters(u1,v1,u2,v2);
1918 if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 &&
1919 v2 <= VM2 && u1 >= Um1 && u2 >= Um2 &&
1920 v1 >= Vm1 && v2 >= Vm2)
1921 pointisvalid = Standard_True;
1925 if(line->NbPoints() >= 1) {
1926 gp_Pnt pf = line->Value(1).Value();
1927 gp_Pnt pl = previousPoint.Value();
1929 if(pf.Distance(pl) < Precision::Confusion()) {
1931 if(dIncKey == 5000) return bOutOfTangentZone;
1932 else bAddPoint = Standard_False;
1936 if(bAddPoint && !bOutOfTangentZone) {
1937 aSeqOfNewPoint.Append(previousPoint);
1938 nbIterWithoutAppend = 0;
1953 Standard_Boolean bExtendLine = Standard_False;
1954 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1956 Standard_Integer pit = 0;
1958 for(pit = 0; !bExtendLine && (pit < 2); pit++) {
1960 previousPoint.Parameters(u1,v1,u2,v2);
1962 if(aSeqOfNewPoint.Length() > 0)
1963 aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2);
1968 if(((u1 - Um1) < ResoU1) ||
1969 ((UM1 - u1) < ResoU1) ||
1970 ((u2 - Um2) < ResoU2) ||
1971 ((UM2 - u2) < ResoU2) ||
1972 ((v1 - Vm1) < ResoV1) ||
1973 ((VM1 - v1) < ResoV1) ||
1974 ((v2 - Vm2) < ResoV2) ||
1975 ((VM2 - v2) < ResoV2))
1976 bExtendLine = Standard_True;
1980 // if(aStatus == IntWalk_OK || aStatus == IntWalk_ArretSurPoint) {
1981 if(aStatus == IntWalk_OK) {
1982 bExtendLine = Standard_True;
1984 if(aSeqOfNewPoint.Length() > 1) {
1985 TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3);
1986 Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2;
1988 aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
1989 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
1990 aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0),
1991 LastParams.ChangeValue(1),
1992 LastParams.ChangeValue(2),
1993 LastParams.ChangeValue(3));
1994 Standard_Integer indexofiso = 0;
1996 if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0;
1997 if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1;
1998 if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2;
1999 if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3;
2001 Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2;
2002 gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)),
2003 gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1)));
2005 gp_Dir2d anIsoDir(0, 1);
2007 if((indexofiso == 1) || (indexofiso == 3))
2008 anIsoDir = gp_Dir2d(1, 0);
2010 if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) {
2011 Standard_Real piquota = M_PI*0.25;
2013 if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) {
2014 Standard_Integer ii = 1, nextii = 2;
2016 Standard_Real asqresol = gp::Resolution();
2017 asqresol *= asqresol;
2020 aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2021 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2022 aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2023 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2024 d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2025 FirstParams.Value(afirstindex + 1)),
2026 gp_Pnt2d(LastParams.Value(afirstindex),
2027 LastParams.Value(afirstindex + 1)));
2030 while((d1.SquareMagnitude() < asqresol) &&
2031 (ii < aSeqOfNewPoint.Length()));
2035 while(nextii < aSeqOfNewPoint.Length()) {
2037 gp_Vec2d nextd1(0, 0);
2038 Standard_Integer jj = nextii;
2041 aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1),
2042 FirstParams.ChangeValue(2), FirstParams.ChangeValue(3));
2043 aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1),
2044 LastParams.ChangeValue(2), LastParams.ChangeValue(3));
2045 nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex),
2046 FirstParams.Value(afirstindex + 1)),
2047 gp_Pnt2d(LastParams.Value(afirstindex),
2048 LastParams.Value(afirstindex + 1)));
2052 while((nextd1.SquareMagnitude() < asqresol) &&
2053 (jj < aSeqOfNewPoint.Length()));
2056 if(fabs(d1.Angle(nextd1)) > piquota) {
2057 bExtendLine = Standard_False;
2063 // end if(fabs(aTangentZoneDir.Angle(anIsoDir)
2070 return Standard_False;
2072 Standard_Integer i = 0;
2074 for(i = 1; i <= aSeqOfNewPoint.Length(); i++) {
2075 AddAPoint(aSeqOfNewPoint.Value(i));
2078 return bOutOfTangentZone;
2081 //=======================================================================
2082 //function : DistanceMinimizeByGradient
2086 // theInit should be initialized before function calling.
2087 //=======================================================================
2088 Standard_Boolean IntWalk_PWalking::
2089 DistanceMinimizeByGradient( const Handle(Adaptor3d_Surface)& theASurf1,
2090 const Handle(Adaptor3d_Surface)& theASurf2,
2091 TColStd_Array1OfReal& theInit,
2092 const Standard_Real* theStep0)
2094 const Standard_Integer aNbIterMAX = 60;
2095 const Standard_Real aTol = 1.0e-14;
2096 const Standard_Real aTolNul = 1.0 / Precision::Infinite();
2098 // I.e. if theU1 = 0.0 then Epsilon(theU1) = DBL_MIN (~1.0e-308).
2099 // Work with this number is impossible: there is a dangerous to
2100 // obtain Floating-point-overflow. Therefore, we limit this value.
2101 const Standard_Real aMinAddValU1 = Max(Epsilon(theInit(1)), aTolNul);
2102 const Standard_Real aMinAddValV1 = Max(Epsilon(theInit(2)), aTolNul);
2103 const Standard_Real aMinAddValU2 = Max(Epsilon(theInit(3)), aTolNul);
2104 const Standard_Real aMinAddValV2 = Max(Epsilon(theInit(4)), aTolNul);
2106 Handle(Geom_Surface) aS1, aS2;
2108 if (theASurf1->GetType() != GeomAbs_BezierSurface &&
2109 theASurf1->GetType() != GeomAbs_BSplineSurface)
2110 return Standard_True;
2111 if (theASurf2->GetType() != GeomAbs_BezierSurface &&
2112 theASurf2->GetType() != GeomAbs_BSplineSurface)
2113 return Standard_True;
2115 Standard_Boolean aStatus = Standard_False;
2118 gp_Vec aD1u, aD1v, aD2U, aD2V;
2120 theASurf1->D1(theInit(1), theInit(2), aP1, aD1u, aD1v);
2121 theASurf2->D1(theInit(3), theInit(4), aP2, aD2U, aD2V);
2123 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
2125 gp_Vec aP12(aP1, aP2);
2127 Standard_Real aGradFu(-aP12.Dot(aD1u));
2128 Standard_Real aGradFv(-aP12.Dot(aD1v));
2129 Standard_Real aGradFU( aP12.Dot(aD2U));
2130 Standard_Real aGradFV( aP12.Dot(aD2V));
2132 Standard_Real aStepU1 = 1.0e-6, aStepV1 = 1.0e-6,
2133 aStepU2 = 1.0e-6, aStepV2 = 1.0e-6;
2137 aStepU1 = theStep0[0];
2138 aStepV1 = theStep0[1];
2139 aStepU2 = theStep0[2];
2140 aStepV2 = theStep0[3];
2143 Standard_Boolean flRepeat = Standard_True;
2144 Standard_Integer aNbIter = aNbIterMAX;
2148 Standard_Real anAdd = aGradFu*aStepU1;
2149 const Standard_Real aPARu = theInit(1) - Sign(Max(Abs(anAdd), aMinAddValU1), anAdd);
2151 anAdd = aGradFv*aStepV1;
2152 const Standard_Real aPARv = theInit(2) - Sign(Max(Abs(anAdd), aMinAddValV1), anAdd);
2154 anAdd = aGradFU*aStepU2;
2155 const Standard_Real aParU = theInit(3) - Sign(Max(Abs(anAdd), aMinAddValU2), anAdd);
2157 anAdd = aGradFV*aStepV2;
2158 const Standard_Real aParV = theInit(4) - Sign(Max(Abs(anAdd), aMinAddValV2), anAdd);
2162 theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
2163 theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
2165 Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
2167 if(aSQDist < aSQDistPrev)
2169 aSQDistPrev = aSQDist;
2175 aStatus = aSQDistPrev < aTol;
2185 flRepeat = Standard_False;
2189 theASurf1->D1(theInit(1), theInit(2), aPt1, aD1u, aD1v);
2190 theASurf2->D1(theInit(3), theInit(4), aPt2, aD2U, aD2V);
2192 gp_Vec aPt12(aPt1, aPt2);
2193 aGradFu = -aPt12.Dot(aD1u);
2194 aGradFv = -aPt12.Dot(aD1v);
2195 aGradFU = aPt12.Dot(aD2U);
2196 aGradFV = aPt12.Dot(aD2V);
2200 aStepU1 = theStep0[0];
2201 aStepV1 = theStep0[1];
2202 aStepU2 = theStep0[2];
2203 aStepV2 = theStep0[3];
2207 aStepU1 = aStepV1 = aStepU2 = aStepV2 = 1.0e-6;
2216 //=======================================================================
2217 //function : DistanceMinimizeByExtrema
2221 // theP0, theU0 and theV0 parameters should be initialized
2222 // before the function calling.
2223 //=======================================================================
2224 Standard_Boolean IntWalk_PWalking::
2225 DistanceMinimizeByExtrema(const Handle(Adaptor3d_Surface)& theASurf,
2226 const gp_Pnt& theP0,
2227 Standard_Real& theU0,
2228 Standard_Real& theV0,
2229 const Standard_Real* theStep0)
2231 const Standard_Real aTol = 1.0e-14;
2233 gp_Vec aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp;
2234 Standard_Real aSQDistPrev = RealLast();
2235 Standard_Real aU = theU0, aV = theV0;
2237 const Standard_Real aStep0[2] = { theStep0 ? theStep0[0] : 1.0,
2238 theStep0 ? theStep0[1] : 1.0 };
2240 Standard_Integer aNbIter = 10;
2243 theASurf->D2(aU, aV, aPS, aD1Su, aD1Sv, aD2Su, aD2Sv, aD2SuvTemp);
2245 gp_Vec aVec(theP0, aPS);
2247 Standard_Real aSQDist = aVec.SquareMagnitude();
2249 if(aSQDist >= aSQDistPrev)
2252 aSQDistPrev = aSQDist;
2257 if(aSQDistPrev < aTol)
2261 const Standard_Real aF1 = aD1Su.Dot(aVec), aF2 = aD1Sv.Dot(aVec);
2264 const Standard_Real aDf1u = aD2Su.Dot(aVec) + aD1Su.Dot(aD1Su),
2265 aDf1v = aD2Su.Dot(aD1Sv),
2267 aDf2v = aD2Sv.Dot(aVec) + aD1Sv.Dot(aD1Sv);
2269 const Standard_Real aDet = aDf1u*aDf2v - aDf1v*aDf2u;
2270 aU -= aStep0[0]*(aDf2v*aF1 - aDf1v*aF2) / aDet;
2271 aV += aStep0[1]*(aDf2u*aF1 - aDf1u*aF2) / aDet;
2275 return (aSQDistPrev < aTol);
2278 //=======================================================================
2279 //function : HandleSingleSingularPoint
2281 //=======================================================================
2282 Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adaptor3d_Surface)& theASurf1,
2283 const Handle(Adaptor3d_Surface)& theASurf2,
2284 const Standard_Real the3DTol,
2285 TColStd_Array1OfReal &thePnt)
2287 // u1, v1, u2, v2 order is used.
2288 Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
2289 theASurf1->FirstVParameter(),
2290 theASurf2->FirstUParameter(),
2291 theASurf2->FirstVParameter()};
2292 Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
2293 theASurf1->LastVParameter(),
2294 theASurf2->LastUParameter(),
2295 theASurf2->LastVParameter()};
2296 IntImp_ConstIsoparametric aLockedDir[4] = {IntImp_UIsoparametricOnCaro1,
2297 IntImp_VIsoparametricOnCaro1,
2298 IntImp_UIsoparametricOnCaro2,
2299 IntImp_VIsoparametricOnCaro2};
2301 // Create new intersector with new tolerance.
2302 IntWalk_TheInt2S anInt(theASurf1, theASurf2, the3DTol);
2303 math_FunctionSetRoot aRsnld(anInt.Function());
2305 for (Standard_Integer i = 1; i <= 4; ++i)
2307 if ( Abs(thePnt(i) - aLowBorder[i - 1]) < Precision::PConfusion() ||
2308 Abs(thePnt(i) - aUppBorder[i - 1]) < Precision::PConfusion())
2311 anInt.Perform(thePnt,aRsnld, aLockedDir[i - 1]);
2313 if (!anInt.IsDone())
2316 if (anInt.IsEmpty())
2319 anInt.Point().Parameters(thePnt(1), thePnt(2), thePnt(3), thePnt(4));
2321 Standard_Boolean isInDomain = Standard_True;
2322 for (Standard_Integer j = 1; isInDomain && (j <= 4); ++j)
2324 if ((thePnt(j) - aLowBorder[j - 1] + Precision::PConfusion())*
2325 (thePnt(j) - aUppBorder[j - 1] - Precision::PConfusion()) > 0.0)
2327 isInDomain = Standard_False;
2332 return Standard_True;
2336 return Standard_False;
2339 //=======================================================================
2340 //function : SeekPointOnBoundary
2342 //=======================================================================
2343 Standard_Boolean IntWalk_PWalking::
2344 SeekPointOnBoundary(const Handle(Adaptor3d_Surface)& theASurf1,
2345 const Handle(Adaptor3d_Surface)& theASurf2,
2346 const Standard_Real theU1,
2347 const Standard_Real theV1,
2348 const Standard_Real theU2,
2349 const Standard_Real theV2,
2350 const Standard_Boolean isTheFirst)
2352 Standard_Boolean isOK = Standard_False;
2354 // u1, v1, u2, v2 order is used.
2355 const Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
2356 theASurf1->FirstVParameter(),
2357 theASurf2->FirstUParameter(),
2358 theASurf2->FirstVParameter()};
2359 const Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
2360 theASurf1->LastVParameter(),
2361 theASurf2->LastUParameter(),
2362 theASurf2->LastVParameter()};
2364 // Tune solution tolerance according with object size.
2365 const Standard_Real aRes1 = Max(Precision::PConfusion() / theASurf1->UResolution(1.0),
2366 Precision::PConfusion() / theASurf1->VResolution(1.0));
2367 const Standard_Real aRes2 = Max(Precision::PConfusion() / theASurf2->UResolution(1.0),
2368 Precision::PConfusion() / theASurf2->VResolution(1.0));
2369 const Standard_Real a3DTol = Max(aRes1, aRes2);
2370 const Standard_Real aTol = Max(Precision::Confusion(), a3DTol);
2372 // u1, v1, u2, v2 order is used.
2373 TColStd_Array1OfReal aPnt(1,4);
2374 aPnt(1) = theU1; aPnt(2) = theV1; aPnt(3) = theU2; aPnt(4) = theV2;
2375 TColStd_Array1OfReal aSingularPnt(aPnt);
2377 Standard_Integer aNbIter = 20;
2378 Standard_Boolean aStatus = Standard_False;
2382 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt);
2383 if (aStatus && !AdjustToDomain(4, &aPnt(1), &aLowBorder[0], &aUppBorder[0]))
2386 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)),
2388 if (aStatus && !AdjustToDomain(2, &aPnt(1), &aLowBorder[0], &aUppBorder[0]))
2391 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)),
2393 if (aStatus && !AdjustToDomain(2, &aPnt(3), &aLowBorder[2], &aUppBorder[2]))
2396 while(!aStatus && (aNbIter > 0));
2398 // Handle singular points.
2399 Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1,
2403 if (aSingularStatus)
2404 aPnt = aSingularPnt;
2406 if (!aStatus && !aSingularStatus)
2411 gp_Pnt aP1 = theASurf1->Value(aPnt(1), aPnt(2));
2412 gp_Pnt aP2 = theASurf2->Value(aPnt(3), aPnt(4));
2413 const gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2415 const Standard_Real aSQDist = aPInt.SquareDistance(aP1);
2416 if (aSQDist > aTol * aTol)
2421 //Found point is true intersection point
2422 IntSurf_PntOn2S anIP;
2423 anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
2425 //The main idea of checks below is to define if insertion of
2426 //addition point (on the boundary) does not lead to invalid
2427 //intersection curve (e.g. having a loop).
2429 //Loops are detected with rotation angle of the Walking-line (WL).
2430 //If there is hairpin bend then insertion is forbidden.
2432 //There are at least two possible problems:
2433 // 1. There are some cases when two neighbor points of the WL
2434 // are almost coincident (the distance between them is less
2435 // than Precision::Confusion). It is impossible to define
2436 // rotation angle in these cases. Therefore, points with
2437 // "good" distances should be selected.
2439 // 2. Intersection point on the surface boundary has highest
2440 // priority in compare with other "middle" points. Therefore,
2441 // if insertion of new point will result in a bend then some
2442 // "middle" points should be deleted in order to provide
2443 // correct insertion.
2445 //Problem test cases:
2446 // test bugs modalg_5 bug24585_1
2447 // test boolean bcut_complex G7
2448 // test bugs moddata_2 bug469
2452 while (line->NbPoints() > 1)
2454 const Standard_Integer aNbPnts = line->NbPoints();
2456 Standard_Integer aPInd = 1;
2457 for (; aPInd <= aNbPnts; aPInd++)
2459 aP1.SetXYZ(line->Value(aPInd).Value().XYZ());
2460 if (aP1.SquareDistance(aPInt) > Precision::SquareConfusion())
2464 else if (aPInd == 1)
2466 // After insertion, we will obtain
2467 // two coincident points in the line.
2468 // Therefore, insertion is forbidden.
2473 for (++aPInd; aPInd <= aNbPnts; aPInd++)
2475 aP2.SetXYZ(line->Value(aPInd).Value().XYZ());
2476 if (aP1.SquareDistance(aP2) > Precision::SquareConfusion())
2480 if (aPInd > aNbPnts)
2485 const gp_XYZ aDir01(aP1.XYZ() - aPInt.XYZ());
2486 const gp_XYZ aDir12(aP2.XYZ() - aP1.XYZ());
2488 if (aDir01.Dot(aDir12) > 0.0)
2496 line->InsertBefore(1, anIP);
2497 isOK = Standard_True;
2501 while (line->NbPoints() > 1)
2503 const Standard_Integer aNbPnts = line->NbPoints();
2505 gp_Pnt aPPrev, aPCurr;
2506 Standard_Integer aPInd = aNbPnts;
2507 for (; aPInd > 0; aPInd--)
2509 aPCurr.SetXYZ(line->Value(aPInd).Value().XYZ());
2510 if (aPCurr.SquareDistance(aPInt) > Precision::SquareConfusion())
2514 else if (aPInd == aNbPnts)
2516 // After insertion, we will obtain
2517 // two coincident points in the line.
2518 // Therefore, insertion is forbidden.
2523 for (--aPInd; aPInd > 0; aPInd--)
2525 aPPrev.SetXYZ(line->Value(aPInd).Value().XYZ());
2526 if (aPCurr.SquareDistance(aPPrev) > Precision::SquareConfusion())
2535 const gp_XYZ aDirPC(aPCurr.XYZ() - aPPrev.XYZ());
2536 const gp_XYZ aDirCN(aPInt.XYZ() - aPCurr.XYZ());
2538 if (aDirPC.Dot(aDirCN) > 0.0)
2543 RemoveAPoint(aNbPnts);
2547 isOK = Standard_True;
2553 //=======================================================================
2554 //function : PutToBoundary
2556 //=======================================================================
2557 Standard_Boolean IntWalk_PWalking::
2558 PutToBoundary(const Handle(Adaptor3d_Surface)& theASurf1,
2559 const Handle(Adaptor3d_Surface)& theASurf2)
2561 const Standard_Real aTolMin = Precision::Confusion();
2563 Standard_Boolean hasBeenAdded = Standard_False;
2565 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2566 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2567 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2568 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2569 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2570 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2571 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2572 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2574 Standard_Real aTol = 1.0;
2575 aTol = Min(aTol, aU1bLast - aU1bFirst);
2576 aTol = Min(aTol, aU2bLast - aU2bFirst);
2577 aTol = Min(aTol, aV1bLast - aV1bFirst);
2578 aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3;
2580 if(aTol <= 2.0*aTolMin)
2581 return hasBeenAdded;
2583 Standard_Boolean isNeedAdding = Standard_False;
2584 Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False;
2585 Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False;
2586 IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel);
2587 IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel);
2589 Standard_Real u1, v1, u2, v2;
2590 line->Value(1).Parameters(u1, v1, u2, v2);
2591 Standard_Real aDelta = 0.0;
2595 aDelta = u1 - aU1bFirst;
2596 if((aTolMin < aDelta) && (aDelta < aTol))
2599 isNeedAdding = Standard_True;
2603 aDelta = aU1bLast - u1;
2604 if((aTolMin < aDelta) && (aDelta < aTol))
2607 isNeedAdding = Standard_True;
2614 aDelta = u2 - aU2bFirst;
2615 if((aTolMin < aDelta) && (aDelta < aTol))
2618 isNeedAdding = Standard_True;
2622 aDelta = aU2bLast - u2;
2623 if((aTolMin < aDelta) && (aDelta < aTol))
2626 isNeedAdding = Standard_True;
2633 aDelta = v1 - aV1bFirst;
2634 if((aTolMin < aDelta) && (aDelta < aTol))
2637 isNeedAdding = Standard_True;
2641 aDelta = aV1bLast - v1;
2642 if((aTolMin < aDelta) && (aDelta < aTol))
2645 isNeedAdding = Standard_True;
2652 aDelta = v2 - aV2bFirst;
2653 if((aTolMin < aDelta) && (aDelta < aTol))
2656 isNeedAdding = Standard_True;
2660 aDelta = aV2bLast - v2;
2661 if((aTolMin < aDelta) && (aDelta < aTol))
2664 isNeedAdding = Standard_True;
2672 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2673 v1, u2, v2, Standard_True);
2676 const Standard_Integer aNbPnts = line->NbPoints();
2677 isNeedAdding = Standard_False;
2678 line->Value(aNbPnts).Parameters(u1, v1, u2, v2);
2682 aDelta = u1 - aU1bFirst;
2683 if((aTolMin < aDelta) && (aDelta < aTol))
2686 isNeedAdding = Standard_True;
2690 aDelta = aU1bLast - u1;
2691 if((aTolMin < aDelta) && (aDelta < aTol))
2694 isNeedAdding = Standard_True;
2701 aDelta = u2 - aU2bFirst;
2702 if((aTolMin < aDelta) && (aDelta < aTol))
2705 isNeedAdding = Standard_True;
2709 aDelta = aU2bLast - u2;
2710 if((aTolMin < aDelta) && (aDelta < aTol))
2713 isNeedAdding = Standard_True;
2720 aDelta = v1 - aV1bFirst;
2721 if((aTolMin < aDelta) && (aDelta < aTol))
2724 isNeedAdding = Standard_True;
2728 aDelta = aV1bLast - v1;
2729 if((aTolMin < aDelta) && (aDelta < aTol))
2732 isNeedAdding = Standard_True;
2739 aDelta = v2 - aV2bFirst;
2740 if((aTolMin < aDelta) && (aDelta < aTol))
2743 isNeedAdding = Standard_True;
2747 aDelta = aV2bLast - v2;
2748 if((aTolMin < aDelta) && (aDelta < aTol))
2751 isNeedAdding = Standard_True;
2759 SeekPointOnBoundary(theASurf1, theASurf2, u1,
2760 v1, u2, v2, Standard_False);
2763 return hasBeenAdded;
2766 //=======================================================================
2767 //function : SeekAdditionalPoints
2769 //=======================================================================
2770 Standard_Boolean IntWalk_PWalking::
2771 SeekAdditionalPoints( const Handle(Adaptor3d_Surface)& theASurf1,
2772 const Handle(Adaptor3d_Surface)& theASurf2,
2773 const Standard_Integer theMinNbPoints)
2775 const Standard_Real aTol = 1.0e-14;
2776 Standard_Integer aNbPoints = line->NbPoints();
2777 if(aNbPoints > theMinNbPoints)
2778 return Standard_True;
2780 const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
2781 const Standard_Real aU1bLast = theASurf1->LastUParameter();
2782 const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
2783 const Standard_Real aU2bLast = theASurf2->LastUParameter();
2784 const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
2785 const Standard_Real aV1bLast = theASurf1->LastVParameter();
2786 const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
2787 const Standard_Real aV2bLast = theASurf2->LastVParameter();
2790 Standard_Boolean isPrecise = Standard_False;
2792 TColStd_Array1OfReal aPnt(1, 4);
2795 Standard_Integer aNbPointsPrev = 0;
2796 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
2798 aNbPointsPrev = aNbPoints;
2799 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
2801 Standard_Real U1f, V1f, U2f, V2f; //first point in 1st and 2nd surafaces
2802 Standard_Real U1l, V1l, U2l, V2l; //last point in 1st and 2nd surafaces
2805 line->Value(fp).Parameters(U1f, V1f, U2f, V2f);
2806 line->Value(lp).Parameters(U1l, V1l, U2l, V2l);
2808 aPnt(1) = 0.5*(U1f + U1l);
2809 if(aPnt(1) < aU1bFirst)
2810 aPnt(1) = aU1bFirst;
2811 if(aPnt(1) > aU1bLast)
2814 aPnt(2) = 0.5*(V1f+V1l);
2815 if(aPnt(2) < aV1bFirst)
2816 aPnt(2) = aV1bFirst;
2817 if(aPnt(2) > aV1bLast)
2820 aPnt(3) = 0.5*(U2f+U2l);
2821 if(aPnt(3) < aU2bFirst)
2822 aPnt(3) = aU2bFirst;
2823 if(aPnt(3) > aU2bLast)
2826 aPnt(4) = 0.5*(V2f+V2l);
2827 if(aPnt(4) < aV2bFirst)
2828 aPnt(4) = aV2bFirst;
2829 if(aPnt(4) > aV2bLast)
2832 Standard_Boolean aStatus = Standard_False;
2833 Standard_Integer aNbIter = 5;
2836 aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt);
2842 aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), aPnt(1), aPnt(2));
2848 aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), aPnt(3), aPnt(4));
2854 while(!aStatus && (--aNbIter > 0));
2858 gp_Pnt aP1 = theASurf1->Value(aPnt(1), aPnt(2)),
2859 aP2 = theASurf2->Value(aPnt(3), aPnt(4));
2860 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
2862 const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
2863 aSQDist2 = aPInt.SquareDistance(aP2);
2865 if((aSQDist1 < aTol) && (aSQDist2 < aTol))
2867 IntSurf_PntOn2S anIP;
2868 anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
2869 line->InsertBefore(lp, anIP);
2871 isPrecise = Standard_True;
2873 if(++aNbPoints >= theMinNbPoints)
2887 void IntWalk_PWalking::
2888 RepartirOuDiviser(Standard_Boolean& DejaReparti,
2889 IntImp_ConstIsoparametric& ChoixIso,
2890 Standard_Boolean& Arrive)
2892 // at the neighborhood of a point, there is a fail of marching
2893 // it is required to divide the steps to try to continue
2894 // if the step is too small if we are on border
2895 // restart in another direction if it was not done, otherwise stop
2898 // Standard_Integer i;
2899 if (Arrive) { //restart in the other direction
2900 if (!DejaReparti ) {
2901 Arrive = Standard_False;
2902 DejaReparti = Standard_True;
2903 previousPoint = line->Value(1);
2904 previoustg = Standard_False;
2905 previousd1 = firstd1;
2906 previousd2 = firstd2;
2908 myTangentIdx = line->NbPoints();
2912 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2913 sensCheminement = -1;
2915 tglast = Standard_False;
2916 ChoixIso = choixIsoSav;
2923 Standard_Real u1,v1,u2,v2;
2924 Standard_Real U1,V1,U2,V2;
2925 Standard_Integer nn=line->NbPoints();
2927 line->Value(nn).Parameters(u1,v1,u2,v2);
2928 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2929 pasuv[0]=Abs(u1-U1);
2930 pasuv[1]=Abs(v1-V1);
2931 pasuv[2]=Abs(u2-U2);
2932 pasuv[3]=Abs(v2-V2);
2939 if ( pasuv[0]*0.5 < ResoU1
2940 && pasuv[1]*0.5 < ResoV1
2941 && pasuv[2]*0.5 < ResoU2
2942 && pasuv[3]*0.5 < ResoV2
2945 tglast = Standard_True; // IS IT ENOUGH ????
2949 { //restart in the other direction
2950 DejaReparti = Standard_True;
2951 previousPoint = line->Value(1);
2952 previoustg = Standard_False;
2953 previousd1 = firstd1;
2954 previousd2 = firstd2;
2956 myTangentIdx = line->NbPoints();
2960 //-- printf("\nIntWalk_PWalking_2.gxx Reverse %3d\n",indextg);
2962 sensCheminement = -1;
2964 tglast = Standard_False;
2965 ChoixIso = choixIsoSav;
2973 Standard_Real u1,v1,u2,v2;
2974 Standard_Real U1,V1,U2,V2;
2975 Standard_Integer nn=line->NbPoints();
2977 line->Value(nn).Parameters(u1,v1,u2,v2);
2978 line->Value(nn-1).Parameters(U1,V1,U2,V2);
2979 pasuv[0]=Abs(u1-U1);
2980 pasuv[1]=Abs(v1-V1);
2981 pasuv[2]=Abs(u2-U2);
2982 pasuv[3]=Abs(v2-V2);
2986 else Arrive = Standard_True;
2998 //OCC431(apo): modified ->
2999 static const Standard_Real CosRef2D = Cos(M_PI/9.0), AngRef2D = M_PI/2.0;
3001 static const Standard_Real d = 7.0;
3004 IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso,
3005 const IntWalk_StatusDeflection theStatus)
3007 // test if vector is observed by calculating an increase of vector
3008 // or the previous point and its tangent, the new calculated point and its
3009 // tangent; it is possible to find a cube passing by the 2 points and having as a
3010 // derivative the tangents of the intersection
3011 // calculate the point with parameter 0.5 on cube=p1
3012 // calculate the medium point of 2 points of intersection=p2
3013 // if arrow/2<=||p1p2||<= arrow consider that the vector is observed
3014 // otherwise adjust the step depending on the ratio ||p1p2||/vector
3015 // and the previous step
3016 // test if in 2 tangent planes of surfaces there is no too great angle2d
3017 // grand : if yes divide the step
3018 // test if there is no change of side
3021 if(line->NbPoints() ==1 ) {
3022 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=STATIC_PRECEDENT_INFLEXION=0;
3025 IntWalk_StatusDeflection aStatus = IntWalk_OK;
3026 Standard_Real FlecheCourante , Ratio = 1.0;
3029 const Handle(Adaptor3d_Surface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
3030 const Handle(Adaptor3d_Surface)& Caro2 = myIntersectionOn2S.Function().AuxillarSurface2();
3032 const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
3033 //==================================================================================
3034 //========= S t o p o n p o i n t ============
3035 //==================================================================================
3036 if (myIntersectionOn2S.IsTangent()) {
3037 return IntWalk_ArretSurPoint;
3040 const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
3042 const Standard_Real aCosBetweenTangent = TgCourante.Dot(previousd);
3044 //==================================================================================
3045 //========= R i s k o f i n f l e x i o n p o i n t ============
3046 //==================================================================================
3047 if (aCosBetweenTangent < 0) {
3048 //------------------------------------------------------------
3049 //-- Risk of inflexion point : Divide the step by 2
3050 //-- Initialize STATIC_PRECEDENT_INFLEXION so that
3051 //-- at the next call to return Pas_OK if there is no
3052 //-- more risk of the point of inflexion
3053 //------------------------------------------------------------
3059 STATIC_PRECEDENT_INFLEXION+=3;
3060 if (pasuv[0] < ResoU1 && pasuv[1] <ResoV1 && pasuv[2] <ResoU2 && pasuv[3] < ResoV2)
3061 return IntWalk_ArretSurPointPrecedent;
3063 return IntWalk_PasTropGrand;
3066 if(STATIC_PRECEDENT_INFLEXION > 0) {
3067 STATIC_PRECEDENT_INFLEXION -- ;
3072 //==================================================================================
3073 //========= D e t e c t c o n f u s e d P o in t s ===========
3074 //==================================================================================
3076 const Standard_Real aSqDist = previousPoint.Value().
3077 SquareDistance(CurrentPoint.Value());
3080 if (aSqDist < Precision::SquareConfusion()) {
3081 pasInit[0] = Max(pasInit[0], 5.0*ResoU1);
3082 pasInit[1] = Max(pasInit[1], 5.0*ResoV1);
3083 pasInit[2] = Max(pasInit[2], 5.0*ResoU2);
3084 pasInit[3] = Max(pasInit[3], 5.0*ResoV2);
3086 for(Standard_Integer i = 0; i < 4; i++)
3088 pasuv[i] = Max(pasuv[i], Min(1.5*pasuv[i], pasInit[i]));
3090 //Compute local resolution: for OCC26717
3091 if (Abs(pasuv[choixIso] - pasInit[choixIso]) <= Precision::Confusion())
3093 Standard_Real CurU, CurV;
3094 if (choixIso == IntImp_UIsoparametricOnCaro1 ||
3095 choixIso == IntImp_VIsoparametricOnCaro1)
3096 previousPoint.ParametersOnS1(CurU, CurV);
3098 previousPoint.ParametersOnS2(CurU, CurV);
3099 gp_Pnt CurPnt = (choixIso == IntImp_UIsoparametricOnCaro1 ||
3100 choixIso == IntImp_VIsoparametricOnCaro1)?
3101 Adaptor3d_HSurfaceTool::Value(Caro1, CurU, CurV) :
3102 Adaptor3d_HSurfaceTool::Value(Caro2, CurU, CurV);
3106 case IntImp_UIsoparametricOnCaro1:
3108 Adaptor3d_HSurfaceTool::Value(Caro1,
3109 CurU + sensCheminement*pasuv[0],
3112 case IntImp_VIsoparametricOnCaro1:
3114 Adaptor3d_HSurfaceTool::Value(Caro1,
3116 CurV + sensCheminement*pasuv[1]);
3118 case IntImp_UIsoparametricOnCaro2:
3120 Adaptor3d_HSurfaceTool::Value(Caro2,
3121 CurU + sensCheminement*pasuv[2],
3124 case IntImp_VIsoparametricOnCaro2:
3126 Adaptor3d_HSurfaceTool::Value(Caro2,
3128 CurV + sensCheminement*pasuv[3]);
3132 Standard_Real RefDist = CurPnt.Distance(OffsetPnt);
3133 Standard_Real LocalResol = 0.;
3134 if (RefDist > gp::Resolution())
3135 LocalResol = pasuv[choixIso] * tolconf / RefDist;
3136 if (pasuv[choixIso] < 2*LocalResol)
3137 pasuv[choixIso] = pasInit[choixIso] = 2*LocalResol;
3139 ////////////////////////////////////////
3140 aStatus = IntWalk_PointConfondu;
3143 //==================================================================================
3144 Standard_Real Up1,Vp1,Uc1,Vc1,Du1,Dv1,AbsDu1,AbsDu2,AbsDv1,AbsDv2;
3145 Standard_Real Up2,Vp2,Uc2,Vc2,Du2,Dv2;
3147 previousPoint.Parameters(Up1,Vp1,Up2,Vp2);
3148 CurrentPoint.Parameters(Uc1,Vc1,Uc2,Vc2);
3150 Du1 = Uc1 - Up1; Dv1 = Vc1 - Vp1;
3151 Du2 = Uc2 - Up2; Dv2 = Vc2 - Vp2;
3157 //=================================================================================
3158 //==== S t e p o f p r o g r e s s i o n (between previous and Current) =======
3159 //=================================================================================
3160 if ( AbsDu1 < ResoU1 && AbsDv1 < ResoV1
3161 && AbsDu2 < ResoU2 && AbsDv2 < ResoV2) {
3162 pasuv[0] = ResoU1; pasuv[1] = ResoV1; pasuv[2] = ResoU2; pasuv[3] = ResoV2;
3163 return(IntWalk_ArretSurPointPrecedent);
3165 //==================================================================================
3167 Standard_Real tolArea = 100.0;
3168 if (ResoU1 < Precision::PConfusion() ||
3169 ResoV1 < Precision::PConfusion() ||
3170 ResoU2 < Precision::PConfusion() ||
3171 ResoV2 < Precision::PConfusion() )
3172 tolArea = tolArea*2.0;
3174 Standard_Real Cosi1, CosRef1, Ang1, AngRef1, ResoUV1, Duv1, d1, tolCoeff1;
3175 Standard_Real Cosi2, CosRef2, Ang2, AngRef2, ResoUV2, Duv2, d2, tolCoeff2;
3176 Cosi1 = Du1*previousd1.X() + Dv1*previousd1.Y();
3177 Cosi2 = Du2*previousd2.X() + Dv2*previousd2.Y();
3178 Duv1 = Du1*Du1 + Dv1*Dv1;
3179 Duv2 = Du2*Du2 + Dv2*Dv2;
3180 ResoUV1 = ResoU1*ResoU1 + ResoV1*ResoV1;
3181 ResoUV2 = ResoU2*ResoU2 + ResoV2*ResoV2;
3183 //modified by NIZNHY-PKV Wed Nov 13 12:25:44 2002 f
3185 Standard_Real aMinDiv2=Precision::Confusion();
3186 aMinDiv2=aMinDiv2*aMinDiv2;
3189 if (Duv1>aMinDiv2) {
3190 d1 = Abs(ResoUV1/Duv1);
3191 d1 = Min(Sqrt(d1)*tolArea, d);
3193 //d1 = Abs(ResoUV1/Duv1);
3194 //d1 = Min(Sqrt(d1)*tolArea,d);
3195 //modified by NIZNHY-PKV Wed Nov 13 12:34:30 2002 t
3196 tolCoeff1 = Exp(d1);
3198 //modified by NIZNHY-PKV Wed Nov 13 12:34:43 2002 f
3200 if (Duv2>aMinDiv2) {
3201 d2 = Abs(ResoUV2/Duv2);
3202 d2 = Min(Sqrt(d2)*tolArea,d);
3204 //d2 = Abs(ResoUV2/Duv2);
3205 //d2 = Min(Sqrt(d2)*tolArea,d);
3206 //modified by NIZNHY-PKV Wed Nov 13 12:34:53 2002 t
3207 tolCoeff2 = Exp(d2);
3208 CosRef1 = CosRef2D/tolCoeff1;
3209 CosRef2 = CosRef2D/tolCoeff2;
3211 //==================================================================================
3212 //== The points are not confused : ==
3213 //== 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 ==
3214 //== N o t T o o G r e a t (angle in space UV) ==
3215 //== C h a n g e o f s i d e ==
3216 //==================================================================================
3217 if (aStatus != IntWalk_PointConfondu) {
3218 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2) {
3219 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3220 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2) {
3221 return(IntWalk_ArretSurPointPrecedent);
3224 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3225 return(IntWalk_PasTropGrand);
3228 const gp_Dir2d& Tg2dcourante1 = myIntersectionOn2S.DirectionOnS1();
3229 const gp_Dir2d& Tg2dcourante2 = myIntersectionOn2S.DirectionOnS2();
3230 Cosi1 = Du1*Tg2dcourante1.X() + Dv1*Tg2dcourante1.Y();
3231 Cosi2 = Du2*Tg2dcourante2.X() + Dv2*Tg2dcourante2.Y();
3232 Ang1 = Abs(previousd1.Angle(Tg2dcourante1));
3233 Ang2 = Abs(previousd2.Angle(Tg2dcourante2));
3234 AngRef1 = AngRef2D*tolCoeff1;
3235 AngRef2 = AngRef2D*tolCoeff2;
3236 //-------------------------------------------------------
3237 //-- Test : Angle too great in space UV -----
3238 //-- Change of side -----
3239 //-------------------------------------------------------
3240 if(Cosi1*Cosi1 < CosRef1*Duv1 || Cosi2*Cosi2 < CosRef2*Duv2 || Ang1 > AngRef1 || Ang2 > AngRef2) {
3241 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3242 if (pasuv[0]<ResoU1 && pasuv[1]<ResoV1 && pasuv[2]<ResoU2 && pasuv[3]<ResoV2)
3243 return(IntWalk_ArretSurPoint);
3245 return(IntWalk_PasTropGrand);
3249 //==================================================================================
3250 //== D e t e c t i o n o f : Step Too Small
3252 //==================================================================================
3254 //---------------------------------------
3255 //-- Estimate of the vector --
3256 //---------------------------------------
3258 Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*aSqDist))/8.;
3260 if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
3261 if(FlecheCourante>1e-16) {
3262 Ratio = 0.5*(fleche/FlecheCourante);
3267 Standard_Real pasSu1 = pasuv[0];
3268 Standard_Real pasSv1 = pasuv[1];
3269 Standard_Real pasSu2 = pasuv[2];
3270 Standard_Real pasSv2 = pasuv[3];
3273 //-- a point at U+DeltaU is required, ....
3274 //-- return a point at U + Epsilon
3275 //-- Epsilon << DeltaU.
3277 if(pasuv[0]< AbsDu1) pasuv[0] = AbsDu1;
3278 if(pasuv[1]< AbsDv1) pasuv[1] = AbsDv1;
3279 if(pasuv[2]< AbsDu2) pasuv[2] = AbsDu2;
3280 if(pasuv[3]< AbsDv2) pasuv[3] = AbsDv2;
3282 if(pasuv[0]<ResoU1) pasuv[0]=ResoU1;
3283 if(pasuv[1]<ResoV1) pasuv[1]=ResoV1;
3284 if(pasuv[2]<ResoU2) pasuv[2]=ResoU2;
3285 if(pasuv[3]<ResoV2) pasuv[3]=ResoV2;
3286 //-- if(Ratio>10.0 ) { Ratio=10.0; }
3287 Standard_Real R1,R = pasInit[0]/pasuv[0];
3288 R1= pasInit[1]/pasuv[1]; if(R1<R) R=R1;
3289 R1= pasInit[2]/pasuv[2]; if(R1<R) R=R1;
3290 R1= pasInit[3]/pasuv[3]; if(R1<R) R=R1;
3291 if(Ratio > R) Ratio=R;
3292 pasuv[0] = Min(Ratio*pasuv[0],pasInit[0]);
3293 pasuv[1] = Min(Ratio*pasuv[1],pasInit[1]);
3294 pasuv[2] = Min(Ratio*pasuv[2],pasInit[2]);
3295 pasuv[3] = Min(Ratio*pasuv[3],pasInit[3]);
3296 if (pasuv[0] != pasSu1 || pasuv[2] != pasSu2||
3297 pasuv[1] != pasSv1 || pasuv[3] != pasSv2) {
3298 if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3299 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3300 return IntWalk_PasTropGrand;
3303 if(aStatus == IntWalk_OK) {
3304 STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3305 //-- Try to increase the step
3309 else { //-- CurrentVector > vector*0.5
3310 if (FlecheCourante > fleche) { //-- Current step too Great
3311 Ratio = fleche/FlecheCourante;
3312 pasuv[0] = Ratio*pasuv[0];
3313 pasuv[1] = Ratio*pasuv[1];
3314 pasuv[2] = Ratio*pasuv[2];
3315 pasuv[3] = Ratio*pasuv[3];
3316 //if(++STATIC_BLOCAGE_SUR_PAS_TROP_GRAND > 5) {
3317 // STATIC_BLOCAGE_SUR_PAS_TROP_GRAND = 0;
3318 return IntWalk_PasTropGrand;
3321 else { //-- vector/2 < CurrentVector <= vector
3322 Ratio = 0.75 * (fleche / FlecheCourante);
3326 if(aStatus != IntWalk_PointConfondu)
3328 //Here, aCosBetweenTangent >= 0.0 definitely.
3331 Brief algorithm description.
3332 We have two (not-coincindent) intersection point (P1 and P2). In every point,
3333 vector of tangent (to the intersection curve) is known (vectors T1 and T2).
3334 Basing on these data, we create osculating circle.
3336 * - arc of osculating circle
3343 Let me draw your attention to the following facts:
3344 1. Vectors T1 and T2 direct FROM (not TO) points P1 and P2. Therefore,
3345 one of previously computed vector should be reversed.
3347 In this case, the absolute (!) value of the deflection between the arc of
3348 the osculating circle and the P1P2 segment can be computed as follows:
3349 e = d*(1-sin(B/2))/(2*cos(B/2)), (1)
3350 where d is the length of P1P2 segment, B is the angle between vectors T1 and T2.
3358 Later, the normal state of algorithm work is (as we apply)
3359 tolconf/2 <= e <= tolconf.
3360 In this case, we keep previous step.
3362 If e < tolconf/2 then the local curvature of the intersection curve is small.
3363 As result, the step should be increased.
3365 If e > tolconf then the step is too big. Therefore, we should decrease one.
3367 Condition (1) is equivalent to
3368 sin(B/2) = 1 - 2/(1+(d/(2*e))^2) = Fs(e),
3369 cos(B) = 1 - 2*Fs(e)^2 = Fd(e),
3370 where Fs(e)and Fd(e) are some function with parameter "deflection".
3372 Let mean that Fs(e) is decreasing function. Fd(e) is increasing function,
3373 in the range, where Fs(e) > 0.0 (i.e. when e < d/2).
3375 Now, let substitute required deflection (tolconf or tolconf/2) to z. Then
3376 it is necessary to check if e < z or if e > z.
3378 In this case, it is enough to comapare Fs(e) and Fs(z).
3379 At that Fs(e) > 0 because sin(B/2) > 0 always.
3381 Therefore, if Fs(z) < 0.0 then Fs(e) > Fs(z) ==> e < z definitely.
3382 If Fs(z) > 0.0 then we can compare Fs(z)^2 and Fs(e)^2 or, in substance,
3383 values Fd(e) and Fd(z). If Fd(e) > Fd(z) then e > z and vice versa.
3386 //Fd(e) is already known (Fd(e) == -aCosBetweenTangent)
3388 const Standard_Real anInvSqAbsArcDeflMax = 0.25*aSqDist/(tolconf*tolconf);
3389 const Standard_Real aSinB2Max = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMax);
3391 if(aSinB2Max >= 0.0 && (aCosBetweenTangent <= 2.0 * aSinB2Max * aSinB2Max - 1.0))
3392 {//Real deflection is greater or equal than tolconf
3393 aStatus = IntWalk_PasTropGrand;
3396 {//Real deflection is less than tolconf
3397 const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax;
3398 const Standard_Real aSinB2Min = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin);
3400 if (theStatus != IntWalk_PasTropGrand &&
3401 ((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0)))
3402 {//Real deflection is less than tolconf/2.0
3403 aStatus = IntWalk_StepTooSmall;
3407 if(aStatus == IntWalk_PasTropGrand)
3409 pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
3413 if(aStatus == IntWalk_StepTooSmall)
3415 pasuv[0] = Max(pasuv[0], AbsDu1);
3416 pasuv[1] = Max(pasuv[1], AbsDv1);
3417 pasuv[2] = Max(pasuv[2], AbsDu2);
3418 pasuv[3] = Max(pasuv[3], AbsDv2);
3420 pasInit[0] = Max(pasInit[0], AbsDu1);
3421 pasInit[1] = Max(pasInit[1], AbsDv1);
3422 pasInit[2] = Max(pasInit[2], AbsDu2);
3423 pasInit[3] = Max(pasInit[3], AbsDv2);
3429 pasuv[0] = Max(myStepMin[0],Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
3430 pasuv[1] = Max(myStepMin[1],Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
3431 pasuv[2] = Max(myStepMin[2],Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
3432 pasuv[3] = Max(myStepMin[3],Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
3434 if(aStatus == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
3438 Standard_Boolean IntWalk_PWalking::
3439 TestArret(const Standard_Boolean DejaReparti,
3440 TColStd_Array1OfReal& Param,
3441 IntImp_ConstIsoparametric& ChoixIso)
3444 // test if the point of intersection set by these parameters remains in the
3445 // natural domain of each square.
3446 // if the point outpasses reframe to find the best iso (border)
3447 // that intersects easiest the other square
3448 // otherwise test if closed line is present
3451 Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
3452 Standard_Real DPc,DPb;
3453 Standard_Integer i = 0, k = 0;
3458 previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
3460 Standard_Real SolParam[4];
3461 myIntersectionOn2S.Point().Parameters(SolParam[0],SolParam[1],SolParam[2],SolParam[3]);
3463 Standard_Boolean Trouve = Standard_False;
3465 Uvd[0]=Um1; Uvf[0]=UM1; Uvd[1]=Vm1; Uvf[1]=VM1;
3466 Uvd[2]=Um2; Uvf[2]=UM2; Uvd[3]=Vm2; Uvf[3]=VM2;
3468 Standard_Integer im1;
3469 for ( i = 1,im1 = 0;i<=4;i++,im1++) {
3476 if (Param(i) < (Uvd[im1]-Epsuv[im1]) ||
3477 SolParam[im1] < (Uvd[im1]-Epsuv[im1])) //-- Current ----- Bound Inf ----- Previous
3479 Trouve = Standard_True; //--
3480 DPc = Uvp[im1]-Param(i); //-- Previous - Current
3481 DPb = Uvp[im1]-Uvd[im1]; //-- Previous - Bound Inf
3482 ParC[im1] = Uvd[im1]; //-- ParamCorrige
3483 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3485 if(dv2>RealEpsilon()) { //-- Progress at the other Direction ?
3486 Duv[im1] = DPc*DPb + dv2;
3487 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3490 Duv[im1]=-1.0; //-- If no progress, do not change
3491 } //-- the choice of iso
3493 else if (Param(i) > (Uvf[im1] + Epsuv[im1]) ||
3494 SolParam[im1] > (Uvf[im1] + Epsuv[im1]))//-- Previous ----- Bound Sup ----- Current
3496 Trouve = Standard_True; //--
3497 DPc = Param(i)-Uvp[im1]; //-- Current - Previous
3498 DPb = Uvf[im1]-Uvp[im1]; //-- Bound Sup - Previous
3499 ParC[im1] = Uvf[im1]; //-- Param Corrige
3500 dv = Param(k)-Uvp[k-1]; //-- Current - Previous (other Direction)
3502 if(dv2>RealEpsilon()) { //-- Progress in other Direction ?
3503 Duv[im1] = DPc*DPb + dv2;
3504 Duv[im1] = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
3507 Duv[im1]=-1.0; //-- If no progress, do not change
3508 } //-- the choice of iso
3517 //--------------------------------------------------
3518 //-- One of Parameters u1,v1,u2,v2 is outside of --
3519 //-- the natural limits. --
3520 //-- Find the best direction of --
3521 //-- progress and reframe the parameters. --
3522 //--------------------------------------------------
3523 Standard_Real ddv = -1.0;
3525 for (i=0;i<=3;i++) {
3526 Param(i+1) = ParC[i];
3533 ChoixIso = ChoixRef(k);
3536 if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
3537 ChoixIso = IntImp_UIsoparametricOnCaro1;
3539 else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
3540 ChoixIso = IntImp_VIsoparametricOnCaro1;
3542 else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
3543 ChoixIso = IntImp_UIsoparametricOnCaro2;
3545 else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
3546 ChoixIso = IntImp_VIsoparametricOnCaro2;
3549 close = Standard_False;
3550 return Standard_True;
3554 if (!DejaReparti) { // find if line closed
3557 const IntSurf_PntOn2S& POn2S1=line->Value(1);
3559 POn2S1.ParametersOnS1(u,v);
3560 gp_Pnt2d P1uvS1(u,v);
3561 previousPoint.ParametersOnS1(u,v);
3562 gp_Pnt2d PrevuvS1(u,v);
3563 myIntersectionOn2S.Point().ParametersOnS1(u,v);
3564 gp_Pnt2d myIntersuvS1(u,v);
3565 Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
3566 (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
3568 POn2S1.ParametersOnS2(u,v);
3569 gp_Pnt2d P1uvS2(u,v);
3570 previousPoint.ParametersOnS2(u,v);
3571 gp_Pnt2d PrevuvS2(u,v);
3572 myIntersectionOn2S.Point().ParametersOnS2(u,v);
3573 gp_Pnt2d myIntersuvS2(u,v);
3574 Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
3575 (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
3577 close = close2dS1 && close2dS2;
3580 else return Standard_False;