1 // Created on: 1993-11-26
2 // Created by: Modelistation
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <IntPatch_ALineToWLine.hxx>
19 #include <Adaptor3d_Surface.hxx>
21 #include <IntPatch_ALine.hxx>
22 #include <IntPatch_Point.hxx>
23 #include <IntPatch_SpecialPoints.hxx>
24 #include <IntPatch_WLine.hxx>
25 #include <IntSurf.hxx>
26 #include <IntSurf_LineOn2S.hxx>
28 //=======================================================================
29 //function : AddPointIntoLine
31 //=======================================================================
32 static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
33 const Standard_Real* const theArrPeriods,
34 IntSurf_PntOn2S &thePoint,
35 IntPatch_Point* theVertex = 0)
37 if(theLine->NbPoints() > 0)
39 if(thePoint.IsSame(theLine->Value(theLine->NbPoints()), Precision::Confusion()))
42 IntPatch_SpecialPoints::AdjustPointAndVertex(theLine->Value(theLine->NbPoints()),
43 theArrPeriods, thePoint, theVertex);
46 theLine->Add(thePoint);
49 //=======================================================================
50 //function : AddVertexPoint
51 //purpose : Extracts IntSurf_PntOn2S from theVertex and adds result in theLine.
52 //=======================================================================
53 static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine,
54 IntPatch_Point &theVertex,
55 const Standard_Real* const theArrPeriods)
57 IntSurf_PntOn2S anApexPoint = theVertex.PntOn2S();
58 AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
61 //=======================================================================
62 //function : IsPoleOrSeam
63 //purpose : Processes theVertex depending on its type
64 // (pole/apex/point on boundary etc.) and adds it in theLine.
65 // thePIsoRef is the reference point using in case when the
66 // value of correspond parameter cannot be precise.
67 // theSingularSurfaceID contains the ID of surface with
68 // special point (0 - none, 1 - theS1, 2 - theS2)
69 //=======================================================================
70 static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_Surface)& theS1,
71 const Handle(Adaptor3d_Surface)& theS2,
72 const IntSurf_PntOn2S& thePIsoRef,
73 Handle(IntSurf_LineOn2S)& theLine,
74 IntPatch_Point &theVertex,
75 const Standard_Real theArrPeriods[4],
76 const Standard_Real theTol3d,
77 Standard_Integer& theSingularSurfaceID)
79 theSingularSurfaceID = 0;
81 for(Standard_Integer i = 0; i < 2; i++)
83 const Standard_Boolean isReversed = (i > 0);
84 const GeomAbs_SurfaceType aType = isReversed? theS2->GetType() : theS1->GetType();
86 IntPatch_SpecPntType anAddedPType = IntPatch_SPntNone;
87 IntSurf_PntOn2S anApexPoint;
94 if(IntPatch_SpecialPoints::
95 AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
96 thePIsoRef, theVertex, anApexPoint,
97 isReversed, Standard_True))
99 anAddedPType = IntPatch_SPntPole;
105 if(aType == GeomAbs_Torus)
107 if(IntPatch_SpecialPoints::
108 AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
109 thePIsoRef, theTol3d,
110 anApexPoint, isReversed))
112 anAddedPType = IntPatch_SPntSeamUV;
117 case GeomAbs_Cylinder:
118 theSingularSurfaceID = i + 1;
119 AddVertexPoint(theLine, theVertex, theArrPeriods);
120 return IntPatch_SPntSeamU;
126 if(anAddedPType != IntPatch_SPntNone)
128 theSingularSurfaceID = i + 1;
129 AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
134 return IntPatch_SPntNone;
137 //=======================================================================
138 //function : IntPatch_ALineToWLine
140 //=======================================================================
141 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_Surface)& theS1,
142 const Handle(Adaptor3d_Surface)& theS2,
143 const Standard_Integer theNbPoints) :
146 myNbPointsInWline(theNbPoints),
147 myTolOpenDomain(1.e-9),
148 myTolTransition(1.e-8),
149 myTol3D(Precision::Confusion())
151 const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
152 const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
157 myQuad1.SetValue(theS1->Plane());
160 case GeomAbs_Cylinder:
161 myQuad1.SetValue(theS1->Cylinder());
165 myQuad1.SetValue(theS1->Sphere());
169 myQuad1.SetValue(theS1->Cone());
173 myQuad1.SetValue(theS1->Torus());
183 myQuad2.SetValue(theS2->Plane());
185 case GeomAbs_Cylinder:
186 myQuad2.SetValue(theS2->Cylinder());
190 myQuad2.SetValue(theS2->Sphere());
194 myQuad2.SetValue(theS2->Cone());
198 myQuad2.SetValue(theS2->Torus());
206 //=======================================================================
207 //function : SetTol3D
209 //=======================================================================
210 void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
214 //=======================================================================
217 //=======================================================================
218 Standard_Real IntPatch_ALineToWLine::Tol3D()const
222 //=======================================================================
223 //function : SetTolTransition
225 //=======================================================================
226 void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
228 myTolTransition = aTol;
230 //=======================================================================
231 //function : TolTransition
233 //=======================================================================
234 Standard_Real IntPatch_ALineToWLine::TolTransition()const
236 return myTolTransition;
238 //=======================================================================
239 //function : SetTolOpenDomain
241 //=======================================================================
242 void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
244 myTolOpenDomain = aTol;
246 //=======================================================================
247 //function : TolOpenDomain
249 //=======================================================================
250 Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
252 return myTolOpenDomain;
255 //=======================================================================
256 //function : GetSectionRadius
258 //=======================================================================
259 Standard_Real IntPatch_ALineToWLine::GetSectionRadius(const gp_Pnt& thePnt3d) const
261 Standard_Real aRetVal = RealLast();
262 for (Standard_Integer i = 0; i < 2; i++)
264 const IntSurf_Quadric& aQuad = i ? myQuad2 : myQuad1;
265 if (aQuad.TypeQuadric() == GeomAbs_Cone)
267 const gp_Cone aCone = aQuad.Cone();
268 const gp_XYZ aRVec = thePnt3d.XYZ() - aCone.Apex().XYZ();
269 const gp_XYZ &aDir = aCone.Axis().Direction().XYZ();
271 aRetVal = Min(aRetVal, Abs(aRVec.Dot(aDir)*Tan(aCone.SemiAngle())));
273 else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
275 const gp_Sphere aSphere = aQuad.Sphere();
276 const gp_XYZ aRVec = thePnt3d.XYZ() - aSphere.Location().XYZ();
277 const gp_XYZ &aDir = aSphere.Position().Direction().XYZ();
278 const Standard_Real aR = aSphere.Radius();
279 const Standard_Real aD = aRVec.Dot(aDir);
280 const Standard_Real aDelta = aR*aR - aD*aD;
288 aRetVal = Min(aRetVal, Sqrt(aDelta));
296 //=======================================================================
297 //function : MakeWLine
299 //=======================================================================
300 void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theAline,
301 IntPatch_SequenceOfLine& theLines) const
303 Standard_Boolean included;
304 Standard_Real f = theAline->FirstParameter(included);
308 Standard_Real l = theAline->LastParameter(included);
313 MakeWLine(theAline, f, l, theLines);
316 //=======================================================================
317 //function : MakeWLine
319 //=======================================================================
320 void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
321 const Standard_Real theFPar,
322 const Standard_Real theLPar,
323 IntPatch_SequenceOfLine& theLines) const
325 const Standard_Integer aNbVert = theALine->NbVertex();
332 //To draw ALine as a wire DRAW-object use the following code.
337 bool flShow = /*(zzz == 1)*/false;
341 std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
342 Standard_Integer aI = 0;
343 const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
344 for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
346 const gp_Pnt aPP(theALine->Value(aPrm));
347 std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
350 gp_Pnt aPP(theALine->Value(theLPar));
351 std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
352 std::cout << " --- DUMP ALine (end) -----" << std::endl;
356 //Copy all output information and apply it as a TCL-code in DRAW.
358 //After that, use TCL-script below:
360 /* ********************************* Script (begin)
363 for {set i 2} {$i <= 10000} {incr i} {
364 distmini dd vprev v$i;
366 if { [dval dd_val] > 1.0e-7} {
372 ********************************** Script (end) */
375 //The same points can be marked by different vertices.
376 //The code below unifies tolerances of all vertices
377 //marking the same points.
378 for (Standard_Integer i = 1; i < aNbVert; i++)
380 IntPatch_Point &aCurVert = theALine->ChangeVertex(i);
381 const IntSurf_PntOn2S &aCurrPt = aCurVert.PntOn2S();
382 const Standard_Real aCurToler = aCurVert.Tolerance();
383 for (Standard_Integer j = i + 1; j <= aNbVert; j++)
385 IntPatch_Point &aVert = theALine->ChangeVertex(j);
386 const IntSurf_PntOn2S &aNewPt = aVert.PntOn2S();
387 const Standard_Real aToler = aVert.Tolerance();
389 const Standard_Real aSumTol = aCurToler + aToler;
390 if (aCurrPt.IsSame(aNewPt, aSumTol))
392 aCurVert.SetTolerance(aSumTol);
393 aVert.SetTolerance(aSumTol);
398 const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
399 const Standard_Real aPrmTol = Max(1.0e-4*(theLPar - theFPar), Precision::PConfusion());
401 IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
403 NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert);
404 NCollection_Array1<IntPatch_Point> aSeqVertex(1, aNbVert);
406 //It is possible to have several vertices with equal parameters.
407 NCollection_Array1<Standard_Boolean> hasVertexBeenChecked(1, aNbVert);
409 Handle(IntSurf_LineOn2S) aLinOn2S;
410 Standard_Real aParameter = theFPar;
412 for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
414 const IntPatch_Point& aVert = theALine->Vertex(i);
415 const Standard_Real aPar = aVert.ParameterOnLine();
416 aVertexParams(i) = aPar;
417 hasVertexBeenChecked(i) = Standard_False;
420 Standard_Integer aSingularSurfaceID = 0;
421 Standard_Real anArrPeriods[] = { 0.0, //U1
426 IntSurf::SetPeriod(myS1, myS2, anArrPeriods);
428 IntSurf_PntOn2S aPrevLPoint;
430 while(aParameter < theLPar)
432 Standard_Real aStep = (theLPar - aParameter) / (Standard_Real)(myNbPointsInWline - 1);
433 if(aStep < Epsilon(theLPar))
436 Standard_Integer aNewVertID = 0;
437 aLinOn2S = new IntSurf_LineOn2S;
439 const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep;
441 Standard_Boolean isLast = Standard_False;
442 Standard_Real aPrevParam = aParameter;
443 for(; !isLast; aParameter += aStep)
445 IntSurf_PntOn2S aPOn2S;
447 if(theLPar <= aParameter)
449 isLast = Standard_True;
450 if(aPrePointExist != IntPatch_SPntNone)
456 aParameter = theLPar;
460 Standard_Boolean isPointValid = Standard_False;
461 Standard_Real aTgMagn = 0.0;
465 theALine->D1(aParameter, aPnt3d, aTg);
466 if (GetSectionRadius(aPnt3d) < 5.0e-6)
468 // We cannot compute 2D-parameters of
471 isPointValid = Standard_False;
475 isPointValid = Standard_True;
478 aTgMagn = aTg.Magnitude();
479 Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
480 myQuad1.Parameters(aPnt3d, u1, v1);
481 myQuad2.Parameters(aPnt3d, u2, v2);
482 aPOn2S.SetValue(aPnt3d, u1, v1, u2, v2);
485 if(aPrePointExist != IntPatch_SPntNone)
487 const Standard_Real aURes = Max(myS1->UResolution(myTol3D),
488 myS2->UResolution(myTol3D)),
489 aVRes = Max(myS1->VResolution(myTol3D),
490 myS2->VResolution(myTol3D));
492 const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 :
493 (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
494 (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
496 IntSurf_PntOn2S aRPT = aPOn2S;
498 if (aPrePointExist == IntPatch_SPntPole)
500 Standard_Real aPrt = 0.5*(aPrevParam + theLPar);
501 for (Standard_Integer i = aVertexParams.Lower();
502 i <= aVertexParams.Upper(); i++)
504 const Standard_Real aParam = aVertexParams(i);
506 if (aParam <= aPrevParam)
509 if ((aParam - aPrevParam) < aPrmTol)
511 const gp_Pnt aPnt3d(theALine->Value(aParam));
512 if (aPOn2S.Value().SquareDistance(aPnt3d) < Precision::SquareConfusion())
514 // i-th vertex is the same as a Pole/Apex.
515 // So, it should be ignored.
520 aPrt = 0.5*(aParam + aPrevParam);
524 const gp_Pnt aPnt3d(theALine->Value(aPrt));
525 Standard_Real u1, v1, u2, v2;
526 myQuad1.Parameters(aPnt3d, u1, v1);
527 myQuad2.Parameters(aPnt3d, u2, v2);
528 aRPT.SetValue(aPnt3d, u1, v1, u2, v2);
530 if (aPOn2S.IsSame(aPrevLPoint, Max(Precision::Approximation(), aTol)))
532 //Set V-parameter as precise value found on the previous step.
533 if (aSingularSurfaceID == 1)
535 aPOn2S.ParametersOnS1(u2, v2);
536 aPOn2S.SetValue(Standard_True, u1, v2);
538 else //if (aSingularSurfaceID == 2)
540 aPOn2S.ParametersOnS2(u1, v1);
541 aPOn2S.SetValue(Standard_False, u2, v1);
546 if(IntPatch_SpecialPoints::
547 ContinueAfterSpecialPoint(myS1, myS2, aRPT,
548 aPrePointExist, aTol2d,
549 aPrevLPoint, Standard_False))
551 AddPointIntoLine(aLinOn2S, anArrPeriods, aPrevLPoint);
553 else if(aParameter == theLPar)
554 {// Strictly equal!!!
559 aPrePointExist = IntPatch_SPntNone;
561 Standard_Integer aVertexNumber = -1;
562 for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
564 if(hasVertexBeenChecked(i))
567 const IntPatch_Point &aVP = theALine->Vertex(i);
568 const Standard_Real aParam = aVertexParams(i);
569 if( ((aPrevParam < aParam) && (aParam <= aParameter)) ||
570 ((aPrevParam == aParameter) && (aParam == aParameter))||
571 (aPOn2S.IsSame(aVP.PntOn2S(), aVP.Tolerance()) &&
572 (Abs(aVP.ParameterOnLine() - aParameter) < aPrmTol)))
574 //We have either jumped over the vertex or "fell" on the vertex.
575 //However, ALine can be self-interfered. Therefore, we need to check
576 //vertex parameter and 3D-distance together.
583 aPrevParam = aParameter;
585 if(aVertexNumber < 0)
589 StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
590 aStepMin, aStepMax, myTol3D, aStep);
591 AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
592 aPrevLPoint = aPOn2S;
598 IntPatch_Point aVtx = theALine->Vertex(aVertexNumber);
599 const Standard_Real aNewVertexParam = aLinOn2S->NbPoints() + 1;
602 // IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects
603 //to some special point. Otherwise, aLinOn2S is not changed.
605 // Find a point for reference parameter. It will be used
606 // if real parameter value cannot be precise (see comment to
607 // IsPoleOrSeam(...) function).
608 IntSurf_PntOn2S aPrefIso = aVtx.PntOn2S();
609 if (aLinOn2S->NbPoints() < 1)
611 for (Standard_Integer i = aVertexNumber + 1; i <= aVertexParams.Upper(); i++)
613 const Standard_Real aParam = aVertexParams(i);
614 if ((aParam - aVertexParams(aVertexNumber)) > Precision::PConfusion())
616 const Standard_Real aPrm = 0.5*(aParam + aVertexParams(aVertexNumber));
617 const gp_Pnt aPnt3d(theALine->Value(aPrm));
618 Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
619 myQuad1.Parameters(aPnt3d, u1, v1);
620 myQuad2.Parameters(aPnt3d, u2, v2);
621 aPrefIso.SetValue(aPnt3d, u1, v1, u2, v2);
628 aPrefIso = aLinOn2S->Value(aLinOn2S->NbPoints());
631 aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
632 anArrPeriods, aTol, aSingularSurfaceID);
634 const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
635 if(aPrePointExist != IntPatch_SPntNone)
637 aPrevParam = aParameter = aCurVertParam;
643 //Take a farther point of ALine (with greater parameter)
647 if(aVtx.Tolerance() > aTol)
649 aVtx.SetValue(aPOn2S);
650 AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
654 AddVertexPoint(aLinOn2S, aVtx, anArrPeriods);
658 aPrevLPoint = aPOn2S = aLinOn2S->Value(aLinOn2S->NbPoints());
661 Standard_Boolean isFound = Standard_False;
662 const Standard_Real aSqTol = aTol*aTol;
663 const gp_Pnt aP1(theALine->Value(aCurVertParam));
664 const IntSurf_PntOn2S& aVertP2S = aVtx.PntOn2S();
665 const Standard_Real aVertToler = aVtx.Tolerance();
667 for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
669 if(hasVertexBeenChecked(i))
672 const gp_Pnt aP2(theALine->Value(aVertexParams(i)));
674 if(aP1.SquareDistance(aP2) < aSqTol)
676 IntPatch_Point aLVtx = theALine->Vertex(i);
677 aLVtx.SetValue(aVertP2S);
678 aLVtx.SetTolerance(aVertToler);
679 Standard_Real aParam = aLVtx.ParameterOnLine();
680 if (Abs(aParam - theLPar) <= Precision::PConfusion()) //in the case of closed curve,
681 aLVtx.SetParameter(-1); //we don't know yet the number of points in the curve
683 aLVtx.SetParameter(aNewVertexParam);
684 aSeqVertex(++aNewVertID) = aLVtx;
685 hasVertexBeenChecked(i) = Standard_True;
686 isFound = Standard_True;
695 if ((aPrePointExist != IntPatch_SPntNone) && (aLinOn2S->NbPoints() > 1))
697 }//for(; !isLast; aParameter += aStep)
699 if(aLinOn2S->NbPoints() < 2)
705 //-----------------------------------------------------------------
706 //-- W L i n e c r e a t i o n ---
707 //-----------------------------------------------------------------
708 Handle(IntPatch_WLine) aWLine;
710 if(theALine->TransitionOnS1() == IntSurf_Touch)
712 aWLine = new IntPatch_WLine(aLinOn2S,
713 theALine->IsTangent(),
714 theALine->SituationS1(),
715 theALine->SituationS2());
716 aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
718 else if(theALine->TransitionOnS1() == IntSurf_Undecided)
720 aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent());
721 aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
725 //Computation of transitions of the line on two surfaces ---
726 const Standard_Integer indice1 = Max(aLinOn2S->NbPoints() / 3, 2);
727 const gp_Pnt &aPP0 = aLinOn2S->Value(indice1 - 1).Value(),
728 &aPP1 = aLinOn2S->Value(indice1).Value();
729 const gp_Vec tgvalid(aPP0, aPP1);
730 const gp_Vec aNQ1(myQuad1.Normale(aPP0)), aNQ2(myQuad2.Normale(aPP0));
732 const Standard_Real dotcross = tgvalid.DotCross(aNQ2, aNQ1);
734 IntSurf_TypeTrans trans1 = IntSurf_Undecided,
735 trans2 = IntSurf_Undecided;
737 if (dotcross > myTolTransition)
739 trans1 = IntSurf_Out;
742 else if (dotcross < -myTolTransition)
745 trans2 = IntSurf_Out;
748 aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent(),
750 aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
753 for(Standard_Integer i = aSeqVertex.Lower(); i <= aNewVertID; i++)
755 IntPatch_Point aVtx = aSeqVertex(i);
756 if (aVtx.ParameterOnLine() == -1) //in the case of closed curve,
757 aVtx.SetParameter (aWLine->NbPnts()); //we set the last parameter
758 aWLine->AddVertex(aVtx);
761 aWLine->SetPeriod(anArrPeriods[0],anArrPeriods[1],anArrPeriods[2],anArrPeriods[3]);
763 //the method ComputeVertexParameters can reduce the number of points in <aWLine>
764 aWLine->ComputeVertexParameters(myTol3D);
766 if (aWLine->NbPnts() > 1)
768 aWLine->EnablePurging(Standard_False);
769 #ifdef INTPATCH_ALINETOWLINE_DEBUG
772 theLines.Append(aWLine);
774 }//while(aParameter < theLPar)
777 //=======================================================================
778 //function : CheckDeflection
780 // -1 - step is too small
781 // 0 - step is normal
782 // +1 - step is too big
783 //=======================================================================
784 Standard_Integer IntPatch_ALineToWLine::CheckDeflection(const gp_XYZ& theMidPt,
785 const Standard_Real theMaxDeflection) const
787 Standard_Real aDist = Abs(myQuad1.Distance(theMidPt));
788 if(aDist > theMaxDeflection)
791 aDist = Max(Abs(myQuad2.Distance(theMidPt)), aDist);
793 if(aDist > theMaxDeflection)
796 if((aDist + aDist) < theMaxDeflection)
802 //=======================================================================
803 //function : StepComputing
805 //=======================================================================
806 Standard_Boolean IntPatch_ALineToWLine::
807 StepComputing(const Handle(IntPatch_ALine)& theALine,
808 const IntSurf_PntOn2S& thePOn2S,
809 const Standard_Real theLastParOfAline,
810 const Standard_Real theCurParam,
811 const Standard_Real theTgMagnitude,
812 const Standard_Real theStepMin,
813 const Standard_Real theStepMax,
814 const Standard_Real theMaxDeflection,
815 Standard_Real& theStep) const
817 if(theTgMagnitude < Precision::Confusion())
818 return Standard_False;
820 const Standard_Real anEps = myTol3D;
822 //Indeed, 1.0e+15 < 2^50 < 1.0e+16. Therefore,
823 //if we apply bisection method to the range with length
824 //1.0e+6 then we will be able to find solution with max error ~1.0e-9.
825 const Standard_Integer aNbIterMax = 50;
827 const Standard_Real aNotFilledRange = theLastParOfAline - theCurParam;
828 Standard_Real aMinStep = theStepMin, aMaxStep = Min(theStepMax, aNotFilledRange);
830 if(aMinStep > aMaxStep)
833 return Standard_True;
836 const Standard_Real aR = IntPatch_PointLine::
837 CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S);
843 std::cout << "*** R" << zzz << " (begin)" << std::endl;
844 Standard_Real aU1, aV1, aU2, aV2;
845 thePOn2S.Parameters(aU1, aV1, aU2, aV2);
846 std::cout << "Prms: " << aU1 << ", " << aV1 << ", " << aU2 << ", " << aV2 << std::endl;
847 std::cout << "Radius = " << aR << std::endl;
848 std::cout << "*** R" << zzz << " (end)" << std::endl;
854 return Standard_False;
858 //The 3D-step is defined as length of the tangent to the osculating circle
859 //by the condition that the distance from end point of the tangent to the
860 //circle is no greater than anEps. theStep is the step in
861 //parameter space of intersection curve (must be converted from 3D-step).
863 theStep = Min(sqrt(anEps*(2.0*aR + anEps))/theTgMagnitude, aMaxStep);
864 theStep = Max(theStep, aMinStep);
867 //The step value has been computed for osculating circle.
868 //Now it should be checked for real intersection curve
869 //and is made more precise in case of necessity.
871 Standard_Integer aNbIter = 0;
876 const gp_XYZ& aP1 = thePOn2S.Value().XYZ();
877 const gp_XYZ aP2(theALine->Value(theCurParam + theStep).XYZ());
878 const Standard_Integer aStatus = CheckDeflection(0.5*(aP1 + aP2), theMaxDeflection);
887 else //if(aStatus > 0)
892 theStep = 0.5*(aMinStep + aMaxStep);
894 while(((aMaxStep - aMinStep) > Precision::PConfusion()) && (aNbIter <= aNbIterMax));
896 if(aNbIter > aNbIterMax)
897 return Standard_False;
899 return Standard_True;