0030480: Visualization - Clear of Select3D_SensitiveGroup does not update internal...
[occt.git] / src / LocOpe / LocOpe_CurveShapeIntersector.cxx
1 // Created on: 1995-05-29
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-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
18 #include <BRepIntCurveSurface_Inter.hxx>
19 #include <Geom_Circle.hxx>
20 #include <GeomAdaptor_Curve.hxx>
21 #include <gp_Ax1.hxx>
22 #include <gp_Circ.hxx>
23 #include <gp_Lin.hxx>
24 #include <LocOpe_CurveShapeIntersector.hxx>
25 #include <LocOpe_PntFace.hxx>
26 #include <Precision.hxx>
27 #include <Standard_OutOfRange.hxx>
28 #include <StdFail_NotDone.hxx>
29 #include <TopoDS_Shape.hxx>
30
31 static void Perform(BRepIntCurveSurface_Inter&,
32                     LocOpe_SequenceOfPntFace&);
33
34
35 //=======================================================================
36 //function : Init
37 //purpose  : 
38 //=======================================================================
39
40 void LocOpe_CurveShapeIntersector::Init(const gp_Ax1& Axis,
41                                         const TopoDS_Shape& S)
42 {
43   myDone = Standard_False;
44   myPoints.Clear();
45   if (S.IsNull()) {
46     return ;
47   }
48   Standard_Real Tol = Precision::Confusion();
49
50   BRepIntCurveSurface_Inter theInt;
51   theInt.Init(S,gp_Lin(Axis),Tol);
52   Perform(theInt,myPoints);
53   myDone = Standard_True;
54 }
55     
56
57 //=======================================================================
58 //function : Init
59 //purpose  : 
60 //=======================================================================
61
62 void LocOpe_CurveShapeIntersector::Init(const gp_Circ& C,
63                                         const TopoDS_Shape& S)
64 {
65   myDone = Standard_False;
66   myPoints.Clear();
67   if (S.IsNull()) {
68     return ;
69   }
70   Standard_Real Tol = Precision::Confusion();
71
72   Handle(Geom_Circle) GC = new Geom_Circle(C);
73   GeomAdaptor_Curve AC(GC,0.,2.*M_PI);
74
75   BRepIntCurveSurface_Inter theInt;
76   theInt.Init(S,AC,Tol);
77
78   Perform(theInt,myPoints);
79   myDone = Standard_True;
80 }
81     
82
83 //=======================================================================
84 //function : LocalizeAfter
85 //purpose  : 
86 //=======================================================================
87
88 Standard_Boolean LocOpe_CurveShapeIntersector::LocalizeAfter
89    (const Standard_Real From,
90     TopAbs_Orientation& Or,
91     Standard_Integer& IndFrom,
92     Standard_Integer& IndTo) const
93 {
94   if (!myDone) {
95     throw StdFail_NotDone();
96   }
97   Standard_Real Eps = Precision::Confusion();
98   Standard_Real param,FMEPS = From - Eps;
99   Standard_Integer i,ifirst,nbpoints = myPoints.Length();
100   for (ifirst=1; ifirst<=nbpoints; ifirst++) {
101     if (myPoints(ifirst).Parameter() >= FMEPS) {
102       break;
103     }
104   }
105   Standard_Boolean RetVal = Standard_False;
106   if (ifirst <= nbpoints) {
107     i = ifirst;
108     IndFrom = ifirst;
109     Standard_Boolean found = Standard_False;
110     while (!found) {
111       Or = myPoints(i).Orientation();
112       param = myPoints(i).Parameter();
113       i = i+1;
114       while (i<=nbpoints) {
115         if (myPoints(i).Parameter()-param <= Eps) {
116           if (Or != TopAbs_EXTERNAL && Or != myPoints(i).Orientation()) {
117             Or = TopAbs_EXTERNAL;
118           }
119           i++;
120         }
121         else {
122           break;
123         }
124       }
125       if (Or == TopAbs_EXTERNAL) {
126         found = (i > nbpoints);
127         IndFrom = i;
128       }
129       else { // on a une intersection franche
130         IndTo = i-1;
131         found = Standard_True;
132         RetVal = Standard_True;
133       }
134     }
135   }
136
137   return RetVal;
138 }
139
140 //=======================================================================
141 //function : LocalizeBefore
142 //purpose  : 
143 //=======================================================================
144
145 Standard_Boolean LocOpe_CurveShapeIntersector::LocalizeBefore
146    (const Standard_Real From,
147      TopAbs_Orientation& Or,
148     Standard_Integer& IndFrom,
149     Standard_Integer& IndTo) const
150 {
151   if (!myDone) {
152     throw StdFail_NotDone();
153   }
154   Standard_Real Eps = Precision::Confusion();
155   Standard_Real param,FPEPS = From + Eps;
156   Standard_Integer i,ifirst,nbpoints = myPoints.Length();
157   for (ifirst=nbpoints; ifirst>=1; ifirst--) {
158     if (myPoints(ifirst).Parameter() <= FPEPS) {
159       break;
160     }
161   }
162   Standard_Boolean RetVal = Standard_False;
163   if (ifirst >= 1) {
164     i = ifirst;
165     IndTo = ifirst;
166     Standard_Boolean found = Standard_False;
167     while (!found) {
168       Or = myPoints(i).Orientation();
169       param = myPoints(i).Parameter();
170       i = i-1;
171       while (i>=1) {
172         if (param - myPoints(i).Parameter() <= Eps) {
173           if (Or != TopAbs_EXTERNAL && Or != myPoints(i).Orientation()) {
174             Or = TopAbs_EXTERNAL;
175           }
176           i--;
177         }
178         else {
179           break;
180         }
181       }
182       if (Or == TopAbs_EXTERNAL) {
183         found = (i < 1);
184         IndTo = i;
185       }
186       else { // on a une intersection franche
187         IndFrom = i+1;
188         found = Standard_True;
189         RetVal = Standard_True;
190       }
191     }
192   }
193
194   return RetVal;
195 }
196
197 //=======================================================================
198 //function : LocalizeAfter
199 //purpose  : 
200 //=======================================================================
201
202 Standard_Boolean LocOpe_CurveShapeIntersector::LocalizeAfter
203    (const Standard_Integer FromInd,
204     TopAbs_Orientation& Or,
205     Standard_Integer& IndFrom,
206     Standard_Integer& IndTo) const
207 {
208   if (!myDone) {
209     throw StdFail_NotDone();
210   }
211   Standard_Integer nbpoints = myPoints.Length();
212   if (FromInd >= nbpoints) {
213     return Standard_False;
214   }
215  
216   Standard_Real Eps = Precision::Confusion();
217   Standard_Real param,FMEPS;
218   Standard_Integer i,ifirst;
219   if (FromInd >= 1) {
220     FMEPS = myPoints(FromInd).Parameter() - Eps;
221     for (ifirst=FromInd+1; ifirst<=nbpoints; ifirst++) {
222       if (myPoints(ifirst).Parameter() >= FMEPS) {
223         break;
224       }
225     }
226   }
227   else {
228     ifirst = 1;
229   }
230
231   Standard_Boolean RetVal = Standard_False;
232   if (ifirst <= nbpoints) {
233     i = ifirst;
234     IndFrom = ifirst;
235     Standard_Boolean found = Standard_False;
236     while (!found) {
237       Or = myPoints(i).Orientation();
238       param = myPoints(i).Parameter();
239       i = i+1;
240       while (i<=nbpoints) {
241         if (myPoints(i).Parameter()-param <= Eps) {
242           if (Or != TopAbs_EXTERNAL && Or != myPoints(i).Orientation()) {
243             Or = TopAbs_EXTERNAL;
244           }
245           i++;
246         }
247         else {
248           break;
249         }
250       }
251       if (Or == TopAbs_EXTERNAL) {
252         found = (i > nbpoints);
253         IndFrom = i;
254       }
255       else { // on a une intersection franche
256         IndTo = i-1;
257         found = Standard_True;
258         RetVal = Standard_True;
259       }
260     }
261   }
262   return RetVal;
263 }
264
265
266 //=======================================================================
267 //function : LocalizeBefore
268 //purpose  : 
269 //=======================================================================
270
271 Standard_Boolean LocOpe_CurveShapeIntersector::LocalizeBefore
272    (const Standard_Integer FromInd,
273      TopAbs_Orientation& Or,
274     Standard_Integer& IndFrom,
275     Standard_Integer& IndTo) const
276 {
277   if (!myDone) {
278     throw StdFail_NotDone();
279   }
280   Standard_Integer nbpoints = myPoints.Length();
281   if (FromInd <= 1) {
282     return Standard_False;
283   }
284  
285   Standard_Real Eps = Precision::Confusion();
286   Standard_Real param,FPEPS;
287   Standard_Integer i,ifirst;
288   if (FromInd <= nbpoints) {
289     FPEPS = myPoints(FromInd).Parameter() + Eps;
290     for (ifirst=FromInd-1; ifirst>=1; ifirst--) {
291       if (myPoints(ifirst).Parameter() <= FPEPS) {
292         break;
293       }
294     }
295   }
296   else {
297     ifirst = nbpoints;
298   }
299
300   Standard_Boolean RetVal = Standard_False;
301   if (ifirst >= 1) {
302     i = ifirst;
303     IndTo = ifirst;
304     Standard_Boolean found = Standard_False;
305     while (!found) {
306       Or = myPoints(i).Orientation();
307       param = myPoints(i).Parameter();
308       i = i-1;
309       while (i>=1) {
310         if (param - myPoints(i).Parameter() <= Eps) {
311           if (Or != TopAbs_EXTERNAL && Or != myPoints(i).Orientation()) {
312             Or = TopAbs_EXTERNAL;
313           }
314           i--;
315         }
316         else {
317           break;
318         }
319       }
320       if (Or == TopAbs_EXTERNAL) {
321         found = (i < 1);
322         IndTo = i;
323       }
324       else { // on a une intersection franche
325         IndFrom = i+1;
326         found = Standard_True;
327         RetVal = Standard_True;
328       }
329     }
330   }
331   return RetVal;
332 }
333
334
335 //=======================================================================
336 //function : Perform
337 //purpose  : 
338 //=======================================================================
339
340 static void Perform(BRepIntCurveSurface_Inter & theInt,
341                     LocOpe_SequenceOfPntFace& thePoints)
342 {
343   Standard_Real param,paramu,paramv;
344   Standard_Integer i, nbpoints=0;
345
346   TopAbs_Orientation theor=TopAbs_FORWARD, orface;
347
348   while (theInt.More()) {
349     const gp_Pnt& thept = theInt.Pnt();
350     const TopoDS_Face& theface = theInt.Face();
351     orface = theface.Orientation();
352     param = theInt.W();
353     paramu = theInt.U();
354     paramv = theInt.V();
355
356     switch (theInt.Transition()) {
357     case IntCurveSurface_In:
358       if ( orface == TopAbs_FORWARD) {
359         theor = TopAbs_FORWARD;
360       }
361       else if (orface == TopAbs_REVERSED) {
362         theor = TopAbs_REVERSED;
363       }
364       else {
365         theor = TopAbs_EXTERNAL;
366       }
367       break;
368     case IntCurveSurface_Out:
369       if ( orface == TopAbs_FORWARD) {
370         theor = TopAbs_REVERSED;
371       }
372       else if (orface == TopAbs_REVERSED) {
373         theor = TopAbs_FORWARD;
374       }
375       else {
376         theor = TopAbs_EXTERNAL;
377       }
378       break;
379     case IntCurveSurface_Tangent:
380       theor = TopAbs_EXTERNAL;
381       break;
382
383     }
384
385     LocOpe_PntFace newpt(thept,theface,theor,param,paramu,paramv);
386
387     for (i=1; i <= nbpoints; i++) {
388       if (thePoints(i).Parameter() - param > 0.) {
389         break;
390       }
391     }
392     if (i <= nbpoints) {
393       thePoints.InsertBefore(i,newpt);
394     }
395     else {
396       thePoints.Append(newpt);
397     }
398     nbpoints++;
399     theInt.Next();
400   }
401 }