0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / BinTools / BinTools_Curve2dSet.cxx
1 // Created on: 2004-05-18
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2004-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BinTools.hxx>
18 #include <BinTools_Curve2dSet.hxx>
19 #include <Geom2d_BezierCurve.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom2d_Circle.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <Geom2d_Ellipse.hxx>
24 #include <Geom2d_Hyperbola.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom2d_OffsetCurve.hxx>
27 #include <Geom2d_Parabola.hxx>
28 #include <Geom2d_TrimmedCurve.hxx>
29 #include <gp_Circ2d.hxx>
30 #include <gp_Elips2d.hxx>
31 #include <gp_Hypr2d.hxx>
32 #include <gp_Lin2d.hxx>
33 #include <gp_Parab2d.hxx>
34 #include <Standard_ErrorHandler.hxx>
35 #include <Standard_Failure.hxx>
36 #include <Standard_OutOfRange.hxx>
37 #include <Standard_Stream.hxx>
38 #include <TColgp_Array1OfPnt2d.hxx>
39 #include <TColStd_Array1OfInteger.hxx>
40 #include <TColStd_Array1OfReal.hxx>
41 #include <Message_ProgressScope.hxx>
42
43 #define LINE      1
44 #define CIRCLE    2
45 #define ELLIPSE   3
46 #define PARABOLA  4
47 #define HYPERBOLA 5
48 #define BEZIER    6
49 #define BSPLINE   7
50 #define TRIMMED   8
51 #define OFFSET    9
52
53 //=======================================================================
54 //function : BinTools_Curve2dSet
55 //purpose  : 
56 //=======================================================================
57
58 BinTools_Curve2dSet::BinTools_Curve2dSet() 
59 {
60 }
61
62
63 //=======================================================================
64 //function : Clear
65 //purpose  : 
66 //=======================================================================
67
68 void  BinTools_Curve2dSet::Clear()
69 {
70   myMap.Clear();
71 }
72
73
74 //=======================================================================
75 //function : Add
76 //purpose  : 
77 //=======================================================================
78
79 Standard_Integer  BinTools_Curve2dSet::Add(const Handle(Geom2d_Curve)& S)
80 {
81   return myMap.Add(S);
82 }
83
84
85 //=======================================================================
86 //function : Curve2d
87 //purpose  : 
88 //=======================================================================
89
90 Handle(Geom2d_Curve)  BinTools_Curve2dSet::Curve2d
91        (const Standard_Integer I)const 
92 {
93   return  Handle(Geom2d_Curve)::DownCast(myMap(I));
94 }
95
96
97 //=======================================================================
98 //function : Index
99 //purpose  : 
100 //=======================================================================
101
102 Standard_Integer  BinTools_Curve2dSet::Index
103   (const Handle(Geom2d_Curve)& S)const 
104 {
105   return myMap.FindIndex(S);
106 }
107
108 //=======================================================================
109 //function : operator << ((Geom2d_Line)& L)
110 //purpose  : 
111 //=======================================================================
112
113 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Line)& L)
114 {
115
116   OS << (Standard_Byte)LINE;
117   gp_Lin2d C2d = L->Lin2d();
118   OS << C2d.Location();//Pnt2d
119   OS << C2d.Direction();//Dir2d
120   return OS;
121 }
122
123 //=======================================================================
124 //function : operator << ((Geom2d_Circle)& C)
125 //purpose  : 
126 //=======================================================================
127
128 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Circle)& C)
129 {
130   OS << (Standard_Byte)CIRCLE;
131   gp_Circ2d C2d = C->Circ2d();
132   OS << C2d.Location();
133   OS << C2d.XAxis().Direction();
134   OS << C2d.YAxis().Direction();
135   OS << C2d.Radius();
136   return OS;
137 }
138
139 //=======================================================================
140 //function : operator <<(Geom2d_Ellipse)
141 //purpose  : 
142 //=======================================================================
143
144 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Ellipse)& E)
145 {
146   OS << (Standard_Byte)ELLIPSE;
147   gp_Elips2d C2d = E->Elips2d();
148   OS << C2d.Location();
149   OS << C2d.XAxis().Direction();
150   OS << C2d.YAxis().Direction();
151   OS << C2d.MajorRadius();
152   OS << C2d.MinorRadius();
153   return OS;
154 }
155
156 //=======================================================================
157 //function :  operator << (Geom2d_Parabola)
158 //purpose  : 
159 //=======================================================================
160
161 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Parabola)& P)
162 {
163   OS << (Standard_Byte)PARABOLA;
164   gp_Parab2d C2d = P->Parab2d();
165   OS << C2d.Location(); // Loc
166   OS << C2d.Axis().XAxis().Direction(); // XDir
167   OS << C2d.Axis().YAxis().Direction(); // YDir
168   OS << C2d.Focal(); // Focal
169   return OS;
170 }
171
172 //=======================================================================
173 //function : operator <<(Geom2d_Hyperbola)
174 //purpose  : 
175 //=======================================================================
176
177 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Hyperbola)& H)
178 {
179   OS << (Standard_Byte)HYPERBOLA;
180   gp_Hypr2d C2d = H->Hypr2d();
181   OS << C2d.Location(); // Loc
182   OS << C2d.XAxis().Direction(); // XDir
183   OS << C2d.YAxis().Direction(); // YDir
184   OS << C2d.MajorRadius(); // MajR
185   OS << C2d.MinorRadius();
186   return OS;
187 }
188
189 //=======================================================================
190 //function : operator <<(Geom2d_BezierCurve)
191 //purpose  : 
192 //=======================================================================
193
194 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_BezierCurve)& B)
195 {
196   OS << (Standard_Byte)BEZIER;
197   Standard_Boolean aRational = B->IsRational() ? 1:0;
198   OS << aRational; // rational
199   // poles and weights
200   Standard_Integer i,aDegree = B->Degree(); 
201   OS << (Standard_ExtCharacter)aDegree; // Degree
202   for (i = 1; i <= aDegree+1; i++) {
203     OS << B->Pole(i); // Pnt2d
204     if (aRational)
205       OS << B->Weight(i); // Real
206   }
207   return OS;
208 }
209
210 //=======================================================================
211 //function : operator <<(Geom2d_BSplineCurve)
212 //purpose  : 
213 //=======================================================================
214
215 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_BSplineCurve)& B)
216 {
217   OS << (Standard_Byte)BSPLINE;
218   Standard_Boolean aRational = B->IsRational() ? 1:0;
219   OS << aRational; //rational
220   Standard_Boolean aPeriodic = B->IsPeriodic() ? 1:0;
221   OS << aPeriodic; //periodic
222   // poles and weights
223   Standard_Integer i,aDegree,aNbPoles,aNbKnots;
224   aDegree = B->Degree();
225   aNbPoles = B->NbPoles();
226   aNbKnots = B->NbKnots();
227   OS << (Standard_ExtCharacter) aDegree;
228   OS <<  aNbPoles;
229   OS <<  aNbKnots;
230   for (i = 1; i <= aNbPoles; i++) {
231     OS << B->Pole(i); // Pnt2d
232     if (aRational)
233       OS << B->Weight(i);
234   }
235
236   for (i = 1; i <= aNbKnots; i++) {
237     OS << B->Knot(i);
238     OS << B->Multiplicity(i);
239   }
240
241   return OS;
242 }
243
244 //=======================================================================
245 //function : operator <<(Geom2d_TrimmedCurve)
246 //purpose  : 
247 //=======================================================================
248
249 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_TrimmedCurve)& C)
250 {
251   OS << (Standard_Byte)TRIMMED;
252   OS << C->FirstParameter(); 
253   OS << C->LastParameter();
254   BinTools_Curve2dSet::WriteCurve2d (C->BasisCurve(), OS);
255   return OS;
256 }
257
258 //=======================================================================
259 //function : operator <<(Geom2d_OffsetCurve)
260 //purpose  : 
261 //=======================================================================
262
263 static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_OffsetCurve)& C)
264 {
265   OS << (Standard_Byte)OFFSET;
266   OS << C->Offset(); // Offset 
267   BinTools_Curve2dSet::WriteCurve2d (C->BasisCurve(), OS);
268   return OS;  
269 }
270
271 //=======================================================================
272 //function : WriteCurve2d
273 //purpose  : 
274 //=======================================================================
275
276 void BinTools_Curve2dSet::WriteCurve2d(
277   const Handle(Geom2d_Curve)& C, BinTools_OStream& OS)
278 {
279   Handle(Standard_Type) TheType = C->DynamicType();
280   try {
281     OCC_CATCH_SIGNALS
282     if ( TheType ==  STANDARD_TYPE(Geom2d_Circle)) {
283       OS << Handle(Geom2d_Circle)::DownCast(C);
284     }
285     else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
286       OS << Handle(Geom2d_Line)::DownCast(C);
287     }
288     else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
289       OS << Handle(Geom2d_Ellipse)::DownCast(C);
290     }
291     else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
292       OS << Handle(Geom2d_Parabola)::DownCast(C);
293     }
294     else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
295       OS << Handle(Geom2d_Hyperbola)::DownCast(C);
296     }
297     else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
298       OS << Handle(Geom2d_BezierCurve)::DownCast(C);
299     }
300     else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
301       OS << Handle(Geom2d_BSplineCurve)::DownCast(C);
302     }
303     else if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
304       OS << Handle(Geom2d_TrimmedCurve)::DownCast(C);
305     }
306     else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) {
307       OS << Handle(Geom2d_OffsetCurve)::DownCast(C);
308     }
309     else {
310       throw Standard_Failure("UNKNOWN CURVE2d TYPE");
311     }
312   }
313   catch(Standard_Failure const& anException) {
314     Standard_SStream aMsg;
315     aMsg << "EXCEPTION in BinTools_Curve2dSet::WriteCurve2d(..)" << std::endl;
316     aMsg << anException << std::endl;
317     throw Standard_Failure(aMsg.str().c_str());
318   }  
319 }
320
321 //=======================================================================
322 //function : Write
323 //purpose  : 
324 //=======================================================================
325
326 void  BinTools_Curve2dSet::Write (Standard_OStream& OS,
327                                   const Message_ProgressRange& theRange) const
328 {
329   Standard_Integer i, aNbCurves = myMap.Extent();
330   Message_ProgressScope aPS(theRange, "Writing 2D curves",aNbCurves);
331   OS << "Curve2ds "<< aNbCurves << "\n";
332   BinTools_OStream aStream (OS);
333   for (i = 1; i <= aNbCurves && aPS.More(); i++, aPS.Next()) {
334     WriteCurve2d (Handle(Geom2d_Curve)::DownCast (myMap (i)), aStream);
335   }
336 }
337
338
339 //=======================================================================
340 //function : ReadPnt2d
341 //purpose  : 
342 //=======================================================================
343
344 static Standard_IStream& operator>>(Standard_IStream& IS, gp_Pnt2d& P)
345 {
346   Standard_Real X=0.,Y=0.;
347   BinTools::GetReal(IS, X);
348   BinTools::GetReal(IS, Y);
349   P.SetCoord(X,Y);
350   return IS;
351 }
352
353 //=======================================================================
354 //function : ReadDir2d
355 //purpose  : 
356 //=======================================================================
357
358 static Standard_IStream& operator>>(Standard_IStream& IS, gp_Dir2d& D)
359 {
360   Standard_Real X=0.,Y=0.;
361   BinTools::GetReal(IS, X);
362   BinTools::GetReal(IS, Y);
363   D.SetCoord(X,Y);
364   return IS;
365 }
366
367
368 //=======================================================================
369 //function : ReadCurve2d
370 //purpose  : 
371 //=======================================================================
372
373 static Standard_IStream& operator>>(Standard_IStream& IS,
374                                     Handle(Geom2d_Line)& L)
375 {
376   gp_Pnt2d P(0.,0.);
377   gp_Dir2d AX(1.,0.);
378   IS >> P >> AX;
379   L = new Geom2d_Line(P,AX);
380   return IS;
381 }
382
383 //=======================================================================
384 //function : ReadCurve2d
385 //purpose  : 
386 //=======================================================================
387 static Standard_IStream& operator>>(Standard_IStream& IS,
388                                     Handle(Geom2d_Circle)& C)
389 {
390   gp_Pnt2d P(0.,0.);
391   gp_Dir2d AX(1.,0.),AY(1.,0.);
392   Standard_Real R=0.;
393   IS >> P >> AX >> AY;
394   BinTools::GetReal(IS, R);
395   C = new Geom2d_Circle(gp_Ax22d(P,AX,AY),R);
396   return IS;
397 }
398
399 //=======================================================================
400 //function : ReadCurve2d
401 //purpose  : 
402 //=======================================================================
403
404 static Standard_IStream& operator>>(Standard_IStream& IS,
405                                     Handle(Geom2d_Ellipse)& E)
406 {
407   gp_Pnt2d P(0.,0.);
408   gp_Dir2d AX(1.,0.),AY(1.,0.);
409   Standard_Real R1=0., R2=0.;
410   IS >> P >> AX >> AY;
411   BinTools::GetReal(IS, R1);
412   BinTools::GetReal(IS, R2);
413   E = new Geom2d_Ellipse(gp_Ax22d(P,AX,AY),R1,R2);
414   return IS;
415 }
416
417 //=======================================================================
418 //function : ReadCurve2d
419 //purpose  : 
420 //=======================================================================
421
422 static Standard_IStream& operator>>(Standard_IStream& IS,
423                                     Handle(Geom2d_Parabola)& C)
424 {
425   gp_Pnt2d P(0.,0.);
426   gp_Dir2d AX(1.,0.),AY(1.,0.);
427   Standard_Real R1=0.;
428   IS >> P >> AX >> AY;
429   BinTools::GetReal(IS, R1);
430   C = new Geom2d_Parabola(gp_Ax22d(P,AX,AY),R1);
431   return IS;
432 }
433
434 //=======================================================================
435 //function : ReadCurve2d
436 //purpose  : 
437 //=======================================================================
438
439 static Standard_IStream& operator>>(Standard_IStream& IS,
440                                     Handle(Geom2d_Hyperbola)& H)
441 {
442   gp_Pnt2d P(0.,0.);
443   gp_Dir2d AX(1.,0.),AY(1.,0.);
444   Standard_Real R1=0.,R2=0.;
445   IS >> P >> AX >> AY;
446   BinTools::GetReal(IS, R1);
447   BinTools::GetReal(IS, R2);
448   H = new Geom2d_Hyperbola(gp_Ax22d(P,AX,AY),R1,R2);
449   return IS;
450 }
451
452 //=======================================================================
453 //function : ReadCurve2d
454 //purpose  : 
455 //=======================================================================
456
457 static Standard_IStream& operator>>(Standard_IStream& IS,
458                                     Handle(Geom2d_BezierCurve)& B)
459 {
460   Standard_Boolean rational=Standard_False;
461   BinTools::GetBool(IS, rational);
462
463 // poles and weights
464   Standard_Integer i=0,degree=0;
465 // degree;
466   Standard_ExtCharacter aVal='\0';
467   BinTools::GetExtChar(IS, aVal);
468   degree = (Standard_Integer)aVal;
469
470   TColgp_Array1OfPnt2d poles(1,degree+1);
471   TColStd_Array1OfReal weights(1,degree+1);
472   
473   for (i = 1; i <= degree+1; i++) {
474     IS >> poles(i);//Pnt2d
475     if (rational)
476       BinTools::GetReal(IS, weights(i));
477   }
478
479   if (rational)
480     B = new Geom2d_BezierCurve(poles,weights);
481   else
482     B = new Geom2d_BezierCurve(poles);
483
484   return IS;
485 }
486
487 //=======================================================================
488 //function : ReadCurve2d
489 //purpose  : 
490 //=======================================================================
491
492 static Standard_IStream& operator>>(Standard_IStream& IS,
493                                     Handle(Geom2d_BSplineCurve)& B)
494 {
495
496   Standard_Boolean rational=Standard_False,periodic=Standard_False;
497   BinTools::GetBool(IS, rational);
498   BinTools::GetBool(IS, periodic);
499 // poles and weights
500   Standard_Integer i=0,degree=0,nbpoles=0,nbknots=0;
501   Standard_ExtCharacter aVal='\0';
502
503   BinTools::GetExtChar(IS, aVal);
504   degree = (Standard_Integer)aVal;
505
506   BinTools::GetInteger(IS, nbpoles);
507   
508   BinTools::GetInteger(IS, nbknots);
509
510   TColgp_Array1OfPnt2d poles(1,nbpoles);
511   TColStd_Array1OfReal weights(1,nbpoles);
512   
513   for (i = 1; i <= nbpoles; i++) {
514     IS >> poles(i);//Pnt2d
515     if (rational)
516       BinTools::GetReal(IS, weights(i));
517   }
518
519   TColStd_Array1OfReal knots(1,nbknots);
520   TColStd_Array1OfInteger mults(1,nbknots);
521
522   for (i = 1; i <= nbknots; i++) {
523     BinTools::GetReal(IS, knots(i));
524     BinTools::GetInteger(IS, mults(i));
525   }
526
527   if (rational)
528     B = new Geom2d_BSplineCurve(poles,weights,knots,mults,degree,periodic);
529   else
530     B = new Geom2d_BSplineCurve(poles,knots,mults,degree,periodic);
531   
532   return IS;
533 }
534
535 //=======================================================================
536 //function : ReadCurve2d
537 //purpose  : 
538 //=======================================================================
539
540 static Standard_IStream& operator>>(Standard_IStream& IS,
541                                     Handle(Geom2d_TrimmedCurve)& C)
542 {
543   Standard_Real p1=0.,p2=0.;
544   BinTools::GetReal(IS, p1);//FirstParameter
545   BinTools::GetReal(IS, p2);//LastParameter
546   Handle(Geom2d_Curve) BC;
547   BinTools_Curve2dSet::ReadCurve2d(IS,BC);
548   C = new Geom2d_TrimmedCurve(BC,p1,p2);
549   return IS;
550 }
551
552 //=======================================================================
553 //function : ReadCurve2d
554 //purpose  : 
555 //=======================================================================
556
557 static Standard_IStream& operator>>(Standard_IStream& IS,
558                                     Handle(Geom2d_OffsetCurve)& C)
559 {
560   Standard_Real p=0.;
561   BinTools::GetReal(IS, p);//Offset
562   Handle(Geom2d_Curve) BC;
563   BinTools_Curve2dSet::ReadCurve2d(IS,BC);
564   C = new Geom2d_OffsetCurve(BC,p);
565   return IS;
566 }
567
568 //=======================================================================
569 //function : ReadCurve2d
570 //purpose  : 
571 //=======================================================================
572
573 Standard_IStream& BinTools_Curve2dSet::ReadCurve2d(Standard_IStream& IS,
574                                                     Handle(Geom2d_Curve)& C)
575 {
576   try {
577     OCC_CATCH_SIGNALS
578     const Standard_Byte ctype = (Standard_Byte) IS.get();
579     switch (ctype) {
580
581     case LINE :
582       {
583         Handle(Geom2d_Line) CC;
584         IS >> CC;
585         C = CC;
586       }
587       break;
588
589     case CIRCLE :
590       {
591         Handle(Geom2d_Circle) CC;
592         IS >> CC;
593         C = CC;
594       }
595       break;
596
597     case ELLIPSE :
598       {
599         Handle(Geom2d_Ellipse) CC;
600         IS >> CC;
601         C = CC;
602       }
603       break;
604
605     case PARABOLA :
606       {
607         Handle(Geom2d_Parabola) CC;
608         IS >> CC;
609         C = CC;
610       }
611       break;
612
613     case HYPERBOLA :
614       {
615         Handle(Geom2d_Hyperbola) CC;
616         IS >> CC;
617         C = CC;
618       }
619       break;
620
621     case BEZIER :
622       {
623         Handle(Geom2d_BezierCurve) CC;
624         IS >> CC;
625         C = CC;
626       }
627       break;
628
629     case BSPLINE :
630       {
631         Handle(Geom2d_BSplineCurve) CC;
632         IS >> CC;
633         C = CC;
634       }
635       break;
636
637     case TRIMMED :
638       {
639         Handle(Geom2d_TrimmedCurve) CC;
640         IS >> CC;
641         C = CC;
642       }
643       break;
644
645     case OFFSET :
646       {
647         Handle(Geom2d_OffsetCurve) CC;
648         IS >> CC;
649         C = CC;
650       }
651       break;
652       
653     default:
654       {
655         C = NULL;
656         throw Standard_Failure("UNKNOWN CURVE2d TYPE");
657       }
658       break;
659     }
660   }
661   catch(Standard_Failure const& anException) {
662     C = NULL;
663     Standard_SStream aMsg;
664     aMsg <<"EXCEPTION in BinTools_Curve2dSet::ReadCurve2d(...)" << std::endl;
665     aMsg << anException << std::endl;
666     throw Standard_Failure(aMsg.str().c_str());
667   }
668   return IS;
669 }
670
671 //=======================================================================
672 //function : Read
673 //purpose  : 
674 //=======================================================================
675
676 void  BinTools_Curve2dSet::Read (Standard_IStream& IS,
677                                  const Message_ProgressRange& theRange)
678 {
679   char buffer[255];
680
681   IS >> buffer;
682   if (IS.fail() || strcmp(buffer,"Curve2ds")) {
683     Standard_SStream aMsg;
684     aMsg << "BinTools_Curve2dSet::Read:  Not a Curve2d table"<<std::endl;
685 #ifdef OCCT_DEBUG
686     std::cout <<"Curve2dSet buffer: " << buffer << std::endl;
687 #endif
688     throw Standard_Failure(aMsg.str().c_str());
689     return;
690   }
691
692   Handle(Geom2d_Curve) C;
693   Standard_Integer i, aNbCurves;
694   IS >> aNbCurves;
695   Message_ProgressScope aPS(theRange, "Reading curves 2d", aNbCurves);
696   IS.get();//remove <lf>                
697   for (i = 1; i <= aNbCurves && aPS.More(); i++, aPS.Next()) {
698     BinTools_Curve2dSet::ReadCurve2d(IS,C);
699     myMap.Add(C);
700   }
701 }