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