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