0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / BinTools / BinTools_ShapeSet.cxx
1 // Created on: 2004-05-11
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 <BinTools_CurveSet.hxx>
20 #include <BinTools_LocationSet.hxx>
21 #include <BinTools_ShapeSet.hxx>
22 #include <BinTools_SurfaceSet.hxx>
23 #include <BRep_CurveOnClosedSurface.hxx>
24 #include <BRep_CurveOnSurface.hxx>
25 #include <BRep_CurveRepresentation.hxx>
26 #include <BRep_GCurve.hxx>
27 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
28 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
29 #include <BRep_PointOnCurve.hxx>
30 #include <BRep_PointOnCurveOnSurface.hxx>
31 #include <BRep_PointOnSurface.hxx>
32 #include <BRep_PointRepresentation.hxx>
33 #include <BRep_Polygon3D.hxx>
34 #include <BRep_PolygonOnTriangulation.hxx>
35 #include <BRep_TEdge.hxx>
36 #include <BRep_TFace.hxx>
37 #include <BRep_Tool.hxx>
38 #include <BRep_TVertex.hxx>
39 #include <BRepTools.hxx>
40 #include <gp_Trsf.hxx>
41 #include <Poly_Polygon2D.hxx>
42 #include <Poly_Polygon3D.hxx>
43 #include <Poly_PolygonOnTriangulation.hxx>
44 #include <Poly_Triangulation.hxx>
45 #include <Precision.hxx>
46 #include <Standard_ErrorHandler.hxx>
47 #include <TColgp_Array1OfPnt2d.hxx>
48 #include <TColStd_HArray1OfInteger.hxx>
49 #include <TColStd_HArray1OfReal.hxx>
50 #include <TopoDS.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Shape.hxx>
53 #include <TopoDS_Vertex.hxx>
54 #include <Message_ProgressRange.hxx>
55
56 #include <string.h>
57
58 //=======================================================================
59 //function : BinTools_ShapeSet
60 //purpose  :
61 //=======================================================================
62 BinTools_ShapeSet::BinTools_ShapeSet ()
63   : BinTools_ShapeSetBase ()
64 {}
65
66 //=======================================================================
67 //function : ~BinTools_ShapeSet
68 //purpose  : 
69 //=======================================================================
70
71 BinTools_ShapeSet::~BinTools_ShapeSet()
72 {}
73
74 //=======================================================================
75 //function : Clear
76 //purpose  : 
77 //=======================================================================
78
79 void  BinTools_ShapeSet::Clear()
80 {
81   mySurfaces.Clear();
82   myCurves.Clear();
83   myCurves2d.Clear();
84   myPolygons3D.Clear();
85   myPolygons2D.Clear();
86   myNodes.Clear();
87   myTriangulations.Clear();
88   myShapes.Clear();
89   myLocations.Clear();
90 }
91 //=======================================================================
92 //function : Add
93 //purpose  : 
94 //=======================================================================
95
96 Standard_Integer BinTools_ShapeSet::Add (const TopoDS_Shape& theShape)
97 {
98   if (theShape.IsNull()) return 0;
99   myLocations.Add(theShape.Location());
100   TopoDS_Shape aS2 = theShape;
101   aS2.Location (TopLoc_Location());
102   Standard_Integer anIndex = myShapes.FindIndex (aS2);
103   if (anIndex == 0) {
104     AddShape  (aS2);
105     for (TopoDS_Iterator its (aS2, Standard_False, Standard_False); its.More(); its.Next())
106       Add (its.Value());
107     anIndex = myShapes.Add (aS2);
108   }
109   return anIndex;
110 }
111
112
113 //=======================================================================
114 //function : Shape
115 //purpose  : 
116 //=======================================================================
117
118 const TopoDS_Shape& BinTools_ShapeSet::Shape (const Standard_Integer theIndx)
119 {
120   return myShapes (theIndx);
121 }
122
123 //=======================================================================
124 //function : Index
125 //purpose  : 
126 //=======================================================================
127
128 Standard_Integer BinTools_ShapeSet::Index (const TopoDS_Shape& theShape) const
129 {
130   return myShapes.FindIndex (theShape);
131 }
132
133 //=======================================================================
134 //function : Locations
135 //purpose  : 
136 //=======================================================================
137
138 const BinTools_LocationSet&  BinTools_ShapeSet::Locations() const 
139 {
140   return myLocations;
141 }
142
143
144 //=======================================================================
145 //function : ChangeLocations
146 //purpose  : 
147 //=======================================================================
148
149 BinTools_LocationSet&  BinTools_ShapeSet::ChangeLocations()
150 {
151   return myLocations;
152 }
153
154 //=======================================================================
155 //function : AddGeometry
156 //purpose  : 
157 //=======================================================================
158
159 void BinTools_ShapeSet::AddShape (const TopoDS_Shape& S)
160 {
161   // Add the geometry
162   
163   if (S.ShapeType() == TopAbs_VERTEX) {
164     
165     Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(S.TShape());
166     BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
167     
168     while (itrp.More()) {
169       const Handle(BRep_PointRepresentation)& PR = itrp.Value();
170
171       if (PR->IsPointOnCurve()) {
172         myCurves.Add(PR->Curve());
173       }
174
175       else if (PR->IsPointOnCurveOnSurface()) {
176         myCurves2d.Add(PR->PCurve());
177         mySurfaces.Add(PR->Surface());
178       }
179       
180       else if (PR->IsPointOnSurface()) {
181         mySurfaces.Add(PR->Surface());
182       }
183
184       ChangeLocations().Add(PR->Location());
185       itrp.Next();
186     }
187
188   }
189   else if (S.ShapeType() == TopAbs_EDGE) {
190
191     // Add the curve geometry
192     Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(S.TShape());
193     BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
194
195     while (itrc.More()) {
196       const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
197       if (CR->IsCurve3D()) {
198         if (!CR->Curve3D().IsNull()) {
199           myCurves.Add(CR->Curve3D());
200           ChangeLocations().Add(CR->Location());
201         }
202       }
203       else if (CR->IsCurveOnSurface()) {
204         mySurfaces.Add(CR->Surface());
205         myCurves2d.Add(CR->PCurve());
206         ChangeLocations().Add(CR->Location());
207         if (CR->IsCurveOnClosedSurface())
208           myCurves2d.Add(CR->PCurve2());
209       }
210       else if (CR->IsRegularity()) {
211         mySurfaces.Add(CR->Surface());
212         ChangeLocations().Add(CR->Location());
213         mySurfaces.Add(CR->Surface2());
214         ChangeLocations().Add(CR->Location2());
215       }
216       else if (IsWithTriangles()) { 
217         if (CR->IsPolygon3D()) {
218           if (!CR->Polygon3D().IsNull()) {
219             myPolygons3D.Add(CR->Polygon3D());
220             ChangeLocations().Add(CR->Location());
221           }
222         }
223         else if (CR->IsPolygonOnTriangulation()) {
224           // NCollection_IndexedDataMap::Add() function use is correct because
225           // Bin(Brep)Tools_ShapeSet::AddGeometry() is called from Bin(Brep)Tools_ShapeSet::Add()
226           // that processes shapes recursively from complex to elementary ones.
227           // As a result, the TopAbs_FACE's will be processed earlier than the TopAbs_EDGE's.
228           myTriangulations.Add(CR->Triangulation(), Standard_False); // edge triangulation does not need normals
229           myNodes.Add(CR->PolygonOnTriangulation());
230           ChangeLocations().Add(CR->Location());
231           if (CR->IsPolygonOnClosedTriangulation())
232             myNodes.Add(CR->PolygonOnTriangulation2());
233         }
234         else if (CR->IsPolygonOnSurface()) {
235           mySurfaces.Add(CR->Surface());
236           myPolygons2D.Add(CR->Polygon());
237           ChangeLocations().Add(CR->Location());
238           if (CR->IsPolygonOnClosedSurface())
239           myPolygons2D.Add(CR->Polygon2());
240         }
241       }
242       itrc.Next();
243     }
244   }
245
246   else if (S.ShapeType() == TopAbs_FACE) {
247
248     // Add the surface geometry
249     Standard_Boolean needNormals (IsWithNormals());
250     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
251     if (!TF->Surface().IsNull())
252     {
253       mySurfaces.Add(TF->Surface());
254     }
255     else
256     {
257       needNormals = Standard_True;
258     }
259     if (IsWithTriangles() || TF->Surface().IsNull())
260     {
261       Handle(Poly_Triangulation) Tr = TF->Triangulation();
262       if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
263     }
264
265     ChangeLocations().Add(TF->Location());
266   }
267 }
268
269 //=======================================================================
270 //function : WriteGeometry
271 //purpose  : 
272 //=======================================================================
273
274 void  BinTools_ShapeSet::WriteGeometry (Standard_OStream& OS,
275                                         const Message_ProgressRange& theRange)const
276 {
277   Message_ProgressScope aPS(theRange, "Writing geometry", 6);
278   myCurves2d.Write(OS, aPS.Next());
279   if (!aPS.More())
280     return;
281   myCurves.Write(OS, aPS.Next());
282   if (!aPS.More())
283     return;
284   WritePolygon3D(OS, aPS.Next());
285   if (!aPS.More())
286     return;
287   WritePolygonOnTriangulation(OS, aPS.Next());
288   if (!aPS.More())
289     return;
290   mySurfaces.Write(OS, aPS.Next());
291   if (!aPS.More())
292     return;
293   WriteTriangulation(OS, aPS.Next());
294 }
295
296 //=======================================================================
297 //function : Write
298 //purpose  : 
299 //=======================================================================
300
301 void  BinTools_ShapeSet::Write (Standard_OStream& OS,
302                                 const Message_ProgressRange& theRange)
303 {
304   // write the copyright
305   OS << "\n" << THE_ASCII_VERSIONS[FormatNb()] << "\n";
306
307   //-----------------------------------------
308   // write the locations
309   //-----------------------------------------
310
311   myLocations.Write(OS);
312
313   //-----------------------------------------
314   // write the geometry
315   //-----------------------------------------
316
317   Message_ProgressScope aPS(theRange, "Writing geometry", 2);
318
319   WriteGeometry(OS, aPS.Next());
320   if (!aPS.More())
321     return;
322
323   //-----------------------------------------
324   // write the shapes
325   //-----------------------------------------
326
327   Standard_Integer i, nbShapes = myShapes.Extent();
328   Message_ProgressScope aPSinner(aPS.Next(), "Writing shapes", nbShapes);
329   OS << "\nTShapes " << nbShapes << "\n";
330   
331   // subshapes are written first
332   for (i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
333
334     const TopoDS_Shape& S = myShapes (i);
335     
336     // Type
337     OS << (Standard_Byte)S.ShapeType();
338
339     // Geometry
340     WriteShape (S, OS);
341
342     // Flags
343     BinTools::PutBool(OS, S.Free()? 1:0);
344     BinTools::PutBool(OS, S.Modified()? 1:0);
345     BinTools::PutBool(OS, S.Checked()? 1:0);
346     BinTools::PutBool(OS, S.Orientable()? 1:0);
347     BinTools::PutBool(OS, S.Closed()? 1:0);
348     BinTools::PutBool(OS, S.Infinite()? 1:0);
349     BinTools::PutBool(OS, S.Convex()? 1:0);
350
351     // sub-shapes
352
353     TopoDS_Iterator its(S,Standard_False,Standard_False);
354     while (its.More()) {
355       Write(its.Value(),OS);
356       its.Next();
357     }
358     Write(TopoDS_Shape(),OS); // Null shape to end the list
359   }
360 }
361
362 //=======================================================================
363 //function : Read
364 //purpose  : 
365 //=======================================================================
366 void  BinTools_ShapeSet::Read (Standard_IStream& IS,
367                                const Message_ProgressRange& theRange)
368 {
369   Clear();
370
371   // Check the version
372   char vers[101];
373   Standard_Boolean anIsSetFormat = Standard_False;
374   do {
375     IS.getline(vers,100,'\n');
376     // BUC60769 PTV 18.10.2000: remove possible '\r' at the end of the line
377     
378     Standard_Size lv = strlen(vers);
379     if (lv > 0) {
380       for (lv--; lv > 0 && (vers[lv] == '\r' || vers[lv] == '\n'); lv--)
381         vers[lv] = '\0';
382     }
383
384     for (Standard_Integer i = BinTools_FormatVersion_LOWER;
385          i <= BinTools_FormatVersion_UPPER; ++i)
386     {
387       if (!strcmp(vers, THE_ASCII_VERSIONS[i]))
388       {
389         SetFormatNb(i);
390         anIsSetFormat = Standard_True;
391         break;
392       }
393     }
394     if (anIsSetFormat)
395     {
396       break;
397     }
398   } 
399   while ( ! IS.fail());
400   if (IS.fail()) {
401     std::cout << "BinTools_ShapeSet::Read: File was not written with this version of the topology" << std::endl;
402     return;
403   }
404
405   //-----------------------------------------
406   // read the locations
407   //-----------------------------------------
408   myLocations.Read(IS);
409   //-----------------------------------------
410   // read the geometry
411   //-----------------------------------------
412   Message_ProgressScope aPSouter(theRange, "Reading", 2);
413   ReadGeometry(IS, aPSouter.Next());
414   if (!aPSouter.More())
415     return;
416   //-----------------------------------------
417   // read the shapes
418   //-----------------------------------------
419
420   char buffer[255];
421   IS >> buffer;
422   if (IS.fail() || strcmp(buffer,"TShapes")) {
423     Standard_SStream aMsg;
424     aMsg << "BinTools_ShapeSet::Read: Not a TShape table"<<std::endl;
425     throw Standard_Failure(aMsg.str().c_str());
426     return;
427   }
428   Standard_Integer nbShapes = 0;
429   IS >> nbShapes;
430   IS.get();//remove lf 
431   Message_ProgressScope aPSinner(aPSouter.Next(), "Reading Shapes", nbShapes);
432   for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next())
433   {
434     TopoDS_Shape S;
435     TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
436     ReadShape (T, IS, S);
437     ReadFlagsAndSubs (S, T, IS, nbShapes);
438     myShapes.Add (S);
439   }
440 }
441
442 //=======================================================================
443 //function : Write
444 //purpose  : 
445 //=======================================================================
446
447 void  BinTools_ShapeSet::Write (const TopoDS_Shape& S, 
448                                 Standard_OStream& OS)
449 {
450   if (S.IsNull()) 
451
452     OS << '*';
453   else {    
454 // {TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL} 
455     OS << (Standard_Byte) S.Orientation();
456     BinTools::PutInteger (OS, myShapes.Extent() - myShapes.FindIndex (S.Located (TopLoc_Location())) + 1);
457     BinTools::PutInteger (OS, Locations().Index (S.Location()));
458   }    
459 }
460
461 //=======================================================================
462 //function : ReadFlagsAndSubs
463 //purpose  : 
464 //=======================================================================
465
466 void BinTools_ShapeSet::ReadFlagsAndSubs(TopoDS_Shape& S, const TopAbs_ShapeEnum T,
467   Standard_IStream& IS, const Standard_Integer nbShapes)
468 {
469   // Set the flags
470   Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
471   BinTools::GetBool(IS, aFree);
472   BinTools::GetBool(IS, aMod);
473   BinTools::GetBool(IS, aChecked);
474   BinTools::GetBool(IS, anOrient);
475   BinTools::GetBool(IS, aClosed);
476   BinTools::GetBool(IS, anInf);
477   BinTools::GetBool(IS, aConv);
478
479   // sub-shapes
480   TopoDS_Shape SS;
481   do {
482     ReadSubs(SS, IS, nbShapes);
483     if (!SS.IsNull())
484       AddShapes(S, SS);
485   } while (!SS.IsNull());
486
487   S.Free(aFree);
488   S.Modified(aMod);
489   if (FormatNb() != BinTools_FormatVersion_VERSION_2 &&
490       FormatNb() != BinTools_FormatVersion_VERSION_3)
491   {
492     aChecked = false; // force check at reading
493   }
494   S.Checked (aChecked);
495   S.Orientable (anOrient);
496   S.Closed (aClosed);
497   S.Infinite (anInf);
498   S.Convex (aConv);
499   // check
500
501   if (FormatNb() == BinTools_FormatVersion_VERSION_1)
502     if (T == TopAbs_FACE) {
503       const TopoDS_Face& F = TopoDS::Face(S);
504       BRepTools::Update(F);
505     }
506 }
507
508 //=======================================================================
509 //function : ReadSubs
510 //purpose  : 
511 //=======================================================================
512 void BinTools_ShapeSet::ReadSubs(TopoDS_Shape& S, Standard_IStream& IS,
513                                  const Standard_Integer nbshapes)
514 {
515   Standard_Character aChar = '\0';
516   IS >> aChar;
517   if (aChar == '*')
518     S = TopoDS_Shape();
519   else {
520     TopAbs_Orientation anOrient;
521     anOrient = (TopAbs_Orientation)aChar;
522     Standard_Integer anIndx;
523     BinTools::GetInteger(IS, anIndx);
524     S = Shape (nbshapes - anIndx + 1);
525     S.Orientation(anOrient);
526
527     Standard_Integer l;
528     BinTools::GetInteger(IS, l);
529     S.Location(myLocations.Location(l));
530   }
531 }
532
533 //=======================================================================
534 //function : ReadGeometry
535 //purpose  : 
536 //=======================================================================
537
538 void BinTools_ShapeSet::ReadGeometry (Standard_IStream& IS,
539                                       const Message_ProgressRange& theRange)
540 {
541
542   Message_ProgressScope aPS(theRange, "Reading geometry", 6);
543   myCurves2d.Read(IS, aPS.Next());
544   if (!aPS.More())
545     return;
546
547   myCurves.Read(IS, aPS.Next());
548   if (!aPS.More())
549     return;
550
551   ReadPolygon3D(IS, aPS.Next());
552   if (!aPS.More())
553     return;
554
555   ReadPolygonOnTriangulation(IS, aPS.Next());
556   if (!aPS.More())
557     return;
558
559   mySurfaces.Read(IS, aPS.Next());
560   if (!aPS.More())
561     return;
562
563   ReadTriangulation(IS, aPS.Next());
564 }
565
566 //=======================================================================
567 //function : WriteGeometry
568 //purpose  : 
569 //=======================================================================
570
571 void BinTools_ShapeSet::WriteShape (const TopoDS_Shape& S, 
572                                     Standard_OStream&   OS) const 
573 {
574 // Write the geometry
575   try {
576     OCC_CATCH_SIGNALS
577     if (S.ShapeType() == TopAbs_VERTEX) {
578     
579 // Write the point geometry
580       TopoDS_Vertex V = TopoDS::Vertex(S);
581       BinTools::PutReal(OS, BRep_Tool::Tolerance(V));
582       gp_Pnt p = BRep_Tool::Pnt(V);
583       OS << p;
584 #ifdef OCCT_DEBUG_POS
585       std::streamoff aPos;
586 #endif
587       Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(S.TShape());
588       BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
589       while (itrp.More()) {
590         const Handle(BRep_PointRepresentation)& PR = itrp.Value();
591 //      BinTools::PutReal(OS, PR->Parameter());
592         if (PR->IsPointOnCurve()) {
593 #ifdef OCCT_DEBUG_POS
594           aPos = OS.tellp();
595 #endif
596           OS << (Standard_Byte)1; // 1
597           BinTools::PutReal(OS, PR->Parameter());
598           BinTools::PutInteger(OS, myCurves.Index(PR->Curve()));
599         }
600
601         else if (PR->IsPointOnCurveOnSurface()) {
602 #ifdef OCCT_DEBUG_POS
603           aPos = OS.tellp();
604 #endif
605           OS << (Standard_Byte)2;// 2
606           BinTools::PutReal(OS, PR->Parameter());
607           BinTools::PutInteger(OS, myCurves2d.Index(PR->PCurve()));
608           BinTools::PutInteger(OS, mySurfaces.Index(PR->Surface()));
609         }
610
611         else if (PR->IsPointOnSurface()) {
612 #ifdef OCCT_DEBUG_POS
613           aPos = OS.tellp();
614 #endif
615           OS << (Standard_Byte)3;// 3
616           BinTools::PutReal(OS, PR->Parameter2());
617           BinTools::PutReal(OS, PR->Parameter());
618           BinTools::PutInteger(OS, mySurfaces.Index(PR->Surface()));
619         }
620         BinTools::PutInteger(OS, Locations().Index(PR->Location()));
621         itrp.Next();
622       }
623     
624 //    OS << "0 0\n"; // end representations
625       OS.put((Standard_Byte)0);
626     }
627
628     else if (S.ShapeType() == TopAbs_EDGE) {
629
630     // Write the curve geometry 
631
632       Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(S.TShape());
633
634       BinTools::PutReal(OS, TE->Tolerance());
635
636       Standard_Boolean aVal = (TE->SameParameter()) ? Standard_True : Standard_False;
637       BinTools::PutBool(OS, aVal);   
638       aVal = (TE->SameRange()) ? Standard_True : Standard_False;
639       BinTools::PutBool(OS, aVal);
640       aVal = (TE->Degenerated())  ? Standard_True : Standard_False;
641       BinTools::PutBool(OS, aVal);
642       
643       Standard_Real first, last;
644       BRep_ListIteratorOfListOfCurveRepresentation itrc = TE->Curves();
645       while (itrc.More()) {
646         const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
647         if (CR->IsCurve3D()) {
648           if (!CR->Curve3D().IsNull()) {
649             Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itrc.Value());
650             GC->Range(first, last);
651             OS << (Standard_Byte)1;//CURVE_3D;
652             BinTools::PutInteger(OS, myCurves.Index(CR->Curve3D()));
653             BinTools::PutInteger(OS, Locations().Index(CR->Location()));
654             BinTools::PutReal(OS, first);
655             BinTools::PutReal(OS, last);
656           }
657         }
658         else if (CR->IsCurveOnSurface()) {
659           Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itrc.Value());
660           GC->Range(first, last);
661           if (!CR->IsCurveOnClosedSurface())
662 // -2- Curve on surf
663             OS << (Standard_Byte)2;
664           else
665 // -3- Curve on closed surf
666             OS << (Standard_Byte)3;
667           BinTools::PutInteger(OS, myCurves2d.Index(CR->PCurve()));
668           if (CR->IsCurveOnClosedSurface()) {//+ int|char
669             BinTools::PutInteger(OS, myCurves2d.Index(CR->PCurve2()));
670             OS << (Standard_Byte)CR->Continuity();
671           }
672           BinTools::PutInteger(OS, mySurfaces.Index(CR->Surface()));
673           BinTools::PutInteger(OS, Locations().Index(CR->Location()));
674           BinTools::PutReal(OS, first);
675           BinTools::PutReal(OS, last);
676
677         // Write UV Points for higher performance
678           if (FormatNb() == BinTools_FormatVersion_VERSION_2
679            || FormatNb() == BinTools_FormatVersion_VERSION_3)
680             {
681               gp_Pnt2d Pf,Pl;
682               if (CR->IsCurveOnClosedSurface()) {
683                 Handle(BRep_CurveOnClosedSurface) COCS = Handle(BRep_CurveOnClosedSurface)::DownCast(CR);
684                 COCS->UVPoints2(Pf,Pl);
685               }
686               else {
687                 Handle(BRep_CurveOnSurface) COS = Handle(BRep_CurveOnSurface)::DownCast(CR);
688                 COS->UVPoints(Pf,Pl);
689               }
690               BinTools::PutReal(OS, Pf.X());
691               BinTools::PutReal(OS, Pf.Y());
692               BinTools::PutReal(OS, Pl.X());
693               BinTools::PutReal(OS, Pl.Y());
694             }
695         }
696         else if (CR->IsRegularity()) {
697 // -4- Regularity
698           OS << (Standard_Byte)4;
699           OS << (Standard_Byte)CR->Continuity();
700           BinTools::PutInteger(OS, mySurfaces.Index(CR->Surface()));
701           BinTools::PutInteger(OS, Locations().Index(CR->Location()));
702           BinTools::PutInteger(OS, mySurfaces.Index(CR->Surface2()));
703           BinTools::PutInteger(OS, Locations().Index(CR->Location2()));
704           
705         }
706
707         else if (IsWithTriangles()) { 
708           if (CR->IsPolygon3D()) {
709             Handle(BRep_Polygon3D) GC = Handle(BRep_Polygon3D)::DownCast(itrc.Value());
710             if (!GC->Polygon3D().IsNull()) {
711 // -5- Polygon3D
712               OS << (Standard_Byte)5;
713               BinTools::PutInteger(OS, myPolygons3D.FindIndex(CR->Polygon3D()));
714               BinTools::PutInteger(OS, Locations().Index(CR->Location())); 
715             }
716           }
717           else if (CR->IsPolygonOnTriangulation()) {
718             Handle(BRep_PolygonOnTriangulation) PT = 
719               Handle(BRep_PolygonOnTriangulation)::DownCast(itrc.Value());
720             if (!CR->IsPolygonOnClosedTriangulation())
721 // -6- Polygon on triangulation
722               OS << (Standard_Byte)6;
723             else
724 // -7- Polygon on closed triangulation
725               OS << (Standard_Byte)7;
726             BinTools::PutInteger(OS, myNodes.FindIndex(PT->PolygonOnTriangulation()));
727             
728             if (CR->IsPolygonOnClosedTriangulation()) {
729               BinTools::PutInteger(OS, myNodes.FindIndex(PT->PolygonOnTriangulation2()));
730             }
731             BinTools::PutInteger(OS, myTriangulations.FindIndex(PT->Triangulation()));
732             BinTools::PutInteger(OS, Locations().Index(CR->Location()));
733           }
734         }
735         
736         itrc.Next();
737       }
738 //   OS << "0\n"; // end of the list of representations
739
740       OS << (Standard_Byte)0;
741     }
742   
743     else if (S.ShapeType() == TopAbs_FACE) {
744
745       Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
746       const TopoDS_Face& F = TopoDS::Face(S);
747
748       // Write the surface geometry
749       Standard_Boolean aNatRes = BRep_Tool::NaturalRestriction(F);
750       BinTools::PutBool (OS, aNatRes);
751       BinTools::PutReal (OS, TF->Tolerance());
752       BinTools::PutInteger (OS, !TF->Surface().IsNull()
753                                ? mySurfaces.Index (TF->Surface())
754                                : 0);
755       BinTools::PutInteger (OS, Locations().Index (TF->Location()));
756
757       if (IsWithTriangles() || TF->Surface().IsNull())
758       {
759         if (!(TF->Triangulation()).IsNull()) {
760           OS << (Standard_Byte) 2;
761         // Write the triangulation
762           BinTools::PutInteger(OS, myTriangulations.FindIndex(TF->Triangulation())); 
763         } else
764           OS << (Standard_Byte) 1;
765       } else
766         OS << (Standard_Byte) 0;//without triangulation
767     }
768   }
769   catch(Standard_Failure const& anException) {
770     Standard_SStream aMsg;
771     aMsg << "EXCEPTION in BinTools_ShapeSet::WriteGeometry(S,OS)" << std::endl;
772     aMsg << anException << std::endl;
773     throw Standard_Failure(aMsg.str().c_str());
774   }
775 }
776
777 //=======================================================================
778 //function : ReadShape
779 //purpose  : 
780 //=======================================================================
781
782 void  BinTools_ShapeSet::ReadShape (const TopAbs_ShapeEnum T,
783                                     Standard_IStream&      IS,
784                                     TopoDS_Shape&          S)
785 {
786   // Read the geometry
787
788   Standard_Integer val, c, pc, pc2 = 0, s, s2, l, l2, t, pt, pt2 = 0;
789   Standard_Real tol, X, Y, Z, first, last, p1 = 0., p2;
790   Standard_Real PfX, PfY, PlX, PlY;
791   gp_Pnt2d aPf, aPl;
792   Standard_Boolean closed, bval;
793   GeomAbs_Shape reg = GeomAbs_C0;
794   try {
795     OCC_CATCH_SIGNALS
796       switch (T) {
797
798
799         //---------
800         // vertex
801         //---------
802
803       case TopAbs_VERTEX:
804       {
805         TopoDS_Vertex& V = TopoDS::Vertex(S);
806
807         // Read the point geometry
808         BinTools::GetReal(IS, tol);
809         BinTools::GetReal(IS, X);
810         BinTools::GetReal(IS, Y);
811         BinTools::GetReal(IS, Z);
812         gp_Pnt aPnt(X, Y, Z);
813         myBuilder.MakeVertex(V, aPnt, tol);
814         Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
815
816         BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
817         TopLoc_Location L;
818         do {
819           if (FormatNb() == BinTools_FormatVersion_VERSION_3) {
820             val = (Standard_Integer)IS.get();//case {0|1|2|3}
821             if (val > 0 && val <= 3)
822               BinTools::GetReal(IS, p1);
823           }
824           else {
825             std::streampos aPos = IS.tellg();
826             BinTools::GetReal(IS, p1);
827             val = (Standard_Integer)IS.get();//case {0|1|2|3}
828 #ifdef OCCT_DEBUG
829             std::cout << "\nVal = " << val << std::endl;
830 #endif    
831             if (val != 1 && val != 2 && val != 3) {
832               IS.seekg(aPos);
833               val = (Standard_Integer)IS.get();
834               if (val > 0 && val <= 3)
835                 BinTools::GetReal(IS, p1);
836             }
837           }
838           Handle(BRep_PointRepresentation) PR;
839           switch (val) {
840           case 0:
841             break;
842
843           case 1:
844           {
845             BinTools::GetInteger(IS, c);
846             if (myCurves.Curve(c).IsNull())
847               break;
848             Handle(BRep_PointOnCurve) POC =
849               new BRep_PointOnCurve(p1,
850                 myCurves.Curve(c),
851                 L);
852             PR = POC;
853           }
854           break;
855
856           case 2:
857           {
858             BinTools::GetInteger(IS, pc);
859             BinTools::GetInteger(IS, s);
860             if (myCurves2d.Curve2d(pc).IsNull() ||
861               mySurfaces.Surface(s).IsNull())
862               break;
863
864             Handle(BRep_PointOnCurveOnSurface) POC =
865               new BRep_PointOnCurveOnSurface(p1,
866                 myCurves2d.Curve2d(pc),
867                 mySurfaces.Surface(s),
868                 L);
869             PR = POC;
870           }
871           break;
872
873           case 3:
874           {
875             BinTools::GetReal(IS, p2);
876             BinTools::GetInteger(IS, s);
877             if (mySurfaces.Surface(s).IsNull())
878               break;
879
880             Handle(BRep_PointOnSurface) POC =
881               new BRep_PointOnSurface(p1, p2,
882                 mySurfaces.Surface(s),
883                 L);
884             PR = POC;
885           }
886           break;
887
888           default:
889           {
890             Standard_SStream aMsg;
891             aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = " << val << std::endl;
892             throw Standard_Failure(aMsg.str().c_str());
893           }
894           }
895
896           if (val > 0) {
897             BinTools::GetInteger(IS, l);//Locations index
898
899             if (!PR.IsNull()) {
900               PR->Location(Locations().Location(l));
901               lpr.Append(PR);
902             }
903           }
904         } while (val > 0);
905       }
906       break;
907
908
909       //---------
910       // edge
911       //---------
912
913
914       case TopAbs_EDGE:
915
916         // Create an edge
917       {
918         TopoDS_Edge& E = TopoDS::Edge(S);
919
920         myBuilder.MakeEdge(E);
921
922         // Read the curve geometry 
923         BinTools::GetReal(IS, tol);
924         BinTools::GetBool(IS, bval);
925         myBuilder.SameParameter(E, bval);
926
927         BinTools::GetBool(IS, bval);
928         myBuilder.SameRange(E, bval);
929
930         BinTools::GetBool(IS, bval);
931         myBuilder.Degenerated(E, bval);
932
933         do {
934           val = (Standard_Integer)IS.get();//{0|1|2|3|4|5|6|7}
935           // -0- no representation
936           // -1- Curve 3D
937           // -2- Curve on surf
938           // -3- Curve on closed surf
939           // -4- Regularity
940           // -5- Polygon3D
941           // -6- Polygon on triangulation
942           // -7- Polygon on closed triangulation
943
944           switch (val) {
945           case 0:
946             break;
947
948           case 1:                               // -1- Curve 3D
949             BinTools::GetInteger(IS, c);
950             BinTools::GetInteger(IS, l);
951             if (!myCurves.Curve(c).IsNull()) {
952               myBuilder.UpdateEdge(E, myCurves.Curve(c),
953                 Locations().Location(l), tol);
954             }
955             BinTools::GetReal(IS, first);
956             BinTools::GetReal(IS, last);
957             if (!myCurves.Curve(c).IsNull()) {
958               Standard_Boolean Only3d = Standard_True;
959               myBuilder.Range(E, first, last, Only3d);
960             }
961             break;
962
963
964           case 2: // -2- Curve on surf
965           case 3: // -3- Curve on closed surf
966             closed = (val == 3);
967             BinTools::GetInteger(IS, pc);
968             if (closed) {
969               BinTools::GetInteger(IS, pc2);
970               reg = (GeomAbs_Shape)IS.get();
971             }
972
973             // surface, location
974             BinTools::GetInteger(IS, s);
975             BinTools::GetInteger(IS, l);
976
977             // range
978             BinTools::GetReal(IS, first);
979             BinTools::GetReal(IS, last);
980
981             // read UV Points // for XML Persistence higher performance
982             if (FormatNb() == BinTools_FormatVersion_VERSION_2
983              || FormatNb() == BinTools_FormatVersion_VERSION_3)
984             {
985               BinTools::GetReal(IS, PfX);
986               BinTools::GetReal(IS, PfY);
987               BinTools::GetReal(IS, PlX);
988               BinTools::GetReal(IS, PlY);
989               aPf = gp_Pnt2d(PfX, PfY);
990               aPl = gp_Pnt2d(PlX, PlY);
991             }
992
993             if (myCurves2d.Curve2d(pc).IsNull() ||
994               (closed && myCurves2d.Curve2d(pc2).IsNull()) ||
995               mySurfaces.Surface(s).IsNull())
996               break;
997
998             if (closed) {
999               if (FormatNb() == BinTools_FormatVersion_VERSION_2
1000                || FormatNb() == BinTools_FormatVersion_VERSION_3)
1001               {
1002                 myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
1003                   myCurves2d.Curve2d(pc2),
1004                   mySurfaces.Surface(s),
1005                   Locations().Location(l), tol,
1006                   aPf, aPl);
1007               }
1008               else
1009               {
1010                 myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
1011                   myCurves2d.Curve2d(pc2),
1012                   mySurfaces.Surface(s),
1013                   Locations().Location(l), tol);
1014               }
1015
1016               myBuilder.Continuity(E,
1017                 mySurfaces.Surface(s),
1018                 mySurfaces.Surface(s),
1019                 Locations().Location(l),
1020                 Locations().Location(l),
1021                 reg);
1022             }
1023             else
1024             {
1025               if (FormatNb() == BinTools_FormatVersion_VERSION_2
1026                || FormatNb() == BinTools_FormatVersion_VERSION_3)
1027               {
1028                 myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
1029                   mySurfaces.Surface(s),
1030                   Locations().Location(l), tol,
1031                   aPf, aPl);
1032               }
1033               else
1034               {
1035                 myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
1036                   mySurfaces.Surface(s),
1037                   Locations().Location(l), tol);
1038               }
1039             }
1040             myBuilder.Range(E,
1041               mySurfaces.Surface(s),
1042               Locations().Location(l),
1043               first, last);
1044             break;
1045
1046           case 4: // -4- Regularity
1047             reg = (GeomAbs_Shape)IS.get();
1048             BinTools::GetInteger(IS, s);
1049             BinTools::GetInteger(IS, l);
1050             BinTools::GetInteger(IS, s2);
1051             BinTools::GetInteger(IS, l2);
1052             if (mySurfaces.Surface(s).IsNull() ||
1053               mySurfaces.Surface(s2).IsNull())
1054               break;
1055             myBuilder.Continuity(E,
1056               mySurfaces.Surface(s),
1057               mySurfaces.Surface(s2),
1058               Locations().Location(l),
1059               Locations().Location(l2),
1060               reg);
1061             break;
1062
1063           case 5: // -5- Polygon3D                     
1064             BinTools::GetInteger(IS, c);
1065             BinTools::GetInteger(IS, l);
1066             //??? Bug?  myBuilder.UpdateEdge(E,myPolygons3D(c));
1067             myBuilder.UpdateEdge(E, myPolygons3D(c), Locations().Location(l));
1068             break;
1069
1070           case 6: // -6- Polygon on triangulation
1071           case 7: // -7- Polygon on closed triangulation
1072             closed = (val == 7);
1073             BinTools::GetInteger(IS, pt);
1074             if (closed)
1075               BinTools::GetInteger(IS, pt2);
1076
1077             BinTools::GetInteger(IS, t);
1078             BinTools::GetInteger(IS, l);
1079             if (closed)
1080             {
1081               myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations.FindKey(t), Locations().Location(l));
1082             }
1083             else
1084             {
1085               myBuilder.UpdateEdge (E, myNodes(pt), myTriangulations.FindKey(t), Locations().Location(l));
1086             }
1087             // range            
1088             break;
1089           default:
1090           {
1091             Standard_SStream aMsg;
1092             aMsg << "Unexpected Curve Representation =" << val << std::endl;
1093             throw Standard_Failure(aMsg.str().c_str());
1094           }
1095
1096           }
1097         } while (val > 0);
1098       }
1099       break;
1100
1101
1102       //---------
1103       // wire
1104       //---------
1105
1106       case TopAbs_WIRE:
1107         myBuilder.MakeWire(TopoDS::Wire(S));
1108         break;
1109
1110
1111         //---------
1112         // face
1113         //---------
1114
1115       case TopAbs_FACE:
1116       {
1117         // create a face :
1118         TopoDS_Face& F = TopoDS::Face(S);
1119         myBuilder.MakeFace(F);
1120         BinTools::GetBool(IS, bval); //NaturalRestriction flag
1121         BinTools::GetReal(IS, tol);
1122         BinTools::GetInteger(IS, s); //surface indx
1123         BinTools::GetInteger(IS, l); //location indx
1124         myBuilder.UpdateFace(F,
1125           s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
1126           Locations().Location(l),
1127           tol);
1128         myBuilder.NaturalRestriction(F, bval);
1129
1130         Standard_Byte aByte = (Standard_Byte)IS.get();
1131         // cas triangulation
1132         if (aByte == 2) {
1133           BinTools::GetInteger(IS, s);
1134           myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations.FindKey(s));
1135         }
1136       }
1137       break;
1138
1139
1140       //---------
1141       // shell
1142       //---------
1143
1144       case TopAbs_SHELL:
1145         myBuilder.MakeShell(TopoDS::Shell(S));
1146         break;
1147
1148
1149         //---------
1150         // solid
1151         //---------
1152
1153       case TopAbs_SOLID:
1154         myBuilder.MakeSolid(TopoDS::Solid(S));
1155         break;
1156
1157
1158         //---------
1159         // compsolid
1160         //---------
1161
1162       case TopAbs_COMPSOLID:
1163         myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
1164         break;
1165
1166
1167         //---------
1168         // compound
1169         //---------
1170
1171       case TopAbs_COMPOUND:
1172         myBuilder.MakeCompound(TopoDS::Compound(S));
1173         break;
1174
1175       default:
1176       {
1177         Standard_SStream aMsg;
1178         aMsg << "Unexpected topology type = " << T << std::endl;
1179         throw Standard_Failure(aMsg.str().c_str());
1180         break;
1181       }
1182       }
1183   }
1184   catch (Standard_Failure const& anException) {
1185     Standard_SStream aMsg;
1186     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadGeometry(S,OS)" << std::endl;
1187     aMsg << anException << std::endl;
1188     throw Standard_Failure(aMsg.str().c_str());
1189   }
1190 }
1191
1192 //=======================================================================
1193 //function : AddShapes
1194 //purpose  : 
1195 //=======================================================================
1196
1197 void BinTools_ShapeSet::AddShapes(TopoDS_Shape&       S1, 
1198                                   const TopoDS_Shape& S2)
1199 {
1200   myBuilder.Add(S1,S2);
1201 }
1202
1203 //=======================================================================
1204 //function : WritePolygonOnTriangulation
1205 //purpose  :
1206 //=======================================================================
1207 void BinTools_ShapeSet::WritePolygonOnTriangulation
1208   (Standard_OStream& OS,
1209    const Message_ProgressRange& theRange) const
1210 {
1211   const Standard_Integer aNbPol = myNodes.Extent();
1212   OS << "PolygonOnTriangulations " << aNbPol << "\n";
1213   try
1214   {
1215     OCC_CATCH_SIGNALS
1216     Message_ProgressScope aPS(theRange, "Writing polygons on triangulation", aNbPol);
1217     for (Standard_Integer aPolIter = 1; aPolIter <= aNbPol && aPS.More(); ++aPolIter, aPS.Next())
1218     {
1219       const Handle(Poly_PolygonOnTriangulation)& aPoly = myNodes.FindKey (aPolIter);
1220       const TColStd_Array1OfInteger& aNodes = aPoly->Nodes();
1221       BinTools::PutInteger(OS, aNodes.Length());
1222       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNodes.Length(); ++aNodeIter)
1223       {
1224         BinTools::PutInteger(OS, aNodes.Value (aNodeIter));
1225       }
1226
1227       // write the deflection
1228       BinTools::PutReal(OS, aPoly->Deflection());
1229
1230       // writing parameters
1231       if (const Handle(TColStd_HArray1OfReal)& aParam = aPoly->Parameters())
1232       {
1233         BinTools::PutBool(OS, Standard_True);
1234         for (Standard_Integer aNodeIter = 1; aNodeIter <= aParam->Length(); ++aNodeIter)
1235         {
1236           BinTools::PutReal(OS, aParam->Value (aNodeIter));
1237         }
1238       }
1239       else
1240       {
1241         BinTools::PutBool(OS, Standard_False);
1242       }
1243     }
1244   }
1245   catch (Standard_Failure const& anException)
1246   {
1247     Standard_SStream aMsg;
1248     aMsg << "EXCEPTION in BinTools_ShapeSet::WritePolygonOnTriangulation(..)\n" << anException << "\n";
1249     throw Standard_Failure(aMsg.str().c_str());
1250   }
1251 }
1252
1253 //=======================================================================
1254 //function : ReadPolygonOnTriangulation
1255 //purpose  :
1256 //=======================================================================
1257 void BinTools_ShapeSet::ReadPolygonOnTriangulation
1258   (Standard_IStream& IS,
1259    const Message_ProgressRange& theRange)
1260 {
1261   char aHeader[255];
1262   IS >> aHeader;
1263   if (IS.fail() || (strstr(aHeader,"PolygonOnTriangulations") == NULL))
1264   {
1265     throw Standard_Failure("BinTools_ShapeSet::ReadPolygonOnTriangulation: Not a PolygonOnTriangulation section");
1266   }
1267
1268   Standard_Integer aNbPol = 0;
1269   IS >> aNbPol;
1270   IS.get();//remove LF
1271   try
1272   {
1273     OCC_CATCH_SIGNALS
1274     Message_ProgressScope aPS(theRange, "Reading Polygones on triangulation", aNbPol);
1275     for (Standard_Integer aPolIter = 1; aPolIter <= aNbPol && aPS.More(); ++aPolIter, aPS.Next())
1276     {
1277       Standard_Integer aNbNodes = 0;
1278       BinTools::GetInteger(IS, aNbNodes);
1279       Handle(Poly_PolygonOnTriangulation) aPoly = new Poly_PolygonOnTriangulation (aNbNodes, Standard_False);
1280       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1281       {
1282         Standard_Integer aNode = 0;
1283         BinTools::GetInteger (IS, aNode);
1284         aPoly->SetNode (aNodeIter, aNode);
1285       }
1286
1287       Standard_Real aDefl = 0.0;
1288       BinTools::GetReal(IS, aDefl);
1289       aPoly->Deflection (aDefl);
1290
1291       Standard_Boolean hasParameters = Standard_False;
1292       BinTools::GetBool(IS, hasParameters);
1293       if (hasParameters)
1294       {
1295         Handle(TColStd_HArray1OfReal) aParams = new TColStd_HArray1OfReal (1, aNbNodes);
1296         for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1297         {
1298           BinTools::GetReal(IS, aParams->ChangeValue (aNodeIter));
1299         }
1300         aPoly->SetParameters (aParams);
1301       }
1302       myNodes.Add (aPoly);
1303     }
1304   }
1305   catch (Standard_Failure const& anException)
1306   {
1307     Standard_SStream aMsg;
1308     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadPolygonOnTriangulation(..)\n" << anException << "\n";
1309     throw Standard_Failure(aMsg.str().c_str());
1310   }
1311 }
1312
1313 //=======================================================================
1314 //function : WritePolygon3D
1315 //purpose  :
1316 //=======================================================================
1317 void BinTools_ShapeSet::WritePolygon3D (Standard_OStream& OS,
1318                                         const Message_ProgressRange& theRange)const
1319 {
1320   const Standard_Integer aNbPol = myPolygons3D.Extent();
1321   OS << "Polygon3D " << aNbPol << "\n";
1322   try
1323   {
1324     OCC_CATCH_SIGNALS
1325     Message_ProgressScope aPS(theRange, "Writing polygons 3D", aNbPol);
1326     for (Standard_Integer aPolIter = 1; aPolIter <= aNbPol && aPS.More(); ++aPolIter, aPS.Next())
1327     {
1328       const Handle(Poly_Polygon3D)& aPoly = myPolygons3D.FindKey (aPolIter);
1329       BinTools::PutInteger(OS, aPoly->NbNodes());
1330       BinTools::PutBool(OS, aPoly->HasParameters());
1331
1332       // write the deflection
1333       BinTools::PutReal(OS, aPoly->Deflection());
1334
1335       // write the nodes
1336       const Standard_Integer  aNbNodes = aPoly->NbNodes();
1337       const TColgp_Array1OfPnt& aNodes = aPoly->Nodes();
1338       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1339       {
1340         const gp_Pnt& aPnt = aNodes.Value (aNodeIter);
1341         BinTools::PutReal(OS, aPnt.X());
1342         BinTools::PutReal(OS, aPnt.Y());
1343         BinTools::PutReal(OS, aPnt.Z());
1344       }
1345       if (aPoly->HasParameters())
1346       {
1347         const TColStd_Array1OfReal& aParam = aPoly->Parameters();
1348         for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1349         {
1350           BinTools::PutReal(OS, aParam.Value (aNodeIter));
1351         }
1352       }
1353     }
1354   }
1355   catch (Standard_Failure const& anException)
1356   {
1357     Standard_SStream aMsg;
1358     aMsg << "EXCEPTION in BinTools_ShapeSet::WritePolygon3D(..)\n" << anException << "\n";
1359     throw Standard_Failure(aMsg.str().c_str());
1360   }
1361 }
1362 //=======================================================================
1363 //function : ReadPolygon3D
1364 //purpose  :
1365 //=======================================================================
1366 void BinTools_ShapeSet::ReadPolygon3D (Standard_IStream& IS,
1367                                        const Message_ProgressRange& theRange)
1368 {
1369   char aHeader[255];
1370   IS >> aHeader;
1371
1372   if (IS.fail() || strstr(aHeader,"Polygon3D") == NULL)
1373   {
1374 #ifdef OCCT_DEBUG
1375     std::cout <<"Buffer: " << aHeader << std::endl;
1376 #endif
1377     throw Standard_Failure("BinTools_ShapeSet::ReadPolygon3D: Not a Polygon3D section");
1378   }
1379
1380   Standard_Integer aNbPol = 0;
1381   IS >> aNbPol;
1382   IS.get();//remove LF
1383   try
1384   {
1385     OCC_CATCH_SIGNALS
1386     Message_ProgressScope aPS(theRange, "Reading polygones 3D", aNbPol);
1387     for (Standard_Integer aPolIter = 1; aPolIter <= aNbPol && aPS.More(); ++aPolIter, aPS.Next())
1388     {
1389       Standard_Integer aNbNodes = 0;
1390       Standard_Boolean hasParameters = Standard_False;
1391       Standard_Real aDefl = 0.0;
1392       BinTools::GetInteger(IS, aNbNodes);
1393       BinTools::GetBool(IS, hasParameters);
1394       BinTools::GetReal(IS, aDefl);
1395
1396       Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D (aNbNodes, hasParameters);
1397       aPoly->Deflection (aDefl);
1398
1399       TColgp_Array1OfPnt& aNodes = aPoly->ChangeNodes();
1400       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1401       {
1402         gp_XYZ& aPnt = aNodes.ChangeValue (aNodeIter).ChangeCoord();
1403         BinTools::GetReal(IS, aPnt.ChangeCoord (1));
1404         BinTools::GetReal(IS, aPnt.ChangeCoord (2));
1405         BinTools::GetReal(IS, aPnt.ChangeCoord (3));
1406       }
1407       if (hasParameters)
1408       {
1409         TColStd_Array1OfReal& aParam = aPoly->ChangeParameters();
1410         for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1411         {
1412           BinTools::GetReal(IS, aParam.ChangeValue (aNodeIter));
1413         }
1414       }
1415
1416       myPolygons3D.Add (aPoly);
1417     }
1418   }
1419   catch (Standard_Failure const& anException)
1420   {
1421     Standard_SStream aMsg;
1422     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadPolygon3D(..)\n" << anException << "\n";
1423     throw Standard_Failure(aMsg.str().c_str());
1424   }
1425 }
1426
1427
1428 //=======================================================================
1429 //function : WriteTriangulation
1430 //purpose  :
1431 //=======================================================================
1432 void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
1433                                             const Message_ProgressRange& theRange) const
1434 {
1435   const Standard_Integer aNbTriangulations = myTriangulations.Extent();
1436   OS << "Triangulations " << aNbTriangulations << "\n";
1437
1438   try
1439   {
1440     OCC_CATCH_SIGNALS
1441     Message_ProgressScope aPS(theRange, "Writing triangulation", aNbTriangulations);
1442     for (Standard_Integer aTriangulationIter = 1; aTriangulationIter <= aNbTriangulations && aPS.More(); ++aTriangulationIter, aPS.Next())
1443     {
1444       const Handle(Poly_Triangulation)& aTriangulation = myTriangulations.FindKey (aTriangulationIter);
1445       Standard_Boolean NeedToWriteNormals = myTriangulations.FindFromIndex(aTriangulationIter);
1446       const Standard_Integer aNbNodes     = aTriangulation->NbNodes();
1447       const Standard_Integer aNbTriangles = aTriangulation->NbTriangles();
1448       BinTools::PutInteger(OS, aNbNodes);
1449       BinTools::PutInteger(OS, aNbTriangles);
1450       BinTools::PutBool(OS, aTriangulation->HasUVNodes() ? 1 : 0);
1451       if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
1452       {
1453         BinTools::PutBool(OS, (aTriangulation->HasNormals() && NeedToWriteNormals) ? 1 : 0);
1454       }
1455       BinTools::PutReal(OS, aTriangulation->Deflection());
1456
1457       // write the 3d nodes
1458       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1459       {
1460         const gp_Pnt aPnt = aTriangulation->Node (aNodeIter);
1461         BinTools::PutReal(OS, aPnt.X());
1462         BinTools::PutReal(OS, aPnt.Y());
1463         BinTools::PutReal(OS, aPnt.Z());
1464       }
1465
1466       if (aTriangulation->HasUVNodes())
1467       {
1468         for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1469         {
1470           const gp_Pnt2d aUV = aTriangulation->UVNode (aNodeIter);
1471           BinTools::PutReal(OS, aUV.X());
1472           BinTools::PutReal(OS, aUV.Y());
1473         }
1474       }
1475
1476       for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
1477       {
1478         const Poly_Triangle aTri = aTriangulation->Triangle (aTriIter);
1479         BinTools::PutInteger(OS, aTri.Value (1));
1480         BinTools::PutInteger(OS, aTri.Value (2));
1481         BinTools::PutInteger(OS, aTri.Value (3));
1482       }
1483
1484       // write the normals
1485       if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
1486       {
1487         if (aTriangulation->HasNormals() && NeedToWriteNormals)
1488         {
1489           gp_Vec3f aNormal;
1490           for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
1491           {
1492             aTriangulation->Normal (aNormalIter, aNormal);
1493             BinTools::PutShortReal (OS, aNormal.x());
1494             BinTools::PutShortReal (OS, aNormal.y());
1495             BinTools::PutShortReal (OS, aNormal.z());
1496           }
1497         }
1498       }
1499     }
1500   }
1501   catch (Standard_Failure const& anException)
1502   {
1503     Standard_SStream aMsg;
1504     aMsg << "EXCEPTION in BinTools_ShapeSet::WriteTriangulation(..)\n" << anException << "\n";
1505     throw Standard_Failure(aMsg.str().c_str());
1506   }
1507 }
1508
1509 //=======================================================================
1510 //function : ReadTriangulation
1511 //purpose  :
1512 //=======================================================================
1513 void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
1514                                            const Message_ProgressRange& theRange)
1515 {
1516   char aHeader[255];
1517   IS >> aHeader;
1518   if (IS.fail() || (strstr(aHeader, "Triangulations") == NULL))
1519   {
1520     throw Standard_Failure("BinTools_ShapeSet::Triangulation: Not a Triangulation section");
1521   }
1522
1523   Standard_Integer aNbTriangulations = 0;
1524   IS >> aNbTriangulations;
1525   IS.get();// remove LF 
1526
1527   try
1528   {
1529     OCC_CATCH_SIGNALS
1530     Message_ProgressScope aPS(theRange, "Reading triangulation", aNbTriangulations);
1531     for (Standard_Integer aTriangulationIter = 1; aTriangulationIter <= aNbTriangulations && aPS.More(); ++aTriangulationIter, aPS.Next())
1532     {
1533       Standard_Integer aNbNodes = 0, aNbTriangles = 0;
1534       Standard_Boolean hasUV = Standard_False;
1535       Standard_Boolean hasNormals = Standard_False;
1536       Standard_Real aDefl = 0.0;
1537       BinTools::GetInteger(IS, aNbNodes);
1538       BinTools::GetInteger(IS, aNbTriangles);
1539       BinTools::GetBool(IS, hasUV);
1540       if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
1541       {
1542         BinTools::GetBool(IS, hasNormals);
1543       }
1544       BinTools::GetReal(IS, aDefl); //deflection
1545       Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation (aNbNodes, aNbTriangles, hasUV, hasNormals);
1546       aTriangulation->Deflection (aDefl);
1547
1548       gp_Pnt aNode;
1549       for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1550       {
1551         BinTools::GetReal(IS, aNode.ChangeCoord().ChangeCoord (1));
1552         BinTools::GetReal(IS, aNode.ChangeCoord().ChangeCoord (2));
1553         BinTools::GetReal(IS, aNode.ChangeCoord().ChangeCoord (3));
1554         aTriangulation->SetNode (aNodeIter, aNode);
1555       }
1556
1557       if (hasUV)
1558       {
1559         gp_Pnt2d aNode2d;
1560         for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
1561         {
1562           BinTools::GetReal(IS, aNode2d.ChangeCoord().ChangeCoord (1));
1563           BinTools::GetReal(IS, aNode2d.ChangeCoord().ChangeCoord (2));
1564           aTriangulation->SetUVNode (aNodeIter, aNode2d);
1565         }
1566       }
1567
1568       // read the triangles
1569       Standard_Integer aTriNodes[3] = {};
1570       for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
1571       {
1572         BinTools::GetInteger(IS, aTriNodes[0]);
1573         BinTools::GetInteger(IS, aTriNodes[1]);
1574         BinTools::GetInteger(IS, aTriNodes[2]);
1575         aTriangulation->SetTriangle (aTriIter, Poly_Triangle (aTriNodes[0], aTriNodes[1], aTriNodes[2]));
1576       }
1577       //IS.ignore(sizeof(Standard_Real) * (hasUV ? 5 : 3) * aNbNodes + sizeof(Standard_Integer) * 3 * aNbTriangles);
1578
1579       if (hasNormals)
1580       {
1581         gp_Vec3f aNormal;
1582         for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
1583         {
1584           BinTools::GetShortReal(IS, aNormal.x());
1585           BinTools::GetShortReal(IS, aNormal.y());
1586           BinTools::GetShortReal(IS, aNormal.z());
1587           aTriangulation->SetNormal (aNormalIter, aNormal);
1588         }
1589       }
1590
1591       myTriangulations.Add (aTriangulation, hasNormals);
1592     }
1593   }
1594   catch (Standard_Failure const& anException)
1595   {
1596     Standard_SStream aMsg;
1597     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadTriangulation(..)\n" << anException << "\n";
1598     throw Standard_Failure(aMsg.str().c_str());
1599   }
1600 }
1601
1602 //=======================================================================
1603 //function : NbShapes
1604 //purpose  : 
1605 //=======================================================================
1606
1607 Standard_Integer  BinTools_ShapeSet::NbShapes() const
1608 {
1609   return myShapes.Extent();
1610 }