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