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