4299960299070cc3aa0792bb4267e7f368cad2f9
[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)) ? Standard_True : Standard_False;
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) ? Standard_True : Standard_False;
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,Handle(Poly_Polygon3D)::DownCast(myPolygons3D(c)));
1038             myBuilder.UpdateEdge(E,Handle(Poly_Polygon3D)::DownCast(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               myBuilder.UpdateEdge
1052                 (E, Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
1053                  Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt2)),
1054                  Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
1055                  Locations().Location(l));
1056             }
1057             else {
1058               myBuilder.UpdateEdge
1059                 (E,Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
1060                  Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
1061                  Locations().Location(l));
1062             }
1063             // range            
1064             break;
1065           default:
1066             {
1067               Standard_SStream aMsg;
1068               aMsg <<"Unexpected Curve Representation ="<< val << std::endl;
1069               throw Standard_Failure(aMsg.str().c_str());
1070             }
1071             
1072           }
1073         } while (val > 0);
1074       }
1075       break;
1076
1077
1078     //---------
1079     // wire
1080     //---------
1081
1082     case TopAbs_WIRE :
1083       myBuilder.MakeWire(TopoDS::Wire(S));
1084       break;
1085
1086
1087     //---------
1088     // face
1089     //---------
1090
1091     case TopAbs_FACE :
1092       {
1093     // create a face :
1094         TopoDS_Face& F = TopoDS::Face(S);
1095         myBuilder.MakeFace(F);
1096         BinTools::GetBool(IS, bval); //NaturalRestriction flag
1097         BinTools::GetReal(IS, tol);
1098         BinTools::GetInteger(IS, s); //surface indx
1099         BinTools::GetInteger(IS, l); //location indx
1100         myBuilder.UpdateFace (F,
1101                         s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
1102                                           Locations().Location(l),
1103                         tol);
1104         myBuilder.NaturalRestriction (F, bval);
1105     
1106         Standard_Byte aByte = (Standard_Byte)IS.get();
1107       // cas triangulation
1108         if(aByte == 2) {
1109           BinTools::GetInteger(IS, s);
1110           myBuilder.UpdateFace(TopoDS::Face(S),
1111                                Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
1112         }
1113       }
1114       break;
1115
1116
1117     //---------
1118     // shell
1119     //---------
1120
1121     case TopAbs_SHELL :
1122       myBuilder.MakeShell(TopoDS::Shell(S));
1123       break;
1124
1125
1126     //---------
1127     // solid
1128     //---------
1129
1130     case TopAbs_SOLID :
1131       myBuilder.MakeSolid(TopoDS::Solid(S));
1132       break;
1133
1134
1135     //---------
1136     // compsolid
1137     //---------
1138
1139     case TopAbs_COMPSOLID :
1140       myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
1141       break;
1142
1143
1144     //---------
1145     // compound
1146     //---------
1147
1148     case TopAbs_COMPOUND :
1149       myBuilder.MakeCompound(TopoDS::Compound(S));
1150       break;
1151
1152     default:
1153       {
1154         Standard_SStream aMsg;
1155         aMsg << "Unexpected topology type = "<< T <<std::endl;
1156         throw Standard_Failure(aMsg.str().c_str());
1157         break;
1158       }
1159     }
1160   }
1161   catch(Standard_Failure const& anException) {
1162     Standard_SStream aMsg;
1163     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadGeometry(S,OS)" << std::endl;
1164     aMsg << anException << std::endl;
1165     throw Standard_Failure(aMsg.str().c_str());
1166   }
1167 }
1168
1169
1170
1171 //=======================================================================
1172 //function : AddShapes
1173 //purpose  : 
1174 //=======================================================================
1175
1176 void  BinTools_ShapeSet::AddShapes(TopoDS_Shape&       S1, 
1177                                     const TopoDS_Shape& S2)
1178 {
1179   myBuilder.Add(S1,S2);
1180 }
1181
1182
1183 //=======================================================================
1184 //function : WritePolygonOnTriangulation
1185 //purpose  : 
1186 //=======================================================================
1187
1188 void BinTools_ShapeSet::WritePolygonOnTriangulation(Standard_OStream& OS) const
1189 {
1190   Standard_Integer i, j, nbpOntri = myNodes.Extent();
1191
1192   OS << "PolygonOnTriangulations " << nbpOntri << "\n";
1193   Handle(Poly_PolygonOnTriangulation) Poly;
1194   Handle(TColStd_HArray1OfReal) Param;
1195   try {
1196     OCC_CATCH_SIGNALS
1197     for (i=1; i<=nbpOntri; i++) {
1198       Poly = Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(i));
1199       const TColStd_Array1OfInteger& Nodes = Poly->Nodes();
1200       BinTools::PutInteger(OS, Nodes.Length());
1201       for (j=1; j <= Nodes.Length(); j++) 
1202         BinTools::PutInteger(OS,  Nodes.Value(j));
1203
1204     // writing parameters:
1205       Param = Poly->Parameters();
1206
1207     // write the deflection
1208       BinTools::PutReal(OS, Poly->Deflection());
1209       if (!Param.IsNull()) {
1210         BinTools::PutBool(OS, Standard_True);
1211         for (j=1; j <= Param->Length(); j++) 
1212           BinTools::PutReal(OS, Param->Value(j)); 
1213       }
1214       else 
1215         BinTools::PutBool(OS, Standard_False);
1216     }
1217   }
1218   catch(Standard_Failure const& anException) {
1219     Standard_SStream aMsg;
1220     aMsg << "EXCEPTION in BinTools_ShapeSet::WritePolygonOnTriangulation(..)" << std::endl;
1221     aMsg << anException << std::endl;
1222     throw Standard_Failure(aMsg.str().c_str());
1223   }
1224 }
1225
1226 //=======================================================================
1227 //function : ReadPolygonOnTriangulation
1228 //purpose  : 
1229 //=======================================================================
1230
1231 void BinTools_ShapeSet::ReadPolygonOnTriangulation(Standard_IStream& IS)
1232 {
1233   char buffer[255];
1234   IS >> buffer;
1235   if (IS.fail() || (strstr(buffer,"PolygonOnTriangulations") == NULL)) {
1236     throw Standard_Failure("BinTools_ShapeSet::ReadPolygonOnTriangulation: Not a PolygonOnTriangulation section");
1237   }
1238   Standard_Integer i, j, val, nbpol = 0, nbnodes =0;
1239   Standard_Boolean hasparameters;
1240   Standard_Real par;
1241   Handle(TColStd_HArray1OfReal) Param;
1242   Handle(Poly_PolygonOnTriangulation) Poly;
1243   IS >> nbpol;
1244   IS.get();//remove LF 
1245   try {
1246     OCC_CATCH_SIGNALS
1247     for (i=1; i<=nbpol; i++) {
1248       BinTools::GetInteger(IS, nbnodes);
1249
1250       TColStd_Array1OfInteger Nodes(1, nbnodes);
1251       for (j = 1; j <= nbnodes; j++) {
1252         BinTools::GetInteger(IS, val);
1253         Nodes(j) = val;
1254       }
1255       Standard_Real def;
1256       BinTools::GetReal(IS, def);
1257       BinTools::GetBool(IS, hasparameters);
1258       if (hasparameters) {
1259         TColStd_Array1OfReal Param1(1, nbnodes);
1260         for (j = 1; j <= nbnodes; j++) {
1261           BinTools::GetReal(IS, par);
1262           Param1(j) = par;
1263         }
1264         Poly = new Poly_PolygonOnTriangulation(Nodes, Param1);
1265       }
1266       else Poly = new Poly_PolygonOnTriangulation(Nodes);
1267       Poly->Deflection(def);
1268       myNodes.Add(Poly);
1269     }
1270   }
1271   catch(Standard_Failure const& anException) {
1272     Standard_SStream aMsg;
1273     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadPolygonOnTriangulation(..)" << std::endl;
1274     aMsg << anException << std::endl;
1275     throw Standard_Failure(aMsg.str().c_str());
1276   }
1277 }
1278
1279
1280
1281 //=======================================================================
1282 //function : WritePolygon3D
1283 //purpose  : 
1284 //=======================================================================
1285
1286 void BinTools_ShapeSet::WritePolygon3D(Standard_OStream& OS)const
1287 {
1288   Standard_Integer i, j, nbpol = myPolygons3D.Extent();
1289   OS << "Polygon3D " << nbpol << "\n";
1290   Handle(Poly_Polygon3D) P;
1291   try {
1292     OCC_CATCH_SIGNALS
1293     for (i = 1; i <= nbpol; i++) {
1294       P = Handle(Poly_Polygon3D)::DownCast(myPolygons3D(i));
1295       BinTools::PutInteger(OS, P->NbNodes());
1296       BinTools::PutBool(OS, P->HasParameters()? 1:0);
1297
1298     // write the deflection
1299       BinTools::PutReal(OS, P->Deflection());
1300
1301     // write the nodes
1302       Standard_Integer i1, nbNodes = P->NbNodes();
1303       const TColgp_Array1OfPnt& Nodes = P->Nodes();
1304       for (j = 1; j <= nbNodes; j++) {
1305         BinTools::PutReal(OS, Nodes(j).X());
1306         BinTools::PutReal(OS, Nodes(j).Y());
1307         BinTools::PutReal(OS, Nodes(j).Z());
1308       }
1309       if (P->HasParameters()) {
1310         const TColStd_Array1OfReal& Param = P->Parameters();
1311         for ( i1 = 1; i1 <= nbNodes; i1++ ) {
1312           BinTools::PutReal(OS, Param(i1));
1313         }
1314       }
1315     }
1316   }
1317   catch(Standard_Failure const& anException) {
1318     Standard_SStream aMsg;
1319     aMsg << "EXCEPTION in BinTools_ShapeSet::WritePolygon3D(..)" << std::endl;
1320     aMsg << anException << std::endl;
1321     throw Standard_Failure(aMsg.str().c_str());
1322   }
1323 }
1324 //=======================================================================
1325 //function : ReadPolygon3D
1326 //purpose  : 
1327 //=======================================================================
1328
1329 void BinTools_ShapeSet::ReadPolygon3D(Standard_IStream& IS)
1330 {
1331   char buffer[255];
1332   Standard_Integer i, j, p, nbpol=0, nbnodes =0;
1333   Standard_Boolean hasparameters = Standard_False;
1334   Standard_Real d, x, y, z;
1335   IS >> buffer;
1336
1337   if (IS.fail() || strstr(buffer,"Polygon3D") == NULL) {
1338 #ifdef OCCT_DEBUG
1339     std::cout <<"Buffer: " << buffer << std::endl;
1340 #endif
1341     throw Standard_Failure("BinTools_ShapeSet::ReadPolygon3D: Not a Polygon3D section");
1342   }
1343   Handle(Poly_Polygon3D) P;
1344   IS >> nbpol;
1345   IS.get();//remove LF 
1346
1347   try {
1348     OCC_CATCH_SIGNALS
1349     for (i=1; i<=nbpol; i++) {
1350       BinTools::GetInteger(IS, nbnodes);
1351       BinTools::GetBool(IS, hasparameters);
1352       TColgp_Array1OfPnt Nodes(1, nbnodes);
1353       BinTools::GetReal(IS, d);
1354       for (j = 1; j <= nbnodes; j++) {
1355         BinTools::GetReal(IS, x);
1356         BinTools::GetReal(IS, y);
1357         BinTools::GetReal(IS, z);
1358         Nodes(j).SetCoord(x,y,z);
1359       }
1360       if (hasparameters) {
1361         TColStd_Array1OfReal Param(1,nbnodes);
1362         for (p = 1; p <= nbnodes; p++) 
1363           BinTools::GetReal(IS, Param(p));
1364
1365         P = new Poly_Polygon3D(Nodes, Param);
1366       }
1367       else P = new Poly_Polygon3D(Nodes);
1368       P->Deflection(d);
1369       myPolygons3D.Add(P);
1370     }
1371   }
1372   catch(Standard_Failure const& anException) {
1373     Standard_SStream aMsg;
1374     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadPolygon3D(..)" << std::endl;
1375     aMsg << anException << std::endl;
1376     throw Standard_Failure(aMsg.str().c_str());
1377   }
1378 }
1379
1380
1381 //=======================================================================
1382 //function : WriteTriangulation
1383 //purpose  : 
1384 //=======================================================================
1385
1386 void BinTools_ShapeSet::WriteTriangulation(Standard_OStream& OS) const
1387 {
1388   Standard_Integer i, j, nbNodes, nbtri = myTriangulations.Extent();
1389   Standard_Integer nbTriangles = 0, n1, n2, n3;
1390     OS << "Triangulations " << nbtri << "\n";
1391   Handle(Poly_Triangulation) T;
1392   try {
1393     OCC_CATCH_SIGNALS
1394     for (i = 1; i <= nbtri; i++) {
1395       T = Handle(Poly_Triangulation)::DownCast(myTriangulations(i));
1396       BinTools::PutInteger(OS, T->NbNodes());
1397       BinTools::PutInteger(OS, T->NbTriangles());
1398       BinTools::PutBool(OS, T->HasUVNodes()? 1:0);
1399     // write the deflection
1400       BinTools::PutReal(OS, T->Deflection());
1401
1402     // write the 3d nodes
1403       nbNodes = T->NbNodes();
1404       const TColgp_Array1OfPnt& Nodes = T->Nodes();
1405       for (j = 1; j <= nbNodes; j++) {
1406         BinTools::PutReal(OS, Nodes(j).X());
1407         BinTools::PutReal(OS, Nodes(j).Y());
1408         BinTools::PutReal(OS, Nodes(j).Z());
1409       }
1410     
1411       if (T->HasUVNodes()) {
1412         const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
1413         for (j = 1; j <= nbNodes; j++) {
1414           BinTools::PutReal(OS, UVNodes(j).X());
1415           BinTools::PutReal(OS, UVNodes(j).Y());
1416         }
1417       }
1418       nbTriangles = T->NbTriangles();
1419       const Poly_Array1OfTriangle& Triangles = T->Triangles();
1420       for (j = 1; j <= nbTriangles; j++) {
1421         Triangles(j).Get(n1, n2, n3);
1422         BinTools::PutInteger(OS, n1);
1423         BinTools::PutInteger(OS, n2);
1424         BinTools::PutInteger(OS, n3);
1425       }
1426     }
1427   }
1428   catch(Standard_Failure const& anException) {
1429     Standard_SStream aMsg;
1430     aMsg << "EXCEPTION in BinTools_ShapeSet::WriteTriangulation(..)" << std::endl;
1431     aMsg << anException << std::endl;
1432     throw Standard_Failure(aMsg.str().c_str());
1433   }
1434 }
1435
1436 //=======================================================================
1437 //function : ReadTriangulation
1438 //purpose  : 
1439 //=======================================================================
1440
1441 void BinTools_ShapeSet::ReadTriangulation(Standard_IStream& IS)
1442 {
1443   char buffer[255];
1444   Standard_Integer i, j, nbtri =0;
1445   Standard_Real d, x, y, z;
1446   Standard_Integer nbNodes =0, nbTriangles=0;
1447   Standard_Boolean hasUV = Standard_False;
1448
1449   Handle(Poly_Triangulation) T;
1450   IS >> buffer;
1451
1452   if (IS.fail() || (strstr(buffer,"Triangulations") == NULL)) {
1453     throw Standard_Failure("BinTools_ShapeSet::Triangulation: Not a Triangulation section");
1454   }
1455   IS >> nbtri;
1456   IS.get();// remove LF 
1457
1458   try {
1459     OCC_CATCH_SIGNALS
1460     for (i=1; i<=nbtri; i++) {
1461       BinTools::GetInteger(IS, nbNodes);
1462       BinTools::GetInteger(IS, nbTriangles);
1463       TColgp_Array1OfPnt Nodes(1, nbNodes);
1464       BinTools::GetBool(IS, hasUV);
1465       TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
1466       BinTools::GetReal(IS, d); //deflection
1467       for (j = 1; j <= nbNodes; j++) {
1468         BinTools::GetReal(IS, x);
1469         BinTools::GetReal(IS, y);
1470         BinTools::GetReal(IS, z);
1471         Nodes(j).SetCoord(x,y,z);
1472       }
1473       
1474       if (hasUV) {
1475         for (j = 1; j <= nbNodes; j++) {
1476           BinTools::GetReal(IS, x);
1477           BinTools::GetReal(IS, y);
1478           UVNodes(j).SetCoord(x,y);
1479         }
1480       }
1481       
1482       // read the triangles
1483       Standard_Integer n1,n2,n3;
1484       Poly_Array1OfTriangle Triangles(1, nbTriangles);
1485       for (j = 1; j <= nbTriangles; j++) {
1486         BinTools::GetInteger(IS, n1);
1487         BinTools::GetInteger(IS, n2);
1488         BinTools::GetInteger(IS, n3);
1489         Triangles(j).Set(n1,n2,n3);
1490       }
1491       
1492       if (hasUV) T =  new Poly_Triangulation(Nodes,UVNodes,Triangles);
1493       else T = new Poly_Triangulation(Nodes,Triangles);      
1494       T->Deflection(d);      
1495       myTriangulations.Add(T);
1496     }
1497   }
1498   catch(Standard_Failure const& anException) {
1499     Standard_SStream aMsg;
1500     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadTriangulation(..)" << std::endl;
1501     aMsg << anException << std::endl;
1502     throw Standard_Failure(aMsg.str().c_str());
1503   }
1504 }
1505
1506 //=======================================================================
1507 //function : NbShapes
1508 //purpose  : 
1509 //=======================================================================
1510
1511 Standard_Integer  BinTools_ShapeSet::NbShapes() const
1512 {
1513   return myShapes.Extent();
1514 }