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