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