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