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