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