0024981: IntTools_FaceFace enters to infinite loop on the attached case
[occt.git] / src / IntTools / IntTools_Tools.cxx
1 // Created on: 2000-11-16
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <IntTools_Tools.ixx>
17
18 #include <Precision.hxx>
19
20 #include <TopExp_Explorer.hxx>
21 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
22
23 #include <TopoDS.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopLoc_Location.hxx>
30
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <BRepAdaptor_Surface.hxx>
36
37 #include <gp_Pnt.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <gp.hxx>
40 #include <gp_Lin.hxx>
41 #include <gp_Dir.hxx>
42 #include <gp_Ax1.hxx>
43
44 #include <Geom_Curve.hxx>
45 #include <GeomAdaptor_Surface.hxx>
46 #include <Geom_Surface.hxx>
47 #include <GeomAPI_ProjectPointOnSurf.hxx>
48 #include <GeomAPI_ProjectPointOnCurve.hxx>
49 #include <GeomAdaptor_Curve.hxx>
50 #include <GeomAbs_CurveType.hxx>
51 #include <Geom_Line.hxx>
52 #include <Geom2d_Curve.hxx>
53 #include <Geom_BoundedCurve.hxx>
54 #include <Geom_Geometry.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <Geom2d_TrimmedCurve.hxx>
57
58 #include <IntTools_FClass2d.hxx>
59 #include <IntTools_Curve.hxx>
60 #include <IntTools_SequenceOfCurves.hxx>
61
62 static
63   void ParabolaTolerance(const Handle(Geom_Curve)& ,
64     const Standard_Real ,
65     const Standard_Real ,
66     const Standard_Real ,
67     Standard_Real& ,
68     Standard_Real& );
69
70 //=======================================================================
71 //function : HasInternalEdge
72 //purpose  : 
73 //=======================================================================
74   Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW)
75 {
76   Standard_Boolean bFlag=Standard_True;
77
78   TopExp_Explorer anExp(aW, TopAbs_EDGE);
79   for (; anExp.More(); anExp.Next()) {
80     const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
81     TopAbs_Orientation anOr=aE.Orientation();
82     if (anOr==TopAbs_INTERNAL) {
83       return bFlag;
84     }
85   }
86   return !bFlag;
87 }
88
89 //=======================================================================
90 //function : IsClosed
91 //purpose  : 
92 //=======================================================================
93   Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D)
94 {
95   Standard_Boolean bRet;
96   Standard_Real aF, aL, aDist, aPC;
97   gp_Pnt aP1, aP2;
98   
99   Handle (Geom_BoundedCurve) aGBC=
100       Handle (Geom_BoundedCurve)::DownCast(aC3D);
101   if (aGBC.IsNull()) {
102     return Standard_False;
103   }
104   
105   aF=aC3D->FirstParameter();
106   aL=aC3D-> LastParameter();
107   
108   aC3D->D0(aF, aP1);
109   aC3D->D0(aL, aP2);
110
111   
112   //
113   aPC=Precision::Confusion();
114   aPC=aPC*aPC;
115   aDist=aP1.SquareDistance(aP2);
116   bRet=aDist<aPC;
117   return bRet;
118 }
119
120 //=======================================================================
121 //function : RejectLines
122 //purpose  : 
123 //=======================================================================
124    void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn,
125         IntTools_SequenceOfCurves& aSOut)
126 {
127   Standard_Integer i, j, aNb;
128   Standard_Boolean bFlag;
129   Handle (Geom_Curve) aC3D;
130
131   gp_Dir aD1, aD2;
132
133   aSOut.Clear();
134
135   aNb=aSIn.Length();
136   for (i=1; i<=aNb; i++) {
137     const IntTools_Curve& IC=aSIn(i);
138     aC3D=IC.Curve();
139     //
140     Handle (Geom_TrimmedCurve) aGTC=
141       Handle (Geom_TrimmedCurve)::DownCast(aC3D);
142     
143     if (!aGTC.IsNull()) {
144       aC3D=aGTC->BasisCurve();
145       IntTools_Curve* pIC=(IntTools_Curve*) &IC;
146       pIC->SetCurve(aC3D);
147     }
148     //
149     Handle (Geom_Line) aGLine=
150       Handle (Geom_Line)::DownCast(aC3D);
151     
152     if (aGLine.IsNull()) {
153       aSOut.Clear();
154       for (j=1; j<=aNb; j++) {
155  aSOut.Append(aSIn(j));
156       }
157       return;
158     }
159     //
160     gp_Lin aLin=aGLine->Lin();
161     aD2=aLin.Direction();
162     if (i==1) {
163       aSOut.Append(IC);
164       aD1=aD2;
165       continue;
166     }
167     
168     bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2);
169     if (!bFlag) {
170       aSOut.Append(IC);
171       return;
172     }
173   }
174 }
175
176 //=======================================================================
177 //function : IsDirsCoinside
178 //purpose  : 
179 //=======================================================================
180   Standard_Boolean IntTools_Tools::IsDirsCoinside  (const gp_Dir& D1, const gp_Dir& D2)
181 {
182   Standard_Boolean bFlag;
183   gp_Pnt P1(D1.X(), D1.Y(), D1.Z());  
184   gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
185   Standard_Real dLim=0.0002, d;
186   d=P1.Distance (P2); 
187   bFlag= (d<dLim || fabs (2.-d)<dLim); 
188   return bFlag;
189 }
190   
191 //=======================================================================
192 //function : IsDirsCoinside
193 //purpose  : 
194 //=======================================================================
195   Standard_Boolean IntTools_Tools::IsDirsCoinside  (const gp_Dir& D1, 
196           const gp_Dir& D2,
197           const Standard_Real dLim)
198 {
199   Standard_Boolean bFlag;
200   Standard_Real d;
201   //
202   gp_Pnt P1(D1.X(), D1.Y(), D1.Z());  
203   gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
204   d=P1.Distance (P2); 
205   bFlag= (d<dLim || fabs (2.-d)<dLim); 
206   return bFlag;
207 }
208 //=======================================================================
209 //function : SplitCurve
210 //purpose  : 
211 //=======================================================================
212   Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC,
213            IntTools_SequenceOfCurves& aCvs)
214 {
215   Handle (Geom_Curve) aC3D =IC.Curve();
216   if(aC3D.IsNull())
217     return 0;
218   //
219   Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d();
220   Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d();
221   Standard_Boolean bIsClosed;
222
223   bIsClosed=IntTools_Tools::IsClosed(aC3D);
224   if (!bIsClosed) {
225     return 0;
226   }
227
228   Standard_Real aF, aL, aMid;
229   
230   //
231   aF=aC3D->FirstParameter();
232   aL=aC3D->LastParameter();
233   aMid=0.5*(aF+aL);
234   GeomAdaptor_Curve aGAC(aC3D);
235   GeomAbs_CurveType aCT=aGAC.GetType();
236   if (aCT==GeomAbs_BSplineCurve ||
237       aCT==GeomAbs_BezierCurve) {
238     //aMid=0.5*aMid;
239     aMid=IntTools_Tools::IntermediatePoint(aF, aL);
240   }
241   //
242   Handle(Geom_Curve) aC3DNewF, aC3DNewL;
243   aC3DNewF =new Geom_TrimmedCurve  (aC3D, aF, aMid);
244   aC3DNewL =new Geom_TrimmedCurve  (aC3D, aMid, aL);
245
246   //
247   Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L;
248   //
249   if(!aC2D1.IsNull()) {
250     aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid);
251     aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL);
252   }
253
254   if(!aC2D2.IsNull()) {
255     aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid);
256     aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL);
257   }
258   // 
259   
260   IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F);
261   IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L);
262   //
263   aCvs.Append(aIC1);
264   //
265   aCvs.Append(aIC2);
266   //
267   return 2;
268 }
269
270 //=======================================================================
271 //function : IntermediatePoint
272 //purpose  : 
273 //=======================================================================
274   Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst,
275          const Standard_Real aLast)
276 {
277   //define parameter division number as 10*e^(-M_PI) = 0.43213918
278   const Standard_Real PAR_T = 0.43213918;
279   Standard_Real aParm;
280   aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
281   return aParm;
282 }
283
284 //=======================================================================
285 //function : IsVertex
286 //purpose  : 
287 //=======================================================================
288   Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP,
289           const Standard_Real aTolPV,
290           const TopoDS_Vertex& aV)
291 {
292   Standard_Boolean bRet;
293   Standard_Real aTolV, aD, dTol;
294   gp_Pnt aPv; 
295   
296   aTolV=BRep_Tool::Tolerance(aV);
297   //
298   dTol=Precision::Confusion();
299   aTolV=aTolV+aTolPV+dTol;
300   //
301   aPv=BRep_Tool::Pnt(aV);
302   //
303   aD=aPv.SquareDistance(aP);
304   aTolV=aTolV*aTolV;
305   bRet=(aD<=aTolV);
306   return bRet;
307 }
308
309
310 //=======================================================================
311 //function : IsVertex
312 //purpose  : 
313 //=======================================================================
314   Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt)
315 {
316   Standard_Boolean anIsVertex;
317   Standard_Real aParam;
318
319   const TopoDS_Edge&    aE1=aCmnPrt.Edge1();
320   const IntTools_Range& aR1=aCmnPrt.Range1();
321   aParam=0.5*(aR1.First()+aR1.Last());
322   anIsVertex=IntTools_Tools::IsVertex (aE1, aParam);
323   
324   if (anIsVertex) {
325     return Standard_True;
326   }
327
328   const TopoDS_Edge&    aE2=aCmnPrt.Edge2();
329   const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2();
330   const IntTools_Range& aR2=aRs2(1);
331   aParam=0.5*(aR2.First()+aR2.Last());
332   anIsVertex=IntTools_Tools::IsVertex (aE2, aParam);
333   if (anIsVertex) {
334     return Standard_True;
335   }
336   return Standard_False;
337 }
338
339 //=======================================================================
340 //function : IsVertex
341 //purpose  : 
342 //=======================================================================
343   Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
344           const TopoDS_Vertex& aV,
345           const Standard_Real t)
346 {
347   Standard_Real aTolV, aTolV2, d2;
348   gp_Pnt aPv, aPt; 
349   
350   BRepAdaptor_Curve aBAC(aE);
351   aBAC.D0(t, aPt);
352
353   aTolV=BRep_Tool::Tolerance(aV);
354   aTolV2=aTolV*aTolV;
355   aPv=BRep_Tool::Pnt(aV);
356   d2=aPv.SquareDistance (aPt);
357   if (d2 < aTolV2) {
358     return Standard_True;
359   }
360   return Standard_False;
361 }
362 //=======================================================================
363 //function : IsVertex
364 //purpose  : 
365 //=======================================================================
366   Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
367           const Standard_Real t)
368 {
369   Standard_Real aTolV, aTolV2, d2;
370   TopoDS_Vertex aV;
371   gp_Pnt aPv, aPt; 
372   
373   BRepAdaptor_Curve aBAC(aE);
374   aBAC.D0(t, aPt);
375
376   TopExp_Explorer anExp(aE, TopAbs_VERTEX);
377   for (; anExp.More(); anExp.Next()) {
378     aV=TopoDS::Vertex (anExp.Current());
379     aTolV=BRep_Tool::Tolerance(aV);
380     aTolV2=aTolV*aTolV;
381     aTolV2=1.e-12;
382      aPv=BRep_Tool::Pnt(aV);
383      d2=aPv.SquareDistance (aPt);
384      if (d2 < aTolV2) {
385        return Standard_True;
386      }
387   }
388   return Standard_False;
389 }
390
391
392 //=======================================================================
393 //function : ComputeVV
394 //purpose  : 
395 //=======================================================================
396   Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1, 
397           const TopoDS_Vertex& aV2)
398 {
399   Standard_Real aTolV1, aTolV2, aTolSum, d;
400   gp_Pnt aP1, aP2;
401
402   aTolV1=BRep_Tool::Tolerance(aV1);
403   aTolV2=BRep_Tool::Tolerance(aV2);
404   aTolSum=aTolV1+aTolV2;
405   
406   aP1=BRep_Tool::Pnt(aV1);
407   aP2=BRep_Tool::Pnt(aV2);
408   aTolSum=aTolSum*aTolSum;
409   d=aP1.SquareDistance(aP2);
410   if (d<aTolSum) {
411     return 0;
412   }
413   return -1;
414 }
415
416 //=======================================================================
417 //function : MakeFaceFromWireAndFace
418 //purpose  : 
419 //=======================================================================
420   void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW,
421             const TopoDS_Face& aF,
422             TopoDS_Face& aFNew)
423 {
424   TopoDS_Face aFF;
425   aFF=aF;
426   aFF.Orientation(TopAbs_FORWARD);
427   aFNew=TopoDS::Face (aFF.EmptyCopied());
428   BRep_Builder BB;
429   BB.Add(aFNew, aW);
430 }
431
432 //=======================================================================
433 //function : ClassifyPointByFace
434 //purpose  : 
435 //=======================================================================
436   TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
437          const gp_Pnt2d& aP2d)
438 {
439   Standard_Real aFaceTolerance;
440   TopAbs_State aState;
441   
442   aFaceTolerance=BRep_Tool::Tolerance(aF);
443   IntTools_FClass2d aClass2d(aF, aFaceTolerance);
444   aState=aClass2d.Perform(aP2d);
445   
446   return aState;
447 }
448
449 //=======================================================================
450 //function : IsMiddlePointsEqual
451 //purpose  : 
452 //=======================================================================
453   Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1,
454              const TopoDS_Edge& aE2)
455              
456 {
457   Standard_Boolean bRet;
458   Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol, aD2;
459   gp_Pnt aP1, aP2;
460
461   aTol1=BRep_Tool::Tolerance(aE1);
462   Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1);
463   m1=0.5*(f1+l1);
464   C1->D0(m1, aP1);
465
466   aTol2=BRep_Tool::Tolerance(aE2);
467   Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2);
468   m2=0.5*(f2+l2);
469   C2->D0(m2, aP2);
470
471   aSumTol=aTol1+aTol2;
472   aSumTol=aSumTol*aSumTol;
473   aD2=aP1.SquareDistance(aP2);
474   bRet=aD2<aSumTol;
475   return bRet;
476 }
477
478 //=======================================================================
479 //function : CurveTolerance
480 //purpose  : 
481 //=======================================================================
482   Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D,
483             const Standard_Real aTolBase)
484 {
485   Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax;
486
487   aTolReached=aTolBase;
488   //
489   if (aC3D.IsNull()) {
490     return aTolReached;
491   }
492   //
493   Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D);
494   if (aCT3D.IsNull()) {
495     return aTolReached;
496   }
497   //
498   aTolMin=aTolBase;
499   aTolMax=aTolBase;
500   //
501   aTf=aCT3D->FirstParameter();
502   aTl=aCT3D->LastParameter();
503   //
504   GeomAdaptor_Curve aGAC(aCT3D);
505   GeomAbs_CurveType aCType=aGAC.GetType();
506   //
507   if (aCType==GeomAbs_Parabola) {
508     Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve();
509     ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax);
510     aTolReached=aTolMax;
511   }
512   //
513   return aTolReached;
514 }
515
516 #include <Geom_Parabola.hxx>
517 #include <gp_Parab.hxx>
518 #include <BndLib_Add3dCurve.hxx>
519 //=======================================================================
520 //function : ParabolaTolerance
521 //purpose  : 
522 //=======================================================================
523 void ParabolaTolerance(const Handle(Geom_Curve)& aC3D,
524          const Standard_Real aTf,
525          const Standard_Real aTl,
526          const Standard_Real aTol,
527          Standard_Real& aTolMin,
528          Standard_Real& aTolMax)
529 {
530   
531   aTolMin=aTol;
532   aTolMax=aTol;
533
534   Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D);
535   if (aGP.IsNull()){
536     return;
537   }
538
539   Standard_Integer aNbPoints;
540   Standard_Real aFocal, aX1, aX2, aTol1, aTol2;
541   gp_Pnt aPf, aPl;
542   gp_Parab aParab=aGP->Parab();
543   gp_Ax1 aXAxis=aParab.XAxis();
544   Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis);
545
546   aFocal=aGP->Focal();
547   if (aFocal==0.) {
548     return;
549   }
550   //
551   // aTol1
552   aTol1=aTol;
553   aX1=0.;
554   aGP->D0(aTf, aPf);
555   GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis);
556   aNbPoints=aProj1.NbPoints();
557   if (aNbPoints) {
558     aX1=aProj1.LowerDistanceParameter();
559   }
560   if (aX1>=0.) {
561     aTol1=aTol*sqrt(0.5*aX1/aFocal);
562   }
563   if (aTol1==0.) {
564     aTol1=aTol;
565   }
566   //
567   // aTol2
568   aTol2=aTol;
569   aX2=0.;
570   aGP->D0(aTl, aPl);
571   GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis);
572   aNbPoints=aProj2.NbPoints();
573   if (aNbPoints) {
574     aX2=aProj2.LowerDistanceParameter();
575   }
576   
577   if (aX2>=0.) {
578     aTol2=aTol*sqrt(0.5*aX2/aFocal);
579   }
580   if (aTol2==0.) {
581     aTol2=aTol;
582   }
583   //
584   aTolMax=(aTol1>aTol2) ? aTol1 : aTol2;
585   aTolMin=(aTol1<aTol2) ? aTol1 : aTol2;
586 }
587 /////////////////////////////////////////////////////////////////////////
588 //=======================================================================
589 //function : CheckCurve
590 //purpose  : 
591 //=======================================================================
592 Standard_Boolean IntTools_Tools::CheckCurve(const Handle (Geom_Curve)& aC3D,
593                                             const Standard_Real aTolR3D,
594                                             Bnd_Box& aBox)
595 {
596   Standard_Boolean bRet;  
597   Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dX, dY, dZ;
598   Standard_Real dS, aTol;
599   GeomAdaptor_Curve aGAC;
600   //
601   aGAC.Load(aC3D);
602   BndLib_Add3dCurve::Add(aGAC, aTolR3D, aBox);
603   // 910/B1
604   aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
605   dX=aXmax-aXmin;
606   dY=aYmax-aYmin;
607   dZ=aZmax-aZmin;
608   dS=1.e-12;
609   aTol=2.*aTolR3D+dS;
610   bRet=(dX>aTol ||  dY>aTol || dZ>aTol);
611   //
612   return bRet;
613 }
614 //=======================================================================
615 //function : IsOnPave
616 //purpose  : 
617 //=======================================================================
618 Standard_Boolean IntTools_Tools::IsOnPave(const Standard_Real aT1,
619                                           const IntTools_Range& aRange,
620                                           const Standard_Real aTolerance)
621 {
622   Standard_Boolean firstisonpave1, firstisonpave2, bIsOnPave;
623   //
624   firstisonpave1  = (Abs(aRange.First() - aT1) < aTolerance);
625   firstisonpave2  = (Abs(aRange.Last()  - aT1) < aTolerance);
626   bIsOnPave=(firstisonpave1 || firstisonpave2);
627   return bIsOnPave;
628 }
629 //=======================================================================
630 // function: VertexParameters
631 // purpose: 
632 //=======================================================================
633 void IntTools_Tools::VertexParameters(const IntTools_CommonPrt& aCPart,
634                                       Standard_Real& aT1, 
635                                       Standard_Real& aT2)
636 {
637   const IntTools_Range& aR1=aCPart.Range1();
638   aT1=0.5*(aR1.First()+aR1.Last());
639   //
640   if((aCPart.VertexParameter1() >= aR1.First()) &&
641      (aCPart.VertexParameter1() <= aR1.Last())) {
642     aT1 = aCPart.VertexParameter1();
643   }
644   //
645   const IntTools_SequenceOfRanges& aRanges2=aCPart.Ranges2();
646   const IntTools_Range& aR2=aRanges2(1);
647   aT2=0.5*(aR2.First()+aR2.Last());
648   //
649   if((aCPart.VertexParameter2() >= aR2.First()) &&
650      (aCPart.VertexParameter2() <= aR2.Last())) {
651     aT2 = aCPart.VertexParameter2();
652   }
653 }
654 //=======================================================================
655 // function: VertexParameter
656 // purpose: 
657 //=======================================================================
658 void IntTools_Tools::VertexParameter(const IntTools_CommonPrt& aCPart,
659                                      Standard_Real& aT)
660 {
661   const IntTools_Range& aR=aCPart.Range1();
662   aT=0.5*(aR.First()+aR.Last());
663   if((aCPart.VertexParameter1() >= aR.First()) &&
664      (aCPart.VertexParameter1() <= aR.Last())) {
665     aT = aCPart.VertexParameter1();
666   }
667 }
668 //=======================================================================
669 // function: IsOnPave1
670 // purpose: 
671 //=======================================================================
672 Standard_Boolean IntTools_Tools::IsOnPave1(const Standard_Real aTR,
673                                            const IntTools_Range& aCPRange,
674                                            const Standard_Real aTolerance)
675 {
676   Standard_Boolean bIsOnPave;
677   Standard_Real aT1, aT2, dT1, dT2;
678   //
679   aT1=aCPRange.First();
680   aT2=aCPRange.Last();
681   bIsOnPave=(aTR>=aT1 && aTR<=aT1);
682   if (bIsOnPave) {
683     return bIsOnPave;
684   }
685   //
686   dT1=Abs(aTR-aT1);  
687   dT2=Abs(aTR-aT2);
688   bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);
689   return bIsOnPave;
690 }
691 //=======================================================================
692 // function: IsInRange
693 // purpose: 
694 //=======================================================================
695 Standard_Boolean IntTools_Tools::IsInRange(const IntTools_Range& aRRef,
696                                            const IntTools_Range& aR,
697                                            const Standard_Real aTolerance)
698 {
699   Standard_Boolean bIsIn;
700   Standard_Real aT1, aT2, aTRef1, aTRef2;
701   //
702   aR.Range(aT1, aT2);
703   aRRef.Range(aTRef1, aTRef2);
704   //
705   aTRef1-=aTolerance;
706   aTRef2+=aTolerance;
707   //
708   bIsIn = (aT1>=aTRef1 && aT1<=aTRef2) ||
709           (aT2>=aTRef1 && aT2<=aTRef2);
710   //
711   return bIsIn;
712 }
713 //=======================================================================
714 //function : SegPln
715 //purpose  : 
716 //=======================================================================
717 Standard_Integer IntTools_Tools::SegPln(const gp_Lin& theLin,
718                                         const Standard_Real theTLin1,
719                                         const Standard_Real theTLin2,
720                                         const Standard_Real theTolLin,
721                                         const gp_Pln& thePln,
722                                         const Standard_Real theTolPln,
723                                         gp_Pnt& theP,
724                                         Standard_Real& theTP,
725                                         Standard_Real& theTolP,
726                                         Standard_Real& theTPmin,
727                                         Standard_Real& theTPmax)
728 {
729   Standard_Integer iRet;
730   Standard_Real aTol, aA, aB, aC, aD, aE, aH, aTP, aDist1, aDist2;
731   gp_Pnt aP1, aP2;
732   //
733   iRet=0;
734   aTol=theTolLin+theTolPln;
735   //
736   const gp_Ax3& aPosPln=thePln.Position();
737   const gp_Dir& aDirPln=aPosPln.Direction();
738   const gp_Pnt& aLocPln=aPosPln.Location();
739   //
740   const gp_Dir& aDirLin=theLin.Direction();
741   const gp_Pnt& aLocLin=theLin.Location();
742   //
743   aP1.SetXYZ(aLocLin.XYZ()+theTLin1*aDirLin.XYZ());
744   aDist1=aDirPln.X()*(aP1.X()-aLocPln.X())+
745          aDirPln.Y()*(aP1.Y()-aLocPln.Y())+
746          aDirPln.Z()*(aP1.Z()-aLocPln.Z());
747   //
748   aP2.SetXYZ(aLocLin.XYZ()+theTLin2*aDirLin.XYZ());
749   aDist2=aDirPln.X()*(aP2.X()-aLocPln.X())+
750          aDirPln.Y()*(aP2.Y()-aLocPln.Y())+
751          aDirPln.Z()*(aP2.Z()-aLocPln.Z());
752   //
753   if (aDist1<aTol && aDist2<aTol){
754     iRet=1; // common block
755     return iRet;
756   }
757   //
758   if (aDist1*aDist2 > 0.) {
759     iRet=2; // segment lays on one side to the Plane
760     return iRet;
761   } 
762   //
763   thePln.Coefficients(aA, aB, aC, aD);
764   aE=aA*aLocLin.X()+aB*aLocLin.Y()+aC*aLocLin.Z()+aD;
765   aH=aA*aDirLin.X()+aB*aDirLin.Y()+aC*aDirLin.Z();
766   aTP=-aE/aH;
767   if (aTP < theTLin1-aTol || aTP > theTLin2+aTol) {
768     iRet=3; // no intersections due to range of the Line
769     return iRet;
770   }
771   //
772   theTP=aTP;
773   theP.SetXYZ(aLocLin.XYZ()+aTP*aDirLin.XYZ());
774   theTolP=aTol;
775   theTPmin=theTP-theTolPln;
776   theTPmax=theTP+theTolPln;
777   iRet=0; // intersection point
778   return iRet;
779 }
780
781 //=======================================================================
782 //function : AdjustPeriodic
783 //purpose  : 
784 //=======================================================================
785 Standard_Boolean IntTools_Tools::AdjustPeriodic(const Standard_Real thePar,
786                                                 const Standard_Real theParMin,
787                                                 const Standard_Real theParMax,
788                                                 const Standard_Real thePeriod,
789                                                 Standard_Real &theNewPar,
790                                                 Standard_Real &theOffset,
791                                                 const Standard_Real theEps)
792 {
793   Standard_Boolean bMin, bMax;
794   //
795   theOffset = 0.;
796   theNewPar = thePar;
797   bMin = theParMin - thePar > theEps;
798   bMax = thePar - theParMax > theEps;
799   //
800   if (bMin || bMax) {
801     Standard_Real dp, aNbPer;
802     //
803     dp = (bMin) ? (theParMax - thePar) : (theParMin - thePar);
804     modf(dp / thePeriod, &aNbPer);
805     //
806     theOffset = aNbPer * thePeriod;
807     theNewPar += theOffset;
808   }
809   //
810   return (theOffset > 0.);
811 }
812