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