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