0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / TopTrans / TopTrans_SurfaceTransition.cxx
CommitLineData
b311480e 1// Created on: 1997-03-04
2// Created by: Prestataire Xuan PHAM PHU
3// Copyright (c) 1995-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
7fd59977 22// Modified: eap Mar 25 2002 (occ102,occ227), touch case
23#include <TopTrans_SurfaceTransition.ixx>
24
25#include <gp_Dir.hxx>
26#include <TopAbs.hxx>
27#include <TopAbs_State.hxx>
28#include <TopAbs_Orientation.hxx>
29#include <Precision.hxx>
30
31#define Msr Standard_Real
32#define Msi Standard_Integer
33#define Msb Standard_Boolean
34#define Msf Standard_False
35#define Mst Standard_True
36#define MTAo TopAbs_Orientation
37#define MTAs TopAbs_State
38
39static Standard_Boolean STATIC_DEFINED = Standard_False;
40
41//#include <TopOpeBRepTool_EXPORT.hxx>
42static gp_Dir FUN_nCinsideS(const gp_Dir& tgC, const gp_Dir& ngS)
43{
44 // Give us a curve C on suface S, <parOnC>, a parameter
45 // Purpose : compute normal vector to C, tangent to S at
46 // given point , oriented INSIDE S
47 // <tgC> : geometric tangent at point of <parOnC>
48 // <ngS> : geometric normal at point of <parOnC>
49 gp_Dir XX(ngS^tgC);
50 return XX;
51}
52
53#define M_REVERSED(st) (st == TopAbs_REVERSED)
54#define M_INTERNAL(st) (st == TopAbs_INTERNAL)
55#define M_UNKNOWN(st) (st == TopAbs_UNKNOWN)
56
57static Standard_Integer FUN_OO(const Standard_Integer i)
58{
59 if (i == 1) return 2;
60 if (i == 2) return 1;
61 return 0;
62}
63
64//static Standard_Real FUN_Ang(const gp_Dir& Normref,
65static Standard_Real FUN_Ang(const gp_Dir& ,
66 const gp_Dir& beafter,
67 const gp_Dir& TgC,
68 const gp_Dir& Norm,
69 const TopAbs_Orientation O)
70{
71 gp_Dir dironF = FUN_nCinsideS(TgC,Norm);
72 if (M_REVERSED(O)) dironF.Reverse();
73
74 Standard_Real ang = beafter.AngleWithRef(dironF,TgC);
75 return ang;
76}
77
78static void FUN_getSTA(const Standard_Real Ang, const Standard_Real tola,
79 Standard_Integer& i, Standard_Integer& j)
80{
81 Standard_Real cos = Cos(Ang);
82 Standard_Real sin = Sin(Ang);
83 Standard_Boolean nullcos = Abs(cos) < tola;
84 Standard_Boolean nullsin = Abs(sin) < tola;
85 if (nullcos) i = 0;
86 else i = (cos > 0.) ? 1 : 2;
87 if (nullsin) j = 0;
88 else j = (sin > 0.) ? 1 : 2;
89}
90
91/*static void FUN_getSTA(const Standard_Real Ang, const Standard_Real tola,
92 const Standard_Real Curv, const Standard_Real CurvRef,
93 Standard_Integer& i, Standard_Integer& j)
94{
95 // Choosing UV referential (beafter,myNorm).
96 // purpose : computes position boundary face relative to the reference surface
97 // notice : j==0 => j==1 : the boundary face is ABOVE the reference surface
98 // j==2 : the boundary face is UNDER the reference surface
99 // - j==0 : the boundary and the reference objects are tangent-
100
101 FUN_getSTA(Ang,tola,i,j);
102 if (j == 0) {
103 Standard_Real diff = Curv - CurvRef;
104 if (Abs(diff) < tola) {STATIC_DEFINED = Standard_False; return;} // nyi FUN_Raise
105 j = (diff < 0.) ? 1 : 2;
106 }
107}*/
108#ifndef DEB
109#define M_Unknown (-100)
110#else
111#define M_Unknown (-100.)
112#endif
113#define M_noupdate (0)
114#define M_updateREF (1)
115#define M_Ointernal (10)
116static Standard_Integer FUN_refnearest(const Standard_Real Angref, const TopAbs_Orientation Oriref,
117 const Standard_Real Ang, const TopAbs_Orientation Ori, const Standard_Real tola)
118{
119 Standard_Boolean undef = (Angref == 100.);
120 if (undef) return M_updateREF;
121
122 Standard_Real cosref = Cos(Angref), cos = Cos(Ang);
123 Standard_Real dcos = Abs(cosref) - Abs(cos);
124 if (Abs(dcos) < tola) {
125 // Analysis for tangent cases : if two boundary faces are same sided
126 // and have tangent normals, if they have opposite orientations
127 // we choose INTERNAL as resulting complex transition (case EXTERNAL
128 // refering to no logical case)
129 if (TopAbs::Complement(Ori) == Oriref) return M_Ointernal;
130 else return (Standard_Integer ) M_Unknown; // nyi FUN_RAISE
131 }
132 Standard_Integer updateref = (dcos > 0.)? M_noupdate : M_updateREF;
133 return updateref;
134}
135
136//=======================================================================
137//function : FUN_refnearest
138//purpose :
139//=======================================================================
140
141static Standard_Integer FUN_refnearest(const Standard_Integer i,
142 const Standard_Integer j,
143 const Standard_Real CurvSref,
144 const Standard_Real Angref,
145 const TopAbs_Orientation Oriref,
146 const Standard_Real Curvref,
147 const Standard_Real Ang,
148 const TopAbs_Orientation Ori,
149 const Standard_Real Curv,
150 const Standard_Real tola,
151 Standard_Boolean & TouchFlag) // eap Mar 25 2002
152{
153 Standard_Boolean iisj = (i == j);
154 Standard_Real abscos = Abs(Cos(Ang));
155 Standard_Boolean i0 = (Abs(1. - abscos) < tola);
156 Standard_Boolean j0 = (abscos < tola);
157 Standard_Boolean nullcurv = (Curv == 0.);
158 Standard_Boolean curvpos = (Curv > tola);
159 Standard_Boolean curvneg = (Curv < -tola);
160 Standard_Boolean nullcsref = (CurvSref == 0.);
161
162 Standard_Boolean undef = (Angref == 100.);
163 if (undef) {
164 if (i0) {
165 if (iisj && curvneg) return M_noupdate;
166 if (!iisj && curvpos) return M_noupdate;
167 }
168 if (j0) {
169 if (!nullcsref && (j == 1) && iisj && (curvpos || nullcurv)) return M_updateREF;
170 if (!nullcsref && (j == 1) && !iisj && (curvneg || nullcurv)) return M_updateREF;
171
172 if (iisj && curvpos) return M_noupdate;
173 if (!iisj && curvneg) return M_noupdate;
174 }
175 return M_updateREF;
176 } // undef
177
178 Standard_Real cosref = Cos(Angref), cos = Cos(Ang);
179 Standard_Real dcos = Abs(cosref) - Abs(cos); Standard_Boolean samecos = Abs(dcos) < tola;
180 if (samecos) {
181 // Analysis for tangent cases : if two boundary faces are same sided
182 // and have sma dironF.
183
184 if (Abs(Curvref - Curv) < 1.e-4) {
185 if (TopAbs::Complement(Ori) == Oriref) return M_Ointernal;
186 else return (Standard_Integer ) M_Unknown; // nyi FUN_RAISE
187 }
188
189 Standard_Boolean noupdate = Standard_False;
190 if (iisj && (Curvref > Curv)) noupdate = Standard_True;
191 if (!iisj && (Curvref < Curv)) noupdate = Standard_True;
192 Standard_Integer updateref = noupdate ? M_noupdate : M_updateREF;
193 if (!j0) return updateref;
194
195 if (!noupdate && !nullcsref) {
196 // check for (j==1) the face is ABOVE Sref
197 // check for (j==2) the face is BELOW Sref
198 if ((j == 2) && (Abs(Curv) < CurvSref)) updateref = M_noupdate;
199 if ((j == 1) && (Abs(Curv) > CurvSref)) updateref = M_noupdate;
200 }
201 return updateref;
202 } // samecos
203
204 Standard_Integer updateref = (dcos > 0.)? M_noupdate : M_updateREF;
205 if (Oriref != Ori) TouchFlag = Standard_True; // eap Mar 25 2002
206
207 return updateref;
208}
209
210// ============================================================
211// methods
212// ============================================================
213
214TopTrans_SurfaceTransition::TopTrans_SurfaceTransition()
215: myAng(1,2,1,2),myCurv(1,2,1,2),myOri(1,2,1,2)
216{
217 STATIC_DEFINED = Standard_False;
218}
219
220void TopTrans_SurfaceTransition::Reset(const gp_Dir& Tgt,
221 const gp_Dir& Norm,
222 const gp_Dir& MaxD,const gp_Dir& MinD,
223 const Standard_Real MaxCurv,const Standard_Real MinCurv)
224{
225 STATIC_DEFINED = Standard_True;
226
227 Standard_Real tola = Precision::Angular();
228 Standard_Boolean curismax = (Abs(MaxD.Dot(myTgt)) < tola);
229 Standard_Boolean curismin = (Abs(MinD.Dot(myTgt)) < tola);
230
231 if ((Abs(MaxCurv) < tola) && (Abs(MinCurv) < tola)) {
232 Reset(Tgt,Norm);
233 return;
234 }
235
236 if (!curismax && !curismin) {
237 // In the plane normal to <myTgt>, we see the boundary face as
238 // a boundary curve.
239 // NYIxpu : compute the curvature of the curve if not MaxCurv
240 // nor MinCurv.
241
242 STATIC_DEFINED = Standard_False;
243 return;
244 }
245
246 if (curismax) myCurvRef = Abs(MaxCurv);
247 if (curismin) myCurvRef = Abs(MinCurv);
248 if (myCurvRef < tola) myCurvRef = 0.;
249
250 // ============================================================
251 // recall : <Norm> is oriented OUTSIDE the "geometric matter" described
252 // by the surface
253 // - if (myCurvRef != 0.) Sref is UNDER axis (sin = 0)
254 // referential (beafter,myNorm,myTgt) -
255 // ============================================================
256
257 // beafter oriented (before, after) the intersection on the reference surface.
258 myNorm = Norm;
259 myTgt = Tgt;
260 beafter = Norm^Tgt;
261 for (Standard_Integer i = 1; i <=2; i++)
262 for (Standard_Integer j = 1; j <=2; j++)
263 myAng(i,j) = 100.;
264
265 myTouchFlag = Standard_False; // eap Mar 25 2002
266}
267
268void TopTrans_SurfaceTransition::Reset(const gp_Dir& Tgt,
269 const gp_Dir& Norm)
270{
271 STATIC_DEFINED = Standard_True;
272
273 // beafter oriented (before, after) the intersection on the reference surface.
274 myNorm = Norm;
275 myTgt = Tgt;
276 beafter = Norm^Tgt;
277 for (Standard_Integer i = 1; i <=2; i++)
278 for (Standard_Integer j = 1; j <=2; j++)
279 myAng(i,j) = 100.;
280
281 myCurvRef = 0.;
282 myTouchFlag = Standard_False; // eap Mar 25 2002
283}
284
285void TopTrans_SurfaceTransition::Compare
286//(const Standard_Real Tole,
287(const Standard_Real ,
288 const gp_Dir& Norm,
289 const gp_Dir& MaxD,const gp_Dir& MinD,
290 const Standard_Real MaxCurv,const Standard_Real MinCurv,
291 const TopAbs_Orientation S,
292 const TopAbs_Orientation O)
293{
294 if (!STATIC_DEFINED) return;
295
296 Standard_Real Curv=0.;
297 // ------
298 Standard_Real tola = Precision::Angular();
299 Standard_Boolean curismax = (Abs(MaxD.Dot(myTgt)) < tola);
300 Standard_Boolean curismin = (Abs(MinD.Dot(myTgt)) < tola);
301 if (!curismax && !curismin) {
302 // In the plane normal to <myTgt>, we see the boundary face as
303 // a boundary curve.
304 // NYIxpu : compute the curvature of the curve if not MaxCurv
305 // nor MinCurv.
306
307 STATIC_DEFINED = Standard_False;
308 return;
309 }
310 if (curismax) Curv = Abs(MaxCurv);
311 if (curismin) Curv = Abs(MinCurv);
312 if (myCurvRef < tola) Curv = 0.;
313 gp_Dir dironF = FUN_nCinsideS(myTgt,Norm);
314 Standard_Real prod = (dironF^Norm).Dot(myTgt);
315 if (prod < 0.) Curv = -Curv;
316
317 Standard_Real Ang;
318 // -----
319 Ang = ::FUN_Ang(myNorm,beafter,myTgt,Norm,O);
320
321 Standard_Integer i,j;
322 // -----
323 // i = 0,1,2 : cos = 0,>0,<0
324 // j = 0,1,2 : sin = 0,>0,<0
325 ::FUN_getSTA(Ang,tola,i,j);
326
327 // update nearest :
328 // ---------------
329 Standard_Integer kmax = M_INTERNAL(O) ? 2 : 1;
330 for (Standard_Integer k=1; k <=kmax; k++) {
331 if (k == 2) {
332 // get the opposite Ang
333 i = ::FUN_OO(i);
334 j = ::FUN_OO(j);
335 }
336 Standard_Boolean i0 = (i == 0), j0 = (j == 0);
337 Standard_Integer nmax = (i0 || j0) ? 2 : 1;
338 for (Standard_Integer n=1; n<=nmax; n++) {
339 if (i0) i = n;
340 if (j0) j = n;
341
342 // if (curvref == 0.) :
343// Standard_Boolean iisj = (i == j);
344// Standard_Boolean Curvpos = (Curv > 0.);
345// if ((Curv != 0.) && i0) {
346// if (iisj && !Curvpos) continue;
347// if (!iisj && Curvpos) continue;
348// }
349// if ((Curv != 0.) && j0) {
350// if (iisj && Curvpos) continue;
351// if (!iisj && !Curvpos) continue;
352// }
353
354 Standard_Integer refn = ::FUN_refnearest(i,j,myCurvRef,myAng(i,j),myOri(i,j),myCurv(i,j),
355 Ang,/*O*/S,Curv,tola,myTouchFlag); // eap Mar 25 2002
356 if (refn == M_Unknown) {STATIC_DEFINED = Standard_False; return;}
357 if (refn > 0) {
358 myAng(i,j) = Ang;
359 myOri(i,j) = (refn == M_Ointernal) ? TopAbs_INTERNAL : S;
360 myCurv(i,j) = Curv;
361 }
362 } // n=1..nmax
363 } // k=1..kmax
364
365}
366
367void TopTrans_SurfaceTransition::Compare
368//(const Standard_Real Tole,
369(const Standard_Real ,
370 const gp_Dir& Norm,
371 const TopAbs_Orientation S,
372 const TopAbs_Orientation O)
373{
374 if (!STATIC_DEFINED) return;
375
376 // oriented Ang(beafter,dironF),
377 // dironF normal to the curve, oriented INSIDE F, the added oriented support
378 Standard_Real Ang = ::FUN_Ang(myNorm,beafter,myTgt,Norm,O);
379 Standard_Real tola = Precision::Angular(); // nyi in arg
380
381 // i = 0,1,2 : cos = 0,>0,<0
382 // j = 0,1,2 : sin = 0,>0,<0
383 Standard_Integer i,j; ::FUN_getSTA(Ang,tola,i,j);
384
385 Standard_Integer kmax = M_INTERNAL(O) ? 2 : 1;
386 for (Standard_Integer k=1; k <=kmax; k++) {
387 if (k == 2) {
388 // get the opposite Ang
389 i = ::FUN_OO(i);
390 j = ::FUN_OO(j);
391 }
392
393 Standard_Boolean i0 = (i == 0), j0 = (j == 0);
394 Standard_Integer nmax = (i0 || j0) ? 2 : 1;
395 for (Standard_Integer n=1; n<=nmax; n++) {
396 if (i0) i = n;
397 if (j0) j = n;
398
399 Standard_Integer refn = ::FUN_refnearest(myAng(i,j),myOri(i,j),
400 Ang,/*O*/S,tola); // eap
401 if (refn == M_Unknown) {STATIC_DEFINED = Standard_False; return;}
402
403 if (refn > 0) {
404 myAng(i,j) = Ang;
405 myOri(i,j) = (refn == M_Ointernal) ? TopAbs_INTERNAL : S;
406 }
407 } // n=1..nmax
408 } // k=1..kmax
409}
410
411#define BEFORE (2)
412#define AFTER (1)
413static TopAbs_State FUN_getstate(const TColStd_Array2OfReal& Ang,
414 const TopTrans_Array2OfOrientation& Ori,
415 const Standard_Integer iSTA,
416 const Standard_Integer iINDEX)
417{
418 if (!STATIC_DEFINED) return TopAbs_UNKNOWN;
419
420 Standard_Real a1 = Ang(iSTA,1), a2 = Ang(iSTA,2);
421 Standard_Boolean undef1 = (a1 == 100.), undef2 = (a2 == 100.);
422 Standard_Boolean undef = undef1 && undef2;
423 if (undef) return TopAbs_UNKNOWN;
424
425 if (undef1 || undef2) {
426 Standard_Integer jok = undef1 ? 2 : 1;
427 TopAbs_Orientation o = Ori(iSTA,jok);
428 TopAbs_State st = (iINDEX == BEFORE) ? TopTrans_SurfaceTransition::GetBefore(o) :
429 TopTrans_SurfaceTransition::GetAfter(o);
430 return st;
431 }
432
433 TopAbs_Orientation o1 = Ori(iSTA,1), o2 = Ori(iSTA,2);
434 TopAbs_State st1 = (iINDEX == BEFORE) ? TopTrans_SurfaceTransition::GetBefore(o1) :
435 TopTrans_SurfaceTransition::GetAfter(o1);
436 TopAbs_State st2 = (iINDEX == BEFORE) ? TopTrans_SurfaceTransition::GetBefore(o2) :
437 TopTrans_SurfaceTransition::GetAfter(o2);
438 if (st1 != st2) return TopAbs_UNKNOWN; // Incoherent data
439 return st1;
440}
441
442
443TopAbs_State TopTrans_SurfaceTransition::StateBefore() const
444{
445 if (!STATIC_DEFINED) return TopAbs_UNKNOWN;
446
447 // we take the state before of before orientations
448 TopAbs_State before = ::FUN_getstate(myAng,myOri,BEFORE,BEFORE);
449 if (M_UNKNOWN(before)) {
450 // looking back in before for defined states
451 // we take the state before of after orientations
452 before = ::FUN_getstate(myAng,myOri,AFTER,BEFORE);
453 // eap Mar 25 2002
eafb234b 454 if (myTouchFlag) {
7fd59977 455 if (before == TopAbs_OUT) before = TopAbs_IN;
456 else if (before == TopAbs_IN) before = TopAbs_OUT;
eafb234b 457 }
7fd59977 458 }
459 return before;
460}
461
462TopAbs_State TopTrans_SurfaceTransition::StateAfter() const
463{
464 if (!STATIC_DEFINED) return TopAbs_UNKNOWN;
465
466 TopAbs_State after = ::FUN_getstate(myAng,myOri,AFTER,AFTER);
467 if (M_UNKNOWN(after)) {
468 // looking back in before for defined states
469 after = ::FUN_getstate(myAng,myOri,BEFORE,AFTER);
470 // eap Mar 25 2002
eafb234b 471 if (myTouchFlag) {
7fd59977 472 if (after == TopAbs_OUT) after = TopAbs_IN;
473 else if (after == TopAbs_IN) after = TopAbs_OUT;
eafb234b 474 }
7fd59977 475 }
476 return after;
477}
478
479TopAbs_State TopTrans_SurfaceTransition::GetBefore
480(const TopAbs_Orientation Tran)
481{
482 if (!STATIC_DEFINED) return TopAbs_UNKNOWN;
483
484 switch (Tran)
485 {
486 case TopAbs_FORWARD :
487 case TopAbs_EXTERNAL :
488 return TopAbs_OUT;
489 case TopAbs_REVERSED :
490 case TopAbs_INTERNAL :
491 return TopAbs_IN;
492 }
493 return TopAbs_OUT;
494}
495
496TopAbs_State TopTrans_SurfaceTransition::GetAfter
497(const TopAbs_Orientation Tran)
498{
499 if (!STATIC_DEFINED) return TopAbs_UNKNOWN;
500
501 switch (Tran)
502 {
503 case TopAbs_FORWARD :
504 case TopAbs_INTERNAL :
505 return TopAbs_IN;
506 case TopAbs_REVERSED :
507 case TopAbs_EXTERNAL :
508 return TopAbs_OUT;
509 }
510 return TopAbs_OUT;
511}