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