0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / GeomToIGES / GeomToIGES_GeomCurve.cxx
CommitLineData
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
100GeomToIGES_GeomCurve::GeomToIGES_GeomCurve()
101:GeomToIGES_GeomEntity()
102{
103}
104
105
106//=============================================================================
107// GeomToIGES_GeomCurve
108//=============================================================================
109
110GeomToIGES_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
122Handle(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
157Handle(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//=============================================================================
187static 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//=============================================================================
206static 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//=============================================================================
238static 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
280Handle(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
411Handle(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
436Handle(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
463Handle(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
507Handle(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
574Handle(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
543a9964 594 const Handle(Geom_Curve)& aCopy = copystart; // to avoid ambiguity
595 GeomConvert_ApproxCurve approx (aCopy, Precision::Approximation(),
7fd59977 596 GeomAbs_C1, 100, 6 );
597 if ( approx.HasResult() ) Bspline = approx.Curve();
598 if ( Bspline.IsNull() )
599 GeomConvert::CurveToBSplineCurve (copystart, Convert_QuasiAngular);
600 TColStd_Array1OfReal Knots(1, Bspline->NbKnots());
601 Bspline->Knots (Knots);
c6541a0c 602 BSplCLib::Reparametrize (Udeb, Udeb + 2 * M_PI, Knots);
7fd59977 603 Bspline->SetKnots (Knots);
604 return TransferCurve (Bspline, Udeb, Ufin);
605 }
606
607 Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc;
608 IGESConvGeom_GeomBuilder Build;
609 Standard_Real U1 = Udeb;
610 Standard_Real U2 = Ufin;
611 if (Abs(Udeb) <= gp::Resolution()) U1 = 0.0;
612
613// creation du "ConicArc" (#104)
614// -----------------------------
615
616 Standard_Real xloc,yloc,zloc;
617 start->Elips().Location().Coord(xloc,yloc,zloc);
618 gp_Pnt Loc;
619 Loc.SetCoord(xloc, yloc, zloc);
620 gp_Ax3 Pos = gp_Ax3(start->Elips().Position());
621 Pos.SetLocation(Loc);
622 Build.SetPosition(Pos);
623
624 Standard_Real Xs, Ys, Zs;
625 Standard_Real Xe, Ye, Ze;
626 Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs);
627 Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze);
628 gp_Elips2d E2d = gp_Elips2d(gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()),
a1096551 629 (start->MajorRadius() / GetUnit()),
630 (start->MinorRadius() / GetUnit()));
7fd59977 631 Standard_Real A, B, C, D, E, F;
632 E2d.Coefficients(A, C, B, D, E, F);//#59 rln 29.12.98 PRO17015 face 67
633 //gp_Elips2d returns 0.5*K not K
634
635 Conic->Init (A, 2 * B, C, 2 * D, 2 * E, F, 0., //#59 rln
636 gp_XY( Xs/GetUnit(), Ys/GetUnit()),
637 gp_XY( Xe/GetUnit(), Ye/GetUnit()));
638
639
640 // creation de la Trsf (#124)
641 // il faut tenir compte de l'unite pour la matrice de transformation
642 // (partie translation).
643
644 if (!Build.IsIdentity()){
645 Handle(IGESGeom_TransformationMatrix) TMat =
646 new IGESGeom_TransformationMatrix;
647 TMat = Build.MakeTransformation(GetUnit());
648 Conic->InitTransf(TMat);
649 }
650 res = Conic;
651 return res;
652}
653
654
655//=============================================================================
656// Transfer des Entites Hyperbola de Geom vers IGES
657// TransferCurve
658//=============================================================================
659
660Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve
661(const Handle(Geom_Hyperbola)& start, const Standard_Real Udeb,
662 const Standard_Real Ufin)
663{
664 Handle(IGESData_IGESEntity) res;
665 if (start.IsNull()) {
666 return res;
667 }
668
669 Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc;
670 IGESConvGeom_GeomBuilder Build;
671 Standard_Real U1 = Udeb;
672 Standard_Real U2 = Ufin;
673 if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite();
674 if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite();
675
676// creation du "ConicArc" (#104)
677// -----------------------------
678 Standard_Real xloc,yloc,zloc;
679 start->Hypr().Location().Coord(xloc,yloc,zloc);
680 gp_Pnt Loc;
681 Loc.SetCoord(xloc, yloc, zloc);
682 gp_Ax3 Pos = gp_Ax3(start->Hypr().Position());
683 Pos.SetLocation(Loc);
684 Build.SetPosition(Pos);
685
686 Standard_Real Xs, Ys, Zs;
687 Standard_Real Xe, Ye, Ze;
688 Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs);
689 Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze);
690 gp_Hypr2d H2d = gp_Hypr2d (gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()),
a1096551 691 (start->MajorRadius() / GetUnit()),
692 (start->MinorRadius() / GetUnit()));
7fd59977 693 Standard_Real A, B, C, D, E, F;
694 H2d.Coefficients(A, C, B, D, E, F);
695
696 Conic->Init (A, B, C, D, E, F, 0.,
697 gp_XY( Xs/GetUnit(), Ys/GetUnit()),
698 gp_XY( Xe/GetUnit(), Ye/GetUnit()));
699
700
701 // creation de la Trsf (#124)
702 // il faut tenir compte de l'unite pour la matrice de transformation
703 // (partie translation).
704
705 if (!Build.IsIdentity()){
706 Handle(IGESGeom_TransformationMatrix) TMat =
707 new IGESGeom_TransformationMatrix;
708 TMat = Build.MakeTransformation(GetUnit());
709 Conic->InitTransf(TMat);
710 }
711 res = Conic;
712 return res;
713}
714
715
716//=============================================================================
717// Transfer des Entites Parabola de Geom vers IGES
718// TransferCurve
719//=============================================================================
720
721Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve
722(const Handle(Geom_Parabola)& start, const Standard_Real Udeb,
723 const Standard_Real Ufin)
724{
725 Handle(IGESData_IGESEntity) res;
726 if (start.IsNull()) {
727 return res;
728 }
729
730 Handle(IGESGeom_ConicArc) Conic = new IGESGeom_ConicArc;
731 IGESConvGeom_GeomBuilder Build;
732 Standard_Real U1 = Udeb;
733 Standard_Real U2 = Ufin;
734 if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite();
735 if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite();
736
737// creation du "ConicArc" (#104)
738// -----------------------------
739 Standard_Real xloc,yloc,zloc;
740 start->Parab().Location().Coord(xloc,yloc,zloc);
741 gp_Pnt Loc;
742 Loc.SetCoord(xloc, yloc, zloc);
743 gp_Ax3 Pos = gp_Ax3(start->Parab().Position());
744 Pos.SetLocation(Loc);
745 Build.SetPosition(Pos);
746
747 Standard_Real Xs, Ys, Zs;
748 Standard_Real Xe, Ye, Ze;
749 Build.EvalXYZ((start->Value(U1)).XYZ(), Xs, Ys, Zs);
750 Build.EvalXYZ((start->Value(U2)).XYZ(), Xe, Ye, Ze);
751 gp_Parab2d P2d = gp_Parab2d (gp_Ax22d(gp::Origin2d(), gp::DX2d(), gp::DY2d()),
752 (start->Focal()*2.));
753 Standard_Real A, B, C, D, E, F;
754 P2d.Coefficients(A, C, B, D, E, F);
755
756 Conic->Init (A, B, C, D, E, F, 0.,
757 gp_XY( Xs/GetUnit(), Ys/GetUnit()),
758 gp_XY( Xe/GetUnit(), Ye/GetUnit()));
759
760
761 // creation de la Trsf (#124)
762 // il faut tenir compte de l'unite pour la matrice de transformation
763 // (partie translation).
764
765 if (!Build.IsIdentity()){
766 Handle(IGESGeom_TransformationMatrix) TMat =
767 new IGESGeom_TransformationMatrix;
768 TMat = Build.MakeTransformation(GetUnit());
769 Conic->InitTransf(TMat);
770 }
771 res = Conic;
772 return res;
773}
774
775
776//=============================================================================
777// Transfer des Entites Line de Geom vers IGES
778// TransferCurve
779//=============================================================================
780
781Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve
782(const Handle(Geom_Line)& start, const Standard_Real Udeb,
783 const Standard_Real Ufin)
784{
785 Handle(IGESData_IGESEntity) res;
786 if (start.IsNull()) {
787 return res;
788 }
789
790 Handle(IGESGeom_Line) Line = new IGESGeom_Line;
791 Standard_Real U1 = Udeb;
792 Standard_Real U2 = Ufin;
793 if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite();
794 if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite();
795
796// creation du "Line" (#110)
797// -------------------------
798
799 Standard_Real X1,Y1,Z1,X2,Y2,Z2;
800 start->Value(U1).Coord(X1,Y1,Z1);
801 start->Value(U2).Coord(X2,Y2,Z2);
802
803 Line->Init((gp_XYZ(X1/GetUnit(),Y1/GetUnit(),Z1/GetUnit())),
804 (gp_XYZ(X2/GetUnit(),Y2/GetUnit(),Z2/GetUnit())));
805 res = Line;
806 return res;
807}
808
809
810//=============================================================================
811// Transfer des Entites OffsetCurve de Geom vers IGES
812// TransferCurve
813//=============================================================================
814
815Handle(IGESData_IGESEntity) GeomToIGES_GeomCurve::TransferCurve
816(const Handle(Geom_OffsetCurve)& start, const Standard_Real Udeb,
817 const Standard_Real Ufin)
818{
819 Handle(IGESData_IGESEntity) res;
820 if (start.IsNull()) {
821 return res;
822 }
823
824 Handle(IGESGeom_OffsetCurve) OffsetC = new IGESGeom_OffsetCurve;
825 Standard_Real U1 = Udeb;
826 Standard_Real U2 = Ufin;
827 if (Precision::IsNegativeInfinite(Udeb)) U1 = -Precision::Infinite();
828 if (Precision::IsPositiveInfinite(Ufin)) U2 = Precision::Infinite();
829
1939140c 830 if (Interface_Static::IVal("write.iges.offset.mode") == 0)
831 {
832 res = TransferCurve(GeomConvert::CurveToBSplineCurve(start),U1,U2);
833 return res;
834 }
835
7fd59977 836 Handle(Geom_Curve) Curve = start->BasisCurve();
837 Standard_Real Deb = Curve->FirstParameter();
838 Standard_Real Fin = Curve->LastParameter();
839 //%11 pdn 12.01.98 offset curve should be planar
840 gp_XYZ Normal;
841 if (!IsPlanar(Curve,Normal)) {
842 //%11 pdn 12.01.98 protection against exceptions
843 try{
844 OCC_CATCH_SIGNALS
845 res = TransferCurve(GeomConvert::CurveToBSplineCurve(start),U1,U2);
846 return res;
847 }
848 catch(Standard_Failure){
0797d9d3 849#ifdef OCCT_DEBUG
7fd59977 850 cout << "writing non-planar offset curve."<<endl;
851 cout << "Warning: GeomConvert::CurveToBSplineCurve raised an exception: ";
852 Standard_Failure::Caught()->Print(cout);
853#endif
854 }
855 }
856
857 Handle(IGESData_IGESEntity) BaseCurve = TransferCurve(Curve, Deb, Fin);
858 Handle(IGESData_IGESEntity) voident;
859
860 OffsetC->Init( BaseCurve, 1,voident, 0, 0, (start->Offset()/GetUnit()), 0.,
861 (start->Offset()/GetUnit()), 0.,
862 start->Direction().XYZ().Reversed(), U1, U2); //%11 pdn 12.01.99 // valeur (0,0,1) pour l'instant
863
864 res = OffsetC;
865 return res;
866}