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