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