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