0025555: Wrong result of classification of a point relative to solid
[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       // Check if the point is already in the face
255       if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN) {
256         gp_Pnt aPnt;
257         surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V);
258         if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion())
259           return Standard_True;
260       }
261
262       //-- Take 4 points in each Quarter of surface
263       //-- -> Index : 1 -> 16
264       //-- 
265       //--
266       //--  Then take a matrix of points on a tight grid
267       //--
268       for(u=du+(U1+U2)*0.5; u<U2; u+=du) {          //--  0  X    u increases
269         for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) {        //--  0  0    v increases
270           if(++NbPntCalc>=IndexPoint) { 
271             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
272               u_=u; v_=v;
273               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
274               IndexPoint = NbPntCalc;
275               return(Standard_True);
276             }
277           }
278         }
279       }
280           
281       for(u=-du+(U1+U2)*0.5; u>U1; u-=du) {         //--  0  0    u decreases
282         for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) {       //--  X  0    v decreases
283           if(++NbPntCalc>=IndexPoint) {
284             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
285               u_=u; v_=v;
286               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
287               IndexPoint = NbPntCalc;
288               return(Standard_True);
289             }
290           }
291         }
292       }
293       for(u=-du+(U1+U2)*0.5; u>U1; u-=du) {         //--  X  0    u decreases
294         for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) {        //--  0  0    v increases
295           if(++NbPntCalc>=IndexPoint) { 
296             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
297               u_=u; v_=v;
298               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
299               IndexPoint = NbPntCalc;
300               return(Standard_True);
301             }
302           }
303         }
304       }
305       for(u=du+(U1+U2)*0.5; u<U2; u+=du) {         //--  0  0     u increases
306         for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) {      //--  0  X     v decreases
307           if(++NbPntCalc>=IndexPoint) {
308             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
309               u_=u; v_=v;
310               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
311               IndexPoint = NbPntCalc;
312               return(Standard_True);
313             }
314           }
315         }
316       }
317       //-- the remainder
318       du = (U2-U1)/37.0;
319       dv = (V2-V1)/37.0;
320       if(du<1e-12) du=1e-12;
321       if(dv<1e-12) dv=1e-12;
322       
323       for(u=du+U1; u<U2; u+=du) { 
324         for(v=dv+V1; v<V2; v+=dv) {
325           if(++NbPntCalc>=IndexPoint) {
326             if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
327               u_=u; v_=v;
328               surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
329               IndexPoint = NbPntCalc;
330               return(Standard_True);
331             }
332           }
333         }
334       }
335       u=(U1+U2)*0.5;
336       v=(V1+V2)*0.5;
337       if(++NbPntCalc>=IndexPoint) {
338         if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { 
339           u_=u; v_=v;
340           surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
341           IndexPoint = NbPntCalc;
342           return(Standard_True);
343         }
344       }
345     }
346     IndexPoint = NbPntCalc;
347   }
348   else { 
349     //printf("BRepClass3d_SolidExplorer Face not found ds the map \n");
350   }
351
352   return BRepClass3d_SolidExplorer
353     ::FindAPointInTheFace (Face,APoint_, u_, v_, param_, theVecD1U, theVecD1V);
354 }
355
356 //=======================================================================
357 //function : LimitInfiniteUV
358 //purpose  : Limit infinite parameters
359 //=======================================================================
360 static void LimitInfiniteUV (Standard_Real& U1,
361                              Standard_Real& V1,
362                              Standard_Real& U2,
363                              Standard_Real& V2)
364 {
365   Standard_Boolean
366     infU1 = Precision::IsNegativeInfinite(U1),
367     infV1 = Precision::IsNegativeInfinite(V1),
368     infU2 = Precision::IsPositiveInfinite(U2),
369     infV2 = Precision::IsPositiveInfinite(V2);
370
371   if (infU1) U1 = -1e10;
372   if (infV1) V1 = -1e10;
373   if (infU2) U2 =  1e10;
374   if (infV2) V2 =  1e10;
375 }
376 //=======================================================================
377 //function : IsInfiniteUV
378 //purpose  : 
379 //=======================================================================
380 static Standard_Integer IsInfiniteUV (Standard_Real& U1, 
381                                       Standard_Real& V1,
382                                       Standard_Real& U2, 
383                                       Standard_Real& V2) 
384 {
385   Standard_Integer aVal = 0;
386
387   if (Precision::IsInfinite(U1))
388     aVal |= 1;
389
390   if (Precision::IsInfinite(V1))
391     aVal |= 2;
392
393   if (Precision::IsInfinite(U2))
394     aVal |= 4;
395
396   if (Precision::IsInfinite(V2))
397     aVal |= 8;
398
399   return aVal;
400 }
401 //<-OCC454
402 //  Modified by skv - Tue Sep 16 13:50:39 2003 OCC578 End
403 //=======================================================================
404 //function : OtherSegment
405 //purpose  : Returns  in <L>, <Par>  a segment having at least
406 //           one  intersection  with  the  shape  boundary  to
407 //           compute  intersections. 
408 //           The First Call to this method returns a line which
409 //           point to a point of the first face of the shape.
410 //           The Second Call provide a line to the second face
411 //           and so on. 
412 //=======================================================================
413 Standard_Integer BRepClass3d_SolidExplorer::OtherSegment(const gp_Pnt& P, 
414                                                          gp_Lin& L, 
415                                                          Standard_Real& _Par) 
416 {
417   const Standard_Real TolU = Precision::PConfusion();
418   const Standard_Real TolV = TolU;
419
420   TopoDS_Face         face;
421   TopExp_Explorer     faceexplorer;
422   gp_Pnt APoint;
423   gp_Vec aVecD1U, aVecD1V;
424   Standard_Real maxscal=0;
425   Standard_Boolean ptfound=Standard_False;
426   Standard_Real Par;
427   Standard_Real _u,_v;
428   Standard_Integer IndexPoint=0;
429   Standard_Integer NbPointsOK=0;
430   Standard_Integer NbFacesInSolid=0;
431
432   for(;;) { 
433     myFirstFace++; 
434     faceexplorer.Init(myShape,TopAbs_FACE);
435     // look for point on face starting from myFirstFace
436 //  Modified by skv - Thu Sep  4 14:31:12 2003 OCC578 Begin
437 //     while (faceexplorer.More()) {
438     for (; faceexplorer.More(); faceexplorer.Next()) {
439 //  Modified by skv - Thu Sep  4 14:31:12 2003 OCC578 End
440       NbFacesInSolid++;
441       if (myFirstFace > NbFacesInSolid) continue;
442       face = TopoDS::Face(faceexplorer.Current());
443
444       Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
445       surf->ChangeSurface().Initialize(face);
446       Standard_Real U1,V1,U2,V2;
447       U1 = surf->FirstUParameter();
448       V1 = surf->FirstVParameter();
449       U2 = surf->LastUParameter();
450       V2 = surf->LastVParameter();
451       face.Orientation(TopAbs_FORWARD);
452       //
453       //avoid process faces from uncorrected shells
454       if( Abs (U2 - U1) < 1.e-12 || Abs(V2 - V1) < 1.e-12) {
455         return 2;
456       }
457       //
458       Standard_Real svmyparam=myParamOnEdge;
459       //
460       // Check if the point is on the face or the face is infinite.
461       Standard_Integer anInfFlag = IsInfiniteUV(U1,V1,U2,V2);
462       // default values
463       _u = (U1 + U2) * 0.5;
464       _v = (V1 + V2) * 0.5;
465
466       GeomAdaptor_Surface GA(BRep_Tool::Surface(face));
467       Extrema_ExtPS Ext(P, GA, TolU, TolV);
468       //
469       if (Ext.IsDone() && Ext.NbExt() > 0) {
470         Standard_Integer i, iNear,  iEnd;
471         Standard_Real  aUx, aVx, Dist2, Dist2Min;
472         Extrema_POnSurf aPx;
473         //
474         iNear = 1;
475         Dist2Min = Ext.SquareDistance(1);
476         iEnd = Ext.NbExt();
477         for (i = 2; i <= iEnd; i++) {
478           aPx=Ext.Point(i);
479           aPx.Parameter(aUx, aVx);
480           if (aUx>=U1 && aUx<=U2 && aVx>=V1 && aVx<=V2) {
481             Dist2 = Ext.SquareDistance(i);
482             if (Dist2 < Dist2Min) {
483               Dist2Min = Dist2; 
484               iNear = i;
485             }
486           }
487         }
488         //
489         Standard_Real aDist2Tresh=1.e-24;
490         //
491         if (Dist2Min<aDist2Tresh) {
492           if (anInfFlag) {
493             return 1;
494           } 
495           else {
496             BRepClass_FaceClassifier classifier2d;
497             Standard_Real            aU;
498             Standard_Real            aV;
499
500             (Ext.Point(iNear)).Parameter(aU, aV);
501
502             gp_Pnt2d aPuv(aU, aV);
503
504             classifier2d.Perform(face,aPuv,Precision::PConfusion());
505
506             TopAbs_State aState = classifier2d.State();
507
508             if (aState == TopAbs_IN || aState == TopAbs_ON) {
509               return 1;
510             }
511             else {
512               return 3; // skv - the point is on surface but outside face.
513             }
514           }
515         }
516         if (anInfFlag) {
517           APoint = (Ext.Point(iNear)).Value();
518           gp_Vec V(P,APoint);
519           _Par = V.Magnitude(); 
520           L = gp_Lin(P,V);
521           ptfound=Standard_True;
522           return 0;
523         }
524
525         // set the parameters found by extrema
526         aPx = Ext.Point(iNear);
527         aPx.Parameter(_u, _v);
528         APoint = aPx.Value();
529       }
530       //The point is not ON the face or surface. The face is restricted.
531       // find point in a face not too far from a projection of P on face
532       do {
533         if (PointInTheFace (face, APoint, _u, _v, myParamOnEdge, ++IndexPoint, surf,
534                             U1, V1, U2, V2,
535                             aVecD1U, aVecD1V))
536         {
537           ++NbPointsOK;
538           gp_Vec V (P, APoint);
539           Par = V.Magnitude();
540           if (Par > gp::Resolution() &&
541               aVecD1U.Magnitude() > gp::Resolution() &&
542               aVecD1V.Magnitude() > gp::Resolution())
543           {
544             gp_Vec Norm = aVecD1U.Crossed (aVecD1V);
545             Standard_Real tt = Norm.Magnitude();
546             tt = Abs (Norm.Dot (V)) / (tt * Par);
547             if (tt > maxscal)
548             {
549               maxscal = tt;
550               L = gp_Lin (P, V);
551               _Par = Par;
552               ptfound = Standard_True;
553               if (maxscal>0.2)
554               {
555                 myParamOnEdge=svmyparam;
556                 return 0;
557               }
558             }
559           }
560         }
561       }
562       while(IndexPoint<200 && NbPointsOK<16);
563
564       myParamOnEdge=svmyparam;
565       if(maxscal>0.2) {                  
566         return 0;
567       }
568
569
570       //  Modified by skv - Thu Sep  4 14:32:14 2003 OCC578 Begin
571       // Next is done in the main for(..) loop.
572       //       faceexplorer.Next();
573       //  Modified by skv - Thu Sep  4 14:32:14 2003 OCC578 End
574       IndexPoint = 0;
575
576       Standard_Boolean encoreuneface = faceexplorer.More();
577       if(ptfound==Standard_False && encoreuneface==Standard_False) { 
578         if(myParamOnEdge < 0.0001) { 
579           //-- This case takes place when the point is on the solid
580           //-- and this solid is reduced to a face 
581           gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
582           gp_Vec V(P,PBidon);
583           Par= 1.0;
584           _Par=Par;
585           L  = gp_Lin(P,V);
586           return 0;
587         }
588       }
589     } //-- Exploration of the faces   
590
591     if(NbFacesInSolid==0) { 
592       _Par=0.0;
593       myReject=Standard_True;
594 #ifdef OCCT_DEBUG
595       cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx  (Solid without face)"<<endl;
596 #endif  
597       return 0;
598     }
599
600     if(ptfound) {
601       return 0;
602     }
603     myFirstFace = 0;
604     if(myParamOnEdge==0.512345)  myParamOnEdge = 0.4;
605     else if(myParamOnEdge==0.4)  myParamOnEdge = 0.6; 
606     else if(myParamOnEdge==0.6)  myParamOnEdge = 0.3; 
607     else if(myParamOnEdge==0.3)  myParamOnEdge = 0.7; 
608     else if(myParamOnEdge==0.7)  myParamOnEdge = 0.2; 
609     else if(myParamOnEdge==0.2)  myParamOnEdge = 0.8; 
610     else if(myParamOnEdge==0.8)  myParamOnEdge = 0.1; 
611     else if(myParamOnEdge==0.1)  myParamOnEdge = 0.9;
612     //
613     else {
614       myParamOnEdge*=0.5;  
615       if(myParamOnEdge < 0.0001) { 
616         gp_Pnt PBidon(P.X()+1.0,P.Y(),P.Z());
617         gp_Vec V(P,PBidon);
618         Par= 1.0;
619         _Par=Par;
620         L  = gp_Lin(P,V);
621         return 0;
622       }
623     }
624   } //-- for(;;) { ...  } 
625 }
626
627 //  Modified by skv - Thu Sep  4 12:30:14 2003 OCC578 Begin
628 //=======================================================================
629 //function : GetFaceSegmentIndex
630 //purpose  : Returns the index of face for which last segment is calculated.
631 //=======================================================================
632
633 Standard_Integer BRepClass3d_SolidExplorer::GetFaceSegmentIndex() const
634 {
635   return myFirstFace;
636 }
637 //  Modified by skv - Thu Sep  4 12:30:14 2003 OCC578 End
638
639 //=======================================================================
640 //function : PointInTheFace
641 //purpose  : 
642 //=======================================================================
643
644 Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
645 (const TopoDS_Face& _face,
646  gp_Pnt& APoint_,
647  Standard_Real& u_, Standard_Real& v_,
648  Standard_Real& param_,
649  Standard_Integer& IndexPoint) const  
650 {   
651   TopoDS_Face Face = _face;
652   Face.Orientation(TopAbs_FORWARD);
653   Handle(BRepAdaptor_HSurface) surf = new BRepAdaptor_HSurface();
654   surf->ChangeSurface().Initialize(Face);
655   Standard_Real U1,V1,U2,V2;//,u,v;
656   U1 = surf->FirstUParameter();
657   V1 = surf->FirstVParameter();
658   U2 = surf->LastUParameter();
659   V2 = surf->LastVParameter();
660   LimitInfiniteUV (U1,V1,U2,V2);
661   return(PointInTheFace(Face,APoint_,u_,v_,param_,IndexPoint,surf,U1,V1,U2,V2));
662 }
663
664 //=======================================================================
665 //function : FindAPointInTheFace
666 //purpose  : 
667 //=======================================================================
668
669 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
670 (const TopoDS_Face& _face,
671  gp_Pnt& APoint_,
672  Standard_Real& u_,Standard_Real& v_) 
673 {
674   Standard_Real param = 0.1;
675   Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u_,v_,param);
676   return r;
677 }
678
679 //=======================================================================
680 //function : FindAPointInTheFace
681 //purpose  : 
682 //=======================================================================
683
684 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
685 (const TopoDS_Face& _face,
686  gp_Pnt& APoint_) 
687 { Standard_Real u,v;
688   Standard_Boolean r = FindAPointInTheFace(_face,APoint_,u,v);
689   return r;
690 }
691
692 //=======================================================================
693 //function : FindAPointInTheFace
694 //purpose  : 
695 //=======================================================================
696
697 Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
698 (const TopoDS_Face& _face,
699  Standard_Real& u_,Standard_Real& v_) 
700 { gp_Pnt APoint;
701   Standard_Boolean r = FindAPointInTheFace(_face,APoint,u_,v_);
702   return r;
703 }
704
705 //=======================================================================
706 //function : BRepClass3d_SolidExplorer
707 //purpose  : 
708 //=======================================================================
709
710 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer() 
711 {
712 }
713 #include <Standard_ConstructionError.hxx>
714
715 //=======================================================================
716 //function : BRepClass3d_SolidExplorer
717 //purpose  : Raise if called.
718 //=======================================================================
719
720 //BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& Oth) 
721 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const BRepClass3d_SolidExplorer& ) 
722 {
723   Standard_ConstructionError::Raise("Magic constructor not allowed");
724 }
725
726 //=======================================================================
727 //function : BRepClass3d_SolidExplorer
728 //purpose  : 
729 //=======================================================================
730
731 BRepClass3d_SolidExplorer::BRepClass3d_SolidExplorer(const TopoDS_Shape& S)
732 {
733   InitShape(S);
734 }
735
736 //=======================================================================
737 //function : Delete
738 //purpose  : 
739 //=======================================================================
740
741 void BRepClass3d_SolidExplorer::Delete()
742 {
743  Destroy() ;
744 }
745
746 //=======================================================================
747 //function : Destroy
748 //purpose  : C++: alias ~
749 //=======================================================================
750
751 void BRepClass3d_SolidExplorer::Destroy() { 
752   BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
753   for(;iter.More();iter.Next()) { 
754     void *ptr=iter.Value();
755     if(ptr) { 
756       delete (IntCurvesFace_Intersector *)ptr;
757       myMapOfInter.ChangeFind(iter.Key()) = NULL;
758     }
759   }
760   myMapOfInter.Clear();
761 }
762
763 //=======================================================================
764 //function : InitShape
765 //purpose  : 
766 //=======================================================================
767
768 void BRepClass3d_SolidExplorer::InitShape(const TopoDS_Shape& S)
769 {
770   myShape = S;
771   myFirstFace = 0;
772   myParamOnEdge = 0.512345;
773   //-- Exploring of the Map and removal of allocated objects
774   
775   
776   BRepClass3d_DataMapIteratorOfMapOfInter iter(myMapOfInter);
777   for(;iter.More();iter.Next()) { 
778     void *ptr=iter.Value();
779     if(ptr) { 
780       delete (IntCurvesFace_Intersector *)ptr;
781       myMapOfInter.ChangeFind(iter.Key()) = NULL;
782     }
783   }
784   
785   myMapOfInter.Clear();
786   
787   myReject = Standard_True; //-- case of infinite solid (without any face)
788
789   TopExp_Explorer Expl;
790   for(Expl.Init(S,TopAbs_FACE);
791       Expl.More();
792       Expl.Next()) { 
793     const TopoDS_Face Face = TopoDS::Face(Expl.Current());
794     void *ptr = (void *)(new IntCurvesFace_Intersector(Face,Precision::Confusion()));
795     myMapOfInter.Bind(Face,ptr);
796     myReject=Standard_False;  //-- at least one face in the solid 
797   }
798   
799 #ifdef OCCT_DEBUG
800   if(myReject) { 
801     cout<<"\nWARNING : BRepClass3d_SolidExplorer.cxx  (Solid without face)"<<endl;
802   }
803 #endif      
804
805 #if REJECTION
806   BRepBndLib::Add(myShape,myBox);
807 #endif
808 }
809
810 //=======================================================================
811 //function : Reject
812 //purpose  : Should return True if P outside of bounding vol. of the shape
813 //=======================================================================
814
815 //Standard_Boolean  BRepClass3d_SolidExplorer::Reject(const gp_Pnt& P) const 
816 Standard_Boolean  BRepClass3d_SolidExplorer::Reject(const gp_Pnt& ) const 
817 {
818   return(myReject);  // case of solid without face 
819 }
820
821 //=======================================================================
822 //function : InitShell
823 //purpose  : Starts an exploration of the shells.
824 //=======================================================================
825
826 void BRepClass3d_SolidExplorer::InitShell()  
827 {
828   myShellExplorer.Init(myShape,TopAbs_SHELL);
829 }
830
831 //=======================================================================
832 //function : MoreShell
833 //purpose  : Returns True if there is a current shell. 
834 //=======================================================================
835
836 Standard_Boolean BRepClass3d_SolidExplorer::MoreShell() const 
837
838   return(myShellExplorer.More());
839 }
840
841 //=======================================================================
842 //function : NextShell
843 //purpose  : Sets the explorer to the next shell.
844 //=======================================================================
845
846 void BRepClass3d_SolidExplorer::NextShell() 
847
848   myShellExplorer.Next();
849 }
850
851 //=======================================================================
852 //function : CurrentShell
853 //purpose  : Returns the current shell.
854 //=======================================================================
855
856 TopoDS_Shell BRepClass3d_SolidExplorer::CurrentShell() const 
857
858   return(TopoDS::Shell(myShellExplorer.Current()));
859 }
860
861 //=======================================================================
862 //function : RejectShell
863 //purpose  : Returns True if the Shell is rejected.
864 //=======================================================================
865
866 Standard_Boolean BRepClass3d_SolidExplorer::RejectShell(const gp_Lin& ) const
867
868   return(Standard_False); 
869 }
870
871 //=======================================================================
872 //function : InitFace
873 //purpose  : Starts an exploration of the faces of the current shell.
874 //=======================================================================
875
876 void BRepClass3d_SolidExplorer::InitFace()  
877 {
878   myFaceExplorer.Init(TopoDS::Shell(myShellExplorer.Current()),TopAbs_FACE);
879 }
880
881 //=======================================================================
882 //function : MoreFace
883 //purpose  : Returns True if current face in current shell. 
884 //=======================================================================
885
886 Standard_Boolean BRepClass3d_SolidExplorer::MoreFace() const 
887
888   return(myFaceExplorer.More());
889 }
890
891 //=======================================================================
892 //function : NextFace
893 //purpose  : Sets the explorer to the next Face of the current shell.
894 //=======================================================================
895
896 void BRepClass3d_SolidExplorer::NextFace() 
897
898   myFaceExplorer.Next();
899 }
900
901 //=======================================================================
902 //function : CurrentFace
903 //purpose  : Returns the current face.
904 //=======================================================================
905
906 TopoDS_Face BRepClass3d_SolidExplorer::CurrentFace() const 
907
908   return(TopoDS::Face(myFaceExplorer.Current()));
909 }
910
911 //=======================================================================
912 //function : RejectFace
913 //purpose  : returns True if the face is rejected.
914 //=======================================================================
915
916 Standard_Boolean BRepClass3d_SolidExplorer::RejectFace(const gp_Lin& ) const 
917
918   return(Standard_False); 
919 }
920
921 #ifdef OCCT_DEBUG
922 #include <TopAbs_State.hxx>
923 #endif
924
925 //=======================================================================
926 //function : Segment
927 //purpose  : Returns  in <L>, <Par>  a segment having at least
928 //           one  intersection  with  the  shape  boundary  to
929 //           compute  intersections. 
930 //=======================================================================
931 Standard_Integer  BRepClass3d_SolidExplorer::Segment(const gp_Pnt& P, 
932                                                      gp_Lin& L, 
933                                                      Standard_Real& Par)  
934 {
935   Standard_Integer bRetFlag;
936   myFirstFace = 0;
937   bRetFlag=OtherSegment(P,L,Par);
938   return bRetFlag;
939 }
940
941 //=======================================================================
942 //function : Intersector
943 //purpose  : 
944 //=======================================================================
945
946 IntCurvesFace_Intersector&  BRepClass3d_SolidExplorer::Intersector(const TopoDS_Face& F) const  { 
947   void *ptr = (void*)(myMapOfInter.Find(F));
948   IntCurvesFace_Intersector& curr = (*((IntCurvesFace_Intersector *)ptr));
949   return curr;
950 }
951
952 //=======================================================================
953 //function : Box
954 //purpose  : 
955 //=======================================================================
956
957 const Bnd_Box& BRepClass3d_SolidExplorer::Box() const { 
958   return(myBox);
959 }
960
961 //=======================================================================
962 //function : DumpSegment
963 //purpose  : 
964 //=======================================================================
965
966 void BRepClass3d_SolidExplorer::DumpSegment(const gp_Pnt&,
967                                             const gp_Lin&,
968                                             const Standard_Real,
969                                             const TopAbs_State) const
970 {
971 #ifdef OCCT_DEBUG
972  
973 #endif
974 }