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