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