0022653: Bad performance of Open CASCADE libraries that are used by Partition Algorit...
[occt.git] / src / IntTools / IntTools_Context.cxx
1 // File:        IntTools_Context.cxx
2 // Created:     Wed Apr  3 16:57:54 2002
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <IntTools_Context.ixx>
8
9 #include <Precision.hxx>
10
11 #include <Geom_Curve.hxx>
12 #include <Geom_BoundedCurve.hxx>
13 #include <GeomAPI_ProjectPointOnCurve.hxx>
14 #include <GeomAPI_ProjectPointOnSurf.hxx>
15 #include <GeomAdaptor_Curve.hxx>
16
17 #include <TopAbs_State.hxx>
18 #include <TopoDS.hxx>
19 #include <TopExp_Explorer.hxx>
20
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23
24 #include <IntTools_Tools.hxx>
25 #include <IntTools_FClass2d.hxx>
26 // 
27 #include <Extrema_LocateExtPC.hxx>
28
29 #include <Geom2d_Curve.hxx>
30
31 //=======================================================================
32 //function : 
33 //purpose  : 
34 //=======================================================================
35   IntTools_Context::IntTools_Context()
36 {
37 }
38 //=======================================================================
39 //function : ~
40 //purpose  : 
41 //=======================================================================
42   IntTools_Context::~IntTools_Context()
43 {
44   Standard_Address anAdr;
45   Standard_Integer i, aNb;
46   //
47   IntTools_FClass2d* pFClass2d;
48   aNb=myFClass2dMap.Extent();
49   for (i=1; i<=aNb; ++i) {
50     anAdr=myFClass2dMap(i);
51     pFClass2d=(IntTools_FClass2d*)anAdr;
52     delete pFClass2d;
53   }
54   myFClass2dMap.Clear();
55   //
56   GeomAPI_ProjectPointOnSurf* pProjPS;
57   aNb=myProjPSMap.Extent();
58   for (i=1; i<=aNb; ++i) {
59     anAdr=myProjPSMap(i);
60     pProjPS=(GeomAPI_ProjectPointOnSurf*)anAdr;
61     delete pProjPS;
62   }
63   myProjPSMap.Clear();
64   //
65   GeomAPI_ProjectPointOnCurve* pProjPC;
66   aNb=myProjPCMap.Extent();
67   for (i=1; i<=aNb; ++i) {
68     anAdr=myProjPCMap(i);
69     pProjPC=(GeomAPI_ProjectPointOnCurve*)anAdr;
70     delete pProjPC;
71   }
72   myProjPCMap.Clear();
73   //
74   GeomAPI_ProjectPointOnCurve* pProjPT;
75   aNb=myProjPTMap.Extent();
76   for (i=1; i<=aNb; ++i) {
77     anAdr=myProjPTMap(i);
78     pProjPT=(GeomAPI_ProjectPointOnCurve*)anAdr;
79     delete pProjPT;
80   }
81   myProjPTMap.Clear();
82   //
83   BRepClass3d_SolidClassifier* pSC;
84   aNb=mySClassMap.Extent();
85   for (i=1; i<=aNb; ++i) {
86     anAdr=mySClassMap(i);
87     pSC=(BRepClass3d_SolidClassifier*)anAdr;
88     delete pSC;
89   }
90   mySClassMap.Clear();
91   //
92   IntTools_SurfaceRangeLocalizeData* pSData = NULL;
93   aNb = myProjSDataMap.Extent();
94   for (i=1; i<=aNb; ++i) {
95     anAdr=myProjSDataMap(i);
96     pSData = (IntTools_SurfaceRangeLocalizeData*)anAdr;
97     if(pSData)
98       delete pSData;
99     pSData = NULL;
100   }
101   myProjSDataMap.Clear();
102 }
103 //=======================================================================
104 //function : FClass2d
105 //purpose  : 
106 //=======================================================================
107   IntTools_FClass2d& IntTools_Context::FClass2d(const TopoDS_Face& aF)
108 {
109   Standard_Address anAdr;
110   IntTools_FClass2d* pFClass2d;
111   //
112   anAdr=myFClass2dMap.FindFromKey1(aF);
113   if (!anAdr) {
114     Standard_Real aTolF;
115     TopoDS_Face aFF=aF;
116     aFF.Orientation(TopAbs_FORWARD);
117     aTolF=BRep_Tool::Tolerance(aFF);
118     //
119     pFClass2d=new IntTools_FClass2d(aFF, aTolF);
120     //
121     anAdr=(Standard_Address)pFClass2d;
122     myFClass2dMap.Add(aFF, anAdr);
123   }
124
125   else {
126     Standard_Address *pAdr=(Standard_Address *)anAdr;
127     pFClass2d=(IntTools_FClass2d*)*pAdr;
128   }
129
130   return *pFClass2d;
131 }
132 //=======================================================================
133 //function : ProjPS
134 //purpose  : 
135 //=======================================================================
136   GeomAPI_ProjectPointOnSurf& IntTools_Context::ProjPS(const TopoDS_Face& aF)
137 {
138   Standard_Address anAdr;
139   GeomAPI_ProjectPointOnSurf* pProjPS;
140   //
141   anAdr=myProjPSMap.FindFromKey1(aF);
142   if (!anAdr) {
143     Standard_Real Umin, Usup, Vmin, Vsup, anEpsT=1.e-12 ;
144     BRepAdaptor_Surface aBAS;
145     //
146     const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
147     aBAS.Initialize (aF, Standard_True);
148     //
149     Umin=aBAS.FirstUParameter();
150     Usup=aBAS.LastUParameter ();
151     Vmin=aBAS.FirstVParameter();
152     Vsup=aBAS.LastVParameter ();
153     //
154     pProjPS=new GeomAPI_ProjectPointOnSurf;
155     pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT);
156     //
157     anAdr=(Standard_Address)pProjPS;
158     myProjPSMap.Add(aF, anAdr);
159   }
160   
161   else {
162     Standard_Address *pAdr=(Standard_Address *)anAdr;
163     pProjPS=(GeomAPI_ProjectPointOnSurf*)*pAdr;
164   }
165   return *pProjPS;
166 }
167 //=======================================================================
168 //function : ProjPC
169 //purpose  : 
170 //=======================================================================
171   GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPC(const TopoDS_Edge& aE)
172 {
173   Standard_Address anAdr;
174   GeomAPI_ProjectPointOnCurve* pProjPC;
175   //
176   anAdr=myProjPCMap.FindFromKey1(aE);
177   if (!anAdr) {
178     Standard_Real f, l;
179     //
180     Handle(Geom_Curve)aC3D=BRep_Tool::Curve (aE, f, l);
181     //
182     pProjPC=new GeomAPI_ProjectPointOnCurve;
183     pProjPC->Init(aC3D, f, l);
184     //
185     anAdr=(Standard_Address)pProjPC;
186     myProjPCMap.Add(aE, anAdr);
187   }
188   else {
189     Standard_Address *pAdr=(Standard_Address *)anAdr;
190     pProjPC=(GeomAPI_ProjectPointOnCurve*)*pAdr;
191   }
192   return *pProjPC;
193 }
194 //=======================================================================
195 //function : ProjPT
196 //purpose  : 
197 //=======================================================================
198   GeomAPI_ProjectPointOnCurve& IntTools_Context::ProjPT(const Handle(Geom_Curve)& aC3D)
199                                                         
200 {
201   Standard_Address anAdr;
202   GeomAPI_ProjectPointOnCurve* pProjPT;
203   //
204   anAdr=myProjPTMap.FindFromKey1(aC3D);
205   if (!anAdr) {
206     Standard_Real f, l;
207     f=aC3D->FirstParameter();
208     l=aC3D->LastParameter();
209     //
210     pProjPT=new GeomAPI_ProjectPointOnCurve;
211     pProjPT->Init(aC3D, f, l);
212     //
213     anAdr=(Standard_Address)pProjPT;
214     myProjPTMap.Add(aC3D, anAdr);
215   }
216   
217   else {
218     Standard_Address *pAdr=(Standard_Address *)anAdr;
219     pProjPT=(GeomAPI_ProjectPointOnCurve*)*pAdr;
220   }
221   return *pProjPT;
222 }
223 //=======================================================================
224 //function : SurfaceData
225 //purpose  : 
226 //=======================================================================
227   IntTools_SurfaceRangeLocalizeData& IntTools_Context::SurfaceData(const TopoDS_Face& aF) 
228 {
229   Standard_Address anAdr;
230   IntTools_SurfaceRangeLocalizeData* pSData;
231   //
232   anAdr=myProjSDataMap.FindFromKey1(aF);
233   if (!anAdr) {
234     //
235     pSData=new IntTools_SurfaceRangeLocalizeData(3, 
236                                                  3, 
237                                                  10. * Precision::PConfusion(), 
238                                                  10. * Precision::PConfusion());
239     //
240     anAdr=(Standard_Address)pSData;
241     myProjSDataMap.Add(aF, anAdr);
242   }
243   
244   else {
245     Standard_Address *pAdr=(Standard_Address *)anAdr;
246     pSData=(IntTools_SurfaceRangeLocalizeData*)*pAdr;
247   }
248   return *pSData;
249
250 }
251 //=======================================================================
252 //function : SolidClassifier
253 //purpose  : 
254 //=======================================================================
255   BRepClass3d_SolidClassifier& IntTools_Context::SolidClassifier(const TopoDS_Solid& aSolid)
256 {
257   Standard_Address anAdr;
258   BRepClass3d_SolidClassifier* pSC;
259   //
260   anAdr=mySClassMap.FindFromKey1(aSolid);
261   if (!anAdr) {
262     //
263     pSC=new BRepClass3d_SolidClassifier(aSolid);
264     //
265     anAdr=(Standard_Address)pSC;
266     mySClassMap.Add(aSolid, anAdr);
267   }
268   else {
269     Standard_Address *pAdr=(Standard_Address *)anAdr;
270     pSC =(BRepClass3d_SolidClassifier*)*pAdr;
271   }
272   return *pSC;
273 }
274 //=======================================================================
275 //function : ComputeVE
276 //purpose  : 
277 //=======================================================================
278   Standard_Integer IntTools_Context::ComputeVE(const TopoDS_Vertex& aV1, 
279                                                const TopoDS_Edge&   aE2,
280                                                Standard_Real& aT)
281 {
282   Standard_Boolean bToUpdate;
283   Standard_Integer iFlag;
284   Standard_Real aDist;
285   //
286   iFlag= IntTools_Context::ComputeVE(aV1, aE2, aT, bToUpdate, aDist);
287   //
288   return iFlag;
289 }
290 //=======================================================================
291 //function : ComputeVE
292 //purpose  : 
293 //=======================================================================
294   Standard_Integer IntTools_Context::ComputeVE(const TopoDS_Vertex& aV1, 
295                                                const TopoDS_Edge&   aE2,
296                                                Standard_Real& aT,
297                                                Standard_Boolean& bToUpdateVertex, 
298                                                Standard_Real& aDist)
299 {
300   bToUpdateVertex=Standard_False;
301   aDist=0.;
302   //
303   if (BRep_Tool::Degenerated(aE2)) {
304     return -1;
305   }
306   //
307   //modified by NIZNHY-PKV Wed Jul 13 08:30:08 2011f
308   //if (!BRep_Tool::IsGeometric(aE2)) { 
309   //  return -2;
310   //}
311   //modified by NIZNHY-PKV Wed Jul 13 08:30:13 2011t
312   //
313   Standard_Real aTolV1, aTolE2, aTolSum, aTolVx;
314   Standard_Integer aNbProj;
315   gp_Pnt aP;
316   //
317   aP=BRep_Tool::Pnt(aV1);
318   //
319   GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
320   aProjector.Perform(aP);
321   aNbProj=aProjector.NbPoints();
322   if (!aNbProj) {
323     return -3;
324   }
325   //
326   aDist=aProjector.LowerDistance();
327   aTolV1=BRep_Tool::Tolerance(aV1);
328   aTolE2=BRep_Tool::Tolerance(aE2);
329   aTolSum=aTolV1+aTolE2;
330   //
331   aT=aProjector.LowerDistanceParameter();
332   if (aDist > aTolSum) {
333     return -4;
334   }
335   //
336   aTolVx=aDist+aTolE2;
337   if (aTolVx>aTolV1) {
338     bToUpdateVertex=!bToUpdateVertex;
339     aDist=aTolVx;
340   }
341   //
342   return 0;
343 }
344 //=======================================================================
345 //function : ComputeVS
346 //purpose  : 
347 //=======================================================================
348   Standard_Integer IntTools_Context::ComputeVS(const TopoDS_Vertex& aV1, 
349                                                const TopoDS_Face&   aF2,
350                                                Standard_Real& U,
351                                                Standard_Real& V)
352 {
353   Standard_Real aTolV1, aTolF2, aTolSum, aDist;
354   gp_Pnt aP;
355
356   aP=BRep_Tool::Pnt(aV1);
357   //
358   // 1. Check if the point is projectable on the surface
359   GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2);
360   aProjector.Perform(aP);
361   //
362   if (!aProjector.IsDone()) {
363     // the point is not  projectable on the surface
364     return -1;
365   }
366   //
367   // 2. Check the distance between the projection point and 
368   //    the original point
369   aDist=aProjector.LowerDistance();
370
371   aTolV1=BRep_Tool::Tolerance(aV1);
372   aTolF2=BRep_Tool::Tolerance(aF2);
373   aTolSum=aTolV1+aTolF2;
374   if (aDist > aTolSum) {
375     // the distance is too large
376     return -2;
377   }
378   aProjector.LowerDistanceParameters(U, V);
379   //
380   gp_Pnt2d aP2d(U, V);
381   Standard_Boolean pri=IsPointInFace (aF2, aP2d);
382   if (!pri) {
383     //  the point lays on the surface but out of the face 
384     return -3;
385   }
386   return 0;
387 }
388 //=======================================================================
389 //function : StatePointFace
390 //purpose  : 
391 //=======================================================================
392   TopAbs_State IntTools_Context::StatePointFace(const TopoDS_Face& aF,
393                                                 const gp_Pnt2d& aP2d)
394 {
395   TopAbs_State aState;
396   IntTools_FClass2d& aClass2d=FClass2d(aF);
397   aState=aClass2d.Perform(aP2d);
398   return aState;
399 }
400 //=======================================================================
401 //function : IsPointInFace
402 //purpose  : 
403 //=======================================================================
404   Standard_Boolean IntTools_Context::IsPointInFace(const TopoDS_Face& aF,
405                                                    const gp_Pnt2d& aP2d)
406 {
407   TopAbs_State aState=StatePointFace(aF, aP2d);
408   if (aState==TopAbs_OUT || aState==TopAbs_ON) {
409     return Standard_False;
410   }
411   return Standard_True;
412 }
413 //=======================================================================
414 //function : IsPointInOnFace
415 //purpose  : 
416 //=======================================================================
417   Standard_Boolean IntTools_Context::IsPointInOnFace(const TopoDS_Face& aF,
418                                                      const gp_Pnt2d& aP2d)
419
420   TopAbs_State aState=StatePointFace(aF, aP2d);
421   if (aState==TopAbs_OUT) {
422     return Standard_False;
423   }
424   return Standard_True;
425 }
426 //=======================================================================
427 //function : IsValidPointForFace
428 //purpose  : 
429 //=======================================================================
430   Standard_Boolean IntTools_Context::IsValidPointForFace(const gp_Pnt& aP,
431                                                          const TopoDS_Face& aF,
432                                                          const Standard_Real aTol) 
433 {
434   Standard_Boolean bFlag;
435   Standard_Real Umin, myEpsT, U, V;
436   myEpsT=1.e-12;
437
438   GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF);
439   aProjector.Perform(aP);
440   
441   bFlag=aProjector.IsDone();
442   if (bFlag) {
443     
444     Umin=aProjector.LowerDistance();
445     //if (Umin > 1.e-3) { // it was 
446     if (Umin > aTol) {
447       return !bFlag; 
448     }
449     //
450     aProjector.LowerDistanceParameters(U, V);
451     gp_Pnt2d aP2D(U, V);
452     bFlag=IsPointInOnFace (aF, aP2D);
453   }
454   return bFlag;
455 }
456 //=======================================================================
457 //function : IsValidPointForFaces
458 //purpose  : 
459 //=======================================================================
460   Standard_Boolean IntTools_Context::IsValidPointForFaces (const gp_Pnt& aP,
461                                                            const TopoDS_Face& aF1,
462                                                            const TopoDS_Face& aF2,
463                                                            const Standard_Real aTol) 
464 {
465   Standard_Boolean bFlag1, bFlag2;
466
467   bFlag1=IsValidPointForFace(aP, aF1, aTol);
468   if (!bFlag1) {
469     return bFlag1;
470   }
471   bFlag2=IsValidPointForFace(aP, aF2, aTol);  
472   return  bFlag2;
473 }
474 //=======================================================================
475 //function : IsValidBlockForFace
476 //purpose  : 
477 //=======================================================================
478   Standard_Boolean IntTools_Context::IsValidBlockForFace (const Standard_Real aT1,
479                                                           const Standard_Real aT2,
480                                                           const IntTools_Curve& aC, 
481                                                           const TopoDS_Face& aF,
482                                                           const Standard_Real aTol) 
483 {
484   Standard_Boolean bFlag;
485   Standard_Real aTInterm, aFirst, aLast;
486   gp_Pnt aPInterm;
487
488   aTInterm=IntTools_Tools::IntermediatePoint(aT1, aT2);
489
490   Handle(Geom_Curve) aC3D=aC.Curve();
491   aFirst=aC3D->FirstParameter();
492   aLast =aC3D->LastParameter();
493   // point 3D
494   aC3D->D0(aTInterm, aPInterm);
495   //
496   bFlag=IsValidPointForFace (aPInterm, aF, aTol);
497   return bFlag;
498 }
499 //=======================================================================
500 //function : IsValidBlockForFaces
501 //purpose  : 
502 //=======================================================================
503   Standard_Boolean IntTools_Context::IsValidBlockForFaces (const Standard_Real aT1,
504                                                            const Standard_Real aT2,
505                                                            const IntTools_Curve& aC, 
506                                                            const TopoDS_Face& aF1,
507                                                            const TopoDS_Face& aF2,
508                                                            const Standard_Real aTol) 
509 {
510   Standard_Boolean bFlag1, bFlag2;
511   //
512   Handle(Geom2d_Curve) aPC1 = aC.FirstCurve2d();
513   Handle(Geom2d_Curve) aPC2 = aC.SecondCurve2d();
514   if( !aPC1.IsNull() && !aPC2.IsNull() ) {
515     Standard_Real aMidPar = IntTools_Tools::IntermediatePoint(aT1, aT2);
516     gp_Pnt2d aPnt2D;
517
518
519     aPC1->D0(aMidPar, aPnt2D);
520     bFlag1 = IsPointInOnFace(aF1, aPnt2D);
521
522     if( !bFlag1 )
523       return bFlag1;
524
525     aPC2->D0(aMidPar, aPnt2D);
526     bFlag2 = IsPointInOnFace(aF2, aPnt2D);
527     return bFlag2;
528   }
529   //
530
531   bFlag1=IsValidBlockForFace (aT1, aT2, aC, aF1, aTol);
532   if (!bFlag1) {
533     return bFlag1;
534   }
535   bFlag2=IsValidBlockForFace (aT1, aT2, aC, aF2, aTol);
536   return bFlag2;
537 }
538 //=======================================================================
539 //function : IsVertexOnLine
540 //purpose  : 
541 //=======================================================================
542   Standard_Boolean IntTools_Context::IsVertexOnLine (const TopoDS_Vertex& aV,
543                                                      const IntTools_Curve& aC, 
544                                                      const Standard_Real aTolC,
545                                                      Standard_Real& aT)
546 {
547   Standard_Boolean bRet;
548   Standard_Real aTolV;
549   //
550   aTolV=BRep_Tool::Tolerance(aV);
551   bRet=IntTools_Context::IsVertexOnLine(aV, aTolV, aC, aTolC , aT);
552   //
553   return bRet;
554 }
555 //=======================================================================
556 //function : IsVertexOnLine
557 //purpose  : 
558 //=======================================================================
559   Standard_Boolean IntTools_Context::IsVertexOnLine (const TopoDS_Vertex& aV,
560                                                      const Standard_Real aTolV,
561                                                      const IntTools_Curve& aC, 
562                                                      const Standard_Real aTolC,
563                                                      Standard_Real& aT)
564 {
565   Standard_Real aFirst, aLast, aDist, aTolSum;
566   Standard_Integer aNbProj;
567   gp_Pnt aPv; 
568   
569   aPv=BRep_Tool::Pnt(aV);
570
571   Handle(Geom_Curve) aC3D=aC.Curve();
572   
573   
574   aTolSum=aTolV+aTolC;
575   //
576   GeomAdaptor_Curve aGAC(aC3D);
577   GeomAbs_CurveType aType=aGAC.GetType();
578   if (aType==GeomAbs_BSplineCurve ||
579       aType==GeomAbs_BezierCurve) {
580     aTolSum=2.*aTolSum;
581     if (aTolSum<1.e-5) {
582       aTolSum=1.e-5;
583     }
584   }
585   else {
586     aTolSum=2.*aTolSum;//xft
587     if(aTolSum < 1.e-6)
588       aTolSum = 1.e-6;
589   }
590   //
591   aFirst=aC3D->FirstParameter();
592   aLast =aC3D->LastParameter();
593   //
594   //Checking extermities first
595   if (!Precision::IsInfinite(aFirst)) {
596     gp_Pnt aPCFirst=aC3D->Value(aFirst);
597     aDist=aPv.Distance(aPCFirst);
598     if (aDist < aTolSum) {
599       aT=aFirst;
600       //
601       if(aDist > aTolV) {
602         Extrema_LocateExtPC anExt(aPv, aGAC, aFirst, 1.e-10);
603
604         if(anExt.IsDone()) {
605           Extrema_POnCurv aPOncurve = anExt.Point();
606           aT = aPOncurve.Parameter();
607
608           if((aT > (aLast + aFirst) * 0.5) ||
609              (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
610              (aPCFirst.Distance(aPOncurve.Value()) < Precision::Confusion()))
611             aT = aFirst;
612         }
613       }
614       //
615       return Standard_True;
616     }
617   }
618   //
619   if (!Precision::IsInfinite(aLast)) {
620     gp_Pnt aPCLast=aC3D->Value(aLast);
621     aDist=aPv.Distance(aPCLast);
622     if (aDist < aTolSum) {
623       aT=aLast;
624       //
625       if(aDist > aTolV) {
626         Extrema_LocateExtPC anExt(aPv, aGAC, aLast, 1.e-10);
627
628         if(anExt.IsDone()) {
629           Extrema_POnCurv aPOncurve = anExt.Point();
630           aT = aPOncurve.Parameter();
631
632           if((aT < (aLast + aFirst) * 0.5) ||
633              (aPv.Distance(aPOncurve.Value()) > aTolSum) ||
634              (aPCLast.Distance(aPOncurve.Value()) < Precision::Confusion()))
635             aT = aLast;
636         }
637       }
638       //
639       return Standard_True;
640     }
641   }
642   //
643   GeomAPI_ProjectPointOnCurve& aProjector=ProjPT(aC3D);
644   aProjector.Perform(aPv);
645   
646   aNbProj=aProjector.NbPoints();
647   if (!aNbProj) {
648     Handle(Geom_BoundedCurve) aBC=
649       Handle(Geom_BoundedCurve)::DownCast(aC3D);
650     if (!aBC.IsNull()) {
651       gp_Pnt aPStart=aBC->StartPoint();
652       gp_Pnt aPEnd  =aBC->EndPoint();
653       
654       aDist=aPv.Distance(aPStart);
655       if (aDist < aTolSum) {
656         aT=aFirst;
657         return Standard_True;
658       }
659       
660       aDist=aPv.Distance(aPEnd);
661       if (aDist < aTolSum) {
662         aT=aLast;
663         return Standard_True;
664       }
665     }
666     
667     return Standard_False;
668   }
669   
670   aDist=aProjector.LowerDistance();
671   
672   if (aDist > aTolSum) {
673     return Standard_False;
674   }
675
676   aT=aProjector.LowerDistanceParameter();
677
678   return Standard_True; 
679 }
680 //=======================================================================
681 //function : ProjectPointOnEdge
682 //purpose  : 
683 //=======================================================================
684   Standard_Boolean IntTools_Context::ProjectPointOnEdge(const gp_Pnt& aP,
685                                                         const TopoDS_Edge& anEdge,
686                                                         Standard_Real& aT)
687 {
688   Standard_Integer aNbPoints;
689
690   GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(anEdge);
691   aProjector.Perform(aP);
692
693   aNbPoints=aProjector.NbPoints();
694   if (aNbPoints) {
695     aT=aProjector.LowerDistanceParameter();
696     return Standard_True;
697   }
698   return Standard_False;
699 }
700