0024242: Hang-up during classification a 3D point relative to a solid
[occt.git] / src / BRepClass3d / BRepClass3d_SolidExplorer.cxx
1 // Created on: 1994-03-10
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // Modifed:     Porting NT 7-5-97 DPF (stdio.h)
22 //              Apr 16 2002 eap, classification against infinite solid (occ299)
23
24
25 //  Modified by skv - Thu Sep  4 12:29:30 2003 OCC578
26
27 //-- Process the case of a hole!!
28 #define REJECTION 1
29
30 //-- To printf on NT
31 #include <stdio.h>
32
33 #include <BRepClass3d_SolidExplorer.ixx>
34 #include <gp.hxx>
35 #include <TopoDS.hxx>
36 #include <BRepAdaptor_Curve2d.hxx>
37 #include <BRepTools.hxx>
38 #include <Geom2d_Curve.hxx>
39 #include <gp_Vec2d.hxx>
40 #include <GeomAbs_Shape.hxx>
41 #include <BRepAdaptor_Surface.hxx>
42 #include <BRepClass_FacePassiveClassifier.hxx>
43 #include <TopAbs_Orientation.hxx>
44 #include <TopExp_Explorer.hxx>
45 #include <BRepClass_Edge.hxx>
46
47 #include <Bnd_Box.hxx>
48 #include <BRepBndLib.hxx>
49
50 #include <BRepAdaptor_HSurface.hxx>
51
52 #include <ElCLib.hxx>
53
54 #include <BRepClass3d_DataMapIteratorOfMapOfInter.hxx>
55 #include <Precision.hxx>
56 //OCC454(apo)->
57 #include <Extrema_ExtPS.hxx>
58 #include <BRep_Tool.hxx> 
59 #include <BRepClass_FaceClassifier.hxx>
60 //<-OCC454(apo)
61
62 //=======================================================================
63 //function : FindAPointInTheFace
64 //purpose  : Compute a point P in the face  F. Param is a Real in
65 //           ]0,1[ and   is  used to  initialise  the algorithm. For
66 //           different values , different points are returned.
67 //=======================================================================
68
69 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
70 (const TopoDS_Face& _face,
71  gp_Pnt& APoint_,
72  Standard_Real& param_)
73 {
74   Standard_Real u,v;
75   Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v,param_);
76   return r;
77 }
78
79 //=======================================================================
80 //function : FindAPointInTheFace
81 //purpose  : 
82 //=======================================================================
83
84 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
85 (const TopoDS_Face& _face,
86  gp_Pnt& APoint_,
87  Standard_Real& u_, Standard_Real& v_,
88  Standard_Real& param_)
89 {
90   gp_Vec aVecD1U, aVecD1V;
91   return FindAPointInTheFace (_face, APoint_, u_, v_, param_, aVecD1U, aVecD1V);
92 }
93
94 //=======================================================================
95 //function : FindAPointInTheFace
96 //purpose  : 
97 //=======================================================================
98
99 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
100 (const TopoDS_Face& _face,
101  gp_Pnt& APoint_,
102  Standard_Real& u_, Standard_Real& v_,
103  Standard_Real& param_,
104  gp_Vec& theVecD1U,
105  gp_Vec& theVecD1V)
106 {
107   TopoDS_Face face = _face;
108   face.Orientation (TopAbs_FORWARD);
109
110   TopExp_Explorer faceexplorer;
111   BRepAdaptor_Curve2d c;
112   gp_Vec2d T;
113   gp_Pnt2d P;
114
115   for (faceexplorer.Init(face,TopAbs_EDGE); 
116        faceexplorer.More(); 
117        faceexplorer.Next())
118   {
119     TopoDS_Edge Edge = TopoDS::Edge (faceexplorer.Current());
120     c.Initialize (Edge, face);
121     c.D1((c.LastParameter() - c.FirstParameter()) * param_ + c.FirstParameter(),P,T);
122
123     Standard_Real x = T.X();
124     Standard_Real y = T.Y();
125     if (Edge.Orientation() == TopAbs_FORWARD)
126     {
127       T.SetCoord (-y,  x);
128     }
129     else
130     {
131       T.SetCoord ( y, -x);
132     }
133     Standard_Real ParamInit = RealLast();
134     Standard_Real TolInit   = 0.00001;
135     Standard_Boolean APointExist = Standard_False;
136
137     BRepClass_FacePassiveClassifier FClassifier;
138
139     T.Normalize();
140     P.SetCoord (P.X() + TolInit * T.X(), P.Y() + TolInit * T.Y());
141     FClassifier.Reset (gp_Lin2d (P, T), ParamInit, RealEpsilon()); //-- Length and Tolerance #######
142
143     TopExp_Explorer otherfaceexplorer;
144     Standard_Integer aNbEdges = 0;
145     for (otherfaceexplorer.Init (face, TopAbs_EDGE);
146          otherfaceexplorer.More(); 
147          otherfaceexplorer.Next(), ++aNbEdges)
148     {
149       TopoDS_Edge OtherEdge = TopoDS::Edge (otherfaceexplorer.Current());
150       if (OtherEdge.Orientation() != TopAbs_EXTERNAL && OtherEdge != Edge)
151       {
152         BRepClass_Edge AEdge (OtherEdge, face);
153         FClassifier.Compare (AEdge, OtherEdge.Orientation());
154         if (FClassifier.ClosestIntersection())
155         {
156           if(ParamInit > FClassifier.Parameter())
157           {
158             ParamInit = FClassifier.Parameter();
159             APointExist = Standard_True;
160           }
161         }
162       }
163     }
164
165     if (aNbEdges == 1)
166     {
167       BRepClass_Edge AEdge (Edge, face);
168       FClassifier.Compare (AEdge, Edge.Orientation());
169       if (FClassifier.ClosestIntersection())
170       {
171         if (ParamInit > FClassifier.Parameter())
172         {
173           ParamInit = FClassifier.Parameter();
174           APointExist = Standard_True;
175         }
176       }
177     }
178
179     if (APointExist)
180     { 
181       ParamInit *= 0.41234;
182       u_ = P.X() + ParamInit* T.X();
183       v_ = P.Y() + ParamInit* T.Y();
184       BRepAdaptor_Surface s;
185       s.Initialize (face, Standard_False);
186       s.D1 (u_, v_, APoint_, theVecD1U, theVecD1V);
187       return Standard_True;
188     }
189   }
190   return Standard_False;
191 }
192
193 //=======================================================================
194 //function : PointInTheFace
195 //purpose  : 
196 //=======================================================================
197
198 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
199 (const TopoDS_Face& Face,
200  gp_Pnt& APoint_,
201  Standard_Real& u_, Standard_Real& v_,
202  Standard_Real& param_,
203  Standard_Integer& IndexPoint,
204  const Handle(BRepAdaptor_HSurface)& surf,
205  const Standard_Real U1,
206  const Standard_Real V1,
207  const Standard_Real U2,
208  const Standard_Real V2) const
209 {
210   gp_Vec aVecD1U, aVecD1V;
211   return PointInTheFace (Face, APoint_, u_, v_, param_, IndexPoint, surf,
212                          U1, V1, U2, V2, aVecD1U, aVecD1V);
213 }
214
215 //=======================================================================
216 //function : PointInTheFace
217 //purpose  : 
218 //=======================================================================
219
220 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
221 (const TopoDS_Face& Face,
222  gp_Pnt& APoint_,
223  Standard_Real& u_, Standard_Real& v_,
224  Standard_Real& param_,
225  Standard_Integer& IndexPoint,
226  const Handle(BRepAdaptor_HSurface)& surf,
227  const Standard_Real U1,
228  const Standard_Real V1,
229  const Standard_Real U2,
230  const Standard_Real V2,
231  gp_Vec& theVecD1U,
232  gp_Vec& theVecD1V) const
233 {
234   Standard_Real u,du = (U2-U1)/6.0;
235   Standard_Real v,dv = (V2-V1)/6.0;
236   if(du<1e-12) du=1e-12;
237   if(dv<1e-12) dv=1e-12;
238   Standard_Integer NbPntCalc=0;
239   if(myMapOfInter.IsBound(Face)) { 
240     void *ptr = (void*)(myMapOfInter.Find(Face));
241     if(ptr) { 
242       const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr));
243       //-- Take 4 points in each Quarter of surface
244       //-- -> Index : 1 -> 16
245       //-- 
246       //--
247       //--  Then take a matrix of points on a tight grid
248       //--
249       for(u=du+(U1+U2)*0.5; u<U2; u+=du) {          //--  0  X    u increases
250         for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) {        //--  0  0    v increases
251           if(++NbPntCalc>=IndexPoint) { 
252             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
253               u_=u; v_=v;
254               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
255               IndexPoint = NbPntCalc;
256               return(Standard_True);
257             }
258           }
259         }
260       }
261           
262       for(u=-du+(U1+U2)*0.5; u>U1; u-=du) {         //--  0  0    u decreases
263         for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) {       //--  X  0    v decreases
264           if(++NbPntCalc>=IndexPoint) {
265             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
266               u_=u; v_=v;
267               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
268               IndexPoint = NbPntCalc;
269               return(Standard_True);
270             }
271           }
272         }
273       }
274       for(u=-du+(U1+U2)*0.5; u>U1; u-=du) {         //--  X  0    u decreases
275         for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) {        //--  0  0    v increases
276           if(++NbPntCalc>=IndexPoint) { 
277             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
278               u_=u; v_=v;
279               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
280               IndexPoint = NbPntCalc;
281               return(Standard_True);
282             }
283           }
284         }
285       }
286       for(u=du+(U1+U2)*0.5; u<U2; u+=du) {         //--  0  0     u increases
287         for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) {      //--  0  X     v decreases
288           if(++NbPntCalc>=IndexPoint) {
289             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
290               u_=u; v_=v;
291               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
292               IndexPoint = NbPntCalc;
293               return(Standard_True);
294             }
295           }
296         }
297       }
298       //-- the remainder
299       du = (U2-U1)/37.0;
300       dv = (V2-V1)/37.0;
301       if(du<1e-12) du=1e-12;
302       if(dv<1e-12) dv=1e-12;
303       
304       for(u=du+U1; u<U2; u+=du) { 
305         for(v=dv+V1; v<V2; v+=dv) {
306           if(++NbPntCalc>=IndexPoint) {
307             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
308               u_=u; v_=v;
309               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
310               IndexPoint = NbPntCalc;
311               return(Standard_True);
312             }
313           }
314         }
315       }
316       u=(U1+U2)*0.5;
317       v=(V1+V2)*0.5;
318       if(++NbPntCalc>=IndexPoint) {
319         if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
320           u_=u; v_=v;
321           surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
322           IndexPoint = NbPntCalc;
323           return(Standard_True);
324         }
325       }
326     }
327     IndexPoint = NbPntCalc;
328   }
329   else { 
330     //printf("BRepClass3d_SolidExplorer Face not found ds the map \n");
331   }
332
333   return BRepClass3d_SolidExplorer
334     ::FindAPointInTheFace (Face,APoint_, u_, v_, param_, theVecD1U, theVecD1V);
335 }
336
337 //=======================================================================
338 //function : LimitInfiniteUV
339 //purpose  : Limit infinite parameters
340 //=======================================================================
341 static void LimitInfiniteUV (Standard_Real& U1,
342                              Standard_Real& V1,
343                              Standard_Real& U2,
344                              Standard_Real& V2)
345 {
346   Standard_Boolean
347     infU1 = Precision::IsNegativeInfinite(U1),
348     infV1 = Precision::IsNegativeInfinite(V1),
349     infU2 = Precision::IsPositiveInfinite(U2),
350     infV2 = Precision::IsPositiveInfinite(V2);
351
352   if (infU1) U1 = -1e10;
353   if (infV1) V1 = -1e10;
354   if (infU2) U2 =  1e10;
355   if (infV2) V2 =  1e10;
356 }
357 //=======================================================================
358 //function : IsInfiniteUV
359 //purpose  : 
360 //=======================================================================
361 static Standard_Integer IsInfiniteUV (Standard_Real& U1, 
362                                       Standard_Real& V1,
363                                       Standard_Real& U2, 
364                                       Standard_Real& V2) 
365 {
366   Standard_Integer aVal = 0;
367
368   if (Precision::IsInfinite(U1))
369     aVal |= 1;
370
371   if (Precision::IsInfinite(V1))
372     aVal |= 2;
373
374   if (Precision::IsInfinite(U2))
375     aVal |= 4;
376
377   if (Precision::IsInfinite(V2))
378     aVal |= 8;
379
380   return aVal;
381 }
382 //<-OCC454
383 //  Modified by skv - Tue Sep 16 13:50:39 2003 OCC578 End
384 //=======================================================================
385 //function : OtherSegment
386 //purpose  : Returns  in <L>, <Par>  a segment having at least
387 //           one  intersection  with  the  shape  boundary  to
388 //           compute  intersections. 
389 //           The First Call to this method returns a line which
390 //           point to a point of the first face of the shape.
391 //           The Second Call provide a line to the second face
392 //           and so on. 
393 //=======================================================================
394 Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P, 
395                                                          gp_Lin& L, 
396                                                          Standard_Real& _Par) 
397 {
398   const Standard_Real TolU = Precision::PConfusion();
399   const Standard_Real TolV = TolU;
400
401   TopoDS_Face         face;
402   TopExp_Explorer     faceexplorer;
403   gp_Pnt APoint;
404   gp_Vec aVecD1U, aVecD1V;
405   Standard_Real maxscal=0;
406   Standard_Boolean ptfound=Standard_False;
407   Standard_Real Par;
408   Standard_Real _u,_v;
409   Standard_Integer IndexPoint=0;
410   Standard_Integer NbPointsOK=0;
411   Standard_Integer NbFacesInSolid=0;
412
413   for(;;) { 
414     myFirstFace++; 
415     faceexplorer.Init(myShape,TopAbs_FACE);
416     // look for point on face starting from myFirstFace
417 //  Modified by skv - Thu Sep  4 14:31:12 2003 OCC578 Begin
418 //     while (faceexplorer.More()) {
419     for (; faceexplorer.More(); faceexplorer.Next()) {
420 //  Modified by skv - Thu Sep  4 14:31:12 2003 OCC578 End
421       NbFacesInSolid++;
422       if (myFirstFace > NbFacesInSolid) continue;
423       face = TopoDS::Face(faceexplorer.Current());
424
425       Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
426       surf->ChangeSurface().Initialize(face);
427       Standard_Real U1,V1,U2,V2;
428       U1 = surf->FirstUParameter();
429       V1 = surf->FirstVParameter();
430       U2 = surf->LastUParameter();
431       V2 = surf->LastVParameter();
432       face.Orientation(TopAbs_FORWARD);
433       //
434       //avoid process faces from uncorrected shells
435       if( Abs (U2 - U1) < 1.e-12 || Abs(V2 - V1) < 1.e-12) {
436         return 2;
437       }
438       //
439       Standard_Real svmyparam=myParamOnEdge;
440       //
441       // Check if the point is on the face or the face is infinite.
442       Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2);
443
444       GeomAdaptor_Surface GA(BRep_Tool::Surface(face));
445       Extrema_ExtPS Ext(P, GA, TolU, TolV);
446       //
447       if (Ext.IsDone() && Ext.NbExt() > 0) {
448         Standard_Integer i, iNear,  iEnd;
449         Standard_Real  aUx, aVx, Dist2, Dist2Min;
450         Extrema_POnSurf aPx;
451         //
452         iNear = 1;
453         Dist2Min = Ext.SquareDistance(1);
454         iEnd = Ext.NbExt();
455         for (i = 2; i <= iEnd; i++) {
456           aPx=Ext.Point(i);
457           aPx.Parameter(aUx, aVx);
458           if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) {
459             Dist2 = Ext.SquareDistance(i);
460             if (Dist2 < Dist2Min) {
461               Dist2Min = Dist2; 
462               iNear = i;
463             }
464           }
465         }
466         //
467         Standard_Real aDist2Tresh=1.e-24;
468         //
469         if (Dist2Min<aDist2Tresh) {
470           if (anInfFlag) {
471             return 1;
472           } 
473           else {
474             BRepClass_FaceClassifier classifier2d;
475             Standard_Real            aU;
476             Standard_Real            aV;
477
478             (Ext.Point(iNear)).Parameter(aU, aV);
479
480             gp_Pnt2d aPuv(aU, aV);
481
482             classifier2d.Perform(face,aPuv,Precision::PConfusion());
483
484             TopAbs_State aState = classifier2d.State();
485
486             if (aState == TopAbs_IN || aState == TopAbs_ON) {
487               return 1;
488             }
489             else {
490               return 3; // skv - the point is on surface but outside face.
491             }
492           }
493         }
494         if (anInfFlag) {
495           APoint = (Ext.Point(iNear)).Value();
496           gp_Vec V(P,APoint);
497           _Par = V.Magnitude(); 
498           L = gp_Lin(P,V);
499           ptfound=Standard_True;
500           return 0;
501         }
502       }
503       //The point is not ON the face or surface. The face is restricted.
504       // find point in a face not too far from a projection of P on face
505       do {
506         if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf,
507                             U1, V1, U2, V2,
508                             aVecD1U, aVecD1V))
509         {
510           ++NbPointsOK;
511           gp_Vec V (P, APoint);
512           Par = V.Magnitude();
513           if (Par > gp::Resolution())
514           {
515             gp_Vec Norm = aVecD1U.Crossed (aVecD1V);
516             Standard_Real tt = Norm.Magnitude();
517             tt = Abs (Norm.Dot (V)) / (tt * Par);
518             if (tt > maxscal)
519             {
520               maxscal = tt;
521               L = gp_Lin (P, V);
522               _Par = Par;
523               ptfound = Standard_True;
524               if (maxscal>0.2)
525               {
526                 myParamOnEdge=svmyparam;
527                 return 0;
528               }
529             }
530           }
531         }
532       }
533       while(IndexPoint<200 && NbPointsOK<16);
534
535       myParamOnEdge=svmyparam;
536       if(maxscal>0.2) {           
537         return 0;
538       }
539
540
541       //  Modified by skv - Thu Sep  4 14:32:14 2003 OCC578 Begin
542       // Next is done in the main for(..) loop.
543       //       faceexplorer.Next();
544       //  Modified by skv - Thu Sep  4 14:32:14 2003 OCC578 End
545       IndexPoint = 0;
546
547       Standard_Boolean encoreuneface = faceexplorer.More();
548       if(ptfound==Standard_False && encoreuneface==Standard_False) { 
549         if(myParamOnEdge < 0.0001) { 
550           //-- This case takes place when the point is on the solid
551           //-- and this solid is reduced to a face 
552           gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
553           gp_Vec V(P,PBidon);
554           Par= 1.0;
555           _Par=Par;
556           L  = gp_Lin(P,V);
557           return 0;
558         }
559       }
560     } //-- Exploration of the faces   
561
562     if(NbFacesInSolid==0) { 
563       _Par=0.0;
564       myReject=Standard_True;
565 #if DEB
566       cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx  (Solid without face)"<<endl;
567 #endif  
568       return 0;
569     }
570
571     if(ptfound) {
572       return 0;
573     }
574     myFirstFace = 0;
575     if(myParamOnEdge==0.512345)  myParamOnEdge = 0.4;
576     else if(myParamOnEdge==0.4)  myParamOnEdge = 0.6; 
577     else if(myParamOnEdge==0.6)  myParamOnEdge = 0.3; 
578     else if(myParamOnEdge==0.3)  myParamOnEdge = 0.7; 
579     else if(myParamOnEdge==0.7)  myParamOnEdge = 0.2; 
580     else if(myParamOnEdge==0.2)  myParamOnEdge = 0.8; 
581     else if(myParamOnEdge==0.8)  myParamOnEdge = 0.1; 
582     else if(myParamOnEdge==0.1)  myParamOnEdge = 0.9;
583     //
584     else {
585       myParamOnEdge*=0.5;  
586       if(myParamOnEdge < 0.0001) { 
587         gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
588         gp_Vec V(P,PBidon);
589         Par= 1.0;
590         _Par=Par;
591         L  = gp_Lin(P,V);
592         return 0;
593       }
594     }
595   } //-- for(;;) { ...  } 
596 }
597
598 //  Modified by skv - Thu Sep  4 12:30:14 2003 OCC578 Begin
599 //=======================================================================
600 //function : GetFaceSegmentIndex
601 //purpose  : Returns the index of face for which last segment is calculated.
602 //=======================================================================
603
604 Standard_Integer BRepClass3d_SolidExplorer::GetFaceSegmentIndex() const
605 {
606   return myFirstFace;
607 }
608 //  Modified by skv - Thu Sep  4 12:30:14 2003 OCC578 End
609
610 //=======================================================================
611 //function : PointInTheFace
612 //purpose  : 
613 //=======================================================================
614
615 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
616 (const TopoDS_Face& _face,
617  gp_Pnt& APoint_,
618  Standard_Real& u_, Standard_Real& v_,
619  Standard_Real& param_,
620  Standard_Integer& IndexPoint) const  
621 {   
622   TopoDS_Face Face = _face;
623   Face.Orientation(TopAbs_FORWARD);
624   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
625   surf->ChangeSurface().Initialize(Face);
626   Standard_Real U1,V1,U2,V2;//,u,v;
627   U1 = surf->FirstUParameter();
628   V1 = surf->FirstVParameter();
629   U2 = surf->LastUParameter();
630   V2 = surf->LastVParameter();
631   LimitInfiniteUV (U1,V1,U2,V2);
632   return(PointInTheFace(Face,APoint_,u_,v_,param_,IndexPoint,surf,U1,V1,U2,V2));
633 }
634
635 //=======================================================================
636 //function : FindAPointInTheFace
637 //purpose  : 
638 //=======================================================================
639
640 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
641 (const TopoDS_Face& _face,
642  gp_Pnt& APoint_,
643  Standard_Real& u_,Standard_Real& v_) 
644 {
645   Standard_Real param = 0.1;
646   Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u_,v_,param);
647   return r;
648 }
649
650 //=======================================================================
651 //function : FindAPointInTheFace
652 //purpose  : 
653 //=======================================================================
654
655 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
656 (const TopoDS_Face& _face,
657  gp_Pnt& APoint_) 
658 { Standard_Real u,v;
659   Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v);
660   return r;
661 }
662
663 //=======================================================================
664 //function : FindAPointInTheFace
665 //purpose  : 
666 //=======================================================================
667
668 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
669 (const TopoDS_Face& _face,
670  Standard_Real& u_,Standard_Real& v_) 
671 { gp_Pnt APoint;
672   Standard_Boolean r = FindAPointInTheFace(_face,APoint,u_,v_);
673   return r;
674 }
675
676 //=======================================================================
677 //function : BRepClass3d_SolidExplorer
678 //purpose  : 
679 //=======================================================================
680
681 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer() 
682 {
683 }
684 #include <Standard_ConstructionError.hxx>
685
686 //=======================================================================
687 //function : BRepClass3d_SolidExplorer
688 //purpose  : Raise if called.
689 //=======================================================================
690
691 //BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& Oth) 
692 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& ) 
693 {
694   Standard_ConstructionError::Raise("Magic constructor not allowed");
695 }
696
697 //=======================================================================
698 //function : BRepClass3d_SolidExplorer
699 //purpose  : 
700 //=======================================================================
701
702 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const TopoDS_Shape& S)
703 {
704   InitShape(S);
705 }
706
707 //=======================================================================
708 //function : Delete
709 //purpose  : 
710 //=======================================================================
711
712 void BRepClass3d_SolidExplorer::Delete()
713 {
714  Destroy() ;
715 }
716
717 //=======================================================================
718 //function : Destroy
719 //purpose  : C++: alias ~
720 //=======================================================================
721
722 void BRepClass3d_SolidExplorer::Destroy() { 
723   BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
724   for(;iter.More();iter.Next()) { 
725     void *ptr=iter.Value();
726     if(ptr) { 
727       delete (IntCurvesFace_Intersector *)ptr;
728       myMapOfInter.ChangeFind(iter.Key()) = NULL;
729     }
730   }
731   myMapOfInter.Clear();
732 }
733
734 //=======================================================================
735 //function : InitShape
736 //purpose  : 
737 //=======================================================================
738
739 void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
740 {
741   myShape = S;
742   myFirstFace = 0;
743   myParamOnEdge = 0.512345;
744   //-- Exploring of the Map and removal of allocated objects
745   
746   
747   BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
748   for(;iter.More();iter.Next()) { 
749     void *ptr=iter.Value();
750     if(ptr) { 
751       delete (IntCurvesFace_Intersector *)ptr;
752       myMapOfInter.ChangeFind(iter.Key()) = NULL;
753     }
754   }
755   
756   myMapOfInter.Clear();
757   
758   myReject = Standard_True; //-- case of infinite solid (without any face)
759
760   TopExp_Explorer Expl;
761   for(Expl.Init(S,TopAbs_FACE);
762       Expl.More();
763       Expl.Next()) { 
764     const TopoDS_Face Face = TopoDS::Face(Expl.Current());
765     void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion()));
766     myMapOfInter.Bind(Face,ptr);
767     myReject=Standard_False;  //-- at least one face in the solid 
768   }
769   
770 #if DEB
771   if(myReject) { 
772     cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx  (Solid without face)"<<endl;
773   }
774 #endif      
775
776 #if REJECTION
777   BRepBndLib::Add(myShape,myBox);
778 #endif
779 }
780
781 //=======================================================================
782 //function : Reject
783 //purpose  : Should return True if P outside of bounding vol. of the shape
784 //=======================================================================
785
786 //Standard_Boolean  BRepClass3d_SolidExplorer::Reject(const gp_Pnt& P) const 
787 Standard_Boolean  BRepClass3d_SolidExplorer::Reject(const gp_Pnt& ) const 
788 {
789   return(myReject);  // case of solid without face 
790 }
791
792 //=======================================================================
793 //function : InitShell
794 //purpose  : Starts an exploration of the shells.
795 //=======================================================================
796
797 void BRepClass3d_SolidExplorer::InitShell()  
798 {
799   myShellExplorer.Init(myShape,TopAbs_SHELL);
800 }
801
802 //=======================================================================
803 //function : MoreShell
804 //purpose  : Returns True if there is a current shell. 
805 //=======================================================================
806
807 Standard_Boolean BRepClass3d_SolidExplorer::MoreShell() const 
808
809   return(myShellExplorer.More());
810 }
811
812 //=======================================================================
813 //function : NextShell
814 //purpose  : Sets the explorer to the next shell.
815 //=======================================================================
816
817 void BRepClass3d_SolidExplorer::NextShell() 
818
819   myShellExplorer.Next();
820 }
821
822 //=======================================================================
823 //function : CurrentShell
824 //purpose  : Returns the current shell.
825 //=======================================================================
826
827 TopoDS_Shell BRepClass3d_SolidExplorer::CurrentShell() const 
828
829   return(TopoDS::Shell(myShellExplorer.Current()));
830 }
831
832 //=======================================================================
833 //function : RejectShell
834 //purpose  : Returns True if the Shell is rejected.
835 //=======================================================================
836
837 Standard_Boolean BRepClass3d_SolidExplorer::RejectShell(const gp_Lin& ) const
838
839   return(Standard_False); 
840 }
841
842 //=======================================================================
843 //function : InitFace
844 //purpose  : Starts an exploration of the faces of the current shell.
845 //=======================================================================
846
847 void BRepClass3d_SolidExplorer::InitFace()  
848 {
849   myFaceExplorer.Init(TopoDS::Shell(myShellExplorer.Current()),TopAbs_FACE);
850 }
851
852 //=======================================================================
853 //function : MoreFace
854 //purpose  : Returns True if current face in current shell. 
855 //=======================================================================
856
857 Standard_Boolean BRepClass3d_SolidExplorer::MoreFace() const 
858
859   return(myFaceExplorer.More());
860 }
861
862 //=======================================================================
863 //function : NextFace
864 //purpose  : Sets the explorer to the next Face of the current shell.
865 //=======================================================================
866
867 void BRepClass3d_SolidExplorer::NextFace() 
868
869   myFaceExplorer.Next();
870 }
871
872 //=======================================================================
873 //function : CurrentFace
874 //purpose  : Returns the current face.
875 //=======================================================================
876
877 TopoDS_Face BRepClass3d_SolidExplorer::CurrentFace() const 
878
879   return(TopoDS::Face(myFaceExplorer.Current()));
880 }
881
882 //=======================================================================
883 //function : RejectFace
884 //purpose  : returns True if the face is rejected.
885 //=======================================================================
886
887 Standard_Boolean BRepClass3d_SolidExplorer::RejectFace(const gp_Lin& ) const 
888
889   return(Standard_False); 
890 }
891
892 #ifdef DEB
893 #include <TopAbs_State.hxx>
894 #endif
895
896 //=======================================================================
897 //function : Segment
898 //purpose  : Returns  in <L>, <Par>  a segment having at least
899 //           one  intersection  with  the  shape  boundary  to
900 //           compute  intersections. 
901 //=======================================================================
902 Standard_Integer  BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P, 
903                                                      gp_Lin& L, 
904                                                      Standard_Real& Par)  
905 {
906   Standard_Integer bRetFlag;
907   myFirstFace = 0;
908   bRetFlag=OtherSegment(P,L,Par);
909   return bRetFlag;
910 }
911
912 //=======================================================================
913 //function : Intersector
914 //purpose  : 
915 //=======================================================================
916
917 IntCurvesFace_Intersector&  BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const  { 
918   void *ptr = (void*)(myMapOfInter.Find(F));
919   IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr));
920   return curr;
921 }
922
923 //=======================================================================
924 //function : Box
925 //purpose  : 
926 //=======================================================================
927
928 const Bnd_Box& BRepClass3d_SolidExplorer::Box() const { 
929   return(myBox);
930 }
931
932 //=======================================================================
933 //function : DumpSegment
934 //purpose  : 
935 //=======================================================================
936
937 void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&,
938                                             const gp_Lin&,
939                                             const Standard_Real,
940                                             const TopAbs_State) const
941 {
942 #ifdef DEB
943  
944 #endif
945 }