b311480e |
1 | // Created on: 1992-01-23 |
2 | // Created by: Didier PIFFAULT |
3 | // Copyright (c) 1992-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
17 | |
18 | #include <gp_Dir.hxx> |
7fd59977 |
19 | #include <TopAbs.hxx> |
42cf5bc1 |
20 | #include <TopTrans_CurveTransition.hxx> |
7fd59977 |
21 | |
22 | #define GREATER 1 |
23 | #define SAME 0 |
24 | #define LOWER -1 |
25 | |
26 | //======================================================================= |
27 | //function : TopTrans_CurveTransition |
28 | //purpose : Empty Constructor. |
29 | //======================================================================= |
30 | |
31 | TopTrans_CurveTransition::TopTrans_CurveTransition () |
d533dafb |
32 | : myCurv(0.0), |
33 | Init(Standard_False), |
34 | CurvFirst(0.0), |
35 | CurvLast(0.0) |
7fd59977 |
36 | { |
37 | } |
38 | |
39 | //======================================================================= |
40 | //function : Reset |
41 | //purpose : Initializer for a complex curve transition with the elements |
42 | // of the intersecting curve. |
43 | //======================================================================= |
44 | |
45 | void TopTrans_CurveTransition::Reset (const gp_Dir& Tgt, |
46 | const gp_Dir& Norm, |
47 | const Standard_Real Curv) |
48 | { |
49 | myTgt=Tgt; myNorm=Norm; myCurv=Curv; Init=Standard_True; |
50 | } |
51 | |
52 | //======================================================================= |
53 | //function : Reset |
54 | //purpose : Initializer for a complex curve transition with the elements |
55 | // of the intersecting straight line. |
56 | //======================================================================= |
57 | |
58 | void TopTrans_CurveTransition::Reset (const gp_Dir& Tgt) |
59 | { |
60 | myTgt=Tgt; myCurv=0.; Init=Standard_True; |
61 | } |
62 | |
63 | //======================================================================= |
64 | //function : Compare |
65 | //purpose : Compare the elements of an interference on an intersected |
66 | // curve with the interference stored in the complex Transition. |
67 | //======================================================================= |
68 | |
69 | void TopTrans_CurveTransition::Compare (const Standard_Real Tole, |
70 | const gp_Dir& T, |
71 | const gp_Dir& N, |
72 | const Standard_Real C, |
73 | const TopAbs_Orientation St, |
74 | const TopAbs_Orientation Or) |
75 | { |
76 | // S is the transition, how the curve cross the boundary |
77 | // O is the orientation, how the intersection is set on the boundary |
78 | TopAbs_Orientation S = St; |
79 | TopAbs_Orientation O = Or; |
80 | |
81 | // adjustment for INTERNAL transition |
82 | if (S == TopAbs_INTERNAL) { |
83 | if (T * myTgt < 0) |
84 | S = TopAbs::Reverse(O); |
85 | else |
86 | S = O; |
87 | } |
88 | |
89 | // It is the first comparaison for this complex transition |
90 | if (Init) { |
91 | Init=Standard_False; |
92 | TgtFirst =T; |
93 | NormFirst=N; |
94 | CurvFirst=C; |
95 | TranFirst=S; |
96 | TgtLast =T; |
97 | NormLast =N; |
98 | CurvLast =C; |
99 | TranLast =S; |
100 | switch (O) { |
101 | // Interference en fin d'arete il faut inverser la tangente |
102 | case TopAbs_REVERSED : |
103 | TgtFirst.Reverse(); |
104 | TgtLast.Reverse(); |
105 | break; |
106 | case TopAbs_INTERNAL : |
107 | // Interference en milieu d'arete il faut inverser en fonction de la |
108 | // position de la tangente de reference |
109 | if (myTgt*T>0) TgtFirst.Reverse(); |
110 | else TgtLast.Reverse(); |
111 | break; |
112 | case TopAbs_FORWARD : |
113 | case TopAbs_EXTERNAL : |
114 | break; |
115 | } |
116 | } |
117 | |
118 | // Compare with the existent first and last transition : |
119 | else { |
120 | Standard_Boolean FirstSet=Standard_False; |
121 | Standard_Real cosAngWithT=myTgt*T; |
122 | switch (O) { |
123 | case TopAbs_REVERSED : |
124 | cosAngWithT= -cosAngWithT; |
125 | break; |
126 | case TopAbs_INTERNAL : |
127 | if (cosAngWithT>0) cosAngWithT=-cosAngWithT; |
128 | break; |
129 | case TopAbs_FORWARD : |
130 | case TopAbs_EXTERNAL : |
131 | break; |
132 | } |
133 | Standard_Real cosAngWith1=myTgt*TgtFirst; |
134 | |
135 | switch (Compare(cosAngWithT, cosAngWith1, Tole)) { |
136 | |
137 | case LOWER : |
138 | // If the angle is greater than the first the new become the first |
139 | FirstSet=Standard_True; |
140 | TgtFirst =T; |
141 | switch (O) { |
142 | case TopAbs_REVERSED : |
143 | TgtFirst.Reverse(); |
144 | break; |
145 | case TopAbs_INTERNAL : |
146 | if (myTgt*T>0) TgtFirst.Reverse(); |
147 | break; |
148 | case TopAbs_FORWARD : |
149 | case TopAbs_EXTERNAL : |
150 | break; |
151 | } |
152 | NormFirst=N; |
153 | CurvFirst=C; |
154 | TranFirst=S; |
155 | break; |
156 | |
157 | case SAME : |
158 | // If same angles we look at the Curvature |
159 | if (IsBefore(Tole, cosAngWithT, N, C, NormFirst, CurvFirst)) { |
160 | FirstSet=Standard_True; |
161 | TgtFirst =T; |
162 | switch (O) { |
163 | case TopAbs_REVERSED : |
164 | TgtFirst.Reverse(); |
165 | break; |
166 | case TopAbs_INTERNAL : |
167 | if (myTgt*T>0) TgtFirst.Reverse(); |
168 | break; |
169 | case TopAbs_FORWARD : |
170 | case TopAbs_EXTERNAL : |
171 | break; |
172 | } |
173 | NormFirst=N; |
174 | CurvFirst=C; |
175 | TranFirst=S; |
176 | } |
177 | break; |
178 | |
179 | case GREATER: |
180 | break; |
181 | } |
182 | |
183 | if (!FirstSet || O==TopAbs_INTERNAL) { |
184 | // Dans les cas de tangence le premier peut etre aussi le dernier |
185 | if (O==TopAbs_INTERNAL) cosAngWithT=-cosAngWithT; |
186 | Standard_Real cosAngWith2=myTgt*TgtLast; |
187 | |
188 | switch (Compare(cosAngWithT, cosAngWith2, Tole)) { |
189 | |
190 | case GREATER: |
191 | // If the angle is lower than the last the new become the last |
192 | TgtLast =T; |
193 | switch (O) { |
194 | case TopAbs_REVERSED : |
195 | TgtLast.Reverse(); |
196 | break; |
197 | case TopAbs_INTERNAL : |
198 | if (myTgt*T<0) TgtLast.Reverse(); |
199 | break; |
200 | case TopAbs_FORWARD : |
201 | case TopAbs_EXTERNAL : |
202 | break; |
203 | } |
204 | NormLast =N; |
205 | CurvLast =C; |
206 | TranLast =S; |
207 | break; |
208 | |
209 | case SAME: |
210 | // If the angle is the same we look at the curvature |
211 | if (IsBefore(Tole, cosAngWithT, NormLast, CurvLast, N, C)) { |
212 | TgtLast =T; |
213 | switch (O) { |
214 | case TopAbs_REVERSED : |
215 | TgtLast.Reverse(); |
216 | break; |
217 | case TopAbs_INTERNAL : |
218 | if (myTgt*T<0) TgtLast.Reverse(); |
219 | break; |
220 | case TopAbs_FORWARD : |
221 | case TopAbs_EXTERNAL : |
222 | break; |
223 | } |
224 | NormLast=N; |
225 | CurvLast=C; |
226 | TranLast=S; |
227 | } |
228 | } |
229 | } |
230 | } |
231 | } |
232 | |
233 | //======================================================================= |
234 | //function : StateBefore |
235 | //purpose : Give the state of the curv before the interference. |
236 | //======================================================================= |
237 | |
238 | TopAbs_State TopTrans_CurveTransition::StateBefore () const |
239 | { |
240 | if (Init) return TopAbs_UNKNOWN; |
241 | switch (TranFirst) |
242 | { |
243 | case TopAbs_FORWARD : |
244 | case TopAbs_EXTERNAL : |
245 | return TopAbs_OUT; |
246 | case TopAbs_REVERSED : |
247 | case TopAbs_INTERNAL : |
248 | return TopAbs_IN; |
249 | } |
250 | return TopAbs_OUT; |
251 | } |
252 | |
253 | //======================================================================= |
254 | //function : StateAfter |
255 | //purpose : give the state of the curve after the interference. |
256 | //======================================================================= |
257 | |
258 | TopAbs_State TopTrans_CurveTransition::StateAfter () const |
259 | { |
260 | if (Init) return TopAbs_UNKNOWN; |
261 | switch (TranLast) |
262 | { |
263 | case TopAbs_FORWARD : |
264 | case TopAbs_INTERNAL : |
265 | return TopAbs_IN; |
266 | case TopAbs_REVERSED : |
267 | case TopAbs_EXTERNAL : |
268 | return TopAbs_OUT; |
269 | } |
270 | return TopAbs_OUT; |
271 | } |
272 | |
273 | |
274 | //======================================================================= |
275 | //function : IsBefore |
276 | //purpose : Compare the curvature of the two transition and return true |
277 | // if T1 is before T2 |
278 | //======================================================================= |
279 | |
280 | Standard_Boolean TopTrans_CurveTransition::IsBefore |
281 | (const Standard_Real Tole, |
282 | const Standard_Real CosAngl, |
283 | const gp_Dir& N1, |
284 | const Standard_Real C1, |
285 | const gp_Dir& N2, |
286 | const Standard_Real C2) const |
287 | { |
288 | Standard_Real TN1=myTgt*N1; |
289 | Standard_Real TN2=myTgt*N2; |
290 | Standard_Boolean OneBefore=Standard_False; |
291 | |
292 | if (Abs(TN1)<=Tole || Abs(TN2)<=Tole) { |
293 | // Tangent : The first is the interference which have the nearest curvature |
294 | // from the reference. |
295 | if (myCurv==0) { |
296 | // The reference is straight |
297 | // The first is the interference which have the lowest curvature. |
298 | if (C1<C2) OneBefore=Standard_True; |
299 | // Modified by Sergey KHROMOV - Wed Dec 27 17:08:49 2000 Begin |
300 | if (CosAngl>0) |
301 | OneBefore=!OneBefore; |
302 | // Modified by Sergey KHROMOV - Wed Dec 27 17:08:50 2000 End |
303 | } |
304 | else { |
305 | // The reference is curv |
306 | // The first is the interference which have the nearest curvature |
307 | // in the direction |
308 | Standard_Real deltaC1, deltaC2; |
309 | if (C1==0. || myCurv==0.) { |
310 | deltaC1=C1-myCurv; |
311 | } |
312 | else { |
313 | deltaC1=(C1-myCurv)*(N1*myNorm); |
314 | } |
315 | if (C2==0. || myCurv==0.) { |
316 | deltaC2=C2-myCurv; |
317 | } |
318 | else { |
319 | deltaC2=(C2-myCurv)*(N2*myNorm); |
320 | } |
321 | if (deltaC1 < deltaC2) OneBefore=Standard_True; |
322 | if (CosAngl>0) OneBefore=!OneBefore; |
323 | } |
324 | } |
325 | else if (TN1<0) { |
326 | // Before the first interference we are in the curvature |
327 | if (TN2>0) { |
328 | // Before the second interference we are out the curvature |
329 | // The first interference is before /* ->)( */ |
330 | OneBefore=Standard_True; |
331 | } |
332 | else { |
333 | // Before the second interference we are in the curvature |
334 | if (C1>C2) { |
335 | // We choice the greater curvature |
336 | // The first interference is before /* ->)) */ |
337 | OneBefore=Standard_True; |
338 | } |
339 | } |
340 | } |
341 | else if (TN1>0) { |
342 | // Before the first interference we are out the curvature |
343 | if (TN2>0) { |
344 | // Before the second interference we are out the curvature /* ->(( */ |
345 | if (C1<C2) { |
346 | // We choice the lower curvature |
347 | // The first interference is before |
348 | OneBefore=Standard_True; |
349 | } |
350 | } |
351 | } |
352 | return OneBefore; |
353 | } |
354 | |
355 | |
356 | //======================================================================= |
357 | //function : Compare |
358 | //purpose : Compare two angles |
359 | //======================================================================= |
360 | |
361 | Standard_Integer TopTrans_CurveTransition::Compare(const Standard_Real Ang1, |
362 | const Standard_Real Ang2, |
363 | const Standard_Real Tole) const |
364 | { |
365 | Standard_Integer res=SAME; |
366 | if (Ang1 - Ang2 > Tole) res=GREATER; |
367 | else if (Ang2 - Ang1 > Tole) res=LOWER; |
368 | |
369 | return res; |
370 | } |