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