1 /************
2 *
3 *   This file is part of a tool for reading 3D content in the PRC format.
4 *   Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
5 *
6 *   This program is free software: you can redistribute it and/or modify
7 *   it under the terms of the GNU Lesser General Public License as published by
8 *   the Free Software Foundation, either version 3 of the License, or
9 *   (at your option) any later version.
10 *
11 *   This program is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *   GNU Lesser General Public License for more details.
15 *
16 *   You should have received a copy of the GNU Lesser General Public License
17 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 *
19 *************/
20 
21 #include <iostream>
22 #include <fstream>
23 #include <iomanip>
24 #include <string>
25 #include <sstream>
26 
27 #include "../PRC.h"
28 #include "describePRC.h"
29 
30 using std::ostringstream; using std::cout; using std::endl;
31 using std::hex; using std::dec; using std::string; using std::setw;
32 using std::setfill;
33 
34 // describe sections
35 
describeGlobals(BitByBitData & mData)36 void describeGlobals(BitByBitData &mData)
37 {
38   mData.tellPosition();
39   cout << getIndent() << "--Globals--" << endl;
40   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGlobals))
41     return;
42   indent();
43 
44   describeContentPRCBase(mData,false);
45   unsigned int numberOfReferencedFileStructures = mData.readUnsignedInt();
46   cout << getIndent() << "numberOfReferencedFileStructures "
47       << numberOfReferencedFileStructures << endl;
48   indent();
49   for(unsigned int i = 0; i < numberOfReferencedFileStructures; ++i)
50   {
51     describeCompressedUniqueID(mData);
52   }
53   dedent();
54 
55   double tessellation_chord_height_ratio = mData.readDouble();
56   cout << getIndent() << "tessellation_chord_height_ratio "
57       << tessellation_chord_height_ratio << endl;
58 
59   double tessellation_angle_degree = mData.readDouble();
60   cout << getIndent() << "tessellation_angle_degree "
61       << tessellation_angle_degree << endl;
62 
63   string default_font_family_name = mData.readString();
64   cout << getIndent() << "default_font_family_name \""
65       << default_font_family_name << '\"' << endl;
66 
67   unsigned int number_of_fonts = mData.readUnsignedInt();
68   cout << getIndent() << "number_of_fonts " << number_of_fonts << endl;
69 
70   indent();
71   for(unsigned int q = 0; q < number_of_fonts; ++q)
72   {
73     string font_name = mData.readString();
74     cout << getIndent() << "font_name \"" << font_name << '\"' << endl;
75     unsigned int char_set = mData.readUnsignedInt();
76     cout << getIndent() << "char_set " << char_set << endl;
77     unsigned int number_of_font_keys = mData.readUnsignedInt();
78     cout << getIndent() << "number_of_font_keys " << number_of_font_keys
79         << endl;
80     indent();
81     for(unsigned int i = 0; i < number_of_font_keys; i++)
82     {
83       unsigned int font_size = mData.readUnsignedInt() - 1;
84       cout << getIndent() << "font_size " << font_size << endl;
85       unsigned char attributes = mData.readChar();
86       cout << getIndent() << "attributes "
87           << static_cast<unsigned int>(attributes) << endl;
88     }
89     dedent();
90   }
91   dedent();
92 
93   unsigned int number_of_colours = mData.readUnsignedInt();
94   cout << getIndent() << "number_of_colours " << number_of_colours << endl;
95   indent();
96   for(unsigned int i = 0; i < number_of_colours; ++i)
97     describeRGBColour(mData);
98   dedent();
99 
100   unsigned int number_of_pictures = mData.readUnsignedInt();
101   cout << getIndent() << "number_of_pictures " << number_of_pictures << endl;
102   indent();
103   for(unsigned int i=0;i<number_of_pictures;i++)
104     describePicture(mData);
105   dedent();
106 
107   unsigned int number_of_texture_definitions = mData.readUnsignedInt();
108   cout << getIndent() << "number_of_texture_definitions "
109       << number_of_texture_definitions << endl;
110   indent();
111   for(unsigned int i=0;i<number_of_texture_definitions;i++)
112     describeTextureDefinition(mData);
113   dedent();
114 
115 
116   unsigned int number_of_materials = mData.readUnsignedInt();
117   cout << getIndent() << "number_of_materials " << number_of_materials << endl;
118   indent();
119   for(unsigned int i=0;i<number_of_materials;i++)
120     describeMaterial(mData);
121   dedent();
122 
123   unsigned int number_of_line_patterns = mData.readUnsignedInt();
124   cout << getIndent() << "number_of_line_patterns "
125       << number_of_line_patterns << endl;
126   indent();
127   for(unsigned int i=0;i<number_of_line_patterns;i++)
128     describeLinePattern(mData);
129   dedent();
130 
131   unsigned int number_of_styles = mData.readUnsignedInt();
132   cout << getIndent() << "number_of_styles " << number_of_styles << endl;
133   indent();
134   for(unsigned int i=0;i<number_of_styles;i++)
135     describeCategory1LineStyle(mData);
136   dedent();
137 
138   unsigned int number_of_fill_patterns = mData.readUnsignedInt();
139   cout << getIndent() << "number_of_fill_patterns "
140       << number_of_fill_patterns << endl;
141   indent();
142   for(unsigned int i=0;i<number_of_fill_patterns;i++)
143     describeFillPattern(mData);
144   dedent();
145 
146   unsigned int number_of_reference_coordinate_systems = mData.readUnsignedInt();
147   cout << getIndent() << "number_of_reference_coordinate_systems "
148       << number_of_reference_coordinate_systems << endl;
149   indent();
150   for(unsigned int i=0;i<number_of_reference_coordinate_systems;i++)
151     //NOTE: must be PRC_TYPE_RI_CoordinateSystem
152     describeRepresentationItem(mData);
153   dedent();
154 
155   describeUserData(mData);
156   dedent();
157   mData.tellPosition();
158 }
159 
describeTree(BitByBitData & mData)160 void describeTree(BitByBitData &mData)
161 {
162   mData.tellPosition();
163   cout << getIndent() << "--Tree--" << endl;
164   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTree))
165     return;
166   indent();
167   describeContentPRCBase(mData,false);
168 
169   unsigned int number_of_part_definitions = mData.readUnsignedInt();
170   cout << getIndent() << "number_of_part_definitions "
171       << number_of_part_definitions << endl;
172   indent();
173   for(unsigned int i = 0; i < number_of_part_definitions; ++i)
174   {
175     describePartDefinition(mData);
176   }
177   dedent();
178 
179   unsigned int number_of_product_occurrences = mData.readUnsignedInt();
180   cout << getIndent() << "number_of_product_occurrences "
181       << number_of_product_occurrences << endl;
182   indent();
183   for(unsigned int i = 0; i < number_of_product_occurrences; ++i)
184   {
185     describeProductOccurrence(mData);
186   }
187   dedent();
188 
189   describeFileStructureInternalData(mData);
190 
191   describeUserData(mData);
192   dedent();
193   mData.tellPosition();
194 }
195 
describeTessellation(BitByBitData & mData)196 void describeTessellation(BitByBitData &mData)
197 {
198   mData.tellPosition();
199   cout << getIndent() << "--Tessellation--" << endl;
200   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTessellation))
201     return;
202   indent();
203 
204   describeContentPRCBase(mData,false);
205 
206   unsigned int number_of_tessellations = mData.readUnsignedInt();
207   cout << getIndent() << "number_of_tessellations "
208       << number_of_tessellations << endl;
209   indent();
210   for(unsigned int i = 0; i < number_of_tessellations; ++i)
211   {
212     unsigned int type = mData.readUnsignedInt();
213     cout << getIndent() << "tessellation type " << type << endl;
214     switch(type)
215     {
216       case PRC_TYPE_TESS_3D:
217         describe3DTess(mData);
218         break;
219       case PRC_TYPE_TESS_3D_Wire:
220         describe3DWireTess(mData);
221         break;
222       case PRC_TYPE_TESS_Markup:
223         describe3DMarkupTess(mData);
224         break;
225       case PRC_TYPE_TESS_3D_Compressed:
226         describeHighlyCompressed3DTess(mData);
227         break;
228       default:
229         cout << getIndent() << "Unrecognized tessellation data type "
230             << type << endl;
231         break;
232     }
233   }
234   dedent();
235 
236   describeUserData(mData);
237 
238   dedent();
239   mData.tellPosition();
240 }
241 
describeGeometry(BitByBitData & mData)242 void describeGeometry(BitByBitData &mData)
243 {
244   mData.tellPosition();
245   cout << getIndent() << "--Geometry--" << endl;
246   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGeometry))
247     return;
248   indent();
249 
250   describeContentPRCBase(mData,false);
251 
252   unsigned int number_of_topological_contexts = mData.readUnsignedInt();
253   cout << getIndent() << "number_of_topological_contexts "
254       << number_of_topological_contexts << endl;
255   indent();
256   for(unsigned int i = 0; i < number_of_topological_contexts; ++i)
257   {
258     describeTopoContext(mData);
259     unsigned int number_of_bodies = mData.readUnsignedInt();
260     cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
261     for(unsigned int i = 0; i < number_of_bodies; ++i)
262     {
263       describeBody(mData);
264     }
265   }
266   dedent();
267 
268   describeUserData(mData);
269   dedent();
270   mData.tellPosition();
271 }
272 
describeExtraGeometry(BitByBitData & mData)273 void describeExtraGeometry(BitByBitData &mData)
274 {
275   mData.tellPosition();
276   cout << getIndent() << "--Extra Geometry--" << endl;
277   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureExtraGeometry))
278     return;
279   indent();
280 
281   describeContentPRCBase(mData,false);
282 
283   unsigned int number_of_contexts = mData.readUnsignedInt();
284   cout << getIndent() << "number_of_contexts " << number_of_contexts << endl;
285   indent();
286   for(unsigned int i = 0; i < number_of_contexts; ++i)
287   {
288     // geometry summary
289     unsigned int number_of_bodies = mData.readUnsignedInt();
290     cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
291     indent();
292     for(unsigned int j = 0; j < number_of_bodies; ++j)
293     {
294       unsigned int serial_type = mData.readUnsignedInt();
295       cout << getIndent() << "serial_type " << serial_type << endl;
296       indent();
297       if(isCompressedSerialType(serial_type))
298         cout << getIndent() << "serialTolerance " << mData.readDouble();
299       dedent();
300     }
301     dedent();
302     // context graphics
303     resetCurrentGraphics();
304     unsigned int number_of_treat_types = mData.readUnsignedInt();
305     cout << getIndent() << "number_of_treat_types "
306         << number_of_treat_types << endl;
307     indent();
308     for(unsigned int i = 0; i < number_of_treat_types; ++i)
309     {
310       cout << getIndent() << "element_type " << mData.readUnsignedInt() << endl;
311       unsigned int number_of_elements = mData.readUnsignedInt();
312       cout << getIndent() << "number_of_elements "
313           << number_of_elements << endl;
314       indent();
315       for(unsigned int j = 0; j < number_of_elements; ++j)
316       {
317         if(mData.readBit())
318         {
319           describeGraphics(mData);
320         }
321         else
322         {
323           cout << getIndent() << "Element has no graphics" << endl;
324         }
325       }
326       dedent();
327     }
328     dedent();
329   }
330   dedent();
331 
332   describeUserData(mData);
333   dedent();
334   mData.tellPosition();
335 }
336 
337 
describeModelFileData(BitByBitData & mData,unsigned int numberOfFileStructures)338 void describeModelFileData(BitByBitData &mData,
339                            unsigned int numberOfFileStructures)
340 {
341   mData.tellPosition();
342   cout << getIndent() << "--Model File--" << endl;
343   if(!checkSectionCode(mData,PRC_TYPE_ASM_ModelFile))
344     return;
345   indent();
346 
347   describeContentPRCBase(mData,false);
348 
349   describeUnit(mData);
350   unsigned int numberOfProductOccurrences = mData.readUnsignedInt();
351   cout << getIndent() << "Number of Product Occurrences "
352       << numberOfProductOccurrences << endl;
353   indent();
354   for(unsigned int i = 0; i < numberOfProductOccurrences; ++i)
355   {
356     describeCompressedUniqueID(mData);
357     cout << getIndent() << "index_position + 1 = "
358         << mData.readUnsignedInt() << endl;
359     cout << getIndent() << "active? " << (mData.readBit()?"yes":"no")
360         << endl << endl;
361   }
362   dedent();
363   for(unsigned int i = 0; i < numberOfFileStructures; ++i)
364   {
365     cout << getIndent() << "File Structure Index in Model File "
366         << mData.readUnsignedInt() << endl;
367   }
368 
369   describeUserData(mData);
370   dedent();
371   mData.tellPosition();
372 }
373 
374 // subsections
375 // void describe(BitByBitData &mData)
376 // {
377 //
378 // }
379 
describeLight(BitByBitData & mData)380 void describeLight(BitByBitData &mData)
381 {
382   unsigned int ID = mData.readUnsignedInt();
383   if(ID == PRC_TYPE_GRAPH_AmbientLight)
384     cout << getIndent() << "--Ambient Light--" << endl;
385   else
386     return;
387 
388   indent();
389 
390   describeContentPRCBase(mData,true);
391 
392   cout << getIndent() << "ambient colour index: " << mData.readUnsignedInt()-1 << endl
393       << getIndent() << "diffuse colour index: " << mData.readUnsignedInt()-1 << endl
394       << getIndent() << "specular colour index: " << mData.readUnsignedInt()-1 << endl;
395 
396   describeUserData(mData);
397   describeUserData(mData); // why?
398   dedent();
399 }
400 
describeCamera(BitByBitData & mData)401 void describeCamera(BitByBitData &mData)
402 {
403   cout << getIndent() << "--Camera--" << endl;
404   if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Camera))
405     return;
406   indent();
407 
408   describeContentPRCBase(mData,true);
409 
410   cout << getIndent() << (mData.readBit()?"orthographic":"perspective") << endl;
411   cout << getIndent() << "Camera Position" << endl;
412   describeVector3d(mData);
413   cout << getIndent() << "Look At Point" << endl;
414   describeVector3d(mData);
415   cout << getIndent() << "Up" << endl;
416   describeVector3d(mData);
417   cout << getIndent() << "X field of view angle (perspective) || X scale (orthographic) "
418       << mData.readDouble() << endl;
419   cout << getIndent() << "Y field of view angle (perspective) || Y scale (orthographic) "
420       << mData.readDouble() << endl;
421   cout << getIndent() << "aspect ratio x/y " << mData.readDouble() << endl;
422   cout << getIndent() << "near z clipping plane distance from viewer " << mData.readDouble() << endl;
423   cout << getIndent() << "far z clipping plane distance from viewer " << mData.readDouble() << endl;
424   cout << getIndent() << "zoom factor " << mData.readDouble() << endl;
425   dedent();
426 }
427 
describeContentCurve(BitByBitData & mData)428 bool describeContentCurve(BitByBitData &mData)
429 {
430   describeBaseGeometry(mData);
431   cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
432   bool is_3d = mData.readBit();
433   cout << getIndent() << "is_3d " << (is_3d?"yes":"no") << endl;
434   return is_3d;
435 }
436 
describeParameterization(BitByBitData & mData)437 void describeParameterization(BitByBitData &mData)
438 {
439   cout << getIndent() << "--Parameterization--" << endl;
440   indent();
441   describeExtent1d(mData);
442   cout << getIndent() << "parameterization_coeff_a " << mData.readDouble()
443       << endl;
444   cout << getIndent() << "parameterization_coeff_b " << mData.readDouble()
445       << endl;
446   dedent();
447 }
448 
describeCurvCircle(BitByBitData & mData)449 void describeCurvCircle(BitByBitData &mData)
450 {
451   cout << getIndent() << "--Circle--" << endl;
452   indent();
453 
454   if(describeContentCurve(mData))
455     describeTransformation3d(mData);
456   else
457     describeTransformation2d(mData);
458 
459   describeParameterization(mData);
460 
461   cout << getIndent() << "radius " << mData.readDouble() << endl;
462 
463   dedent();
464 }
465 
describeCurvLine(BitByBitData & mData)466 void describeCurvLine(BitByBitData &mData)
467 {
468   cout << getIndent() << "--Line--" << endl;
469   indent();
470 
471   if(describeContentCurve(mData))
472     describeTransformation3d(mData);
473   else
474     describeTransformation2d(mData);
475 
476   describeParameterization(mData);
477 
478   dedent();
479 }
480 
describeContentWireEdge(BitByBitData & mData)481 void describeContentWireEdge(BitByBitData &mData)
482 {
483   cout << getIndent() << "--WireEdge--" << endl;
484   indent();
485 
486   describeBaseTopology(mData);
487 
488   describeObject(mData); //3d_curve
489 
490   bool curve_trim_interval = mData.readBit();
491   cout << getIndent() << "curve_trim_interval "
492       << (curve_trim_interval?"yes":"no") << endl;
493   if(curve_trim_interval)
494   {
495     describeExtent1d(mData);
496   }
497 
498   dedent();
499 }
500 
describeUVParametrization(BitByBitData & mData)501 void describeUVParametrization(BitByBitData &mData)
502 {
503   cout << getIndent() << "--UV Parameterization--" << endl;
504   indent();
505 
506   cout << getIndent() << "swap_uv " << (mData.readBit()?"yes":"no") << endl;
507   cout << getIndent() << "Domain" << endl;
508   indent(); describeExtent2d(mData); dedent();
509   cout << getIndent() << "parameterization_on_u_coeff_a "
510       << mData.readDouble() << endl;
511   cout << getIndent() << "parameterization_on_v_coeff_a "
512       << mData.readDouble() << endl;
513   cout << getIndent() << "parameterization_on_u_coeff_b "
514       << mData.readDouble() << endl;
515   cout << getIndent() << "parameterization_on_v_coeff_b "
516       << mData.readDouble() << endl;
517 
518   dedent();
519 }
520 
isCompressedSerialType(unsigned int type)521 bool isCompressedSerialType(unsigned int type)
522 {
523   return false; // TODO: actually check the type!!!
524 }
525 
describeSurfNURBS(BitByBitData & mData)526 void describeSurfNURBS(BitByBitData &mData)
527 {
528   cout << getIndent() << "--NURBS surface--" << endl;
529   indent();
530 
531   describeContentSurface(mData);
532 
533   bool is_rational = mData.readBit();
534   cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
535 
536   unsigned int degree_in_u = mData.readUnsignedInt();
537   cout << getIndent() << "degree_in_u " << degree_in_u << endl;
538   unsigned int degree_in_v = mData.readUnsignedInt();
539   cout << getIndent() << "degree_in_v " << degree_in_v << endl;
540 
541   unsigned int number_of_control_points_in_u = mData.readUnsignedInt()+1;
542   cout << getIndent() << "number_of_control_points_in_u "
543       << number_of_control_points_in_u << endl;
544   unsigned int number_of_control_points_in_v = mData.readUnsignedInt()+1;
545   cout << getIndent() << "number_of_control_points_in_v "
546       << number_of_control_points_in_v << endl;
547 
548   unsigned int number_of_knots_in_u = mData.readUnsignedInt()+1;
549   cout << getIndent() << "number_of_knots_in_u "
550       << number_of_knots_in_u << endl;
551   unsigned int number_of_knots_in_v = mData.readUnsignedInt()+1;
552   cout << getIndent() << "number_of_knots_in_v "
553       << number_of_knots_in_v << endl;
554 
555   indent();
556   for(unsigned int i = 0; i < number_of_control_points_in_u; ++i)
557   {
558     for(unsigned int j = 0; j < number_of_control_points_in_v; ++j)
559     {
560       double x = mData.readDouble();
561       double y = mData.readDouble();
562       double z = mData.readDouble();
563       cout << getIndent() << "control point " << i << ' ' << j << ": ("
564           << x << ',' << y << ',' << z;
565 
566       if(is_rational)
567         cout << ',' << mData.readDouble();
568 
569       cout << ')' << endl;
570     }
571   }
572   dedent();
573 
574   cout << getIndent() << "knots in u" << endl;
575   indent();
576   for(unsigned int i = 0; i < number_of_knots_in_u; ++i)
577     cout << getIndent() << mData.readDouble() << endl;
578   dedent();
579 
580   cout << getIndent() << "knots in v" << endl;
581   indent();
582   for(unsigned int i = 0; i < number_of_knots_in_v; ++i)
583     cout << getIndent() << mData.readDouble() << endl;
584   dedent();
585 
586   cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
587   cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
588 
589   dedent();
590 }
591 
describeCurvNURBS(BitByBitData & mData)592 void describeCurvNURBS(BitByBitData &mData)
593 {
594   cout << getIndent() << "--NURBS curve--" << endl;
595   indent();
596   describeContentCurve(mData);
597 
598   bool is_rational = mData.readBit();
599   cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
600 
601   unsigned int degree = mData.readUnsignedInt();
602   cout << getIndent() << "degree " << degree << endl;
603 
604   unsigned int number_of_control_points = mData.readUnsignedInt()+1;
605   cout << getIndent() << "number_of_control_points "
606       << number_of_control_points << endl;
607 
608   unsigned int number_of_knots = mData.readUnsignedInt()+1;
609   cout << getIndent() << "number_of_knots " << number_of_knots << endl;
610 
611   indent();
612   for(unsigned int i = 0; i < number_of_control_points; ++i)
613   {
614     double x = mData.readDouble();
615     double y = mData.readDouble();
616     double z = mData.readDouble();
617     cout << getIndent() << "control point " << i << ": ("
618         << x << ',' << y << ',' << z;
619 
620     if(is_rational)
621       cout << ',' << mData.readDouble();
622 
623     cout << ')' << endl;
624   }
625   dedent();
626 
627   cout << getIndent() << "knots" << endl;
628   indent();
629   for(unsigned int i = 0; i < number_of_knots; ++i)
630     cout << getIndent() << mData.readDouble() << endl;
631   dedent();
632 
633   cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
634   cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
635 
636   dedent();
637 }
638 
describeCurvPolyLine(BitByBitData & mData)639 void describeCurvPolyLine(BitByBitData &mData)
640 {
641   cout << getIndent() << "--PolyLine--" << endl;
642   indent();
643   describeContentCurve(mData);
644   describeTransformation3d(mData);
645   describeParameterization(mData);
646 
647   unsigned int number_of_points = mData.readUnsignedInt();
648   cout << getIndent() << "number_of_points " << number_of_points << endl;
649 
650   indent();
651   for(unsigned int i = 0; i < number_of_points; ++i)
652   {
653     describeVector3d(mData);
654   }
655   dedent();
656 
657   dedent();
658 }
659 
describeSurfCylinder(BitByBitData & mData)660 void describeSurfCylinder(BitByBitData &mData)
661 {
662   cout << getIndent() << "--Cylinder surface--" << endl;
663   indent();
664 
665   describeContentSurface(mData);
666   describeTransformation3d(mData);
667   describeUVParametrization(mData);
668   cout << getIndent() << "radius " << mData.readDouble() << endl;
669 
670   dedent();
671 }
672 
describeSurfPlane(BitByBitData & mData)673 void describeSurfPlane(BitByBitData &mData)
674 {
675   cout << getIndent() << "--Plane surface--" << endl;
676   indent();
677   mData.setShowBits(true);
678   describeContentSurface(mData);
679   mData.tellPosition();
680   //TODO: something is wrong, very wrong!!!
681   // For now, all this does is search until the end of the data block,
682   // assuming that the default parameterization [-inf,inf]x[-inf,inf] was used
683   BitPosition bp = mData.getPosition();
684   double nInf1 = mData.readDouble();
685   double nInf2 = mData.readDouble();
686   double inf1 = mData.readDouble();
687   double inf2 = mData.readDouble();
688   double one1 = mData.readDouble();
689   double one2 = mData.readDouble();
690   double zero1 = mData.readDouble();
691   double zero2 = mData.readDouble();
692   while(!(nInf1 == -12345.0 && nInf2 == -12345.0 && inf1 == 12345.0
693           && inf2 == 12345.0 && one1 == 1.0 && one2 == 1.0 && zero1 == 0.0
694           && zero2 == 0.0))
695   {
696     mData.setPosition(bp);
697     cout << mData.readBit();
698     bp = mData.getPosition();
699 
700     nInf1 = mData.readDouble();
701     nInf2 = mData.readDouble();
702     inf1 = mData.readDouble();
703     inf2 = mData.readDouble();
704     one1 = mData.readDouble();
705     one2 = mData.readDouble();
706     zero1 = mData.readDouble();
707     zero2 = mData.readDouble();
708   }
709   cout << endl;
710   if(bp.bitIndex == 0)
711   {
712     bp.bitIndex = 7;
713     --bp.byteIndex;
714   }
715   else
716   {
717     --bp.bitIndex;
718   }
719   mData.setPosition(bp);
720 
721 /*
722   // this is what the 8137 docs say it should be
723   describeTransformation3d(mData);
724   cout << getIndent() << "UV domain" << endl;
725   indent();
726   cout << getIndent() << "Min: " << endl;
727   describeVector2d(mData);
728   cout << getIndent() << "Max: " << endl;
729   describeVector2d(mData);
730   dedent();
731 
732   cout << getIndent() << "u coef. a = " << mData.readDouble() << endl;
733   cout << getIndent() << "v coef. a = " << mData.readDouble() << endl;
734   cout << getIndent() << "u coef. b = " << mData.readDouble() << endl;
735   cout << getIndent() << "v coef. b = " << mData.readDouble() << endl;
736 */
737   mData.setShowBits(false);
738   dedent();
739 }
740 
describeTopoFace(BitByBitData & mData)741 void describeTopoFace(BitByBitData &mData)
742 {
743   cout << getIndent() << "--Face--" << endl;
744   indent();
745 
746   describeBaseTopology(mData);
747 
748   cout << getIndent() << "base_surface" << endl;
749   indent();
750   describeObject(mData);
751   dedent();
752 
753   bool surface_trim_domain = mData.readBit();
754   cout << getIndent() << "surface_trim_domain "
755       << (surface_trim_domain?"yes":"no") << endl;
756   if(surface_trim_domain)
757   {
758     indent();
759     describeExtent2d(mData);
760     dedent();
761   }
762 
763   bool have_tolerance = mData.readBit();
764   cout << getIndent() << "have_tolerance "
765       << (have_tolerance?"yes":"no") << endl;
766   if(have_tolerance)
767     cout << getIndent() << "tolerance " << mData.readDouble() << endl;
768 
769   unsigned int number_of_loops = mData.readUnsignedInt();
770   cout << getIndent() << "number_of_loops " << number_of_loops << endl;
771   cout << getIndent() << "outer_loop_index " << mData.readInt() << endl;
772   indent();
773   for(unsigned int i = 0; i < number_of_loops; ++i)
774   {
775     describeObject(mData);
776   }
777   dedent();
778 
779   dedent();
780 }
781 
describeTopoLoop(BitByBitData & mData)782 void describeTopoLoop(BitByBitData &mData)
783 {
784   cout << getIndent() << "--Loop--" << endl;
785   indent();
786 
787   describeBaseTopology(mData);
788 
789   cout << getIndent() << "orientation_with_surface "
790       << static_cast<unsigned int>(mData.readChar()) << endl;
791   unsigned int number_of_coedge = mData.readUnsignedInt();
792   cout << getIndent() << "number_of_coedge " << number_of_coedge << endl;
793   indent();
794   for(unsigned int i = 0; i < number_of_coedge; ++i)
795   {
796     describeObject(mData);
797     cout << getIndent() << "neigh_serial_index "
798         << mData.readUnsignedInt() << endl;
799   }
800   dedent();
801 
802   dedent();
803 }
804 
describeTopoCoEdge(BitByBitData & mData)805 void describeTopoCoEdge(BitByBitData &mData)
806 {
807   cout << getIndent() << "--CoEdge--" << endl;
808   indent();
809 
810   describeBaseTopology(mData);
811 
812   describeObject(mData); // edge
813   describeObject(mData); // uv_curve
814   cout << getIndent() << "orientation_with_loop "
815       << static_cast<unsigned int>(mData.readChar()) << endl;
816   cout << getIndent() << "orientation_uv_with_loop "
817       << static_cast<unsigned int>(mData.readChar()) << endl;
818   dedent();
819 }
820 
describeTopoEdge(BitByBitData & mData)821 void describeTopoEdge(BitByBitData &mData)
822 {
823   cout << getIndent() << "--Edge--" << endl;
824   indent();
825 
826   describeContentWireEdge(mData);
827 
828   describeObject(mData); // vertex_start
829   describeObject(mData); // vertex_end
830 
831   bool have_tolerance = mData.readBit();
832   cout << getIndent() << "have_tolerance "
833       << (have_tolerance?"yes":"no") << endl;
834   if(have_tolerance)
835     cout << getIndent() << "tolerance " << mData.readDouble() << endl;
836   dedent();
837 }
838 
describeTopoUniqueVertex(BitByBitData & mData)839 void describeTopoUniqueVertex(BitByBitData &mData)
840 {
841   cout << getIndent() << "--Unique Vertex--" << endl;
842   indent();
843 
844   describeBaseTopology(mData);
845   describeVector3d(mData);
846 
847   bool have_tolerance = mData.readBit();
848   cout << getIndent() << "have_tolerance "
849       << (have_tolerance?"yes":"no") << endl;
850   if(have_tolerance)
851     cout << getIndent() << "tolerance " << mData.readDouble() << endl;
852 
853   dedent();
854 }
855 
describeTopoConnex(BitByBitData & mData)856 void describeTopoConnex(BitByBitData &mData)
857 {
858   cout << getIndent() << "--Connex--" << endl;
859   indent();
860   describeBaseTopology(mData);
861   unsigned int number_of_shells = mData.readUnsignedInt();
862   cout << getIndent() << "number_of_shells "
863       << number_of_shells << endl;
864   indent();
865   for(unsigned int i = 0; i < number_of_shells; ++i)
866   {
867     // NOTE: this does not check if the objects are actually shells!
868     describeObject(mData);
869   }
870   dedent();
871 
872   dedent();
873 }
874 
describeTopoShell(BitByBitData & mData)875 void describeTopoShell(BitByBitData &mData)
876 {
877   cout << getIndent() << "--Shell--" << endl;
878   indent();
879 
880   describeBaseTopology(mData);
881 
882   cout << getIndent() << "shell_is_closed "
883       << (mData.readBit()?"yes":"no") << endl;
884 
885   unsigned int number_of_faces = mData.readUnsignedInt();
886   cout << getIndent() << "number_of_faces " << number_of_faces << endl;
887   for(unsigned int i = 0; i < number_of_faces; ++i)
888   {
889     // NOTE: this does not check if the objects are actually faces!
890     describeObject(mData);
891     unsigned char orientation = mData.readChar();
892     cout << getIndent() << "orientation_surface_with_shell "
893         << static_cast<unsigned int>(orientation) << endl;
894   }
895 
896   dedent();
897 }
898 
describeObject(BitByBitData & mData)899 void describeObject(BitByBitData &mData)
900 {
901   cout << getIndent() << "--Object--" << endl;
902   bool already_stored = mData.readBit();
903   cout << getIndent() << "already_stored "
904       << (already_stored?"yes":"no") << endl;
905   if(already_stored) // reverse of documentation?
906   {
907     cout << getIndent() << "index of stored item "
908         << mData.readUnsignedInt() << endl;
909   }
910   else
911   {
912     unsigned int type = mData.readUnsignedInt();
913     switch(type)
914     {
915       case PRC_TYPE_ROOT:
916         cout << getIndent() << "NULL Object" << endl;
917         break;
918       // topological items
919       case PRC_TYPE_TOPO_Connex:
920         describeTopoConnex(mData);
921         break;
922       case PRC_TYPE_TOPO_Shell:
923         describeTopoShell(mData);
924         break;
925       case PRC_TYPE_TOPO_Face:
926         describeTopoFace(mData);
927         break;
928       case PRC_TYPE_TOPO_Loop:
929         describeTopoLoop(mData);
930         break;
931       case PRC_TYPE_TOPO_CoEdge:
932         describeTopoCoEdge(mData);
933         break;
934       case PRC_TYPE_TOPO_Edge:
935         describeTopoEdge(mData);
936         break;
937       case PRC_TYPE_TOPO_UniqueVertex:
938         describeTopoUniqueVertex(mData);
939         break;
940       case PRC_TYPE_TOPO_WireEdge:
941         describeContentWireEdge(mData);
942         break;
943 
944       // curves
945       case PRC_TYPE_CRV_Circle:
946         describeCurvCircle(mData);
947         break;
948       case PRC_TYPE_CRV_NURBS:
949         describeCurvNURBS(mData);
950         break;
951       case PRC_TYPE_CRV_PolyLine:
952         describeCurvPolyLine(mData);
953         break;
954       case PRC_TYPE_CRV_Line:
955         describeCurvLine(mData);
956         break;
957       // surfaces
958       case PRC_TYPE_SURF_NURBS:
959         describeSurfNURBS(mData);
960         break;
961       case PRC_TYPE_SURF_Cylinder:
962         describeSurfCylinder(mData);
963         break;
964       case PRC_TYPE_SURF_Plane:
965         describeSurfPlane(mData);
966         break;
967 
968       // topological items
969       case PRC_TYPE_TOPO_Item:
970       case PRC_TYPE_TOPO_MultipleVertex:
971 
972 
973       // curves
974       case PRC_TYPE_CRV_Base:
975       case PRC_TYPE_CRV_Blend02Boundary:
976       case PRC_TYPE_CRV_Composite:
977       case PRC_TYPE_CRV_OnSurf:
978       case PRC_TYPE_CRV_Ellipse:
979       case PRC_TYPE_CRV_Equation:
980       case PRC_TYPE_CRV_Helix:
981       case PRC_TYPE_CRV_Hyperbola:
982       case PRC_TYPE_CRV_Intersection:
983       case PRC_TYPE_CRV_Offset:
984       case PRC_TYPE_CRV_Parabola:
985       case PRC_TYPE_CRV_Transform:
986 
987       // surfaces
988       case PRC_TYPE_SURF_Base:
989       case PRC_TYPE_SURF_Blend01:
990       case PRC_TYPE_SURF_Blend02:
991       case PRC_TYPE_SURF_Blend03:
992       case PRC_TYPE_SURF_Cone:
993       case PRC_TYPE_SURF_Cylindrical:
994       case PRC_TYPE_SURF_Offset:
995       case PRC_TYPE_SURF_Pipe:
996       case PRC_TYPE_SURF_Ruled:
997       case PRC_TYPE_SURF_Sphere:
998       case PRC_TYPE_SURF_Revolution:
999       case PRC_TYPE_SURF_Extrusion:
1000       case PRC_TYPE_SURF_FromCurves:
1001       case PRC_TYPE_SURF_Torus:
1002       case PRC_TYPE_SURF_Transform:
1003       case PRC_TYPE_SURF_Blend04:
1004         cout << getIndent() << "TODO: Unhandled object of type "
1005             << type << endl;
1006         break;
1007       default:
1008         cout << getIndent() << "Invalid object of type " << type << endl;
1009         break;
1010     }
1011   }
1012 }
1013 
describeBaseTopology(BitByBitData & mData)1014 void describeBaseTopology(BitByBitData &mData)
1015 {
1016   bool base_information = mData.readBit();
1017   cout << getIndent() << "base_information " <<
1018       (base_information?"yes":"no") << endl;
1019   if(base_information)
1020   {
1021     describeAttributes(mData);
1022     describeName(mData);
1023     cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
1024   }
1025 }
1026 
describeBaseGeometry(BitByBitData & mData)1027 void describeBaseGeometry(BitByBitData &mData)
1028 {
1029   bool base_information = mData.readBit();
1030   cout << getIndent() << "base_information " <<
1031       (base_information?"yes":"no") << endl;
1032   if(base_information)
1033   {
1034     describeAttributes(mData);
1035     describeName(mData);
1036     cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
1037   }
1038 }
1039 
describeContentBody(BitByBitData & mData)1040 unsigned int describeContentBody(BitByBitData &mData)
1041 {
1042   describeBaseTopology(mData);
1043   unsigned int behaviour = static_cast<unsigned int>(mData.readChar());
1044   cout << getIndent() << "behaviour " << behaviour << endl;
1045   return behaviour;
1046 }
1047 
describeContentSurface(BitByBitData & mData)1048 void describeContentSurface(BitByBitData &mData)
1049 {
1050   describeBaseGeometry(mData);
1051   cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
1052 }
1053 
describeBody(BitByBitData & mData)1054 void describeBody(BitByBitData &mData)
1055 {
1056   cout << getIndent() << "--Body--" << endl;
1057   unsigned int type = mData.readUnsignedInt();
1058   switch(type)
1059   {
1060     case PRC_TYPE_TOPO_BrepData:
1061     {
1062       cout << getIndent() << "--PRC_TYPE_TOPO_BrepData--" << endl;
1063       unsigned int behaviour = describeContentBody(mData);
1064 
1065       unsigned int number_of_connex = mData.readUnsignedInt();
1066       cout << getIndent() << "number_of_connex " << number_of_connex << endl;
1067       indent();
1068       for(unsigned int i = 0; i < number_of_connex; ++i)
1069       {
1070         describeObject(mData);
1071       }
1072       dedent();
1073       if(behaviour != 0)
1074       {
1075         cout << getIndent() << "bbox " << endl;
1076         indent();
1077         describeExtent3d(mData);
1078         dedent();
1079       }
1080       break;
1081     }
1082     case PRC_TYPE_TOPO_SingleWireBody:
1083     {
1084       cout << getIndent() << "--PRC_TYPE_TOPO_SingleWireBody--" << endl;
1085       // unsigned int behaviour = describeContentBody(mData);
1086       // TODO: is behaviour needed to get data about how to describe?
1087       describeContentBody(mData);
1088 
1089       describeObject(mData); // curve
1090 
1091       break;
1092     }
1093     case PRC_TYPE_TOPO_BrepDataCompress:
1094     case PRC_TYPE_TOPO_SingleWireBodyCompress:
1095       cout << getIndent() << "TODO: Unhandled body type " << type << endl;
1096       break;
1097     default:
1098       cout << getIndent() << "Invalid body type " << type << endl;
1099       break;
1100   }
1101 }
1102 
describeTopoContext(BitByBitData & mData)1103 void describeTopoContext(BitByBitData &mData)
1104 {
1105   cout << getIndent() << "--Topological Context--" << endl;
1106   if(!checkSectionCode(mData,PRC_TYPE_TOPO_Context))
1107     return;
1108   indent();
1109 
1110   describeContentPRCBase(mData,false);
1111 
1112   cout << getIndent() << "behaviour "
1113       << static_cast<unsigned int>(mData.readChar()) << endl;
1114   cout << getIndent() << "granularity " << mData.readDouble() << endl;
1115   cout << getIndent() << "tolerance " << mData.readDouble() << endl;
1116 
1117   bool have_smallest_face_thickness = mData.readBit();
1118   cout << getIndent() << "have_smallest_face_thickness "
1119       << (have_smallest_face_thickness?"yes":"no") << endl;
1120   if(have_smallest_face_thickness)
1121     cout << getIndent() << "smallest_thickness " << mData.readDouble() << endl;
1122 
1123   bool have_scale = mData.readBit();
1124   cout << getIndent() << "have_scale " << (have_scale?"yes":"no") << endl;
1125   if(have_scale)
1126     cout << getIndent() << "scale " << mData.readDouble() << endl;
1127 
1128   dedent();
1129 }
1130 
describeLineAttr(BitByBitData & mData)1131 void describeLineAttr(BitByBitData& mData)
1132 {
1133   cout << getIndent() << "index_of_line_style "
1134       << mData.readUnsignedInt()-1 << endl;
1135 }
1136 
describeArrayRGBA(BitByBitData & mData,int number_of_colours,int number_by_vector)1137 void describeArrayRGBA(BitByBitData& mData, int number_of_colours,
1138                        int number_by_vector)
1139 {
1140   // bool new_colour = true; // not currently used
1141   for(int i = 0; i < number_by_vector; ++i)
1142   {
1143     cout << getIndent() << static_cast<unsigned int>(mData.readChar()) << ' ';
1144     cout << static_cast<unsigned int>(mData.readChar()) << ' ';
1145     cout << static_cast<unsigned int>(mData.readChar()) << endl;
1146     //TODO: finish this
1147   }
1148 }
1149 
describeContentBaseTessData(BitByBitData & mData)1150 void describeContentBaseTessData(BitByBitData &mData)
1151 {
1152   cout << getIndent() << "is_calculated "
1153       << (mData.readBit()?"yes":"no") << endl;
1154   unsigned int number_of_coordinates = mData.readUnsignedInt();
1155   cout << getIndent() << "number_of_coordinates "
1156       << number_of_coordinates << endl;
1157   indent();
1158   for(unsigned int i = 0; i < number_of_coordinates; ++i)
1159   {
1160     cout << getIndent() << mData.readDouble() << endl;
1161   }
1162   dedent();
1163 }
1164 
describeTessFace(BitByBitData & mData)1165 void describeTessFace(BitByBitData &mData)
1166 {
1167   cout << getIndent() << "--Tessellation Face--" << endl;
1168   if(!checkSectionCode(mData,PRC_TYPE_TESS_Face))
1169     return;
1170   indent();
1171 
1172   unsigned int size_of_line_attributes = mData.readUnsignedInt();
1173   cout << getIndent() << "size_of_line_attributes "
1174       << size_of_line_attributes << endl;
1175   indent();
1176   for(unsigned int i = 0; i < size_of_line_attributes; ++i)
1177   {
1178     describeLineAttr(mData);
1179   }
1180   dedent();
1181 
1182   unsigned int start_wire = mData.readUnsignedInt();
1183   cout << getIndent() << "start_wire " << start_wire << endl;
1184   unsigned int size_of_sizes_wire = mData.readUnsignedInt();
1185   cout << getIndent() << "size_of_sizes_wire " << size_of_sizes_wire << endl;
1186   indent();
1187   for(unsigned int i = 0; i < size_of_sizes_wire; ++i)
1188   {
1189     cout << getIndent() << mData.readUnsignedInt() << endl;
1190   }
1191   dedent();
1192 
1193 
1194   unsigned int used_entities_flag = mData.readUnsignedInt();
1195   cout << getIndent() << "used_entities_flag " << used_entities_flag << endl;
1196 
1197   unsigned int start_triangulated = mData.readUnsignedInt();
1198   cout << getIndent() << "start_triangulated " << start_triangulated << endl;
1199   unsigned int size_of_sizes_triangulated = mData.readUnsignedInt();
1200   cout << getIndent() << "size_of_sizes_triangulated "
1201       << size_of_sizes_triangulated << endl;
1202   indent();
1203   for(unsigned int i = 0; i < size_of_sizes_triangulated; ++i)
1204   {
1205     cout << getIndent() << mData.readUnsignedInt() << endl;
1206   }
1207   dedent();
1208 
1209   cout << getIndent() << "number_of_texture_coordinate_indexes "
1210       << mData.readUnsignedInt() << endl;
1211 
1212   bool has_vertex_colors = mData.readBit();
1213   cout << getIndent() << "has_vertex_colors "
1214       << (has_vertex_colors?"yes":"no") << endl;
1215   indent();
1216   if(has_vertex_colors)
1217   {
1218     bool is_rgba = mData.readBit();
1219     cout << getIndent() << "is_rgba " << (is_rgba?"yes":"no") << endl;
1220 
1221     bool b_optimised = mData.readBit();
1222     cout << getIndent() << "b_optimised " << (b_optimised?"yes":"no") << endl;
1223     if(!b_optimised)
1224     {
1225       indent();
1226       //TODO: compute size of Array and pass it instead of 0
1227       describeArrayRGBA(mData,0,(is_rgba ? 4 : 3));
1228       dedent();
1229     }
1230     else
1231     {
1232       // not described
1233       // what does this mean? that this should not happen?
1234       // or is omitted from the docs?
1235     }
1236   }
1237   dedent();
1238 
1239   if(size_of_line_attributes)
1240   {
1241     cout << getIndent() << "behaviour " << mData.readUnsignedInt() << endl;
1242   }
1243 
1244   dedent();
1245 }
1246 
describe3DTess(BitByBitData & mData)1247 void describe3DTess(BitByBitData &mData)
1248 {
1249   cout << getIndent() << "--3D Tessellation--" << endl;
1250   indent();
1251 
1252   describeContentBaseTessData(mData);
1253 
1254   cout << getIndent() << "has_faces " << (mData.readBit()?"yes":"no") << endl;
1255   cout << getIndent() << "has_loops " << (mData.readBit()?"yes":"no") << endl;
1256 
1257   bool must_recalculate_normals = mData.readBit();
1258   cout << getIndent() << "must_recalculate_normals "
1259       << (must_recalculate_normals?"yes":"no") << endl;
1260   indent();
1261   if(must_recalculate_normals)
1262   {
1263     cout << getIndent()
1264         << "Docs were wrong: must_recalculate_normals is true." << endl;
1265     cout << getIndent() << "normals_recalculation_flags "
1266         << static_cast<unsigned int>(mData.readChar()) << endl;
1267     cout << getIndent() << "crease_angle " << mData.readDouble() << endl;
1268   }
1269   dedent();
1270 
1271   unsigned int number_of_normal_coordinates = mData.readUnsignedInt();
1272   cout << getIndent() << "number_of_normal_coordinates "
1273       << number_of_normal_coordinates << endl;
1274   indent();
1275   for(unsigned int i = 0; i < number_of_normal_coordinates; ++i)
1276   {
1277     cout << getIndent() << mData.readDouble() << endl;
1278   }
1279   dedent();
1280 
1281   unsigned int number_of_wire_indices = mData.readUnsignedInt();
1282   cout << getIndent() << "number_of_wire_indices "
1283       << number_of_wire_indices << endl;
1284   indent();
1285   for(unsigned int i = 0; i < number_of_wire_indices; ++i)
1286   {
1287     cout << getIndent() << mData.readUnsignedInt() << endl;
1288   }
1289   dedent();
1290 
1291   unsigned int number_of_triangulated_indices = mData.readUnsignedInt();
1292   cout << getIndent() << "number_of_triangulated_indices "
1293       << number_of_triangulated_indices << endl;
1294   indent();
1295   for(unsigned int i = 0; i < number_of_triangulated_indices; ++i)
1296   {
1297     cout << getIndent() << mData.readUnsignedInt() << endl;
1298   }
1299   dedent();
1300 
1301   unsigned int number_of_face_tessellation = mData.readUnsignedInt();
1302   cout << getIndent() << "number_of_face_tessellation "
1303       << number_of_face_tessellation << endl;
1304   indent();
1305   for(unsigned int i = 0; i < number_of_face_tessellation; ++i)
1306   {
1307     describeTessFace(mData);
1308   }
1309   dedent();
1310 
1311   unsigned int number_of_texture_coordinates = mData.readUnsignedInt();
1312   cout << getIndent() << "number_of_texture_coordinates "
1313       << number_of_texture_coordinates << endl;
1314   indent();
1315   for(unsigned int i = 0; i < number_of_texture_coordinates; ++i)
1316   {
1317     cout << getIndent() << mData.readDouble() << endl;
1318   }
1319   dedent();
1320 
1321   dedent();
1322 }
1323 
describe3DWireTess(BitByBitData & mData)1324 void describe3DWireTess(BitByBitData &mData)
1325 {
1326   //TODO
1327 }
1328 
describe3DMarkupTess(BitByBitData & mData)1329 void describe3DMarkupTess(BitByBitData &mData)
1330 {
1331   //TODO
1332 }
1333 
describeHighlyCompressed3DTess(BitByBitData & mData)1334 void describeHighlyCompressed3DTess(BitByBitData &mData)
1335 {
1336   //TODO
1337 }
1338 
describeSceneDisplayParameters(BitByBitData & mData)1339 void describeSceneDisplayParameters(BitByBitData &mData)
1340 {
1341   cout << getIndent() << "--Scene Display Parameters--" << endl;
1342   if(!checkSectionCode(mData,PRC_TYPE_GRAPH_SceneDisplayParameters))
1343     return;
1344   indent();
1345   describeContentPRCBase(mData,true);
1346 
1347   cout << getIndent() << "is active? " << (mData.readBit()?"yes":"no") << endl;
1348 
1349   unsigned int number_of_lights = mData.readUnsignedInt();
1350   cout << getIndent() << "number of lights " << number_of_lights << endl;
1351   indent();
1352   for(unsigned int i = 0; i < number_of_lights; ++i)
1353   {
1354     describeLight(mData);
1355   }
1356   dedent();
1357 
1358   bool camera = mData.readBit();
1359   cout << getIndent() << "camera? " << (camera?"yes":"no") << endl;
1360   if(camera)
1361     describeCamera(mData);
1362 
1363   bool rotation_centre = mData.readBit();
1364   cout << getIndent() << "rotation centre? " << (rotation_centre?"yes":"no") << endl;
1365   if(rotation_centre)
1366     describeVector3d(mData);
1367 
1368   unsigned int number_of_clipping_planes = mData.readUnsignedInt();
1369   cout << getIndent() << "number of clipping planes " << number_of_clipping_planes << endl;
1370   indent();
1371   for(unsigned int i = 0; i < number_of_clipping_planes; ++i)
1372   {
1373     cout << "Can't describe planes!!!" << endl;
1374     //describePlane(mData);
1375   }
1376   dedent();
1377 
1378   cout << getIndent() << "Background line style index: " << mData.readUnsignedInt()-1 << endl;
1379   cout << getIndent() << "Default line style index: " << mData.readUnsignedInt()-1 << endl;
1380 
1381   unsigned int number_of_default_styles_per_type = mData.readUnsignedInt();
1382   cout << getIndent() << "number_of_default_styles_per_type " << number_of_default_styles_per_type << endl;
1383   indent();
1384   for(unsigned int i = 0; i < number_of_default_styles_per_type; ++i)
1385   {
1386     cout << getIndent() << "type " << mData.readUnsignedInt() << endl;
1387     cout << getIndent() << "line style index: " << mData.readUnsignedInt()-1 << endl;
1388   }
1389   dedent();
1390 
1391   dedent();
1392 }
1393 
describeCartesionTransformation3d(BitByBitData & mData)1394 void describeCartesionTransformation3d(BitByBitData& mData)
1395 {
1396   cout << getIndent() << "--3d Cartesian Transformation--" << endl;
1397   if(!checkSectionCode(mData,PRC_TYPE_MISC_CartesianTransformation))
1398     return;
1399   indent();
1400   unsigned char behaviour = mData.readChar();
1401   cout << getIndent() << "behaviour "
1402       << static_cast<unsigned int>(behaviour) << endl;
1403   if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
1404   {
1405     cout << getIndent() << "Translation" << endl;
1406     describeVector3d(mData);
1407   }
1408 
1409   if((behaviour & PRC_TRANSFORMATION_NonOrtho) != 0)
1410   {
1411     cout << getIndent() << "Non orthogonal transformation" << endl;
1412     cout << getIndent() << "X" << endl; describeVector3d(mData);
1413     cout << getIndent() << "Y" << endl; describeVector3d(mData);
1414     cout << getIndent() << "Z" << endl; describeVector3d(mData);
1415   }
1416   else if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
1417   {
1418     cout << getIndent() << "Rotation" << endl;
1419     cout << getIndent() << "X" << endl; describeVector3d(mData);
1420     cout << getIndent() << "Y" << endl; describeVector3d(mData);
1421   }
1422 
1423   // this is different from the docs!!! but it works...
1424   if ((behaviour & PRC_TRANSFORMATION_NonUniformScale) != 0)
1425   {
1426     cout << getIndent() << "Non-uniform scale by " << endl;
1427     describeVector3d(mData);
1428   }
1429 
1430   // this is different from the docs!!! but it works...
1431   if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
1432   {
1433     cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
1434   }
1435 
1436   if((behaviour & PRC_TRANSFORMATION_Homogeneous) != 0)
1437   {
1438     cout << getIndent() << "transformation has homogenous values" << endl;
1439     cout << getIndent() << "x = " << mData.readDouble() << endl;
1440     cout << getIndent() << "y = " << mData.readDouble() << endl;
1441     cout << getIndent() << "z = " << mData.readDouble() << endl;
1442     cout << getIndent() << "w = " << mData.readDouble() << endl;
1443   }
1444   dedent();
1445 }
1446 
describeTransformation3d(BitByBitData & mData)1447 void describeTransformation3d(BitByBitData& mData)
1448 {
1449   cout << getIndent() << "--3d Transformation--" << endl;
1450   indent();
1451   bool has_transformation = mData.readBit();
1452   cout << getIndent() << "has_transformation "
1453       << (has_transformation?"yes":"no") << endl;
1454   if(has_transformation)
1455   {
1456     unsigned char behaviour = mData.readChar();
1457     cout << getIndent() << "behaviour "
1458         << static_cast<unsigned int>(behaviour) << endl;
1459     if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
1460     {
1461       cout << getIndent() << "Translation" << endl;
1462       describeVector3d(mData);
1463     }
1464     if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
1465     {
1466       cout << getIndent() << "Rotation" << endl;
1467       cout << getIndent() << "X" << endl; describeVector3d(mData);
1468       cout << getIndent() << "Y" << endl; describeVector3d(mData);
1469     }
1470 
1471     if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
1472     {
1473       cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
1474     }
1475   }
1476   dedent();
1477 }
1478 
describeTransformation2d(BitByBitData & mData)1479 void describeTransformation2d(BitByBitData& mData)
1480 {
1481   cout << getIndent() << "--2d Transformation--" << endl;
1482   indent();
1483   bool has_transformation = mData.readBit();
1484   cout << "has_transformation " << (has_transformation?"yes":"no") << endl;
1485   if(has_transformation)
1486   {
1487     unsigned char behaviour = mData.readChar();
1488     cout << getIndent() << "behaviour "
1489         << static_cast<unsigned int>(behaviour) << endl;
1490     if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
1491     {
1492       cout << getIndent() << "Translation" << endl;
1493       describeVector2d(mData);
1494     }
1495     if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
1496     {
1497       cout << getIndent() << "Rotation" << endl;
1498       cout << getIndent() << "X" << endl; describeVector2d(mData);
1499       cout << getIndent() << "Y" << endl; describeVector2d(mData);
1500     }
1501 
1502     if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
1503     {
1504       cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
1505     }
1506   }
1507   dedent();
1508 }
1509 
describeFileStructureInternalData(BitByBitData & mData)1510 void describeFileStructureInternalData(BitByBitData &mData)
1511 {
1512   cout << getIndent() << "--File Structure Internal Data--" << endl;
1513   if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructure))
1514     return;
1515   indent();
1516   describeContentPRCBase(mData,false);
1517   cout << getIndent() << "next_available_index "
1518       << mData.readUnsignedInt() << endl;
1519   cout << getIndent() << "index_product_occurence "
1520       << mData.readUnsignedInt() << endl;
1521   dedent();
1522 }
1523 
describeProductOccurrence(BitByBitData & mData)1524 void describeProductOccurrence(BitByBitData &mData)
1525 {
1526   cout << getIndent() << "--Product Occurrence--" << endl;
1527   if(!checkSectionCode(mData,PRC_TYPE_ASM_ProductOccurence))
1528     return;
1529   indent();
1530 
1531   describeContentPRCBaseWithGraphics(mData,true);
1532 
1533   cout << getIndent() << "index_part "
1534       << static_cast<int>(mData.readUnsignedInt()-1) << endl;
1535   unsigned int index_prototype = mData.readUnsignedInt()-1;
1536   cout << getIndent() << "index_prototype "
1537       << static_cast<int>(index_prototype) << endl;
1538   if(index_prototype+1 != 0)
1539   {
1540     bool prototype_in_same_file_structure = mData.readBit();
1541     cout << getIndent() << "prototype_in_same_file_structure "
1542         << (prototype_in_same_file_structure?"yes":"no") << endl;
1543     if(!prototype_in_same_file_structure)
1544       describeCompressedUniqueID(mData);
1545   }
1546 
1547   unsigned int index_external_data = mData.readUnsignedInt()-1;
1548   cout << getIndent() << "index_external_data "
1549       << static_cast<int>(index_external_data) << endl;
1550   if(index_external_data+1 != 0)
1551   {
1552     bool external_data_in_same_file_structure = mData.readBit();
1553     cout << getIndent() << "external_data_in_same_file_structure "
1554         << (external_data_in_same_file_structure?"yes":"no") << endl;
1555     if(!external_data_in_same_file_structure)
1556       describeCompressedUniqueID(mData);
1557   }
1558 
1559   unsigned int number_of_son_product_occurences = mData.readUnsignedInt();
1560   cout << getIndent() << "number_of_son_product_occurences "
1561       << number_of_son_product_occurences << endl;
1562   indent();
1563   for(unsigned int i = 0; i < number_of_son_product_occurences; ++i)
1564     cout << getIndent() << mData.readUnsignedInt() << endl;
1565   dedent();
1566 
1567   cout << getIndent() << "product_behaviour "
1568       << static_cast<unsigned int>(mData.readChar()) << endl;
1569 
1570   describeUnit(mData);
1571   cout << getIndent() << "Product information flags "
1572       << static_cast<unsigned int>(mData.readChar()) << endl;
1573   cout << getIndent() << "product_load_status "
1574       << mData.readUnsignedInt() << endl;
1575 
1576   bool has_location = mData.readBit();
1577   cout << getIndent() << "has_location " << has_location << endl;
1578   if(has_location)
1579   {
1580     describeCartesionTransformation3d(mData);
1581   }
1582 
1583   unsigned int number_of_references = mData.readUnsignedInt();
1584   cout << getIndent() << "number_of_references "
1585       << number_of_references << endl;
1586   indent();
1587   for(unsigned int i = 0; i < number_of_references; ++i)
1588   {
1589     //TODO: describeReferenceToPRCBase(mData);
1590   }
1591   dedent();
1592 
1593   describeMarkups(mData);
1594 
1595   unsigned int number_of_views = mData.readUnsignedInt();
1596   cout << getIndent() << "number_of_views " << number_of_views << endl;
1597   indent();
1598   for(unsigned int i = 0; i < number_of_views; ++i)
1599   {
1600     describeAnnotationView(mData);
1601   }
1602   dedent();
1603 
1604   bool has_entity_filter = mData.readBit();
1605   cout << getIndent() << "has_entity_filter "
1606       << (has_entity_filter?"yes":"no") << endl;
1607   if(has_entity_filter)
1608   {
1609     //TODO: describeEntityFilter(mData);
1610   }
1611 
1612   unsigned int number_of_display_filters = mData.readUnsignedInt();
1613   cout << getIndent() << "number_of_display_filters "
1614       << number_of_display_filters << endl;
1615   indent();
1616   for(unsigned int i = 0; i < number_of_display_filters; ++i)
1617   {
1618     //TODO: describeFilter(mData);
1619   }
1620   dedent();
1621 
1622   unsigned int number_of_scene_display_parameters = mData.readUnsignedInt();
1623   cout << getIndent() << "number_of_scene_display_parameters "
1624       << number_of_scene_display_parameters << endl;
1625   indent();
1626   for(unsigned int i = 0; i < number_of_scene_display_parameters; ++i)
1627   {
1628     describeSceneDisplayParameters(mData);
1629   }
1630   dedent();
1631 
1632   describeUserData(mData);
1633   dedent();
1634 }
1635 
describeGraphics(BitByBitData & mData)1636 void describeGraphics(BitByBitData &mData)
1637 {
1638   bool sameGraphicsAsCurrent = mData.readBit();
1639   cout << getIndent() << "Same graphics as current graphics? "
1640       << (sameGraphicsAsCurrent?"yes":"no") << endl;
1641   if(!sameGraphicsAsCurrent)
1642   {
1643     layer_index = mData.readUnsignedInt()-1;
1644     cout << getIndent() << "layer_index " << layer_index << endl;
1645     index_of_line_style = mData.readUnsignedInt()-1;
1646     cout << getIndent() << "index_of_line_style "
1647         << index_of_line_style << endl;
1648     unsigned char c1 = mData.readChar();
1649     unsigned char c2 = mData.readChar();
1650     behaviour_bit_field = c1 | (static_cast<unsigned short>(c2) << 8);
1651     cout << getIndent() << "behaviour_bit_field "
1652         << behaviour_bit_field << endl;
1653   }
1654 }
1655 
describeContentPRCBaseWithGraphics(BitByBitData & mData,bool efr)1656 void describeContentPRCBaseWithGraphics(BitByBitData &mData, bool efr)
1657 {
1658   describeContentPRCBase(mData,efr);
1659   describeGraphics(mData);
1660 }
1661 
describePartDefinition(BitByBitData & mData)1662 void describePartDefinition(BitByBitData &mData)
1663 {
1664   cout << getIndent() << "--Part Definition--" << endl;
1665   if(!checkSectionCode(mData,PRC_TYPE_ASM_PartDefinition))
1666     return;
1667   indent();
1668 
1669   describeContentPRCBaseWithGraphics(mData,true);
1670   describeExtent3d(mData);
1671 
1672   unsigned int number_of_representation_items = mData.readUnsignedInt();
1673   cout << getIndent() << "number_of_representation_items "
1674       << number_of_representation_items << endl;
1675   indent();
1676   for(unsigned int i = 0; i < number_of_representation_items; ++i)
1677   {
1678     describeRepresentationItem(mData);
1679   }
1680   dedent();
1681 
1682   describeMarkups(mData);
1683 
1684   unsigned int number_of_views = mData.readUnsignedInt();
1685   cout << getIndent() << "number_of_views " << number_of_views << endl;
1686   indent();
1687   for(unsigned int i = 0; i < number_of_views; ++i)
1688   {
1689     describeAnnotationView(mData);
1690   }
1691   dedent();
1692 
1693   describeUserData(mData);
1694   dedent();
1695 }
1696 
describeMarkups(BitByBitData & mData)1697 void describeMarkups(BitByBitData& mData)
1698 {
1699   cout << getIndent() << "--Markups--" << endl;
1700   indent();
1701 
1702   unsigned int number_of_linked_items = mData.readUnsignedInt();
1703   cout << getIndent() << "number_of_linked_items "
1704       << number_of_linked_items << endl;
1705   for(unsigned int i = 0; i < number_of_linked_items; ++i)
1706   {
1707     cout << "describe linked item!" << endl;
1708   }
1709 
1710   unsigned int number_of_leaders = mData.readUnsignedInt();
1711   cout << getIndent() << "number_of_leaders " << number_of_leaders << endl;
1712   for(unsigned int i = 0; i < number_of_leaders; ++i)
1713   {
1714     cout << "describe leader!" << endl;
1715   }
1716 
1717   unsigned int number_of_markups = mData.readUnsignedInt();
1718   cout << getIndent() << "number_of_markups " << number_of_markups << endl;
1719   for(unsigned int i=0; i < number_of_markups; ++i)
1720   {
1721     cout << "describe markup!" << endl;
1722   }
1723 
1724   unsigned int number_of_annotation_entities = mData.readUnsignedInt();
1725   cout << getIndent() << "number_of_annotation_entities "
1726       << number_of_annotation_entities << endl;
1727   for(unsigned int i=0; i < number_of_annotation_entities; ++i)
1728   {
1729     cout << "describe annotation entity!" << endl;
1730   }
1731 
1732   dedent();
1733 }
1734 
describeAnnotationView(BitByBitData & mData)1735 void describeAnnotationView(BitByBitData &mData)
1736 {
1737   cout << getIndent() << "--Annotation View--" << endl;
1738   if(!checkSectionCode(mData,PRC_TYPE_MKP_View))
1739     return;
1740   indent();
1741   describeContentPRCBaseWithGraphics(mData,true);
1742   unsigned int number_of_annotations = mData.readUnsignedInt();
1743   for(unsigned int i = 0; i < number_of_annotations; ++i)
1744   {
1745     //TODO: describeReferenceUniqueIdentifier(mData);
1746   }
1747   //TODO: describePlane(mData);
1748   bool scene_display_parameters = mData.readBit();
1749   if(scene_display_parameters)
1750   {
1751     describeSceneDisplayParameters(mData);
1752   }
1753   describeUserData(mData);
1754   dedent();
1755 }
1756 
describeExtent3d(BitByBitData & mData)1757 void describeExtent3d(BitByBitData &mData)
1758 { // I suspect the order of min/max should be flipped
1759   cout << getIndent() << "Minimum" << endl;
1760   indent(); describeVector3d(mData); dedent();
1761   cout << getIndent() << "Maximum" << endl;
1762   indent(); describeVector3d(mData); dedent();
1763 }
1764 
describeExtent1d(BitByBitData & mData)1765 void describeExtent1d(BitByBitData &mData)
1766 {
1767   cout << getIndent() << "Minimum " << mData.readDouble() << endl;
1768   cout << getIndent() << "Maximum " << mData.readDouble() << endl;
1769 }
1770 
describeExtent2d(BitByBitData & mData)1771 void describeExtent2d(BitByBitData &mData)
1772 {
1773   cout << getIndent() << "Minimum" << endl;
1774   indent(); describeVector2d(mData); dedent();
1775   cout << getIndent() << "Maximum" << endl;
1776   indent(); describeVector2d(mData); dedent();
1777 }
1778 
describeVector3d(BitByBitData & mData)1779 void describeVector3d(BitByBitData &mData)
1780 {
1781   double x = mData.readDouble();
1782   double y = mData.readDouble();
1783   double z = mData.readDouble();
1784   cout << getIndent() << '(' << x << ',' << y << ',' << z << ')' << endl;
1785 }
1786 
describeVector2d(BitByBitData & mData)1787 void describeVector2d(BitByBitData &mData)
1788 {
1789   double x = mData.readDouble();
1790   double y = mData.readDouble();
1791   cout << getIndent() << '(' << x << ',' << y << ')' << endl;
1792 }
1793 
describePicture(BitByBitData & mData)1794 void describePicture(BitByBitData &mData)
1795 {
1796   cout << getIndent() << "--Picture--" << endl;
1797   unsigned int sectionCode = mData.readUnsignedInt();
1798   if(sectionCode != PRC_TYPE_GRAPH_Picture)
1799   {
1800     cout << getIndent() << "Invalid section code." << endl;
1801   }
1802 
1803   describeContentPRCBase(mData,false);
1804 
1805   int format = mData.readInt();
1806   switch(format)
1807   {
1808     case KEPRCPicture_PNG:
1809       cout << getIndent() << "PNG format" << endl;
1810       break;
1811     case KEPRCPicture_JPG:
1812       cout << getIndent() << "JPG format" << endl;
1813       break;
1814     case KEPRCPicture_BITMAP_RGB_BYTE:
1815       cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a RGB triple. (3 components)" << endl;
1816       break;
1817     case KEPRCPicture_BITMAP_RGBA_BYTE:
1818       cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a complete RGBA element. (4 components)" << endl;
1819       break;
1820     case KEPRCPicture_BITMAP_GREY_BYTE:
1821       cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a single luminance value. (1 components)" << endl;
1822       break;
1823     case KEPRCPicture_BITMAP_GREYA_BYTE:
1824       cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a luminance/alpha pair. (2 components)" << endl;
1825       break;
1826     default:
1827       cout << getIndent() << "Invalid picture format." << endl;
1828       break;
1829   }
1830   cout << getIndent() << "uncompressed_file_index "
1831       << mData.readUnsignedInt()-1 << endl;
1832   cout << getIndent() << "pixel width " << mData.readUnsignedInt() << endl;
1833   cout << getIndent() << "pixel height " << mData.readUnsignedInt() << endl;
1834 }
1835 
describeTextureDefinition(BitByBitData & mData)1836 void describeTextureDefinition(BitByBitData &mData)
1837 {
1838   cout << getIndent() << "--Texture Definition--" << endl;
1839   if(!checkSectionCode(mData,PRC_TYPE_GRAPH_TextureDefinition))
1840     return;
1841 
1842   cout << getIndent() << "TODO: Can't describe textures yet." << endl;
1843 }
1844 
describeMaterial(BitByBitData & mData)1845 void describeMaterial(BitByBitData &mData)
1846 {
1847   cout << getIndent() << "--Material--" << endl;
1848   unsigned int code = mData.readUnsignedInt();
1849   if(code == PRC_TYPE_GRAPH_Material)
1850   {
1851     describeContentPRCBase(mData,true);
1852     cout << getIndent() << "index of ambient color "
1853         << mData.readUnsignedInt() - 1 << endl;
1854     cout << getIndent() << "index of diffuse color "
1855         << mData.readUnsignedInt() - 1 << endl;
1856     cout << getIndent() << "index of emissive color "
1857         << mData.readUnsignedInt() - 1 << endl;
1858     cout << getIndent() << "index of specular color "
1859         << mData.readUnsignedInt() - 1 << endl;
1860     cout << getIndent() << "shininess " << mData.readDouble() << endl;
1861     cout << getIndent() << "ambient_alpha " << mData.readDouble() << endl;
1862     cout << getIndent() << "diffuse_alpha " << mData.readDouble() << endl;
1863     cout << getIndent() << "emissive_alpha " << mData.readDouble() << endl;
1864     cout << getIndent() << "specular_alpha " << mData.readDouble() << endl;
1865   }
1866   else if(code == PRC_TYPE_GRAPH_TextureApplication)
1867   {
1868     describeContentPRCBase(mData,true);
1869     cout << getIndent() << "material_generic_index "
1870         << mData.readUnsignedInt() - 1 << endl;
1871     cout << getIndent() << "texture_definition_index "
1872         << mData.readUnsignedInt() - 1 << endl;
1873     cout << getIndent() << "next_texture_index "
1874         << mData.readUnsignedInt() - 1 << endl;
1875     cout << getIndent() << "UV_coordinates_index "
1876         << mData.readUnsignedInt() - 1 << endl;
1877   }
1878   else
1879   {
1880     cout << getIndent() << "Invalid section code in material definition."
1881         << endl;
1882   }
1883 }
1884 
describeLinePattern(BitByBitData & mData)1885 void describeLinePattern(BitByBitData &mData)
1886 {
1887   cout << getIndent() << "--Line Pattern--" << endl;
1888   if(!checkSectionCode(mData,PRC_TYPE_GRAPH_LinePattern))
1889     return;
1890   indent();
1891 
1892   describeContentPRCBase(mData,true);
1893   unsigned int size_lengths = mData.readUnsignedInt();
1894   cout << getIndent() << "size_lengths " << size_lengths << endl;
1895   indent();
1896   for(unsigned int i=0;i<size_lengths;i++)
1897   {
1898     cout << getIndent() << "length " << mData.readDouble() << endl;
1899   }
1900   dedent();
1901   cout << getIndent() << "phase " << mData.readDouble() << endl;
1902   cout << getIndent() << "is real length "
1903       << (mData.readBit()?"yes":"no") << endl;
1904 
1905   dedent();
1906 }
1907 
describeCategory1LineStyle(BitByBitData & mData)1908 void describeCategory1LineStyle(BitByBitData &mData)
1909 {
1910   cout << getIndent() << "--Category 1 Line Style--" << endl;
1911   if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Style))
1912     return;
1913   indent();
1914 
1915   // This was missing from the docs!!!!! argh!
1916   describeContentPRCBase(mData,true);
1917 
1918 
1919   cout << getIndent() << "line_width " << mData.readDouble() << " mm" << endl;
1920 
1921   cout << getIndent() << "is_vpicture " << (mData.readBit()?"yes":"no") << endl;
1922 
1923   cout << getIndent() << "line_pattern_index/vpicture_index "
1924       << static_cast<int>(mData.readUnsignedInt()-1) << endl;
1925   cout << getIndent() << "is_material " << (mData.readBit()?"yes":"no") << endl;
1926   cout << getIndent() << "color_index / material_index "
1927       << static_cast<int>(mData.readUnsignedInt()-1) << endl;
1928 
1929   bool is_transparency_defined = mData.readBit();
1930   cout << getIndent() << "is_transparency_defined "
1931       << (is_transparency_defined?"yes":"no") << endl;
1932   if(is_transparency_defined)
1933   {
1934     indent();
1935     cout << getIndent() << "transparency "
1936         << static_cast<unsigned int>(mData.readChar()) << endl;
1937     dedent();
1938   }
1939 
1940   bool is_additional_1_defined = mData.readBit();
1941   cout << getIndent() << "is_additional_1_defined "
1942       << (is_additional_1_defined?"yes":"no") << endl;
1943   if(is_additional_1_defined)
1944   {
1945     indent();
1946     cout << getIndent() << "additional_1 "
1947         << static_cast<unsigned int>(mData.readChar()) << endl;
1948     dedent();
1949   }
1950 
1951   bool is_additional_2_defined = mData.readBit();
1952   cout << getIndent() << "is_additional_2_defined "
1953       << (is_additional_2_defined?"yes":"no") << endl;
1954   if(is_additional_2_defined)
1955   {
1956     indent();
1957     cout << getIndent() << "additional_2 "
1958         << static_cast<unsigned int>(mData.readChar()) << endl;
1959     dedent();
1960   }
1961 
1962   bool is_additional_3_defined = mData.readBit();
1963   cout << getIndent() << "is_additional_3_defined "
1964       << (is_additional_3_defined?"yes":"no") << endl;
1965   if(is_additional_3_defined)
1966   {
1967     indent();
1968     cout << getIndent() << "additional_3 "
1969         << static_cast<unsigned int>(mData.readChar()) << endl;
1970     dedent();
1971   }
1972   dedent();
1973 }
1974 
describeFillPattern(BitByBitData & mData)1975 void describeFillPattern(BitByBitData &mData)
1976 {
1977   cout << getIndent() << "--Fill Pattern--" << endl;
1978   unsigned int type = mData.readUnsignedInt();
1979   cout << getIndent() << "type " << type << endl;
1980   switch(type)
1981   {
1982     //TODO: actually describe fill patterns
1983     default:
1984       cout << getIndent() << "Invalid fill pattern type " << type << endl;
1985   }
1986 }
1987 
describeRepresentationItemContent(BitByBitData & mData)1988 void describeRepresentationItemContent(BitByBitData &mData)
1989 {
1990   describeContentPRCBaseWithGraphics(mData,true);
1991   unsigned int index_local_coordinate_system = mData.readUnsignedInt()-1;
1992   unsigned int index_tessellation = mData.readUnsignedInt()-1;
1993   //cast to int will not be right for big indices
1994   cout << getIndent() << "index_local_coordinate_system "
1995       << static_cast<int>(index_local_coordinate_system) << endl;
1996   cout << getIndent() << "index_tessellation "
1997       << static_cast<int>(index_tessellation) << endl;
1998 }
1999 
describeRepresentationItem(BitByBitData & mData)2000 void describeRepresentationItem(BitByBitData &mData)
2001 {
2002   cout << getIndent() << "--Representation Item--" << endl;
2003   unsigned int type = mData.readUnsignedInt();
2004   switch(type)
2005   {
2006     case PRC_TYPE_RI_Curve:
2007     {
2008       cout << getIndent() << "--PRC_TYPE_RI_Curve--" << endl;
2009       describeRepresentationItemContent(mData);
2010       bool has_wire_body = mData.readBit();
2011       if(has_wire_body)
2012       {
2013         cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
2014         cout << getIndent() << "body_id " << mData.readUnsignedInt() << endl;
2015       }
2016       describeUserData(mData);
2017       break;
2018     }
2019     case PRC_TYPE_RI_PolyBrepModel:
2020     {
2021       cout << getIndent() << "--PRC_TYPE_RI_PolyBrepModel--" << endl;
2022       describeRepresentationItemContent(mData);
2023       cout << getIndent() << "is_closed "
2024           << (mData.readBit()?"yes":"no") << endl;
2025       describeUserData(mData);
2026       break;
2027     }
2028     case PRC_TYPE_RI_BrepModel:
2029     {
2030       cout << getIndent() << "--PRC_TYPE_RI_BrepModel--" << endl;
2031       describeRepresentationItemContent(mData);
2032       bool has_brep_data = mData.readBit();
2033       cout << getIndent() << "has_brep_data "
2034           << (has_brep_data?"yes":"no") << endl;
2035       if(has_brep_data)
2036       {
2037         cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
2038         cout << getIndent() << "object_id " << mData.readUnsignedInt() << endl;
2039       }
2040       cout << getIndent() << "is_closed "
2041           << (mData.readBit()?"yes":"no") << endl;
2042       describeUserData(mData);
2043       break;
2044     }
2045     case PRC_TYPE_RI_Direction:
2046 
2047     case PRC_TYPE_RI_Plane:
2048     case PRC_TYPE_RI_CoordinateSystem:
2049     case PRC_TYPE_RI_PointSet:
2050     case PRC_TYPE_RI_Set:
2051     case PRC_TYPE_RI_PolyWire:
2052       cout << getIndent() << "TODO: Unhandled representation item "
2053           << type << endl;
2054       break;
2055     default:
2056       cout << getIndent() << "Invalid representation item type "
2057           << type << endl;
2058       break;
2059   }
2060 }
2061 
describeRGBColour(BitByBitData & mData)2062 void describeRGBColour(BitByBitData &mData)
2063 {
2064   cout << getIndent() << "R: " << mData.readDouble();
2065   cout << " G: " << mData.readDouble();
2066   cout << " B: " << mData.readDouble() << endl;
2067 }
2068 
describeSchema(BitByBitData & mData)2069 void describeSchema(BitByBitData &mData)
2070 {
2071   cout << getIndent() << "--Schema--" << endl;
2072   indent();
2073   unsigned int numSchemas = mData.readUnsignedInt();
2074   cout << getIndent() << "Number of Schemas " << numSchemas << endl;
2075   if(numSchemas != 0)
2076   {
2077     cout << "Error: Don't know how to handle multiple schemas." << endl;
2078   }
2079   dedent();
2080 }
2081 
2082 string currentName;
2083 int layer_index;
2084 int index_of_line_style;
2085 unsigned short behaviour_bit_field;
2086 
resetCurrentGraphics()2087 void resetCurrentGraphics()
2088 {
2089   layer_index = -1;
2090   index_of_line_style = -1;
2091   behaviour_bit_field = 1;
2092 }
2093 
unFlushSerialization()2094 void unFlushSerialization()
2095 {
2096   currentName = "";
2097 
2098   resetCurrentGraphics();
2099 }
2100 
describeName(BitByBitData & mData)2101 void describeName(BitByBitData &mData)
2102 {
2103   bool sameNameAsCurrent = mData.readBit();
2104   cout << getIndent() << "Same name as current name? "
2105       << (sameNameAsCurrent?"yes":"no") << endl;
2106   if(!sameNameAsCurrent)
2107     currentName = mData.readString();
2108   cout << getIndent() << "Name \"" << currentName << '\"' << endl;
2109 }
2110 
describeUnit(BitByBitData & mData)2111 void describeUnit(BitByBitData &mData)
2112 {
2113   cout << getIndent() << "Unit is from CAD file? "
2114       << (mData.readBit()?"yes":"no") << endl;
2115   cout << getIndent() << "Unit is " << mData.readDouble() << " mm" << endl;
2116 }
2117 
describeAttributes(BitByBitData & mData)2118 void describeAttributes(BitByBitData &mData)
2119 {
2120   cout << getIndent() << "--Attributes--" << endl;
2121   indent();
2122 
2123   unsigned int numAttribs = mData.readUnsignedInt();
2124   cout << getIndent() << "Number of Attributes " << numAttribs << endl;
2125   indent();
2126   for(unsigned int i = 0; i < numAttribs; ++i)
2127   {
2128     cout << getIndent() << "PRC_TYPE_MISC_Attribute "
2129         << mData.readUnsignedInt() << endl;
2130     bool titleIsInt = mData.readBit();
2131     cout << getIndent() << "Title is integer? "
2132         << (titleIsInt?"yes":"no") << endl;
2133     indent();
2134     if(titleIsInt)
2135     {
2136       cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
2137     }
2138     else
2139     {
2140       cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
2141     }
2142     unsigned int sizeOfAttributeKeys = mData.readUnsignedInt();
2143     cout << getIndent() << "Size of Attribute Keys "
2144         << sizeOfAttributeKeys << endl;
2145     for(unsigned int a = 0; a < sizeOfAttributeKeys; ++a)
2146     {
2147       bool titleIsInt = mData.readBit();
2148       cout << getIndent() << "Title is integer? "
2149           << (titleIsInt?"yes":"no") << endl;
2150       indent();
2151       if(titleIsInt)
2152       {
2153         cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
2154       }
2155       else
2156       {
2157         cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
2158       }
2159       dedent();
2160       unsigned int attributeType = mData.readUnsignedInt();
2161       cout << getIndent() << "Attribute Type " << attributeType << endl;
2162       switch(attributeType)
2163       {
2164         case KEPRCModellerAttributeTypeInt:
2165           cout << getIndent() << "Attribute Value (int) "
2166               << mData.readInt() << endl;
2167           break;
2168         case KEPRCModellerAttributeTypeReal:
2169           cout << getIndent() << "Attribute Value (double) "
2170               << mData.readDouble() << endl;
2171           break;
2172         case KEPRCModellerAttributeTypeTime:
2173           cout << getIndent() << "Attribute Value (time_t) "
2174               << mData.readUnsignedInt() << endl;
2175           break;
2176         case KEPRCModellerAttributeTypeString:
2177           cout << getIndent() << "Attribute Value (string) \""
2178               << mData.readString() << '\"' << endl;
2179           break;
2180         default:
2181           break;
2182       }
2183     }
2184     dedent();
2185 
2186     cout << endl;
2187   }
2188   dedent();
2189 
2190 
2191   dedent();
2192 }
2193 
describeContentPRCBase(BitByBitData & mData,bool typeEligibleForReference)2194 void describeContentPRCBase(BitByBitData &mData, bool typeEligibleForReference)
2195 {
2196   cout << getIndent() << "--ContentPRCBase--" << endl;
2197   indent();
2198   describeAttributes(mData);
2199   describeName(mData);
2200   if(typeEligibleForReference)
2201   {
2202     cout << getIndent() << "CAD_identifier "
2203         << mData.readUnsignedInt() << endl;
2204     cout << getIndent() << "CAD_persistent_identifier "
2205         << mData.readUnsignedInt() << endl;
2206     cout << getIndent() << "PRC_unique_identifier "
2207         << mData.readUnsignedInt() << endl;
2208   }
2209   dedent();
2210 }
2211 
describeCompressedUniqueID(BitByBitData & mData)2212 void describeCompressedUniqueID(BitByBitData &mData)
2213 {
2214   cout << getIndent() << "UUID: " << hex << setfill('0');
2215   for(int i = 0; i < 4; ++i)
2216     cout << setw(8) << mData.readUnsignedInt() << ' ';
2217   cout << dec << setfill(' ') << endl;
2218 }
2219 
describeUserData(BitByBitData & mData)2220 void describeUserData(BitByBitData &mData)
2221 {
2222   unsigned int bits = mData.readUnsignedInt();
2223   cout << getIndent() << bits << " bits of user data" << endl;
2224   indent();
2225   for(unsigned int i = 0; i < bits; ++i)
2226   {
2227     if(i%64 == 0)
2228       cout << getIndent();
2229     cout << mData.readBit();
2230     if(i%64 == 63)
2231       cout << endl;
2232   }
2233   if(bits%64 != 0)
2234     cout << endl;
2235   dedent();
2236 }
2237 
checkSectionCode(BitByBitData & mData,unsigned int code)2238 bool checkSectionCode(BitByBitData &mData, unsigned int code)
2239 {
2240   unsigned int num = mData.readUnsignedInt();
2241   if(code != num)
2242   {
2243     cout << getIndent() << "Invalid section code " << num <<
2244         ". Expected " << code << " at "; mData.tellPosition();
2245     return false;
2246   }
2247   else
2248   {
2249     cout << getIndent() << "Section code " << code << endl;
2250     return true;
2251   }
2252 }
2253 
2254 unsigned int currentIndent = 0;
2255 
getIndent()2256 string getIndent()
2257 {
2258   ostringstream out;
2259   for(unsigned int i = 0; i < currentIndent; ++i)
2260     out << "  ";
2261   return out.str();
2262 }
2263 
indent()2264 void indent()
2265 {
2266   ++currentIndent;
2267 }
2268 
dedent()2269 void dedent()
2270 {
2271   --currentIndent;
2272 }
2273