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