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