0023024: Update headers of OCCT files
[occt.git] / src / IntCurvesFace / IntCurvesFace_Intersector.cxx
1 // Created on: 1996-06-03
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23 //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578
24
25
26 #define OPTIMISATION 1 
27
28
29 #include <IntCurvesFace_Intersector.ixx>
30
31 #include <IntCurveSurface_ThePolyhedronToolOfHInter.hxx>
32 #include <Bnd_BoundSortBox.hxx>
33
34 #include <IntCurveSurface_IntersectionPoint.hxx>
35 #include <gp_Lin.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopAbs.hxx>
38
39
40 #include <IntCurveSurface_HInter.hxx>
41 #include <BRepAdaptor_HSurface.hxx>
42 #include <Geom_Line.hxx>
43 #include <gp_Pnt2d.hxx>
44 #include <BRepClass_FaceClassifier.hxx>
45
46 #include <GeomAdaptor_Curve.hxx>
47
48 #include <GeomAdaptor_HCurve.hxx>
49 #include <BRepAdaptor_HSurface.hxx>
50
51
52
53 #include <Adaptor3d_HSurfaceTool.hxx>
54 #include <IntCurveSurface_TheHCurveTool.hxx>
55 #include <Adaptor3d_HCurve.hxx>
56 #include <Bnd_Box.hxx>
57 #include <Intf_Tool.hxx>
58 #include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
59 #include <IntCurveSurface_ThePolygonOfHInter.hxx>
60 #include <IntCurveSurface_SequenceOfPnt.hxx>
61
62
63
64 GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const { 
65   return(Adaptor3d_HSurfaceTool::GetType(Hsurface));
66 }
67  
68
69 //============================================================================
70 IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
71                                                      const Standard_Real aTol)
72
73   Tol(aTol),done(Standard_False),nbpnt(0),PtrOnPolyhedron(NULL),PtrOnBndBounding(NULL)
74
75   BRepAdaptor_Surface surface;
76   face = Face;
77   surface.Initialize(Face,Standard_True);
78   Hsurface = new BRepAdaptor_HSurface(surface);
79   myTopolTool = new BRepTopAdaptor_TopolTool(Hsurface);
80   
81   GeomAbs_SurfaceType SurfaceType = Adaptor3d_HSurfaceTool::GetType(Hsurface);
82   if(   (SurfaceType != GeomAbs_Plane) 
83      && (SurfaceType != GeomAbs_Cylinder)
84      && (SurfaceType != GeomAbs_Cone) 
85      && (SurfaceType != GeomAbs_Sphere)
86      && (SurfaceType != GeomAbs_Torus)) {
87     Standard_Integer nbsu,nbsv;
88     Standard_Real U0,V0,U1,V1;
89     U0 = Hsurface->FirstUParameter();
90     U1 = Hsurface->LastUParameter();
91     V0 = Hsurface->FirstVParameter();
92     V1 = Hsurface->LastVParameter();
93     //-- nbsu = Adaptor3d_HSurfaceTool::NbSamplesU(Hsurface,U0,U1);
94     //-- nbsv = Adaptor3d_HSurfaceTool::NbSamplesV(Hsurface,V0,V1);
95     nbsu = myTopolTool->NbSamplesU();
96     nbsv = myTopolTool->NbSamplesV();
97     if(nbsu>40) nbsu = 40;
98     if(nbsv>40) nbsv = 40;
99     //-- printf("\n IntCurvesFace_Intersector : nbsu=(%3d)->%3d  nbsv=(%3d)->%3d",myTopolTool->NbSamplesU(),nbsu,myTopolTool->NbSamplesV(),nbsv);
100     PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
101   }
102 }
103 //============================================================================
104
105 void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
106                                              const Standard_Real parinf,const Standard_Real parsup) {
107   if(HICS.IsDone()) {
108     for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {  
109       const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
110       gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
111       
112       TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
113       if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) { 
114         Standard_Real HICSW = HICSPointindex.W();
115         if(HICSW >= parinf && HICSW <= parsup ) { 
116           Standard_Real U          = HICSPointindex.U();
117           Standard_Real V          = HICSPointindex.V();
118           Standard_Real W          = HICSW; 
119           IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
120           gp_Pnt pnt        = HICSPointindex.Pnt();
121           //      state      = currentstate;
122           //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
123           Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
124           //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
125
126           if(transition != IntCurveSurface_Tangent && face.Orientation()==TopAbs_REVERSED) { 
127             if(transition == IntCurveSurface_In) 
128               transition = IntCurveSurface_Out;
129             else 
130               transition = IntCurveSurface_In;
131           }
132           //----- Insertion du point 
133           if(nbpnt==0) { 
134             IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
135             SeqPnt.Append(PPP);
136             //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
137             mySeqState.Append(anIntState);
138             //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
139           }
140           else { 
141             Standard_Integer i = 1;
142             Standard_Integer b = nbpnt+1;                    
143             while(i<=nbpnt) {
144               const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
145               Standard_Real wi = Pnti.W();
146               if(wi >= W) { b=i; i=nbpnt; }
147               i++;
148             }
149             IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
150             //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
151 //          if(b>nbpnt)          { SeqPnt.Append(PPP); } 
152 //          else if(b>0)             { SeqPnt.InsertBefore(b,PPP); } 
153             if(b>nbpnt) {
154               SeqPnt.Append(PPP);
155               mySeqState.Append(anIntState);
156             } else if(b>0) {
157               SeqPnt.InsertBefore(b,PPP);
158               mySeqState.InsertBefore(b, anIntState);
159             }
160             //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
161           }
162
163  
164           nbpnt++;
165         } 
166       } //-- classifier state is IN or ON
167     } //-- Loop on Intersection points.
168   } //-- HICS.IsDone()
169 }
170
171 //--------------------------------------------------------------------------------
172
173
174
175
176 void IntCurvesFace_Intersector::Perform(const gp_Lin& L,const Standard_Real ParMin,const Standard_Real ParMax) { 
177   done = Standard_True;
178   SeqPnt.Clear();
179   //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
180   mySeqState.Clear();
181   //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
182   nbpnt = 0;
183   IntCurveSurface_HInter            HICS; 
184   
185   Handle(Geom_Line) geomline = new Geom_Line(L);
186   GeomAdaptor_Curve LL(geomline);
187   
188   //--
189   Handle(GeomAdaptor_HCurve) HLL  = new GeomAdaptor_HCurve(LL);
190   //-- 
191   Standard_Real parinf=ParMin;
192   Standard_Real parsup=ParMax;
193
194   if(PtrOnPolyhedron == NULL) { 
195     HICS.Perform(HLL,Hsurface);
196   }
197   else { 
198     Intf_Tool                         bndTool;
199     Bnd_Box                          boxLine;
200     bndTool.LinBox(L,((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding(),boxLine);
201     if(bndTool.NbSegments() == 0) 
202       return;
203     for(Standard_Integer nbseg=1; nbseg<= bndTool.NbSegments(); nbseg++) { 
204       Standard_Real pinf = bndTool.BeginParam(nbseg);
205       Standard_Real psup = bndTool.EndParam(nbseg);
206       Standard_Real pppp = 0.05*(psup-pinf);
207       pinf-=pppp;
208       psup+=pppp;
209       if((psup - pinf)<1e-10) { pinf-=1e-10; psup+=1e-10; } 
210       if(nbseg==1) { parinf=pinf; parsup=psup; }
211       else { 
212         if(parinf>pinf) parinf = pinf;
213         if(parsup<psup) parsup = psup;
214       }
215     }
216     if(parinf>ParMax) { return; } 
217     if(parsup<ParMin) { return; }
218     if(parinf<ParMin) parinf=ParMin;
219     if(parsup>ParMax) parsup=ParMax;
220     if(parinf>(parsup-1e-9)) return; 
221     IntCurveSurface_ThePolygonOfHInter polygon(HLL,
222                                                parinf,
223                                                parsup,
224                                                2);
225 #if OPTIMISATION
226     if(PtrOnBndBounding==NULL) { 
227       PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
228       IntCurveSurface_ThePolyhedronOfHInter *thePolyh=(IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
229       ((Bnd_BoundSortBox *)(PtrOnBndBounding))->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
230                                                            IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
231     }
232     HICS.Perform(HLL,
233                  polygon,
234                  Hsurface,
235                  *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
236                  *((Bnd_BoundSortBox *)PtrOnBndBounding));
237 #else
238     HICS.Perform(HLL,
239                  polygon,
240                  Hsurface,
241                  *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
242 #endif
243   }
244   
245   InternalCall(HICS,parinf,parsup);
246
247 #if 0 
248   if(HICS.IsDone()) {
249     for(Standard_Integer index=HICS.NbPoints(); index>=1; index--) {  
250       const IntCurveSurface_IntersectionPoint& HICSPointindex = HICS.Point(index);
251       gp_Pnt2d Puv(HICSPointindex.U(),HICSPointindex.V());
252       
253       TopAbs_State currentstate = myTopolTool->Classify(Puv,Tol);
254       if(currentstate==TopAbs_IN || currentstate==TopAbs_ON) { 
255         Standard_Real HICSW = HICSPointindex.W();
256         if(HICSW >= parinf && HICSW <= parsup ) { 
257           Standard_Real U          = HICSPointindex.U();
258           Standard_Real V          = HICSPointindex.V();
259           Standard_Real W          = HICSW; 
260           IntCurveSurface_TransitionOnCurve transition = HICSPointindex.Transition();
261           gp_Pnt pnt        = HICSPointindex.Pnt();
262           //      state      = currentstate;
263           //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
264           Standard_Integer anIntState = (currentstate == TopAbs_IN) ? 0 : 1;
265           //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
266           
267           if(face.Orientation()==TopAbs_REVERSED) { 
268             if(transition == IntCurveSurface_In) 
269               transition = IntCurveSurface_Out;
270             else 
271               transition = IntCurveSurface_In;
272           }
273           //----- Insertion du point 
274           if(nbpnt==0) { 
275             IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
276             SeqPnt.Append(PPP);
277             //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
278             mySeqState.Append(anIntState);
279             //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
280           }
281           else { 
282             Standard_Integer i = 1;
283             Standard_Integer b = nbpnt+1;                    
284             while(i<=nbpnt) {
285               const IntCurveSurface_IntersectionPoint& Pnti=SeqPnt.Value(i);
286               Standard_Real wi = Pnti.W();
287               if(wi >= W) { b=i; i=nbpnt; }
288               i++;
289             }
290             IntCurveSurface_IntersectionPoint PPP(pnt,U,V,W,transition);
291             //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
292 //          if(b>nbpnt)          { SeqPnt.Append(PPP); } 
293 //          else if(b>0)         { SeqPnt.InsertBefore(b,PPP); } 
294             if(b>nbpnt) {
295               SeqPnt.Append(PPP);
296               mySeqState.Append(anIntState);
297             } else if(b>0) {
298               SeqPnt.InsertBefore(b,PPP);
299               mySeqState.InsertBefore(b, anIntState);
300             }
301             //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
302           }
303
304  
305           nbpnt++;
306         } 
307       } //-- classifier state is IN or ON
308     } //-- Loop on Intersection points.
309   } //-- HICS.IsDone()
310 #endif
311 }
312
313
314
315 //============================================================================
316 void IntCurvesFace_Intersector::Perform(const Handle(Adaptor3d_HCurve)& HCu,const Standard_Real ParMin,const Standard_Real ParMax) { 
317   done = Standard_True;
318   SeqPnt.Clear();
319   //  Modified by skv - Wed Sep  3 16:14:10 2003 OCC578 Begin
320   mySeqState.Clear();
321   //  Modified by skv - Wed Sep  3 16:14:11 2003 OCC578 End
322   nbpnt = 0;
323   IntCurveSurface_HInter            HICS; 
324   
325   //-- 
326   Standard_Real parinf=ParMin;
327   Standard_Real parsup=ParMax;
328
329   if(PtrOnPolyhedron == NULL) { 
330     HICS.Perform(HCu,Hsurface);
331   }
332   else { 
333     parinf = IntCurveSurface_TheHCurveTool::FirstParameter(HCu);
334     parsup = IntCurveSurface_TheHCurveTool::LastParameter(HCu);
335     if(parinf<ParMin) parinf = ParMin;
336     if(parsup>ParMax) parsup = ParMax;
337     if(parinf>(parsup-1e-9)) return; 
338     Standard_Integer nbs;
339     nbs = IntCurveSurface_TheHCurveTool::NbSamples(HCu,parinf,parsup);
340     
341     IntCurveSurface_ThePolygonOfHInter polygon(HCu,
342                                                parinf,
343                                                parsup,
344                                                nbs);
345 #if OPTIMISATION
346     if(PtrOnBndBounding==NULL) { 
347       PtrOnBndBounding = (Bnd_BoundSortBox *) new Bnd_BoundSortBox();
348       IntCurveSurface_ThePolyhedronOfHInter *thePolyh=(IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
349       ((Bnd_BoundSortBox *)(PtrOnBndBounding))->Initialize(IntCurveSurface_ThePolyhedronToolOfHInter::Bounding(*thePolyh),
350                                                            IntCurveSurface_ThePolyhedronToolOfHInter::ComponentsBounding(*thePolyh));
351     }
352     HICS.Perform(HCu,
353                  polygon,
354                  Hsurface,
355                  *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron),
356                  *((Bnd_BoundSortBox *)PtrOnBndBounding));
357 #else
358     HICS.Perform(HCu,
359                  polygon,
360                  Hsurface,
361                  *((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron));
362 #endif
363   }
364   InternalCall(HICS,parinf,parsup);
365 }
366
367 //============================================================================
368 Bnd_Box IntCurvesFace_Intersector::Bounding() const {
369   if(PtrOnPolyhedron !=NULL) {
370     return(((IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron)->Bounding());
371   }
372   else { 
373     Bnd_Box B;
374     return(B);
375   }
376 }
377 TopAbs_State IntCurvesFace_Intersector::ClassifyUVPoint(const gp_Pnt2d& Puv) const { 
378   TopAbs_State state = myTopolTool->Classify(Puv,1e-7);
379   return(state);
380 }
381 //============================================================================
382 void IntCurvesFace_Intersector::Destroy() { 
383   if(PtrOnPolyhedron !=NULL) { 
384     delete (IntCurveSurface_ThePolyhedronOfHInter *)PtrOnPolyhedron;
385     PtrOnPolyhedron = NULL;
386   }
387   if(PtrOnBndBounding !=NULL) { 
388     delete (Bnd_BoundSortBox *)PtrOnBndBounding;
389     PtrOnBndBounding=NULL;
390   }
391 }
392
393
394