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