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