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