71432b39a131845d090b183dcd5d923207a7af11
[occt.git] / src / IntTools / IntTools_Context.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <IntTools_Context.ixx>
16
17 #include <Precision.hxx>
18
19 #include <Geom_Curve.hxx>
20 #include <Geom_BoundedCurve.hxx>
21 #include <GeomAPI_ProjectPointOnCurve.hxx>
22 #include <GeomAPI_ProjectPointOnSurf.hxx>
23 #include <GeomAdaptor_Curve.hxx>
24
25 #include <Geom2dHatch_Intersector.hxx>
26 #include <Geom2d_TrimmedCurve.hxx>
27
28 #include <TopAbs_State.hxx>
29 #include <TopoDS.hxx>
30 #include <TopExp_Explorer.hxx>
31
32 #include <BRep_Tool.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34
35 #include <IntTools_Tools.hxx>
36 #include <IntTools_FClass2d.hxx>
37 // 
38 #include <Extrema_LocateExtPC.hxx>
39
40 #include <Geom2d_Curve.hxx>
41 #include <NCollection_IncAllocator.hxx>
42 #include <IntTools_SurfaceRangeLocalizeData.hxx>
43
44
45 //=======================================================================
46 //function : 
47 //purpose  : 
48 //=======================================================================
49 IntTools_Context::IntTools_Context()
50 :
51   myAllocator(new NCollection_IncAllocator()),
52   myFClass2dMap(100, myAllocator),
53   myProjPSMap(100, myAllocator),
54   myProjPCMap(100, myAllocator),
55   mySClassMap(100, myAllocator),
56   myProjPTMap(100, myAllocator),
57   myHatcherMap(100, myAllocator),
58   myProjSDataMap(100, myAllocator),
59   myCreateFlag(0)
60 {
61 }
62 //=======================================================================
63 //function : 
64 //purpose  : 
65 //=======================================================================
66 IntTools_Context::IntTools_Context
67   (const Handle(NCollection_BaseAllocator)& theAllocator)
68 :
69   myAllocator(theAllocator),
70   myFClass2dMap(100, myAllocator),
71   myProjPSMap(100, myAllocator),
72   myProjPCMap(100, myAllocator),
73   mySClassMap(100, myAllocator),
74   myProjPTMap(100, myAllocator),
75   myHatcherMap(100, myAllocator),
76   myProjSDataMap(100, myAllocator),
77   myCreateFlag(1)
78 {
79 }
80 //=======================================================================
81 //function : ~
82 //purpose  : 
83 //=======================================================================
84 IntTools_Context::~IntTools_Context()
85 {
86   Standard_Address anAdr;
87   BOPCol_DataMapIteratorOfDataMapOfShapeAddress aIt;
88   BOPCol_DataMapIteratorOfDataMapOfTransientAddress aIt1;
89   //
90   IntTools_FClass2d* pFClass2d;
91   //
92   aIt.Initialize(myFClass2dMap);
93   for (; aIt.More(); aIt.Next()) {
94     anAdr=aIt.Value();
95     pFClass2d=(IntTools_FClass2d*)anAdr;
96     (*pFClass2d).~IntTools_FClass2d();
97     myAllocator->Free(anAdr); 
98   }
99   myFClass2dMap.Clear();
100   //
101   GeomAPI_ProjectPointOnSurf* pProjPS;
102   aIt.Initialize(myProjPSMap);
103   for (; aIt.More(); aIt.Next()) {
104     anAdr=aIt.Value();
105     pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
106     (*pProjPS).~GeomAPI_ProjectPointOnSurf();
107     myAllocator->Free(anAdr); 
108   }
109   myProjPSMap.Clear();
110   //
111   GeomAPI_ProjectPointOnCurve* pProjPC;
112   aIt.Initialize(myProjPCMap);
113   for (; aIt.More(); aIt.Next()) {
114     anAdr=aIt.Value();
115     pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
116     (*pProjPC).~GeomAPI_ProjectPointOnCurve();
117     myAllocator->Free(anAdr); 
118   }
119   myProjPCMap.Clear();
120   //
121   //
122   BRepClass3d_SolidClassifier* pSC;
123   aIt.Initialize(mySClassMap);
124   for (; aIt.More(); aIt.Next()) {
125     anAdr=aIt.Value();
126     pSC=(BRepClass3d_SolidClassifier*)anAdr;
127     (*pSC).~BRepClass3d_SolidClassifier();
128     myAllocator->Free(anAdr); 
129   }
130   mySClassMap.Clear();
131   //
132   GeomAPI_ProjectPointOnCurve* pProjPT;
133   aIt1.Initialize(myProjPTMap);
134   for (; aIt1.More(); aIt1.Next()) {
135     anAdr=aIt1.Value();
136     pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
137     (*pProjPT).~GeomAPI_ProjectPointOnCurve();
138     myAllocator->Free(anAdr); 
139   }
140   myProjPTMap.Clear();
141   //
142   Geom2dHatch_Hatcher* pHatcher;
143   aIt.Initialize(myHatcherMap);
144   for (; aIt.More(); aIt.Next()) {
145     anAdr=aIt.Value();
146     pHatcher=(Geom2dHatch_Hatcher*)anAdr;
147     (*pHatcher).~Geom2dHatch_Hatcher();
148     myAllocator->Free(anAdr);
149   }
150   myHatcherMap.Clear();
151   //
152   IntTools_SurfaceRangeLocalizeData* pSData = NULL;
153   aIt.Initialize(myProjSDataMap);
154   for (; aIt.More(); aIt.Next()) {
155     anAdr=aIt.Value();
156     pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
157     (*pSData).~IntTools_SurfaceRangeLocalizeData();
158     myAllocator->Free(anAdr);
159   }
160   myProjSDataMap.Clear();
161 }
162 //=======================================================================
163 //function : FClass2d
164 //purpose  : 
165 //=======================================================================
166 IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
167 {
168   Standard_Address anAdr;
169   IntTools_FClass2d* pFClass2d;
170   //
171   if (!myFClass2dMap.IsBound(aF)) {
172     Standard_Real aTolF;
173     TopoDS_Face aFF;
174     //
175     aFF=aF;
176     aFF.Orientation(TopAbs_FORWARD);
177     aTolF=BRep_Tool::Tolerance(aFF);
178     //
179     pFClass2d=(IntTools_FClass2d*)myAllocator->Allocate(sizeof(IntTools_FClass2d));
180     new (pFClass2d) IntTools_FClass2d(aFF, aTolF);
181     //
182     anAdr=(Standard_Address)pFClass2d;
183     myFClass2dMap.Bind(aFF, anAdr);
184   }
185   else {
186     anAdr=myFClass2dMap.Find(aF);
187     pFClass2d=(IntTools_FClass2d*)anAdr;
188   }
189   return *pFClass2d;
190 }
191 //=======================================================================
192 //function : ProjPS
193 //purpose  : 
194 //=======================================================================
195 GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
196 {
197   Standard_Address anAdr;
198   GeomAPI_ProjectPointOnSurf* pProjPS;
199  
200   if (!myProjPSMap.IsBound(aF)) {
201     Standard_Real Umin, Usup, Vmin, Vsup, anEpsT=1.e-12 ;
202     BRepAdaptor_Surface aBAS;
203     //
204     const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
205     aBAS.Initialize (aF, Standard_True);
206     //
207     Umin=aBAS.FirstUParameter();
208     Usup=aBAS.LastUParameter ();
209     Vmin=aBAS.FirstVParameter();
210     Vsup=aBAS.LastVParameter ();
211     //
212     pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf));
213     new (pProjPS) GeomAPI_ProjectPointOnSurf();
214     pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT/*, Extrema_ExtAlgo_Tree*/);
215     Extrema_ExtPS& anExtAlgo = const_cast<Extrema_ExtPS&>(pProjPS->Extrema());
216     anExtAlgo.SetFlag(Extrema_ExtFlag_MIN);
217     //
218     anAdr=(Standard_Address)pProjPS;
219     myProjPSMap.Bind(aF, anAdr);
220   }
221   
222   else {
223     anAdr=myProjPSMap.Find(aF);
224     pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
225   }
226   return *pProjPS;
227 }
228 //=======================================================================
229 //function : ProjPC
230 //purpose  : 
231 //=======================================================================
232 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPC(const TopoDS_Edge& aE)
233 {
234   Standard_Address anAdr;
235   GeomAPI_ProjectPointOnCurve* pProjPC;
236  
237   if (!myProjPCMap.IsBound(aE)) {
238     Standard_Real f, l;
239     //
240     Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l);
241     //
242     pProjPC=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
243     new (pProjPC) GeomAPI_ProjectPointOnCurve();
244     pProjPC->Init(aC3D, f, l);
245     //
246     anAdr=(Standard_Address)pProjPC;
247     myProjPCMap.Bind(aE, anAdr);
248   }
249   
250   else {
251     anAdr=myProjPCMap.Find(aE);
252     pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
253   }
254   return *pProjPC;
255 }
256
257 //=======================================================================
258 //function : ProjPT
259 //purpose  : 
260 //=======================================================================
261 GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPT
262   (const Handle(Geom_Curve)& aC3D)
263
264 {
265   Standard_Address anAdr;
266   GeomAPI_ProjectPointOnCurve* pProjPT;
267  
268   if (!myProjPTMap.IsBound(aC3D)) {
269     Standard_Real f, l;
270     f=aC3D->FirstParameter();
271     l=aC3D->LastParameter();
272     //
273     pProjPT=(GeomAPI_ProjectPointOnCurve*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnCurve));
274     new (pProjPT) GeomAPI_ProjectPointOnCurve();
275     pProjPT->Init(aC3D, f, l);
276     //
277     anAdr=(Standard_Address)pProjPT;
278     myProjPTMap.Bind(aC3D, anAdr);
279   }
280   
281   else {
282     anAdr=myProjPTMap.Find(aC3D);
283     pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
284   }
285   return *pProjPT;
286 }
287 //=======================================================================
288 //function : SolidClassifier
289 //purpose  : 
290 //=======================================================================
291 BRepClass3d_SolidClassifier& IntTools_Context::SolidClassifier
292   (const TopoDS_Solid& aSolid)
293 {
294   Standard_Address anAdr;
295   BRepClass3d_SolidClassifier* pSC;
296  
297   if (!mySClassMap.IsBound(aSolid)) {
298     //
299     pSC=(BRepClass3d_SolidClassifier*)myAllocator->Allocate(sizeof(BRepClass3d_SolidClassifier));
300     new (pSC) BRepClass3d_SolidClassifier(aSolid);
301     //
302     anAdr=(Standard_Address)pSC;
303     mySClassMap.Bind(aSolid, anAdr);
304   }
305   
306   else {
307     anAdr=mySClassMap.Find(aSolid);
308     pSC =(BRepClass3d_SolidClassifier*)anAdr;
309   }
310   return *pSC;
311 }
312
313 //=======================================================================
314 //function : Hatcher
315 //purpose  : 
316 //=======================================================================
317 Geom2dHatch_Hatcher& IntTools_Context::Hatcher(const TopoDS_Face& aF)
318 {
319   Standard_Address anAdr;
320   Geom2dHatch_Hatcher* pHatcher;
321   //
322   if (!myHatcherMap.IsBound(aF)) {
323     Standard_Real aTolArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
324     Standard_Real aU1, aU2, aEpsT;
325     TopAbs_Orientation aOrE;
326     Handle(Geom_Surface) aS;
327     Handle(Geom2d_Curve) aC2D;
328     Handle(Geom2d_TrimmedCurve) aCT2D;
329     TopoDS_Face aFF;
330     TopExp_Explorer aExp;
331     //
332     aTolHatch2D=1.e-8;
333     aTolHatch3D=1.e-8;
334     aTolArcIntr=1.e-10;
335     aTolTangfIntr=1.e-10;
336     aEpsT=Precision::PConfusion();
337     //
338     Geom2dHatch_Intersector aIntr(aTolArcIntr, aTolTangfIntr);
339     pHatcher=new Geom2dHatch_Hatcher(aIntr,
340                                      aTolHatch2D, aTolHatch3D,
341                                      Standard_True, Standard_False);
342     
343     //
344     aFF=aF;
345     aFF.Orientation(TopAbs_FORWARD);
346     aS=BRep_Tool::Surface(aFF);
347
348     aExp.Init (aFF, TopAbs_EDGE);
349     for (; aExp.More() ; aExp.Next()) {
350       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
351       aOrE=aE.Orientation();
352       //
353       aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
354       if (aC2D.IsNull() ) {
355         continue;
356       }
357       if (fabs(aU1-aU2) < aEpsT) {
358         continue;
359       }
360       //
361       aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
362       pHatcher->AddElement(aCT2D, aOrE);
363     }// for (; aExp.More() ; aExp.Next()) {
364     //
365     anAdr=(Standard_Address)pHatcher;
366     myHatcherMap.Bind(aFF, anAdr);
367   }//if (!myHatcherMap.IsBound(aF)) {
368   //
369   else {
370     anAdr=myHatcherMap.Find(aF);
371     pHatcher=(Geom2dHatch_Hatcher*)anAdr;
372   }
373
374   return *pHatcher;
375 }
376
377 //=======================================================================
378 //function : SurfaceData
379 //purpose  : 
380 //=======================================================================
381 IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData
382   (const TopoDS_Face& aF) 
383 {
384   Standard_Address anAdr;
385   IntTools_SurfaceRangeLocalizeData* pSData;
386   //
387   if (!myProjSDataMap.IsBound(aF)) {
388     pSData=new IntTools_SurfaceRangeLocalizeData
389       (3, 
390        3, 
391        10. * Precision::PConfusion(), 
392        10. * Precision::PConfusion());
393     //
394     anAdr=(Standard_Address)pSData;
395     myProjSDataMap.Bind(aF, anAdr);
396   }
397   
398   else {
399     anAdr=myProjSDataMap.Find(aF);
400     pSData=(IntTools_SurfaceRangeLocalizeData*)anAdr;
401   }
402   return *pSData;
403
404 }
405
406 //=======================================================================
407 //function : ComputePE
408 //purpose  : 
409 //=======================================================================
410 Standard_Integer IntTools_Context::ComputePE
411   (const gp_Pnt& aP1,
412    const Standard_Real aTolP1,
413    const TopoDS_Edge& aE2,
414    Standard_Real& aT)
415 {
416   if (!BRep_Tool::IsGeometric(aE2)) { 
417     return -2;
418   }
419   Standard_Real aDist, aTolE2, aTolSum;
420   Standard_Integer aNbProj;
421   //
422   GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
423   aProjector.Perform(aP1);
424
425   aNbProj=aProjector.NbPoints();
426   if (!aNbProj) {
427     return -3;
428   }
429   //
430   aDist=aProjector.LowerDistance();
431   //
432   aTolE2=BRep_Tool::Tolerance(aE2);
433   aTolSum=aTolP1+aTolE2;
434   //
435   aT=aProjector.LowerDistanceParameter();
436   if (aDist > aTolSum) {
437     return -4;
438   }
439   return 0;
440 }
441 //=======================================================================
442 //function : ComputeVE
443 //purpose  : 
444 //=======================================================================
445 Standard_Integer IntTools_Context::ComputeVE
446   (const TopoDS_Vertex& aV1, 
447    const TopoDS_Edge&   aE2,
448    Standard_Real& aT)
449 {
450   if (BRep_Tool::Degenerated(aE2)) {
451     return -1;
452   }
453   if (!BRep_Tool::IsGeometric(aE2)) { 
454     return -2;
455   }
456   Standard_Real aDist, aTolV1, aTolE2, aTolSum;
457   Standard_Integer aNbProj;
458   gp_Pnt aP;
459   //
460   aP=BRep_Tool::Pnt(aV1);
461   //
462   GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
463   aProjector.Perform(aP);
464
465   aNbProj=aProjector.NbPoints();
466   if (!aNbProj) {
467     return -3;
468   }
469   //
470   aDist=aProjector.LowerDistance();
471
472   // tolerance of check for coincidence is sum of tolerances of edge and vertex 
473   // extended by additional Precision::Confusion() to allow for interference where
474   // it is very close but not fit to tolerance (see #24108)
475   aTolV1=BRep_Tool::Tolerance(aV1);
476   aTolE2=BRep_Tool::Tolerance(aE2);
477   aTolSum = aTolV1 + aTolE2 + Precision::Confusion();
478   //
479   aT=aProjector.LowerDistanceParameter();
480   if (aDist > aTolSum) {
481     return -4;
482   }
483   return 0;
484 }
485 //=======================================================================
486 //function : ComputeVS
487 //purpose  : 
488 //=======================================================================
489 Standard_Integer IntTools_Context::ComputeVF
490   (const TopoDS_Vertex& aV1, 
491    const TopoDS_Face&   aF2,
492    Standard_Real& U,
493    Standard_Real& V)
494 {
495   Standard_Real aTolV1, aTolF2, aTolSum, aDist;
496   gp_Pnt aP;
497
498   aP=BRep_Tool::Pnt(aV1);
499   //
500   // 1. Check if the point is projectable on the surface
501   GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2);
502   aProjector.Perform(aP);
503   //
504   if (!aProjector.IsDone()) { // the point is not  projectable on the surface
505     return -1;
506   }
507   //
508   // 2. Check the distance between the projection point and 
509   //    the original point
510   aDist=aProjector.LowerDistance();
511
512   aTolV1=BRep_Tool::Tolerance(aV1);
513   aTolF2=BRep_Tool::Tolerance(aF2);
514   aTolSum=aTolV1+aTolF2;
515   if (aDist > aTolSum) {
516     // the distance is too large
517     return -2;
518   }
519   aProjector.LowerDistanceParameters(U, V);
520   //
521   gp_Pnt2d aP2d(U, V);
522   Standard_Boolean pri=IsPointInFace (aF2, aP2d);
523   if (!pri) {//  the point lays on the surface but out of the face 
524     return -3;
525   }
526   return 0;
527 }
528 //=======================================================================
529 //function : StatePointFace
530 //purpose  : 
531 //=======================================================================
532 TopAbs_State IntTools_Context::StatePointFace
533   (const TopoDS_Face& aF,
534    const gp_Pnt2d& aP2d)
535 {
536   TopAbs_State aState;
537   IntTools_FClass2d& aClass2d=FClass2d(aF);
538   aState=aClass2d.Perform(aP2d);
539   return aState;
540 }
541 //=======================================================================
542 //function : IsPointInFace
543 //purpose  : 
544 //=======================================================================
545 Standard_Boolean IntTools_Context::IsPointInFace
546   (const TopoDS_Face& aF,
547    const gp_Pnt2d& aP2d)
548 {
549   TopAbs_State aState=StatePointFace(aF, aP2d);
550   if (aState==TopAbs_OUT || aState==TopAbs_ON) {
551     return Standard_False;
552   }
553   return Standard_True;
554 }
555 //=======================================================================
556 //function : IsPointInFace
557 //purpose  : 
558 //=======================================================================
559 Standard_Boolean IntTools_Context::IsPointInFace
560   (const gp_Pnt& aP,
561    const TopoDS_Face& aF,
562    const Standard_Real aTol) 
563 {
564   Standard_Boolean bIn;
565   Standard_Real aDist;
566   //
567   GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
568   aProjector.Perform(aP);
569   //
570   bIn = aProjector.IsDone();
571   if (bIn) {
572     aDist = aProjector.LowerDistance();
573     if (aDist < aTol) {
574       Standard_Real U, V;
575       //
576       aProjector.LowerDistanceParameters(U, V);
577       gp_Pnt2d aP2D(U, V);
578       bIn = IsPointInFace(aF, aP2D);
579     }
580   }
581   //
582   return bIn;
583 }
584 //=======================================================================
585 //function : IsPointInOnFace
586 //purpose  : 
587 //=======================================================================
588   Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
589                                                    const gp_Pnt2d& aP2d)
590
591   TopAbs_State aState=StatePointFace(aF, aP2d);
592   if (aState==TopAbs_OUT) {
593     return Standard_False;
594   }
595   return Standard_True;
596 }
597 //=======================================================================
598 //function : IsValidPointForFace
599 //purpose  : 
600 //=======================================================================
601 Standard_Boolean IntTools_Context::IsValidPointForFace
602   (const gp_Pnt& aP,
603    const TopoDS_Face& aF,
604    const Standard_Real aTol) 
605 {
606   Standard_Boolean bFlag;
607   Standard_Real Umin, U, V;
608
609   GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
610   aProjector.Perform(aP);
611   
612   bFlag=aProjector.IsDone();
613   if (bFlag) {
614     
615     Umin=aProjector.LowerDistance();
616     //if (Umin > 1.e-3) { // it was 
617     if (Umin > aTol) {
618       return !bFlag; 
619     }
620     //
621     aProjector.LowerDistanceParameters(U, V);
622     gp_Pnt2d aP2D(U, V);
623     bFlag=IsPointInOnFace (aF, aP2D);
624   }
625   return bFlag;
626 }
627 //=======================================================================
628 //function : IsValidPointForFaces
629 //purpose  : 
630 //=======================================================================
631 Standard_Boolean IntTools_Context::IsValidPointForFaces 
632   (const gp_Pnt& aP,
633    const TopoDS_Face& aF1,
634    const TopoDS_Face& aF2,
635    const Standard_Real aTol) 
636 {
637   Standard_Boolean bFlag1, bFlag2;
638
639   bFlag1=IsValidPointForFace(aP, aF1, aTol);
640   if (!bFlag1) {
641     return bFlag1;
642   }
643   bFlag2=IsValidPointForFace(aP, aF2, aTol);  
644   return  bFlag2;
645 }
646 //=======================================================================
647 //function : IsValidBlockForFace
648 //purpose  : 
649 //=======================================================================
650 Standard_Boolean IntTools_Context::IsValidBlockForFace 
651   (const Standard_Real aT1,
652    const Standard_Real aT2,
653    const IntTools_Curve& aC, 
654    const TopoDS_Face& aF,
655    const Standard_Real aTol) 
656 {
657   Standard_Boolean bFlag;
658   Standard_Real aTInterm;
659   gp_Pnt aPInterm;
660
661   aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
662
663   Handle(Geom_Curve) aC3D=aC.Curve();
664   // point 3D
665   aC3D->D0(aTInterm, aPInterm);
666   //
667   bFlag=IsValidPointForFace (aPInterm, aF, aTol);
668   return bFlag;
669 }
670 //=======================================================================
671 //function : IsValidBlockForFaces
672 //purpose  : 
673 //=======================================================================
674 Standard_Boolean IntTools_Context::IsValidBlockForFaces 
675   (const Standard_Real aT1,
676    const Standard_Real aT2,
677    const IntTools_Curve& aC, 
678    const TopoDS_Face& aF1,
679    const TopoDS_Face& aF2,
680    const Standard_Real aTol) 
681 {
682   Standard_Boolean bFlag1, bFlag2;
683   //
684   Handle(Geom2d_Curve) aPC1 = aC.FirstCurve2d();
685   Handle(Geom2d_Curve) aPC2 = aC.SecondCurve2d();
686   if( !aPC1.IsNull() && !aPC2.IsNull() ) {
687     Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(aT1, aT2);
688     gp_Pnt2d aPnt2D;
689
690
691     aPC1->D0(aMidPar, aPnt2D);
692     bFlag1 = IsPointInOnFace(aF1, aPnt2D);
693
694     if( !bFlag1 )
695       return bFlag1;
696
697     aPC2->D0(aMidPar, aPnt2D);
698     bFlag2 = IsPointInOnFace(aF2, aPnt2D);
699     return bFlag2;
700   }
701   //
702
703   bFlag1=IsValidBlockForFace (aT1, aT2, aC, aF1, aTol);
704   if (!bFlag1) {
705     return bFlag1;
706   }
707   bFlag2=IsValidBlockForFace (aT1, aT2, aC, aF2, aTol);
708   return bFlag2;
709 }
710 //=======================================================================
711 //function : IsVertexOnLine
712 //purpose  : 
713 //=======================================================================
714 Standard_Boolean IntTools_Context::IsVertexOnLine 
715   (const TopoDS_Vertex& aV,
716    const IntTools_Curve& aC, 
717    const Standard_Real aTolC,
718    Standard_Real& aT)
719 {
720   Standard_Boolean bRet;
721   Standard_Real aTolV;
722   //
723   aTolV=BRep_Tool::Tolerance(aV);
724   bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
725   //
726   return bRet;
727 }
728 //=======================================================================
729 //function : IsVertexOnLine
730 //purpose  : 
731 //=======================================================================
732 Standard_Boolean IntTools_Context::IsVertexOnLine 
733   (const TopoDS_Vertex& aV,
734    const Standard_Real aTolV,
735    const IntTools_Curve& aC, 
736    const Standard_Real aTolC,
737    Standard_Real& aT)
738 {
739   Standard_Real aFirst, aLast, aDist, aTolSum;
740   Standard_Integer aNbProj;
741   gp_Pnt aPv; 
742   
743   aPv=BRep_Tool::Pnt(aV);
744
745   Handle(Geom_Curve) aC3D=aC.Curve();
746   
747   
748   aTolSum=aTolV+aTolC;
749   //
750   GeomAdaptor_Curve aGAC(aC3D);
751   GeomAbs_CurveType aType=aGAC.GetType();
752   if (aType==GeomAbs_BSplineCurve ||
753       aType==GeomAbs_BezierCurve) {
754     aTolSum=2.*aTolSum;
755     if (aTolSum<1.e-5) {
756       aTolSum=1.e-5;
757     }
758   }
759   else {
760     aTolSum=2.*aTolSum;//xft
761     if(aTolSum < 1.e-6)
762       aTolSum = 1.e-6;
763   }
764   //
765   aFirst=aC3D->FirstParameter();
766   aLast =aC3D->LastParameter();
767   //
768   //Checking extermities first
769   if (!Precision::IsInfinite(aFirst)) {
770     gp_Pnt aPCFirst=aC3D->Value(aFirst);
771     aDist=aPv.Distance(aPCFirst);
772     if (aDist < aTolSum) {
773       aT=aFirst;
774       //
775       if(aDist > aTolV) {
776         Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
777         
778         if(anExt.IsDone()) {
779           Extrema_POnCurv aPOncurve = anExt.Point();
780           aT = aPOncurve.Parameter();
781           
782           if((aT > (aLast + aFirst) * 0.5) ||
783              (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
784              (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
785             aT = aFirst;
786         }
787       }
788       //
789       return Standard_True;
790     }
791   }
792   //
793   //if (!Precision::IsInfinite(aFirst)) {
794   if (!Precision::IsInfinite(aLast)) {
795     gp_Pnt aPCLast=aC3D->Value(aLast);
796     aDist=aPv.Distance(aPCLast);
797     if (aDist < aTolSum) {
798       aT=aLast;
799       //
800       if(aDist > aTolV) {
801         Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
802         
803         if(anExt.IsDone()) {
804           Extrema_POnCurv aPOncurve = anExt.Point();
805           aT = aPOncurve.Parameter();
806           
807           if((aT < (aLast + aFirst) * 0.5) ||
808              (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
809              (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
810             aT = aLast;
811         }
812       }
813       //
814       return Standard_True;
815     }
816   }
817   //
818   GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
819   aProjector.Perform(aPv);
820   
821   aNbProj=aProjector.NbPoints();
822   if (!aNbProj) {
823     Handle(Geom_BoundedCurve) aBC=
824       Handle(Geom_BoundedCurve)::DownCast(aC3D);
825     if (!aBC.IsNull()) {
826       gp_Pnt aPStart=aBC->StartPoint();
827       gp_Pnt aPEnd  =aBC->EndPoint();
828       
829       aDist=aPv.Distance(aPStart);
830       if (aDist < aTolSum) {
831         aT=aFirst;
832         return Standard_True;
833       }
834       
835       aDist=aPv.Distance(aPEnd);
836       if (aDist < aTolSum) {
837         aT=aLast;
838         return Standard_True;
839       }
840     }
841     
842     return Standard_False;
843   }
844   
845   aDist=aProjector.LowerDistance();
846   
847   if (aDist > aTolSum) {
848     return Standard_False;
849   }
850
851   aT=aProjector.LowerDistanceParameter();
852
853   return Standard_True; 
854 }
855 //=======================================================================
856 //function : ProjectPointOnEdge
857 //purpose  : 
858 //=======================================================================
859 Standard_Boolean IntTools_Context::ProjectPointOnEdge
860   (const gp_Pnt& aP,
861    const TopoDS_Edge& anEdge,
862    Standard_Real& aT)
863 {
864   Standard_Integer aNbPoints;
865
866   GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
867   aProjector.Perform(aP);
868
869   aNbPoints=aProjector.NbPoints();
870   if (aNbPoints) {
871     aT=aProjector.LowerDistanceParameter();
872     return Standard_True;
873   }
874   return Standard_False;
875 }
876