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