0025747: Bad IGES file after import and export with different units
[occt.git] / src / IGESGeom / IGESGeom_ConicArc.cxx
CommitLineData
b311480e 1// Created by: CKY / Contract Toubro-Larsen
2// Copyright (c) 1993-1999 Matra Datavision
973c2be1 3// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
7fd59977 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
7fd59977 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
16//--------------------------------------------------------------------
7fd59977 17//--------------------------------------------------------------------
18//#59 rln 29.12.98 PRO17015
19
20#include <IGESGeom_ConicArc.ixx>
21#include <gp_Dir2d.hxx>
22#include <gp_GTrsf.hxx>
23
24
b311480e 25IGESGeom_ConicArc::IGESGeom_ConicArc () { }
7fd59977 26
27
28 void IGESGeom_ConicArc::Init
29 (const Standard_Real A, const Standard_Real B,
30 const Standard_Real C, const Standard_Real D, const Standard_Real E,
31 const Standard_Real F, const Standard_Real ZT, const gp_XY& aStart,
32 const gp_XY& anEnd)
33{
34 theA = A;
35 theB = B;
36 theC = C;
37 theD = D;
38 theE = E;
39 theF = F;
40 theZT = ZT;
41 theStart = aStart;
42 theEnd = anEnd;
43
44 Standard_Integer fn = FormNumber();
45 if (fn == 0) fn = ComputedFormNumber();
46 InitTypeAndForm(104,fn);
47}
48
49 Standard_Boolean IGESGeom_ConicArc::OwnCorrect ()
50{
51 Standard_Integer cfn = ComputedFormNumber();
52 if (FormNumber() == cfn) return Standard_False;
53 InitTypeAndForm(104,cfn);
54 return Standard_True;
55}
56
57 void IGESGeom_ConicArc::Equation
58 (Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& D,
59 Standard_Real& E, Standard_Real& F) const
60{
61 A = theA;
62 B = theB;
63 C = theC;
64 D = theD;
65 E = theE;
66 F = theF;
67}
68
69 Standard_Real IGESGeom_ConicArc::ZPlane () const
70{
71 return theZT;
72}
73
74 gp_Pnt2d IGESGeom_ConicArc::StartPoint () const
75{
76 gp_Pnt2d start(theStart.X(), theStart.Y());
77 return start;
78}
79
80 gp_Pnt IGESGeom_ConicArc::TransformedStartPoint () const
81{
82 gp_XYZ start(theStart.X(), theStart.Y(), theZT);
83 if (HasTransf()) Location().Transforms(start);
84 gp_Pnt transStart(start);
85 return transStart;
86}
87
88 gp_Pnt2d IGESGeom_ConicArc::EndPoint () const
89{
90 gp_Pnt2d end(theEnd.X(), theEnd.Y());
91 return end;
92}
93
94 gp_Pnt IGESGeom_ConicArc::TransformedEndPoint () const
95{
96 gp_XYZ end(theEnd.X(), theEnd.Y(), theZT);
97 if (HasTransf()) Location().Transforms(end);
98 gp_Pnt transEnd(end);
99 return transEnd;
100}
101
102 Standard_Integer IGESGeom_ConicArc::ComputedFormNumber () const
103{
104 Standard_Real eps,eps2,eps4;
105 eps = 1.E-08; eps2 = eps*eps; eps4 = eps2*eps2;//#59 rln
106 Standard_Real Q1 = theA * (theC*theF - theE*theE/4.)
107 + theB/2. * (theE*theD/4. - theB*theF/2.)
108 + theD/2. * (theB*theE/4. - theC*theD/2.);
109 Standard_Real Q2 = theA*theC - theB*theB/4;
110 Standard_Real Q3 = theA + theC;
111
112// Resultats
113 //#59 rln 29.12.98 PRO17015 face#67, ellipse
114 //each Qi has its own dimension:
115 //[Q1] = L^-4, [Q2]=L^-4, [Q3]=L^-2
116 if (Q2 > eps4 && Q1*Q3 < 0 ) return 1; // Ellipse
117 if (Q2 < -eps4 && Abs (Q1) > eps4) return 2; // Hyperbola
118 if (Abs (Q2) <= eps4 && Abs (Q1) > eps4) return 3; // Parabola
119 return 0;
120}
121
122 Standard_Boolean IGESGeom_ConicArc::IsFromParabola () const
123{
124 Standard_Integer fn = FormNumber();
125 if (fn == 0) fn = ComputedFormNumber();
126 return (fn == 3);
127}
128
129 Standard_Boolean IGESGeom_ConicArc::IsFromEllipse () const
130{
131 Standard_Integer fn = FormNumber();
132 if (fn == 0) fn = ComputedFormNumber();
133 return (fn == 1);
134}
135
136 Standard_Boolean IGESGeom_ConicArc::IsFromHyperbola () const
137{
138 Standard_Integer fn = FormNumber();
139 if (fn == 0) fn = ComputedFormNumber();
140 return (fn == 2);
141}
142
143 Standard_Boolean IGESGeom_ConicArc::IsClosed () const
144{
145 return ((theStart.X() == theEnd.X()) && (theStart.Y() == theEnd.Y()));
146}
147
148 gp_Dir IGESGeom_ConicArc::Axis () const
149{
150 gp_Dir axis(0.0 , 0.0, 1.0);
151 return axis;
152}
153
154// Valeurs calculees
155
156 gp_Dir IGESGeom_ConicArc::TransformedAxis () const
157{
158 gp_XYZ axis(0.0 , 0.0, 1.0);
159 if (!HasTransf()) return gp_Dir(axis);
160 gp_GTrsf loc = Location();
161 loc.SetTranslationPart (gp_XYZ(0.,0.,0.));
162 loc.Transforms(axis);
163 return gp_Dir(axis);
164}
165
166
167 void IGESGeom_ConicArc::Definition
168 (gp_Pnt& Center, gp_Dir& MainAxis,
169 Standard_Real& Rmin, Standard_Real& Rmax) const
170{
171 Standard_Real Xcen,Ycen, Xax,Yax;
172 ComputedDefinition (Xcen,Ycen, Xax,Yax, Rmin,Rmax);
173 Center.SetCoord (Xcen,Ycen,theZT);
174 MainAxis.SetCoord (Xax,Yax,0.);
175}
176
177 void IGESGeom_ConicArc::TransformedDefinition
178 (gp_Pnt& Center, gp_Dir& MainAxis,
179 Standard_Real& Rmin, Standard_Real& Rmax) const
180{
181 if (!HasTransf()) {
182 Definition (Center,MainAxis,Rmin,Rmax);
183 return;
184 }
185 Standard_Real Xcen,Ycen, Xax,Yax;
186 ComputedDefinition (Xcen,Ycen, Xax,Yax, Rmin,Rmax);
187 gp_GTrsf loc = Location();
188 gp_XYZ cen (Xcen,Ycen,theZT);
189 gp_XYZ axis (Xax, Yax, 0.);
190 loc.Transforms (cen);
191 loc.SetTranslationPart (gp_XYZ(0.,0.,0.));
192 loc.Transforms (axis);
193 Center.SetCoord (cen.X(), cen.Y(), cen.Z() );
194 MainAxis.SetCoord (axis.X(),axis.Y(),axis.Z());
195}
196
197
198 void IGESGeom_ConicArc::ComputedDefinition
199 (Standard_Real& Xcen, Standard_Real& Ycen,
200 Standard_Real& Xax, Standard_Real& Yax,
201 Standard_Real& Rmin, Standard_Real& Rmax) const
202{
203 Standard_Real a,b,c,d,e,f;
204 // conic : a*x2 + 2*b*x*y + c*y2 + 2*d*x + 2*e*y + f = 0.
205 Equation (a,b,c,d,e,f);
206 b = b/2.; d = d/2.; e = e/2.; // chgt de variable
207
208 Standard_Real eps = 1.E-08; // ?? comme ComputedForm
209
210 if (IsFromParabola()) {
211 Rmin = Rmax = -1.; // rayons : yena pas
212 if ( (Abs(a) <= eps) && (Abs(b) <= eps)) {
213 Xcen = (f*c - e*e) /c /d /2.;
214 Ycen = e/c;
215 Standard_Real focal = -d/c;
216 Xax = (focal >= 0 ? 1. : -1.);
217 Yax = 0.;
218 Rmin = Rmax = Abs(focal);
219 }
220 else {
221 Standard_Real ss = a+c;
222 Standard_Real cc = - (a*d+b*e) / ss;
223 Standard_Real dd = d + (c*d - b*e) / ss;
224 Standard_Real fc = (a*e - b*d) / ss;
225 Standard_Real ee = e + fc;
226
227 Standard_Real dn = a*ee - dd*b;
228 Xcen = ( cc*ee + f*b) / dn;
229 Ycen = (-cc*dd - f*a) / dn;
230
c6541a0c 231 Standard_Real teta = M_PI/2.;
7fd59977 232 if (Abs(b) > eps) teta = ATan (-a/b);
c6541a0c 233 if (fc < 0) teta += M_PI;
7fd59977 234 Xax = Cos(teta);
235 Yax = Sin(teta);
236
237 Rmin = Rmax = Abs(fc)/sqrt(a*a+b*b)/2.;
238 }
239 }
240
241 else {
242 // -> Conique a centre, cas general
243 // On utilise les Determinants des matrices :
244 // | a b d |
245 // gdet (3x3) = | b c e | et pdet (2X2) = | a b |
246 // | d e f | | b c |
247
248 Standard_Real gdet = a*c*f + 2*b*d*e - c*d*d - a*e*e - b*b*f;
249 Standard_Real pdet = a*c - b*b;
250
251 Xcen = (b*e - c*d) / pdet;
252 Ycen = (b*d - a*e) / pdet;
253
254 Standard_Real term1 = a-c;
255 Standard_Real term2 = 2*b;
256 Standard_Real cos2t;
257 Standard_Real auxil;
258
a1096551 259 if (Abs(term1)< gp::Resolution()) {
7fd59977 260 cos2t = 1.;
a1096551 261 auxil = term2;
7fd59977 262 }
263 else {
264 Standard_Real t2d = term2/term1; //skl 28.12.2001
265 cos2t = 1./sqrt(1+t2d*t2d);
266 auxil = sqrt (term1*term1 + term2*term2);
267 }
268
269 Standard_Real cost = sqrt ( (1+cos2t)/2. );
270 Standard_Real sint = sqrt ( (1-cos2t)/2. );
271
272 Standard_Real aprim = (a+c+auxil)/2.;
273 Standard_Real cprim = (a+c-auxil)/2.;
274
275 term1 = -gdet/(aprim*pdet);
276 term2 = -gdet/(cprim*pdet);
277
278 if (IsFromEllipse()) {
279 Xax = cost;
280 Yax = sint;
281 Rmin = sqrt ( term1);
282 Rmax = sqrt ( term2);
283 if(Rmax<Rmin){ //skl 28.12.2001
284 Rmax = sqrt ( term1);
285 Rmin = sqrt ( term2);
286 }
287 }
288 else if (term1 <= eps){
289 Xax = -sint;
290 Yax = cost;
291 Rmin = sqrt (-term1);
292 Rmax = sqrt (term2);
293 }
294 else {
295 Xax = cost;
296 Yax = sint;
297 Rmin = sqrt (-term2);
298 Rmax = sqrt (term1);
299 }
300 }
301}