Scribus
Open source desktop publishing at your fingertips
oPRCFile.h
1 /************
2 *
3 * This file is part of a tool for producing 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 #ifndef __O_PRC_FILE_H
22 #define __O_PRC_FILE_H
23 
24 #include <iostream>
25 #include <fstream>
26 #include <vector>
27 #include <map>
28 #include <set>
29 #include <list>
30 #include <stack>
31 #include <string>
32 #include <cstring>
33 
34 #ifdef HAVE_CONFIG_H
35 #include "scconfig.h"
36 #endif
37 
38 #include "PRC.h"
39 #include "PRCbitStream.h"
40 #include "writePRC.h"
41 
42 class oPRCFile;
43 class PRCFileStructure;
44 
45 struct RGBAColour
46 {
47  RGBAColour(double r=0.0, double g=0.0, double b=0.0, double a=1.0) :
48  R(r), G(g), B(b), A(a) {}
49  double R,G,B,A;
50 
51  void Set(double r, double g, double b, double a=1.0)
52  {
53  R = r; G = g; B = b; A = a;
54  }
55  bool operator==(const RGBAColour &c) const
56  {
57  return (R==c.R && G==c.G && B==c.B && A==c.A);
58  }
59  bool operator!=(const RGBAColour &c) const
60  {
61  return !(R==c.R && G==c.G && B==c.B && A==c.A);
62  }
63  bool operator<(const RGBAColour &c) const
64  {
65  if(R!=c.R)
66  return (R<c.R);
67  if(G!=c.G)
68  return (G<c.G);
69  if(B!=c.B)
70  return (B<c.B);
71  return (A<c.A);
72  }
73  friend RGBAColour operator * (const RGBAColour& a, const double d)
74  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
75  friend RGBAColour operator * (const double d, const RGBAColour& a)
76  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
77 
78 };
79 typedef std::map<RGBAColour,uint32_t> PRCcolourMap;
80 
82 {
83  RGBAColourWidth(double r=0.0, double g=0.0, double b=0.0, double a=1.0, double w=1.0) :
84  R(r), G(g), B(b), A(a), W(w) {}
85  double R,G,B,A,W;
86 
87  bool operator==(const RGBAColourWidth &c) const
88  {
89  return (R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
90  }
91  bool operator!=(const RGBAColourWidth &c) const
92  {
93  return !(R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
94  }
95  bool operator<(const RGBAColourWidth &c) const
96  {
97  if(R!=c.R)
98  return (R<c.R);
99  if(G!=c.G)
100  return (G<c.G);
101  if(B!=c.B)
102  return (B<c.B);
103  if(A!=c.A)
104  return (A<c.A);
105  return (W<c.W);
106  }
107 };
108 typedef std::map<RGBAColourWidth,uint32_t> PRCcolourwidthMap;
109 
110 typedef std::map<PRCRgbColor,uint32_t> PRCcolorMap;
111 
113 {
114  PRCmaterial() : alpha(1.0),shininess(1.0),
115  picture_data(NULL), picture_format(KEPRCPicture_BITMAP_RGB_BYTE), picture_width(0), picture_height(0), picture_size(0),
116  picture_replace(false), picture_repeat(false) {}
117  PRCmaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e,
118  const RGBAColour &s, double p, double h,
119  const uint8_t* pic=NULL, EPRCPictureDataFormat picf=KEPRCPicture_BITMAP_RGB_BYTE,
120  uint32_t picw=0, uint32_t pich=0, uint32_t pics=0, bool picreplace=false, bool picrepeat=false) :
121  ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h),
122  picture_data(pic), picture_format(picf), picture_width(picw), picture_height(pich), picture_size(pics),
123  picture_replace(picreplace), picture_repeat(picrepeat) {
124  if(picture_size==0)
125  {
126  if (picture_format==KEPRCPicture_BITMAP_RGB_BYTE)
127  picture_size = picture_width*picture_height*3;
128  if (picture_format==KEPRCPicture_BITMAP_RGBA_BYTE)
129  picture_size = picture_width*picture_height*4;
130  if (picture_format==KEPRCPicture_BITMAP_GREY_BYTE)
131  picture_size = picture_width*picture_height*1;
132  if (picture_format==KEPRCPicture_BITMAP_GREYA_BYTE)
133  picture_size = picture_width*picture_height*2;
134  }
135  }
136  RGBAColour ambient,diffuse,emissive,specular;
137  double alpha,shininess;
138  const uint8_t* picture_data;
139  EPRCPictureDataFormat picture_format;
140  uint32_t picture_width;
141  uint32_t picture_height;
142  uint32_t picture_size;
143  bool picture_replace; // replace material color with texture color? if false - just modify
144  bool picture_repeat; // repeat texture? if false - clamp to edge
145 
146  bool operator==(const PRCmaterial &m) const
147  {
148  return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
149  && specular==m.specular && alpha==m.alpha && shininess==m.shininess
150  && picture_replace==m.picture_replace && picture_repeat==m.picture_repeat
151  && picture_format==m.picture_format
152  && picture_width==m.picture_width && picture_height==m.picture_height && picture_size==m.picture_size
153  && (picture_data==m.picture_data || memcmp(picture_data,m.picture_data,picture_size)==0) );
154  }
155  bool operator<(const PRCmaterial &m) const
156  {
157  if(ambient!=m.ambient)
158  return (ambient<m.ambient);
159  if(diffuse!=m.diffuse)
160  return (diffuse<m.diffuse);
161  if(emissive!=m.emissive)
162  return (emissive<m.emissive);
163  if(specular!=m.specular)
164  return (specular<m.specular);
165  if(alpha!=m.alpha)
166  return (alpha<m.alpha);
167  if(shininess!=m.shininess)
168  return (shininess<m.shininess);
169  if(picture_replace!=m.picture_replace)
170  return (picture_replace<m.picture_replace);
171  if(picture_repeat!=m.picture_repeat)
172  return (picture_repeat<m.picture_repeat);
173  if(picture_format!=m.picture_format)
174  return (picture_format<m.picture_format);
175  if(picture_width!=m.picture_width)
176  return (picture_width<m.picture_width);
177  if(picture_height!=m.picture_height)
178  return (picture_height<m.picture_height);
179  if(picture_size!=m.picture_size)
180  return (picture_size<m.picture_size);
181  if(picture_data!=m.picture_data)
182  return (memcmp(picture_data,m.picture_data,picture_size)<0);
183  return false;
184  }
185 };
186 typedef std::map<PRCmaterial,uint32_t> PRCmaterialMap;
187 
189 {
190  PRCpicture() :
191  data(NULL), format(KEPRCPicture_BITMAP_RGB_BYTE),
192  width(0), height(0), size(0) {}
193  PRCpicture(const uint8_t* pic, EPRCPictureDataFormat picf,
194  uint32_t picw, uint32_t pich, uint32_t pics=0) :
195  data(pic), format(picf),
196  width(picw), height(pich), size(pics)
197  {
198  if(size==0)
199  {
200  if (format==KEPRCPicture_BITMAP_RGB_BYTE)
201  size = width*height*3;
202  if (format==KEPRCPicture_BITMAP_RGBA_BYTE)
203  size = width*height*4;
204  if (format==KEPRCPicture_BITMAP_GREY_BYTE)
205  size = width*height*1;
206  if (format==KEPRCPicture_BITMAP_GREYA_BYTE)
207  size = width*height*2;
208  }
209  }
210  PRCpicture(const PRCmaterial& m) :
211  data(m.picture_data), format(m.picture_format),
212  width(m.picture_width), height(m.picture_height), size(m.picture_size) {}
213 
214  const uint8_t* data;
215  EPRCPictureDataFormat format;
216  uint32_t width;
217  uint32_t height;
218  uint32_t size;
219  bool operator==(const PRCpicture& p) const
220  {
221  return ( format==p.format
222  && width==p.width && height==p.height && size==p.size
223  && (data==p.data || memcmp(data,p.data,size)==0) );
224  }
225  bool operator<(const PRCpicture& p) const
226  {
227  if(format!=p.format)
228  return (format<p.format);
229  if(width!=p.width)
230  return (width<p.width);
231  if(height!=p.height)
232  return (height<p.height);
233  if(size!=p.size)
234  return (size<p.size);
235  if(data!=p.data)
236  return (memcmp(data,p.data,size)<0);
237  return false;
238  }
239 };
240 
241 typedef std::map<PRCpicture,uint32_t> PRCpictureMap;
242 
244 {
245  PRCmaterialgeneric() : alpha(1.0),shininess(1.0) {}
246  PRCmaterialgeneric(const RGBAColour& a, const RGBAColour& d, const RGBAColour& e,
247  const RGBAColour& s, double p, double h) :
248  ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
249  PRCmaterialgeneric(const PRCmaterial& m) :
250  ambient(m.ambient), diffuse(m.diffuse), emissive(m.emissive), specular(m.specular), alpha(m.alpha), shininess(m.shininess) {}
251  RGBAColour ambient,diffuse,emissive,specular;
252  double alpha,shininess;
253 
254  bool operator==(const PRCmaterialgeneric& m) const
255  {
256  return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
257  && specular==m.specular && alpha==m.alpha && shininess==m.shininess);
258  }
259  bool operator<(const PRCmaterialgeneric& m) const
260  {
261  if(ambient!=m.ambient)
262  return (ambient<m.ambient);
263  if(diffuse!=m.diffuse)
264  return (diffuse<m.diffuse);
265  if(emissive!=m.emissive)
266  return (emissive<m.emissive);
267  if(specular!=m.specular)
268  return (specular<m.specular);
269  if(alpha!=m.alpha)
270  return (alpha<m.alpha);
271  if(shininess!=m.shininess)
272  return (shininess<m.shininess);
273  return false;
274  }
275 };
276 typedef std::map<PRCmaterialgeneric,uint32_t> PRCmaterialgenericMap;
277 
279 {
281  picture_index(m1), picture_replace(false), picture_repeat(false) {}
282  PRCtexturedefinition(uint32_t picindex, bool picreplace=false, bool picrepeat=false) :
283  picture_index(picindex), picture_replace(picreplace), picture_repeat(picrepeat) {}
284  PRCtexturedefinition(uint32_t picindex, const PRCmaterial& m) :
285  picture_index(picindex), picture_replace(m.picture_replace), picture_repeat(m.picture_repeat) {}
286  uint32_t picture_index;
287  bool picture_replace; // replace material color with texture color? if false - just modify
288  bool picture_repeat; // repeat texture? if false - clamp to edge
289 
290  bool operator==(const PRCtexturedefinition& t) const
291  {
292  return (picture_index==t.picture_index
293  && picture_replace==t.picture_replace && picture_repeat==t.picture_repeat);
294  }
295  bool operator<(const PRCtexturedefinition& t) const
296  {
297  if(picture_index!=t.picture_index)
298  return (picture_index<t.picture_index);
299  if(picture_replace!=t.picture_replace)
300  return (picture_replace<t.picture_replace);
301  if(picture_repeat!=t.picture_repeat)
302  return (picture_repeat<t.picture_repeat);
303  return false;
304  }
305 };
306 typedef std::map<PRCtexturedefinition,uint32_t> PRCtexturedefinitionMap;
307 
309 {
311  material_generic_index(m1), texture_definition_index(m1) {}
312  PRCtextureapplication(uint32_t matindex, uint32_t texindex) :
313  material_generic_index(matindex), texture_definition_index(texindex) {}
314  uint32_t material_generic_index;
315  uint32_t texture_definition_index;
316 
317  bool operator==(const PRCtextureapplication& t) const
318  {
319  return (material_generic_index==t.material_generic_index
320  && texture_definition_index==t.texture_definition_index);
321  }
322  bool operator<(const PRCtextureapplication& t) const
323  {
324  if(material_generic_index!=t.material_generic_index)
325  return (material_generic_index<t.material_generic_index);
326  if(texture_definition_index!=t.texture_definition_index)
327  return (texture_definition_index<t.texture_definition_index);
328  return false;
329  }
330 };
331 typedef std::map<PRCtextureapplication,uint32_t> PRCtextureapplicationMap;
332 
333 struct PRCstyle
334 {
335  PRCstyle() :
336  line_width(0), alpha(1), is_material(false), color_material_index(m1) {}
337  PRCstyle(double linewidth, double alph, bool ismat, uint32_t colindex=m1) :
338  line_width(linewidth), alpha(alph), is_material(ismat), color_material_index(colindex) {}
339  double line_width;
340  double alpha;
341  bool is_material;
342  uint32_t color_material_index;
343 
344  bool operator==(const PRCstyle& s) const
345  {
346  return (line_width==s.line_width && alpha==s.alpha && is_material==s.is_material
347  && color_material_index==s.color_material_index);
348  }
349  bool operator<(const PRCstyle& s) const
350  {
351  if(line_width!=s.line_width)
352  return (line_width<s.line_width);
353  if(alpha!=s.alpha)
354  return (alpha<s.alpha);
355  if(is_material!=s.is_material)
356  return (is_material<s.is_material);
357  if(color_material_index!=s.color_material_index)
358  return (color_material_index<s.color_material_index);
359  return false;
360  }
361 };
362 typedef std::map<PRCstyle,uint32_t> PRCstyleMap;
363 
364 struct PRCtessrectangle // rectangle
365 {
366  PRCVector3d vertices[4];
367  uint32_t style;
368 };
369 typedef std::vector<PRCtessrectangle> PRCtessrectangleList;
370 
371 struct PRCtessquad // rectangle
372 {
373  PRCVector3d vertices[4];
374  RGBAColour colours[4];
375 };
376 typedef std::vector<PRCtessquad> PRCtessquadList;
377 /*
378 struct PRCtesstriangle // textured triangle
379 {
380  PRCtesstriangle() :
381  style(m1) {}
382  PRCVector3d vertices[3];
383 // PRCVector3d normals[3];
384 // RGBAColour colors[3];
385  PRCVector2d texcoords[3];
386  uint32_t style;
387 };
388 typedef std::vector<PRCtesstriangle> PRCtesstriangleList;
389 */
390 struct PRCtessline // polyline
391 {
392  std::vector<PRCVector3d> point;
393  PRCRgbColor color;
394 };
395 typedef std::list<PRCtessline> PRCtesslineList;
396 typedef std::map<double, PRCtesslineList> PRCtesslineMap;
397 
398 struct PRCface
399 {
400  PRCface() : transform(NULL), face(NULL) {}
401  uint32_t style;
402  bool transparent;
403  PRCGeneralTransformation3d* transform;
404  PRCFace* face;
405 };
406 typedef std::vector <PRCface> PRCfaceList;
407 
409 {
410  PRCcompface() : face(NULL) {}
411  uint32_t style;
412  bool transparent;
413  PRCCompressedFace* face;
414 };
415 typedef std::vector <PRCcompface> PRCcompfaceList;
416 
417 struct PRCwire
418 {
419  PRCwire() : style(m1), transform(NULL), curve(NULL) {}
420  uint32_t style;
421  PRCGeneralTransformation3d* transform;
422  PRCCurve* curve;
423 };
424 typedef std::vector <PRCwire> PRCwireList;
425 
426 typedef std::map <uint32_t,std::vector<PRCVector3d> > PRCpointsetMap;
427 
429 {
430 public:
431  double compression;
432  double granularity;
433 
434  bool closed; // render the surface as one-sided; may yield faster rendering
435  bool tess; // use tessellated mesh to store straight patches
436  bool do_break; //
437  bool no_break; // do not render transparent patches as one-faced nodes
438  double crease_angle; // crease angle for meshes
439 
440  PRCoptions(double compression=0.0, double granularity=0.0, bool closed=false,
441  bool tess=false, bool do_break=true, bool no_break=false, double crease_angle=25.8419)
442  : compression(compression), granularity(granularity), closed(closed),
443  tess(tess), do_break(do_break), no_break(no_break), crease_angle(crease_angle) {}
444 };
445 
446 class PRCgroup
447 {
448  public:
449  PRCgroup() :
450  product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {}
451  PRCgroup(const std::string& name) :
452  product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {}
453  PRCProductOccurrence *product_occurrence, *parent_product_occurrence;
454  PRCPartDefinition *part_definition, *parent_part_definition;
455  PRCfaceList faces;
456  PRCcompfaceList compfaces;
457  PRCtessrectangleList rectangles;
458 // PRCtesstriangleList triangles;
459  PRCtessquadList quads;
460  PRCtesslineMap lines;
461  PRCwireList wires;
462  PRCpointsetMap points;
463  std::vector<PRCPointSet*> pointsets;
464  std::vector<PRCPolyBrepModel*> polymodels;
465  std::vector<PRCPolyWire*> polywires;
466  PRCGeneralTransformation3d* transform;
467  std::string name;
468  PRCoptions options;
469 };
470 
471 void makeFileUUID(PRCUniqueId&);
472 void makeAppUUID(PRCUniqueId&);
473 
475 {
476  public:
477  PRCUncompressedFile() : file_size(0), data(NULL) {}
478  PRCUncompressedFile(uint32_t fs, uint8_t *d) : file_size(fs), data(d) {}
479  ~PRCUncompressedFile() { if(data != NULL) delete[] data; }
480  uint32_t file_size;
481  uint8_t *data;
482 
483  void write(std::ostream&) const;
484 
485  uint32_t getSize() const;
486 };
487 typedef std::deque <PRCUncompressedFile*> PRCUncompressedFileList;
488 
490 {
491  public:
492  uint32_t minimal_version_for_read; // PRCVersion
493  uint32_t authoring_version; // PRCVersion
494  PRCUniqueId file_structure_uuid;
495  PRCUniqueId application_uuid; // should be 0
496 
497  PRCStartHeader() :
498  minimal_version_for_read(PRCVersion), authoring_version(PRCVersion) {}
499  void serializeStartHeader(std::ostream&) const;
500 
501  uint32_t getStartHeaderSize() const;
502 };
503 
505 {
506  public:
507  uint32_t number_of_referenced_file_structures;
508  double tessellation_chord_height_ratio;
509  double tessellation_angle_degree;
510  std::string default_font_family_name;
511  std::vector<PRCRgbColor> colors;
512  std::vector<PRCPicture> pictures;
513  PRCUncompressedFileList uncompressed_files;
514  PRCTextureDefinitionList texture_definitions;
515  PRCMaterialList materials;
516  PRCStyleList styles;
517  PRCCoordinateSystemList reference_coordinate_systems;
518  std::vector<PRCFontKeysSameFont> font_keys_of_font;
519  PRCPartDefinitionList part_definitions;
520  PRCProductOccurrenceList product_occurrences;
521 // PRCMarkupList markups;
522 // PRCAnnotationItemList annotation_entities;
523  double unit;
524  PRCTopoContextList contexts;
525  PRCTessList tessellations;
526 
527  uint32_t sizes[6];
528  uint8_t *globals_data;
529  PRCbitStream globals_out; // order matters: PRCbitStream must be initialized last
530  uint8_t *tree_data;
531  PRCbitStream tree_out;
532  uint8_t *tessellations_data;
533  PRCbitStream tessellations_out;
534  uint8_t *geometry_data;
535  PRCbitStream geometry_out;
536  uint8_t *extraGeometry_data;
537  PRCbitStream extraGeometry_out;
538 
539  ~PRCFileStructure () {
540  for(PRCUncompressedFileList::iterator it=uncompressed_files.begin(); it!=uncompressed_files.end(); ++it) delete *it;
541  for(PRCTextureDefinitionList::iterator it=texture_definitions.begin(); it!=texture_definitions.end(); ++it) delete *it;
542  for(PRCMaterialList::iterator it=materials.begin(); it!=materials.end(); ++it) delete *it;
543  for(PRCStyleList::iterator it=styles.begin(); it!=styles.end(); ++it) delete *it;
544  for(PRCTopoContextList::iterator it=contexts.begin(); it!=contexts.end(); ++it) delete *it;
545  for(PRCTessList::iterator it=tessellations.begin(); it!=tessellations.end(); ++it) delete *it;
546  for(PRCPartDefinitionList::iterator it=part_definitions.begin(); it!=part_definitions.end(); ++it) delete *it;
547  for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it;
548  for(PRCCoordinateSystemList::iterator it=reference_coordinate_systems.begin(); it!=reference_coordinate_systems.end(); it++)
549  delete *it;
550 
551  free(globals_data);
552  free(tree_data);
553  free(tessellations_data);
554  free(geometry_data);
555  free(extraGeometry_data);
556  }
557 
558  PRCFileStructure() :
559  number_of_referenced_file_structures(0),
560  tessellation_chord_height_ratio(2000.0),tessellation_angle_degree(40.0),
561  default_font_family_name(""),
562  unit(1),
563  globals_data(NULL),globals_out(globals_data,0),
564  tree_data(NULL),tree_out(tree_data,0),
565  tessellations_data(NULL),tessellations_out(tessellations_data,0),
566  geometry_data(NULL),geometry_out(geometry_data,0),
567  extraGeometry_data(NULL),extraGeometry_out(extraGeometry_data,0) {}
568  void write(std::ostream&);
569  void prepare();
570  uint32_t getSize();
571  void serializeFileStructureGlobals(PRCbitStream&);
572  void serializeFileStructureTree(PRCbitStream&);
573  void serializeFileStructureTessellation(PRCbitStream&);
574  void serializeFileStructureGeometry(PRCbitStream&);
575  void serializeFileStructureExtraGeometry(PRCbitStream&);
576  uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0, std::string name="");
577  uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition);
578  uint32_t addRgbColor(const PRCRgbColor &color);
579  uint32_t addRgbColorUnique(const PRCRgbColor &color);
580  uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric);
581  uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication);
582  uint32_t addStyle(PRCStyle*& pStyle);
583  uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition);
584  uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence);
585  uint32_t addTopoContext(PRCTopoContext*& pTopoContext);
586  uint32_t getTopoContext(PRCTopoContext*& pTopoContext);
587  uint32_t add3DTess(PRC3DTess*& p3DTess);
588  uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess);
589 /*
590  uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess);
591  uint32_t addMarkup(PRCMarkup*& pMarkup);
592  uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem);
593  */
594  uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem);
595  uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem);
596 };
597 
599 {
600  public:
601  PRCUniqueId UUID;
602  uint32_t reserved; // 0
603  uint32_t number_of_offsets;
604  uint32_t *offsets;
605 
606  void write(std::ostream&);
607 
608  uint32_t getSize();
609 };
610 
611 class PRCHeader : public PRCStartHeader
612 {
613  public :
614  uint32_t number_of_file_structures;
615  PRCFileStructureInformation *fileStructureInformation;
616  uint32_t model_file_offset;
617  uint32_t file_size; // not documented
618  PRCUncompressedFileList uncompressed_files;
619 
620  void write(std::ostream&);
621  uint32_t getSize();
622 };
623 
624 typedef std::map <PRCGeneralTransformation3d,uint32_t> PRCtransformMap;
625 
626 class oPRCFile
627 {
628  public:
629  oPRCFile(std::ostream &os, double u=1, uint32_t n=1) :
630  number_of_file_structures(n),
631  fileStructures(new PRCFileStructure*[n]),
632  unit(u),
633  modelFile_data(NULL),modelFile_out(modelFile_data,0),
634  fout(NULL),output(os)
635  {
636  for(uint32_t i = 0; i < number_of_file_structures; ++i)
637  {
638  fileStructures[i] = new PRCFileStructure();
639  fileStructures[i]->minimal_version_for_read = PRCVersion;
640  fileStructures[i]->authoring_version = PRCVersion;
641  makeFileUUID(fileStructures[i]->file_structure_uuid);
642  makeAppUUID(fileStructures[i]->application_uuid);
643  fileStructures[i]->unit = u;
644  }
645 
646  groups.push(PRCgroup());
647  PRCgroup &group = groups.top();
648  group.name="root";
649  group.transform = NULL;
650  group.product_occurrence = new PRCProductOccurrence(group.name);
651  group.parent_product_occurrence = NULL;
652  group.part_definition = new PRCPartDefinition;
653  group.parent_part_definition = NULL;
654  }
655 
656  oPRCFile(const std::string &name, double u=1, uint32_t n=1) :
657  number_of_file_structures(n),
658  fileStructures(new PRCFileStructure*[n]),
659  unit(u),
660  modelFile_data(NULL),modelFile_out(modelFile_data,0),
661  fout(new std::ofstream(name.c_str(),
662  std::ios::out|std::ios::binary|std::ios::trunc)),
663  output(*fout)
664  {
665  for(uint32_t i = 0; i < number_of_file_structures; ++i)
666  {
667  fileStructures[i] = new PRCFileStructure();
668  fileStructures[i]->minimal_version_for_read = PRCVersion;
669  fileStructures[i]->authoring_version = PRCVersion;
670  makeFileUUID(fileStructures[i]->file_structure_uuid);
671  makeAppUUID(fileStructures[i]->application_uuid);
672  fileStructures[i]->unit = u;
673  }
674 
675  groups.push(PRCgroup());
676  PRCgroup &group = groups.top();
677  group.name="root";
678  group.transform = NULL;
679  group.product_occurrence = new PRCProductOccurrence(group.name);
680  group.parent_product_occurrence = NULL;
681  group.part_definition = new PRCPartDefinition;
682  group.parent_part_definition = NULL;
683  }
684 
685  ~oPRCFile()
686  {
687  for(uint32_t i = 0; i < number_of_file_structures; ++i)
688  delete fileStructures[i];
689  delete[] fileStructures;
690  if(fout != NULL)
691  delete fout;
692  free(modelFile_data);
693  for(PRCpictureMap::iterator it=pictureMap.begin(); it!=pictureMap.end(); ++it) delete it->first.data;
694  }
695 
696  void begingroup(const char *name, PRCoptions *options=NULL,
697  const double* t=NULL);
698  void endgroup();
699 
700  std::string lastgroupname;
701  std::vector<std::string> lastgroupnames;
702  std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence);
703 
704  bool finish();
705  uint32_t getSize();
706 
707  const uint32_t number_of_file_structures;
708  PRCFileStructure **fileStructures;
709  PRCHeader header;
710  PRCUnit unit;
711  uint8_t *modelFile_data;
712  PRCbitStream modelFile_out; // order matters: PRCbitStream must be initialized last
713  PRCcolorMap colorMap;
714  PRCcolourMap colourMap;
715  PRCcolourwidthMap colourwidthMap;
716  PRCmaterialgenericMap materialgenericMap;
717  PRCtexturedefinitionMap texturedefinitionMap;
718  PRCtextureapplicationMap textureapplicationMap;
719  PRCstyleMap styleMap;
720  PRCpictureMap pictureMap;
721  PRCgroup rootGroup;
722  PRCtransformMap transformMap;
723  std::stack<PRCgroup> groups;
724  PRCgroup& findGroup();
725  void doGroup(PRCgroup& group);
726  uint32_t addColor(const PRCRgbColor &color);
727  uint32_t addColour(const RGBAColour &colour);
728  uint32_t addColourWidth(const RGBAColour &colour, double width);
729  uint32_t addLineMaterial(const RGBAColour& c, double width)
730  { return addColourWidth(c,width); }
731  uint32_t addMaterial(const PRCmaterial &material);
732  uint32_t addTransform(PRCGeneralTransformation3d*& transform);
733  uint32_t addTransform(const double* t);
734  uint32_t addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale);
735  void addPoint(const double P[3], const RGBAColour &c, double w=1.0);
736  void addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0);
737  void addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
738  const RGBAColour& c, double w,
739  bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
740  uint32_t createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
741  bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
742  void addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial &m,
743  uint32_t nN, const double N[][3], const uint32_t NI[][3],
744  uint32_t nT, const double T[][2], const uint32_t TI[][3],
745  uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
746  uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca);
747  uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], uint32_t style_index,
748  uint32_t nN, const double N[][3], const uint32_t NI[][3],
749  uint32_t nT, const double T[][2], const uint32_t TI[][3],
750  uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
751  uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca);
752  uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
753  uint32_t nN, const double N[][3], const uint32_t NI[][3],
754  uint32_t nT, const double T[][2], const uint32_t TI[][3],
755  uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
756  uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
757  {
758  const uint32_t style = addMaterial(m);
759  if(M!=NULL && nM>0)
760  {
761  uint32_t* const styles = new uint32_t[nM];
762  for(uint32_t i=0; i<nM; i++)
763  styles[i]=addMaterial(M[i]);
764  const uint32_t meshid = createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
765  delete[] styles;
766  return meshid;
767  }
768  else
769  return createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
770  }
771  void addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial &m,
772  uint32_t nN, const double N[][3], const uint32_t NI[][4],
773  uint32_t nT, const double T[][2], const uint32_t TI[][4],
774  uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
775  uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca);
776  uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
777  uint32_t nN, const double N[][3], const uint32_t NI[][4],
778  uint32_t nT, const double T[][2], const uint32_t TI[][4],
779  uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
780  uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca);
781  uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
782  uint32_t nN, const double N[][3], const uint32_t NI[][4],
783  uint32_t nT, const double T[][2], const uint32_t TI[][4],
784  uint32_t nC, const RGBAColour C[], const uint32_t CI[][4],
785  uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
786  {
787  const uint32_t style = addMaterial(m);
788  if(M!=NULL && nM>0)
789  {
790  uint32_t* const styles = new uint32_t[nM];
791  for(uint32_t i=0; i<nM; i++)
792  styles[i]=addMaterial(M[i]);
793  const uint32_t meshid = createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
794  delete[] styles;
795  return meshid;
796  }
797  else
798  return createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
799  }
800 #define PRCTRANSFORM const double origin[3]=NULL, const double x_axis[3]=NULL, const double y_axis[3]=NULL, double scale=1, const double* t=NULL
801 #define PRCCARTRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale
802 #define PRCGENTRANSFORM const double* t=NULL
803 #define PRCNOMATERIALINDEX m1
804  void useMesh(uint32_t tess_index, uint32_t style_index, PRCGENTRANSFORM);
805  void useMesh(uint32_t tess_index, const PRCmaterial& m, PRCGENTRANSFORM)
806  { useMesh(tess_index,addMaterial(m),t); }
807  void useMesh(uint32_t tess_index, uint32_t style_index, PRCCARTRANSFORM);
808  void useMesh(uint32_t tess_index, const PRCmaterial& m, PRCCARTRANSFORM)
809  { useMesh(tess_index,addMaterial(m),origin, x_axis, y_axis, scale); }
810 
811  void useLines(uint32_t tess_index, uint32_t style_index, PRCGENTRANSFORM);
812  void useLines(uint32_t tess_index, const RGBAColour& c, double w, PRCGENTRANSFORM)
813  { useLines(tess_index, addLineMaterial(c,w), t); }
814  void useLines(uint32_t tess_index, uint32_t style_index, PRCCARTRANSFORM);
815  void useLines(uint32_t tess_index, const RGBAColour& c, double w, PRCCARTRANSFORM)
816  { useLines(tess_index,addLineMaterial(c,w),origin, x_axis, y_axis, scale); }
817 
818 // void addTriangle(const double P[][3], const double T[][2], uint32_t style_index);
819 
820  void addLine(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0);
821  void addBezierCurve(uint32_t n, const double cP[][3], const RGBAColour &c);
822  void addCurve(uint32_t d, uint32_t n, const double cP[][3], const double *k, const RGBAColour &c, const double w[]);
823  void addQuad(const double P[][3], const RGBAColour C[]);
824 
825  void addRectangle(const double P[][3], const PRCmaterial &m);
826  void addPatch(const double cP[][3], const PRCmaterial &m);
827  void addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
828  const double cP[][3], const double *kU, const double *kV, const PRCmaterial &m,
829  const double w[]);
830  void addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial& m, PRCTRANSFORM);
831  void addHemisphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
832  void addSphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
833  void addDisk(double radius, const PRCmaterial& m, PRCTRANSFORM);
834  void addCylinder(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
835  void addCone(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
836  void addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial& m, PRCTRANSFORM);
837 #undef PRCTRANSFORM
838 #undef PRCCARTRANSFORM
839 #undef PRCGENTRANSFORM
840 
841 
842  uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0,
843  std::string name="", uint32_t fileStructure=0)
844  { return fileStructures[fileStructure]->addPicture(format, size, picture, width, height, name); }
845  uint32_t addPicture(const PRCpicture& pic,
846  std::string name="", uint32_t fileStructure=0)
847  { return fileStructures[fileStructure]->addPicture(pic.format, pic.size, pic.data, pic.width, pic.height, name); }
848  uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition, uint32_t fileStructure=0)
849  {
850  return fileStructures[fileStructure]->addTextureDefinition(pTextureDefinition);
851  }
852  uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication, uint32_t fileStructure=0)
853  {
854  return fileStructures[fileStructure]->addTextureApplication(pTextureApplication);
855  }
856  uint32_t addRgbColor(const PRCRgbColor &color,
857  uint32_t fileStructure=0)
858  {
859  return fileStructures[fileStructure]->addRgbColor(color);
860  }
861  uint32_t addRgbColorUnique(const PRCRgbColor &color,
862  uint32_t fileStructure=0)
863  {
864  return fileStructures[fileStructure]->addRgbColorUnique(color);
865  }
866  uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric,
867  uint32_t fileStructure=0)
868  {
869  return fileStructures[fileStructure]->addMaterialGeneric(pMaterialGeneric);
870  }
871  uint32_t addStyle(PRCStyle*& pStyle, uint32_t fileStructure=0)
872  {
873  return fileStructures[fileStructure]->addStyle(pStyle);
874  }
875  uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition, uint32_t fileStructure=0)
876  {
877  return fileStructures[fileStructure]->addPartDefinition(pPartDefinition);
878  }
879  uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence, uint32_t fileStructure=0)
880  {
881  return fileStructures[fileStructure]->addProductOccurrence(pProductOccurrence);
882  }
883  uint32_t addTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
884  {
885  return fileStructures[fileStructure]->addTopoContext(pTopoContext);
886  }
887  uint32_t getTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
888  {
889  return fileStructures[fileStructure]->getTopoContext(pTopoContext);
890  }
891  uint32_t add3DTess(PRC3DTess*& p3DTess, uint32_t fileStructure=0)
892  {
893  return fileStructures[fileStructure]->add3DTess(p3DTess);
894  }
895  uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess, uint32_t fileStructure=0)
896  {
897  return fileStructures[fileStructure]->add3DWireTess(p3DWireTess);
898  }
899 /*
900  uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess, uint32_t fileStructure=0)
901  {
902  return fileStructures[fileStructure]->addMarkupTess(pMarkupTess);
903  }
904  uint32_t addMarkup(PRCMarkup*& pMarkup, uint32_t fileStructure=0)
905  {
906  return fileStructures[fileStructure]->addMarkup(pMarkup);
907  }
908  uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem, uint32_t fileStructure=0)
909  {
910  return fileStructures[fileStructure]->addAnnotationItem(pAnnotationItem);
911  }
912  */
913  uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
914  {
915  return fileStructures[fileStructure]->addCoordinateSystem(pCoordinateSystem);
916  }
917  uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
918  {
919  return fileStructures[fileStructure]->addCoordinateSystemUnique(pCoordinateSystem);
920  }
921  private:
922  void serializeModelFileData(PRCbitStream&);
923  std::ofstream *fout;
924  std::ostream &output;
925 };
926 
927 #endif // __O_PRC_FILE_H
Definition: writePRC.h:452
Definition: oPRCFile.h:398
Definition: oPRCFile.h:446
Definition: oPRCFile.h:626
Definition: oPRCFile.h:188
Definition: oPRCFile.h:278
Definition: writePRC.h:1273
Definition: writePRC.h:1424
Definition: oPRCFile.h:390
Definition: oPRCFile.h:243
Definition: oPRCFile.h:504
Definition: writePRC.h:855
Definition: writePRC.h:1377
Definition: writePRC.h:733
Definition: oPRCFile.h:428
Definition: writePRC.h:38
Definition: oPRCFile.h:81
Definition: oPRCFile.h:408
Definition: writePRC.h:1037
Definition: oPRCFile.h:45
Definition: writePRC.h:540
Definition: oPRCFile.h:474
Definition: writePRC.h:240
Definition: writePRC.h:481
Definition: writePRC.h:1342
Definition: oPRCFile.h:112
Definition: oPRCFile.h:611
Definition: writePRC.h:1402
Definition: oPRCFile.h:598
Definition: writePRC.h:562
Definition: writePRC.h:380
Definition: writePRC.h:1414
Definition: writePRC.h:285
Definition: oPRCFile.h:371
Definition: PRCbitStream.h:46
Definition: oPRCFile.h:364
Definition: writePRC.h:1453
Definition: writePRC.h:423
Definition: oPRCFile.h:489
Definition: oPRCFile.h:417
Definition: oPRCFile.h:308
Definition: oPRCFile.h:333