973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
7fd59977 |
13 | |
14 | // modif du 04/03/96 mjm |
15 | // modif dans IGESConvGeom_GeomBuilder |
16 | //#53 rln 24.12.98 CCI60005 |
17 | //#59 rln 29.12.98 PRO17015 |
18 | //%11 pdn 12.01.99 CTS22023: writing offset curves and detecting planar curves |
19 | //%12 pdn 13.01.99: CTS22023: cutting bspline curves (for Euclid3) |
20 | //:l7 abv 13.01.99: CTS22021: using QuasiAngular parametrisation for circles (more precise) |
21 | //:l5 abv 14.01.99: CTS22022-1: protection against exceptions in Segment() |
22 | //:q3 abv 17.03.99: PRO17828: using GeomConvert_ApproxCurve for converting circle to bspline |
23 | |
42cf5bc1 |
24 | #include <BSplCLib.hxx> |
25 | #include <Geom_BezierCurve.hxx> |
7fd59977 |
26 | #include <Geom_BoundedCurve.hxx> |
27 | #include <Geom_BSplineCurve.hxx> |
7fd59977 |
28 | #include <Geom_Circle.hxx> |
42cf5bc1 |
29 | #include <Geom_Conic.hxx> |
30 | #include <Geom_Curve.hxx> |
7fd59977 |
31 | #include <Geom_Ellipse.hxx> |
32 | #include <Geom_Hyperbola.hxx> |
33 | #include <Geom_Line.hxx> |
42cf5bc1 |
34 | #include <Geom_OffsetCurve.hxx> |
7fd59977 |
35 | #include <Geom_Parabola.hxx> |
42cf5bc1 |
36 | #include <Geom_TrimmedCurve.hxx> |
7fd59977 |
37 | #include <GeomConvert.hxx> |
42cf5bc1 |
38 | #include <GeomConvert_ApproxCurve.hxx> |
39 | #include <GeomToIGES_GeomCurve.hxx> |
40 | #include <GeomToIGES_GeomEntity.hxx> |
7fd59977 |
41 | #include <gp.hxx> |
42 | #include <gp_Ax2.hxx> |
43 | #include <gp_Ax3.hxx> |
44 | #include <gp_Ax22d.hxx> |
45 | #include <gp_Circ.hxx> |
46 | #include <gp_Dir.hxx> |
47 | #include <gp_Elips.hxx> |
48 | #include <gp_Elips2d.hxx> |
49 | #include <gp_Hypr.hxx> |
50 | #include <gp_Hypr2d.hxx> |
51 | #include <gp_Parab.hxx> |
52 | #include <gp_Parab2d.hxx> |
53 | #include <gp_Pnt.hxx> |
54 | #include <gp_XY.hxx> |
55 | #include <gp_XYZ.hxx> |
7fd59977 |
56 | #include <IGESConvGeom_GeomBuilder.hxx> |
7fd59977 |
57 | #include <IGESData_IGESEntity.hxx> |
58 | #include <IGESData_ToolLocation.hxx> |
7fd59977 |
59 | #include <IGESGeom_BSplineCurve.hxx> |
60 | #include <IGESGeom_CircularArc.hxx> |
61 | #include <IGESGeom_CompositeCurve.hxx> |
62 | #include <IGESGeom_ConicArc.hxx> |
63 | #include <IGESGeom_CopiousData.hxx> |
64 | #include <IGESGeom_CurveOnSurface.hxx> |
65 | #include <IGESGeom_Line.hxx> |
7fd59977 |
66 | #include <IGESGeom_OffsetCurve.hxx> |
42cf5bc1 |
67 | #include <IGESGeom_Point.hxx> |
7fd59977 |
68 | #include <IGESGeom_TransformationMatrix.hxx> |
7fd59977 |
69 | #include <Interface_Macros.hxx> |
1939140c |
70 | #include <Interface_Static.hxx> |
7fd59977 |
71 | #include <Precision.hxx> |
42cf5bc1 |
72 | #include <ShapeCustom_BSplineRestriction.hxx> |
73 | #include <Standard_ErrorHandler.hxx> |
74 | #include <Standard_Failure.hxx> |
7fd59977 |
75 | #include <TColgp_Array1OfPnt.hxx> |
42cf5bc1 |
76 | #include <TColgp_HArray1OfXYZ.hxx> |
7fd59977 |
77 | #include <TColStd_Array1OfReal.hxx> |
78 | #include <TColStd_HArray1OfReal.hxx> |
1939140c |
79 | |
7fd59977 |
80 | // Pour toutes les courbes infinies soit |
81 | // Udeb <= -Precision::Infinite() et/ou Ufin >= Precision::Infinite() |
82 | // on choisit arbitrairement de les construire entre |
83 | // Udeb = -Precision::Infinite() et Ufin = Precision::Infinite() |
7fd59977 |
84 | //============================================================================= |
85 | // GeomToIGES_GeomCurve |
86 | //============================================================================= |
7fd59977 |
87 | GeomToIGES_GeomCurve::GeomToIGES_GeomCurve() |
88 | :GeomToIGES_GeomEntity() |
89 | { |
90 | } |
91 | |
92 | |
93 | //============================================================================= |
94 | // GeomToIGES_GeomCurve |
95 | //============================================================================= |
96 | |
97 | GeomToIGES_GeomCurve::GeomToIGES_GeomCurve |
98 | (const GeomToIGES_GeomEntity& GE) |
99 | :GeomToIGES_GeomEntity(GE) |
100 | { |
101 | } |
102 | |
103 | |
104 | //============================================================================= |
105 | // Transfer des Entites Curve de Geom vers IGES |
106 | // TransferCurve |
107 | //============================================================================= |
108 | |
109 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
110 | (const Handle(Geom_Curve)& start, const Standard_Real Udeb, |
111 | const Standard_Real Ufin) |
112 | { |
113 | Handle(IGESData_IGESEntity) res; |
114 | if (start.IsNull()) { |
115 | return res; |
116 | } |
117 | |
118 | if (start->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { |
119 | DeclareAndCast(Geom_BoundedCurve, Bounded, start); |
120 | res = TransferCurve(Bounded, Udeb, Ufin); |
121 | } |
122 | else if (start->IsKind(STANDARD_TYPE(Geom_Conic))) { |
123 | DeclareAndCast(Geom_Conic, Conic, start); |
124 | res = TransferCurve(Conic, Udeb, Ufin); |
125 | } |
126 | else if ( start->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) { |
127 | DeclareAndCast(Geom_OffsetCurve, OffsetC, start); |
128 | res = TransferCurve(OffsetC, Udeb, Ufin); |
129 | } |
130 | else if ( start->IsKind(STANDARD_TYPE(Geom_Line))) { |
131 | DeclareAndCast(Geom_Line, Line, start); |
132 | res = TransferCurve(Line, Udeb, Ufin); |
133 | } |
134 | return res; |
135 | } |
136 | |
137 | |
138 | |
139 | //============================================================================= |
140 | // Transfer des Entites BoundedCurve de Geom vers IGES |
141 | // TransferCurve |
142 | //============================================================================= |
143 | |
144 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
145 | (const Handle(Geom_BoundedCurve)& start, const Standard_Real Udeb, |
146 | const Standard_Real Ufin) |
147 | { |
148 | Handle(IGESData_IGESEntity) res; |
149 | if (start.IsNull()) { |
150 | return res; |
151 | } |
152 | |
153 | if (start->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { |
154 | DeclareAndCast(Geom_BSplineCurve, Bspline, start); |
155 | res = TransferCurve(Bspline, Udeb, Ufin); |
156 | } |
157 | else if (start->IsKind(STANDARD_TYPE(Geom_BezierCurve))) { |
158 | DeclareAndCast(Geom_BezierCurve, Bezier, start); |
159 | res = TransferCurve(Bezier, Udeb, Ufin); |
160 | } |
161 | else if ( start->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { |
162 | DeclareAndCast(Geom_TrimmedCurve, Trimmed, start); |
163 | res = TransferCurve(Trimmed, Udeb, Ufin); |
164 | } |
165 | |
166 | return res; |
167 | } |
168 | |
169 | //%11 pdn 12.01.98 |
170 | //============================================================================= |
171 | // Detects if curve lies in some plane and returns normal |
172 | // IsPlanar |
173 | //============================================================================= |
174 | static gp_XYZ GetAnyNormal ( gp_XYZ orig ) |
175 | { |
176 | gp_XYZ Norm; |
177 | if ( Abs ( orig.Z() ) < Precision::Confusion() ) |
178 | Norm.SetCoord ( 0, 0, 1 ); |
179 | else { |
180 | Norm.SetCoord ( orig.Z(), 0, -orig.X() ); |
181 | Standard_Real nrm = Norm.Modulus(); |
182 | if ( nrm < Precision::Confusion() ) Norm.SetCoord ( 0, 0, 1 ); |
183 | else Norm = Norm / nrm; |
184 | } |
185 | return Norm; |
186 | } |
187 | |
188 | //%11 pdn 12.01.98 |
189 | //============================================================================= |
190 | // Detects if curve lies in some plane and returns normal |
191 | // IsPlanar |
192 | //============================================================================= |
193 | static Standard_Boolean ArePolesPlanar (const TColgp_Array1OfPnt& Poles, |
194 | gp_XYZ& Normal) |
195 | { |
196 | if(Poles.Length()<3) { |
197 | Normal = GetAnyNormal(Poles(1).XYZ()-Poles(2).XYZ()); |
198 | return Standard_True; |
199 | } |
200 | |
201 | Normal = Poles(Poles.Length()).XYZ() ^ Poles(1).XYZ(); |
202 | Standard_Integer i; // svv Jan 10 2000 : porting on DEC |
203 | for ( i = 1; i < Poles.Length(); i++) |
204 | Normal += Poles ( i ).XYZ() ^ Poles ( i + 1 ).XYZ(); |
205 | |
206 | Standard_Real tol = Precision::Confusion(); |
207 | Standard_Real nrm = Normal.Modulus(); |
208 | if ( nrm < tol ) { |
209 | Normal.SetCoord ( 0, 0, 1 ); |
210 | return Standard_False; |
211 | } |
212 | Normal = Normal / nrm; |
213 | |
214 | Standard_Real scl = Poles(1).XYZ() * Normal; |
215 | for ( i = 2; i <= Poles.Length(); i++ ) |
216 | if ( Abs ( Poles(i).XYZ() * Normal - scl ) > tol ) return Standard_False; |
217 | return Standard_True; |
218 | } |
219 | |
220 | //%11 pdn 12.01.98 |
221 | //============================================================================= |
222 | // Detects if curve lies in some plane and returns normal |
223 | // IsPlanar |
224 | //============================================================================= |
225 | static Standard_Boolean IsPlanar(const Handle(Geom_Curve)& curve, |
226 | gp_XYZ& Normal) |
227 | { |
228 | Normal.SetCoord(0,0,0); |
229 | if ( curve->IsKind(STANDARD_TYPE(Geom_Line))) { |
230 | DeclareAndCast(Geom_Line, Line, curve); |
231 | Normal = GetAnyNormal(Line->Position().Direction().XYZ()); |
232 | return Standard_True; |
233 | } |
234 | if ( curve->IsKind(STANDARD_TYPE(Geom_Conic))) { |
235 | DeclareAndCast(Geom_Conic, Conic, curve); |
236 | Normal = Conic->Axis().Direction().XYZ(); |
237 | return Standard_True; |
238 | } |
239 | if ( curve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { |
240 | DeclareAndCast(Geom_TrimmedCurve, Trimmed, curve); |
241 | return IsPlanar(Trimmed->BasisCurve(),Normal); |
242 | } |
243 | if ( curve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) { |
244 | DeclareAndCast(Geom_OffsetCurve, OffsetC, curve); |
245 | return IsPlanar(OffsetC->BasisCurve(),Normal); |
246 | } |
247 | if ( curve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { |
248 | DeclareAndCast(Geom_BSplineCurve, BSpline, curve); |
249 | TColgp_Array1OfPnt Poles(1,BSpline->NbPoles()); |
250 | BSpline->Poles(Poles); |
251 | return ArePolesPlanar(Poles,Normal); |
252 | } |
253 | if ( curve->IsKind(STANDARD_TYPE(Geom_BezierCurve))) { |
254 | DeclareAndCast(Geom_BezierCurve, Bezier, curve); |
255 | TColgp_Array1OfPnt Poles(1,Bezier->NbPoles()); |
256 | Bezier->Poles(Poles); |
257 | return ArePolesPlanar(Poles,Normal); |
258 | } |
259 | return Standard_False; |
260 | } |
261 | |
262 | //============================================================================= |
263 | // Transfer des Entites BSplineCurve de Geom vers IGES |
264 | // TransferCurve |
265 | //============================================================================= |
266 | |
267 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
268 | (const Handle(Geom_BSplineCurve)& start, const Standard_Real Udeb, |
269 | const Standard_Real Ufin) |
270 | { |
271 | Handle(IGESData_IGESEntity) res; |
272 | if (start.IsNull()) { |
273 | return res; |
274 | } |
275 | |
276 | Handle(Geom_BSplineCurve) mycurve; |
277 | Standard_Boolean IPlan = Standard_False; |
278 | gp_XYZ Norm = gp_XYZ(0.,0.,1.); |
279 | |
280 | // Si la courbe est periodique, on passe par une fonction pour recuperer tous |
281 | // les parametres necessaires a l`ecriture IGES. |
282 | |
283 | Standard_Boolean IPerio = start->IsPeriodic(); |
284 | |
285 | if (IPerio) { |
286 | mycurve = Handle(Geom_BSplineCurve)::DownCast(start->Copy()); |
287 | mycurve->SetNotPeriodic(); |
288 | } |
289 | else { |
290 | mycurve = start; |
291 | } |
292 | |
293 | Standard_Real Umin = Udeb; |
294 | Standard_Real Umax = Ufin; |
295 | if (Precision::IsNegativeInfinite(Udeb)) Umin = -Precision::Infinite(); |
296 | if (Precision::IsPositiveInfinite(Ufin)) Umax = Precision::Infinite(); |
297 | |
298 | //%12 pdn: cut curve for E3 |
299 | Standard_Real First = mycurve->FirstParameter(); |
300 | Standard_Real Last = mycurve->LastParameter(); |
301 | //:l5 abv 14 Jan 99: protect against exceptions in Segment() |
302 | if ( Umin - First < Precision::PConfusion() ) Umin = First; |
303 | if ( Last - Umax < Precision::PConfusion() ) Umax = Last; |
304 | if ( Umin - First > Precision::PConfusion() || Last - Umax > Precision::PConfusion() ) { |
305 | try { |
306 | OCC_CATCH_SIGNALS |
307 | Handle(Geom_BSplineCurve) bspl = Handle(Geom_BSplineCurve)::DownCast ( mycurve->Copy() ); |
308 | if ( ! bspl.IsNull() ) { |
fdabc211 |
309 | if (Abs(Umax-Umin) > Precision::PConfusion()) |
310 | bspl->Segment ( Umin, Umax ); |
7fd59977 |
311 | mycurve = bspl; |
312 | } |
313 | } |
9775fa61 |
314 | catch ( Standard_Failure const& anException) { |
0797d9d3 |
315 | #ifdef OCCT_DEBUG |
7fd59977 |
316 | cout << "Warning: GeomToIGES_GeomCurve: can't trim bspline" << endl; |
317 | cout << "Warning: Exception in Segment(): " ; |
9775fa61 |
318 | anException.Print(cout); |
7fd59977 |
319 | #endif |
9775fa61 |
320 | (void)anException; |
7fd59977 |
321 | } |
322 | } |
323 | |
324 | Standard_Boolean IClos = mycurve->IsClosed(); |
325 | // Standard_Boolean IRatio = mycurve->IsRational(); |
326 | Standard_Boolean IPolyn = !(mycurve->IsRational()); |
327 | //Standard_Boolean IPerio = mycurve->IsPeriodic(); |
328 | Standard_Integer Deg = mycurve->Degree(); |
329 | Standard_Integer Nbpoles = mycurve->NbPoles(); |
330 | // Standard_Integer Nbknots = mycurve->NbKnots(); |
331 | Standard_Integer Index = Nbpoles -1; |
332 | |
333 | |
334 | // Sequence des Knots de [-Deg, Index+1] dans IGESGeom. |
335 | // et de [1, Nbpoles+Deg+1] dans Geom |
336 | Standard_Integer Knotindex; |
337 | Standard_Real rtampon; |
338 | TColStd_Array1OfReal K(1, Nbpoles+Deg+1); |
339 | mycurve->KnotSequence(K); |
340 | Standard_Integer itampon = -Deg; |
341 | Handle(TColStd_HArray1OfReal) Knots = new TColStd_HArray1OfReal(-Deg,Index+1); |
342 | for ( Knotindex=K.Lower(); Knotindex<=K.Upper(); Knotindex++) { |
343 | rtampon = K.Value(Knotindex); |
344 | Knots->SetValue(itampon, rtampon); |
345 | itampon++; |
346 | } |
347 | |
348 | |
349 | // Tableau Weights de [0,Index] |
350 | TColStd_Array1OfReal W(1, Nbpoles); |
351 | mycurve->Weights(W); |
352 | itampon = 0; |
353 | Handle(TColStd_HArray1OfReal) Weights = new TColStd_HArray1OfReal(0,Index); |
354 | for ( Knotindex=W.Lower(); Knotindex<=W.Upper(); Knotindex++) { |
355 | rtampon = W.Value(Knotindex); |
356 | Weights->SetValue(itampon, rtampon); |
357 | itampon++; |
358 | } |
359 | |
360 | |
361 | // Tableau Poles de [0,Index] |
362 | TColgp_Array1OfPnt P(1, Nbpoles); |
363 | mycurve->Poles(P); |
364 | Standard_Integer Poleindex; |
365 | itampon = 0; |
366 | Standard_Real Xpt, Ypt, Zpt; |
367 | Handle(TColgp_HArray1OfXYZ) Poles = new TColgp_HArray1OfXYZ(0,Index); |
368 | for ( Poleindex=P.Lower(); Poleindex<=P.Upper(); Poleindex++) { |
369 | gp_Pnt ptampon = P.Value(Poleindex); |
370 | ptampon.Coord(Xpt, Ypt, Zpt); |
371 | gp_XYZ xyztampon = gp_XYZ (Xpt/GetUnit(), Ypt/GetUnit(), Zpt/GetUnit()); |
372 | Poles->SetValue(itampon, xyztampon); |
373 | itampon++; |
374 | } |
375 | |
376 | // modif mjm du 9/10/97 : mise en place d'une protection. |
377 | //%12 Standard_Real First = mycurve->FirstParameter(); |
378 | //%12 Standard_Real Last = mycurve->LastParameter(); |
379 | //:l5 if (First > Umin) Umin = First; |
380 | //:l5 if (Last < Umax) Umax = Last; |
381 | Handle(IGESGeom_BSplineCurve) BSplineC = new IGESGeom_BSplineCurve; |
382 | //%11 pdn 13.01.98 computing planar flag and normal |
383 | IPlan = IsPlanar(start,Norm); |
384 | if ( Norm.Z() <0 ) Norm.Reverse(); |
385 | BSplineC->Init |
386 | (Index, Deg, IPlan, IClos, IPolyn, IPerio, Knots, Weights, Poles, |
387 | Umin, Umax, Norm); |
388 | |
389 | res = BSplineC; |
390 | return res; |
391 | } |
392 | |
393 | |
394 | //============================================================================= |
395 | // Transfer des Entites BezierCurve de Geom vers IGES |
396 | // TransferCurve |
397 | //============================================================================= |
398 | |
399 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
400 | (const Handle(Geom_BezierCurve)& start, const Standard_Real Udeb, |
401 | const Standard_Real Ufin) |
402 | { |
403 | Handle(IGESData_IGESEntity) res; |
404 | if (start.IsNull()) { |
405 | return res; |
406 | } |
407 | |
408 | Handle(Geom_TrimmedCurve) mycurve3d = |
409 | new Geom_TrimmedCurve(start, Udeb, Ufin); |
410 | Handle(Geom_BSplineCurve) Bspline = GeomConvert::CurveToBSplineCurve(mycurve3d, |
411 | Convert_RationalC1);//#28 rln 19.10.98 UKI60155 |
412 | Standard_Real First = Bspline->FirstParameter(); |
413 | Standard_Real Last = Bspline->LastParameter(); |
414 | res = TransferCurve(Bspline, First, Last); |
415 | return res; |
416 | } |
417 | |
418 | |
419 | //============================================================================= |
420 | // Transfer des Entites TrimmedCurve de Geom vers IGES |
421 | // TransferCurve |
422 | //============================================================================= |
423 | |
424 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
425 | (const Handle(Geom_TrimmedCurve)& start, const Standard_Real Udeb, |
426 | const Standard_Real Ufin) |
427 | { |
428 | Handle(IGESData_IGESEntity) res; |
429 | if (start.IsNull()) { |
430 | return res; |
431 | } |
432 | |
433 | Handle(Geom_Curve) st = start->BasisCurve(); |
434 | if (st->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { |
435 | DeclareAndCast(Geom_TrimmedCurve, Trimmed, st); |
436 | Handle(Geom_Curve) st1 = Trimmed->BasisCurve(); |
437 | res = TransferCurve(st1, Udeb, Ufin); |
438 | } |
439 | |
440 | res = TransferCurve(st, Udeb, Ufin); |
441 | return res; |
442 | } |
443 | |
444 | |
445 | |
446 | //============================================================================= |
447 | // Transfer des Entites Conic de Geom vers IGES |
448 | // TransferCurve |
449 | //============================================================================= |
450 | |
451 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
452 | (const Handle(Geom_Conic)& start, const Standard_Real Udeb, |
453 | const Standard_Real Ufin) |
454 | { |
455 | Handle(IGESData_IGESEntity) res; |
456 | if (start.IsNull()) { |
457 | return res; |
458 | } |
459 | |
460 | // conic curve : Ellipse, Circle, Hyperbola, Parabola. |
461 | // All the conics are planar curves. An axis placement (two axis) |
462 | // defines the local coordinate system of the conic. |
463 | // The Location point, the XDirection and the YDirection of this |
464 | // axis placement define the plane of the conic. |
465 | // The XDirection defines the origin of the curve's parametrization. |
466 | // The Direction (main direction) of the axis placement is normal |
467 | // to the plane of the conic. |
468 | |
469 | if (start->IsKind(STANDARD_TYPE(Geom_Circle))) { |
470 | DeclareAndCast(Geom_Circle, Circle, start); |
471 | res = TransferCurve(Circle, Udeb, Ufin); |
472 | } |
473 | else if (start->IsKind(STANDARD_TYPE(Geom_Ellipse))) { |
474 | DeclareAndCast(Geom_Ellipse, Ellipse, start); |
475 | res = TransferCurve(Ellipse, Udeb, Ufin); |
476 | } |
477 | else if ( start->IsKind(STANDARD_TYPE(Geom_Hyperbola))) { |
478 | DeclareAndCast(Geom_Hyperbola, Hyperbola, start); |
479 | res = TransferCurve(Hyperbola, Udeb, Ufin); |
480 | } |
481 | else if ( start->IsKind(STANDARD_TYPE(Geom_Parabola))) { |
482 | DeclareAndCast(Geom_Parabola, Parabola, start); |
483 | res = TransferCurve(Parabola, Udeb, Ufin); |
484 | } |
485 | |
486 | return res; |
487 | } |
488 | |
489 | |
490 | //============================================================================= |
491 | // Transfer des Entites Circle de Geom vers IGES |
492 | // TransferCurve |
493 | //============================================================================= |
494 | |
495 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
496 | (const Handle(Geom_Circle)& start , const Standard_Real Udeb, |
497 | const Standard_Real Ufin) |
498 | { |
499 | |
500 | Handle(IGESData_IGESEntity) res; |
501 | if (start.IsNull()) { |
502 | return res; |
503 | } |
504 | Handle(IGESGeom_CircularArc) Circle = new IGESGeom_CircularArc;; |
505 | IGESConvGeom_GeomBuilder Build; |
506 | |
507 | Standard_Real U1 = Udeb; |
508 | Standard_Real U2 = Ufin; |
509 | if (Abs(Udeb) <= gp::Resolution()) U1 = 0.0; |
510 | |
511 | // creation du "CircularArc" (#100) |
512 | // -------------------------------- |
513 | Standard_Real xloc,yloc,zloc; |
514 | start->Circ().Location().Coord(xloc,yloc,zloc); |
515 | gp_Pnt Loc; |
516 | Loc.SetCoord(xloc,yloc,zloc); |
517 | gp_Ax3 Pos = gp_Ax3(start->Circ().Position()); |
518 | // unusable Standard_Boolean IsDirect = Pos.Direct(); |
519 | Pos.SetLocation(Loc); |
520 | Build.SetPosition(Pos); |
521 | |
522 | Standard_Real Xc, Yc, Zc; |
523 | Standard_Real Xs, Ys, Zs; |
524 | Standard_Real Xe, Ye, Ze; |
525 | //gka BUG 6542 1.09.04 BSpline curve was written in the IGES instead circle. |
526 | gp_Pnt pfirst,plast; |
527 | start->D0(U1,pfirst); |
c6541a0c |
528 | if(Abs (Ufin - Udeb - 2 * M_PI) <= Precision::PConfusion()) |
7fd59977 |
529 | plast = pfirst; |
530 | else |
531 | start->D0(U2,plast); |
532 | // |
533 | Build.EvalXYZ(((start->Circ()).Location()).XYZ(), Xc, Yc, Zc); |
534 | Build.EvalXYZ(pfirst.XYZ(), Xs, Ys, Zs); |
535 | Build.EvalXYZ(plast.XYZ(), Xe, Ye, Ze); |
536 | Circle->Init (Zc/GetUnit(), |
537 | gp_XY( Xc/GetUnit(), Yc/GetUnit()), |
538 | gp_XY( Xs/GetUnit(), Ys/GetUnit()), |
539 | gp_XY( Xe/GetUnit(), Ye/GetUnit())); |
540 | |
541 | // creation de la Trsf (#124) |
542 | // il faut tenir compte de l`unite pour la matrice de transformation |
543 | // (partie translation). |
544 | |
545 | if (!Build.IsIdentity()){ |
546 | Handle(IGESGeom_TransformationMatrix) TMat = |
547 | new IGESGeom_TransformationMatrix; |
548 | TMat = Build.MakeTransformation(GetUnit()); |
549 | Circle->InitTransf(TMat); |
550 | } |
551 | |
552 | res = Circle; |
553 | return res; |
554 | } |
555 | |
556 | |
557 | //============================================================================= |
558 | // Transfer des Entites Ellipse de Geom vers IGES |
559 | // TransferCurve |
560 | //============================================================================= |
561 | |
562 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
563 | (const Handle(Geom_Ellipse)& start, const Standard_Real Udeb, |
564 | const Standard_Real Ufin) |
565 | { |
566 | |
567 | Handle(IGESData_IGESEntity) res; |
568 | if (start.IsNull()) { |
569 | return res; |
570 | } |
571 | |
572 | //#35 rln 22.10.98 BUC60391 face 9 |
573 | //Closed Conic Arc is incorrectly oriented when reading back to CAS.CADE |
c6541a0c |
574 | if (Abs (Ufin - Udeb - 2 * M_PI) <= Precision::PConfusion()) { |
7fd59977 |
575 | //#53 rln 24.12.98 CCI60005 |
576 | //Trimmed ellipse. To avoid huge weights in B-Spline first rotate it and then convert |
577 | Handle(Geom_Ellipse) copystart = Handle(Geom_Ellipse)::DownCast (start->Copy()); |
578 | gp_Ax2 pos = copystart->Position(); |
c6541a0c |
579 | copystart->SetPosition (pos.Rotated (pos.Axis(), gp_Ax3 (pos).Direct() ? Udeb : 2 * M_PI - Udeb)); |
7fd59977 |
580 | Handle(Geom_BSplineCurve) Bspline; |
581 | //:q3 abv 17 Mar 99: use GeomConvert_ApproxCurve for precise conversion |
543a9964 |
582 | const Handle(Geom_Curve)& aCopy = copystart; // to avoid ambiguity |
583 | GeomConvert_ApproxCurve approx (aCopy, Precision::Approximation(), |
7fd59977 |
584 | GeomAbs_C1, 100, 6 ); |
585 | if ( approx.HasResult() ) Bspline = approx.Curve(); |
586 | if ( Bspline.IsNull() ) |
587 | GeomConvert::CurveToBSplineCurve (copystart, Convert_QuasiAngular); |
588 | TColStd_Array1OfReal Knots(1, Bspline->NbKnots()); |
589 | Bspline->Knots (Knots); |
c6541a0c |
590 | BSplCLib::Reparametrize (Udeb, Udeb + 2 * M_PI, Knots); |
7fd59977 |
591 | Bspline->SetKnots (Knots); |
592 | return TransferCurve (Bspline, Udeb, Ufin); |
593 | } |
594 | |
595 | Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc; |
596 | IGESConvGeom_GeomBuilder Build; |
597 | Standard_Real U1 = Udeb; |
598 | Standard_Real U2 = Ufin; |
599 | if (Abs(Udeb) <= gp::Resolution()) U1 = 0.0; |
600 | |
601 | // creation du "ConicArc" (#104) |
602 | // ----------------------------- |
603 | |
604 | Standard_Real xloc,yloc,zloc; |
605 | start->Elips().Location().Coord(xloc,yloc,zloc); |
606 | gp_Pnt Loc; |
607 | Loc.SetCoord(xloc, yloc, zloc); |
608 | gp_Ax3 Pos = gp_Ax3(start->Elips().Position()); |
609 | Pos.SetLocation(Loc); |
610 | Build.SetPosition(Pos); |
611 | |
612 | Standard_Real Xs, Ys, Zs; |
613 | Standard_Real Xe, Ye, Ze; |
614 | Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs); |
615 | Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze); |
616 | gp_Elips2d E2d = gp_Elips2d(gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()), |
a1096551 |
617 | (start->MajorRadius() / GetUnit()), |
618 | (start->MinorRadius() / GetUnit())); |
7fd59977 |
619 | Standard_Real A, B, C, D, E, F; |
620 | E2d.Coefficients(A, C, B, D, E, F);//#59 rln 29.12.98 PRO17015 face 67 |
621 | //gp_Elips2d returns 0.5*K not K |
622 | |
623 | Conic->Init (A, 2 * B, C, 2 * D, 2 * E, F, 0., //#59 rln |
624 | gp_XY( Xs/GetUnit(), Ys/GetUnit()), |
625 | gp_XY( Xe/GetUnit(), Ye/GetUnit())); |
626 | |
627 | |
628 | // creation de la Trsf (#124) |
629 | // il faut tenir compte de l'unite pour la matrice de transformation |
630 | // (partie translation). |
631 | |
632 | if (!Build.IsIdentity()){ |
633 | Handle(IGESGeom_TransformationMatrix) TMat = |
634 | new IGESGeom_TransformationMatrix; |
635 | TMat = Build.MakeTransformation(GetUnit()); |
636 | Conic->InitTransf(TMat); |
637 | } |
638 | res = Conic; |
639 | return res; |
640 | } |
641 | |
642 | |
643 | //============================================================================= |
644 | // Transfer des Entites Hyperbola de Geom vers IGES |
645 | // TransferCurve |
646 | //============================================================================= |
647 | |
648 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
649 | (const Handle(Geom_Hyperbola)& start, const Standard_Real Udeb, |
650 | const Standard_Real Ufin) |
651 | { |
652 | Handle(IGESData_IGESEntity) res; |
653 | if (start.IsNull()) { |
654 | return res; |
655 | } |
656 | |
657 | Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc; |
658 | IGESConvGeom_GeomBuilder Build; |
659 | Standard_Real U1 = Udeb; |
660 | Standard_Real U2 = Ufin; |
661 | if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite(); |
662 | if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite(); |
663 | |
664 | // creation du "ConicArc" (#104) |
665 | // ----------------------------- |
666 | Standard_Real xloc,yloc,zloc; |
667 | start->Hypr().Location().Coord(xloc,yloc,zloc); |
668 | gp_Pnt Loc; |
669 | Loc.SetCoord(xloc, yloc, zloc); |
670 | gp_Ax3 Pos = gp_Ax3(start->Hypr().Position()); |
671 | Pos.SetLocation(Loc); |
672 | Build.SetPosition(Pos); |
673 | |
674 | Standard_Real Xs, Ys, Zs; |
675 | Standard_Real Xe, Ye, Ze; |
676 | Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs); |
677 | Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze); |
678 | gp_Hypr2d H2d = gp_Hypr2d (gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()), |
a1096551 |
679 | (start->MajorRadius() / GetUnit()), |
680 | (start->MinorRadius() / GetUnit())); |
7fd59977 |
681 | Standard_Real A, B, C, D, E, F; |
682 | H2d.Coefficients(A, C, B, D, E, F); |
683 | |
684 | Conic->Init (A, B, C, D, E, F, 0., |
685 | gp_XY( Xs/GetUnit(), Ys/GetUnit()), |
686 | gp_XY( Xe/GetUnit(), Ye/GetUnit())); |
687 | |
688 | |
689 | // creation de la Trsf (#124) |
690 | // il faut tenir compte de l'unite pour la matrice de transformation |
691 | // (partie translation). |
692 | |
693 | if (!Build.IsIdentity()){ |
694 | Handle(IGESGeom_TransformationMatrix) TMat = |
695 | new IGESGeom_TransformationMatrix; |
696 | TMat = Build.MakeTransformation(GetUnit()); |
697 | Conic->InitTransf(TMat); |
698 | } |
699 | res = Conic; |
700 | return res; |
701 | } |
702 | |
703 | |
704 | //============================================================================= |
705 | // Transfer des Entites Parabola de Geom vers IGES |
706 | // TransferCurve |
707 | //============================================================================= |
708 | |
709 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
710 | (const Handle(Geom_Parabola)& start, const Standard_Real Udeb, |
711 | const Standard_Real Ufin) |
712 | { |
713 | Handle(IGESData_IGESEntity) res; |
714 | if (start.IsNull()) { |
715 | return res; |
716 | } |
717 | |
718 | Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc; |
719 | IGESConvGeom_GeomBuilder Build; |
720 | Standard_Real U1 = Udeb; |
721 | Standard_Real U2 = Ufin; |
722 | if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite(); |
723 | if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite(); |
724 | |
725 | // creation du "ConicArc" (#104) |
726 | // ----------------------------- |
727 | Standard_Real xloc,yloc,zloc; |
728 | start->Parab().Location().Coord(xloc,yloc,zloc); |
729 | gp_Pnt Loc; |
730 | Loc.SetCoord(xloc, yloc, zloc); |
731 | gp_Ax3 Pos = gp_Ax3(start->Parab().Position()); |
732 | Pos.SetLocation(Loc); |
733 | Build.SetPosition(Pos); |
734 | |
735 | Standard_Real Xs, Ys, Zs; |
736 | Standard_Real Xe, Ye, Ze; |
737 | Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs); |
738 | Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze); |
739 | gp_Parab2d P2d = gp_Parab2d (gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()), |
740 | (start->Focal()*2.)); |
741 | Standard_Real A, B, C, D, E, F; |
742 | P2d.Coefficients(A, C, B, D, E, F); |
743 | |
744 | Conic->Init (A, B, C, D, E, F, 0., |
745 | gp_XY( Xs/GetUnit(), Ys/GetUnit()), |
746 | gp_XY( Xe/GetUnit(), Ye/GetUnit())); |
747 | |
748 | |
749 | // creation de la Trsf (#124) |
750 | // il faut tenir compte de l'unite pour la matrice de transformation |
751 | // (partie translation). |
752 | |
753 | if (!Build.IsIdentity()){ |
754 | Handle(IGESGeom_TransformationMatrix) TMat = |
755 | new IGESGeom_TransformationMatrix; |
756 | TMat = Build.MakeTransformation(GetUnit()); |
757 | Conic->InitTransf(TMat); |
758 | } |
759 | res = Conic; |
760 | return res; |
761 | } |
762 | |
763 | |
764 | //============================================================================= |
765 | // Transfer des Entites Line de Geom vers IGES |
766 | // TransferCurve |
767 | //============================================================================= |
768 | |
769 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
770 | (const Handle(Geom_Line)& start, const Standard_Real Udeb, |
771 | const Standard_Real Ufin) |
772 | { |
773 | Handle(IGESData_IGESEntity) res; |
774 | if (start.IsNull()) { |
775 | return res; |
776 | } |
777 | |
778 | Handle(IGESGeom_Line) Line = new IGESGeom_Line; |
779 | Standard_Real U1 = Udeb; |
780 | Standard_Real U2 = Ufin; |
781 | if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite(); |
782 | if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite(); |
783 | |
784 | // creation du "Line" (#110) |
785 | // ------------------------- |
786 | |
787 | Standard_Real X1,Y1,Z1,X2,Y2,Z2; |
788 | start->Value(U1).Coord(X1,Y1,Z1); |
789 | start->Value(U2).Coord(X2,Y2,Z2); |
790 | |
791 | Line->Init((gp_XYZ(X1/GetUnit(),Y1/GetUnit(),Z1/GetUnit())), |
792 | (gp_XYZ(X2/GetUnit(),Y2/GetUnit(),Z2/GetUnit()))); |
793 | res = Line; |
794 | return res; |
795 | } |
796 | |
797 | |
798 | //============================================================================= |
799 | // Transfer des Entites OffsetCurve de Geom vers IGES |
800 | // TransferCurve |
801 | //============================================================================= |
802 | |
803 | Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve |
804 | (const Handle(Geom_OffsetCurve)& start, const Standard_Real Udeb, |
805 | const Standard_Real Ufin) |
806 | { |
807 | Handle(IGESData_IGESEntity) res; |
808 | if (start.IsNull()) { |
809 | return res; |
810 | } |
811 | |
812 | Handle(IGESGeom_OffsetCurve) OffsetC = new IGESGeom_OffsetCurve; |
813 | Standard_Real U1 = Udeb; |
814 | Standard_Real U2 = Ufin; |
815 | if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite(); |
816 | if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite(); |
817 | |
1939140c |
818 | if (Interface_Static::IVal("write.iges.offset.mode") == 0) |
819 | { |
820 | res = TransferCurve(GeomConvert::CurveToBSplineCurve(start),U1,U2); |
821 | return res; |
822 | } |
823 | |
7fd59977 |
824 | Handle(Geom_Curve) Curve = start->BasisCurve(); |
825 | Standard_Real Deb = Curve->FirstParameter(); |
826 | Standard_Real Fin = Curve->LastParameter(); |
827 | //%11 pdn 12.01.98 offset curve should be planar |
828 | gp_XYZ Normal; |
829 | if (!IsPlanar(Curve,Normal)) { |
830 | //%11 pdn 12.01.98 protection against exceptions |
831 | try{ |
832 | OCC_CATCH_SIGNALS |
833 | res = TransferCurve(GeomConvert::CurveToBSplineCurve(start),U1,U2); |
834 | return res; |
835 | } |
9775fa61 |
836 | catch(Standard_Failure const& anException) { |
0797d9d3 |
837 | #ifdef OCCT_DEBUG |
7fd59977 |
838 | cout << "writing non-planar offset curve."<<endl; |
839 | cout << "Warning: GeomConvert::CurveToBSplineCurve raised an exception: "; |
9775fa61 |
840 | anException.Print(cout); |
7fd59977 |
841 | #endif |
9775fa61 |
842 | (void)anException; |
7fd59977 |
843 | } |
844 | } |
845 | |
846 | Handle(IGESData_IGESEntity) BaseCurve = TransferCurve(Curve, Deb, Fin); |
847 | Handle(IGESData_IGESEntity) voident; |
848 | |
849 | OffsetC->Init( BaseCurve, 1,voident, 0, 0, (start->Offset()/GetUnit()), 0., |
850 | (start->Offset()/GetUnit()), 0., |
851 | start->Direction().XYZ().Reversed(), U1, U2); //%11 pdn 12.01.99 // valeur (0,0,1) pour l'instant |
852 | |
853 | res = OffsetC; |
854 | return res; |
855 | } |