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