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