summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/prc/oPRCFile.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/prc/oPRCFile.cc')
-rw-r--r--Build/source/utils/asymptote/prc/oPRCFile.cc1593
1 files changed, 1131 insertions, 462 deletions
diff --git a/Build/source/utils/asymptote/prc/oPRCFile.cc b/Build/source/utils/asymptote/prc/oPRCFile.cc
index 73c7ef32efe..37397b1e675 100644
--- a/Build/source/utils/asymptote/prc/oPRCFile.cc
+++ b/Build/source/utils/asymptote/prc/oPRCFile.cc
@@ -2,6 +2,7 @@
*
* This file is part of a tool for producing 3D content in the PRC format.
* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+* with enhancements contributed by Michail Vidiassov.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -21,269 +22,37 @@
#include "oPRCFile.h"
#include <time.h>
#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <zlib.h>
+#include <string.h>
+
+#define WriteUnsignedInteger( value ) out << (uint32_t)(value);
+#define WriteInteger( value ) out << (int32_t)(value);
+#define SerializeContentPRCBase write(out);
+#define SerializeRgbColor( value ) (value).serializeRgbColor(out);
+#define SerializePicture( value ) (value).serializePicture(out);
+#define SerializeTextureDefinition( value ) (value)->serializeTextureDefinition(out);
+#define SerializeMarkup( value ) (value)->serializeMarkup(out);
+#define SerializeAnnotationEntity( value ) (value)->serializeAnnotationEntity(out);
+#define SerializeFontKeysSameFont( value ) (value).serializeFontKeysSameFont(out);
+#define SerializeMaterial( value ) (value)->serializeMaterial(out);
+
+#define SerializeCategory1LineStyle( value ) (value)->serializeCategory1LineStyle(out);
+#define SerializeCoordinateSystem( value ) (value)->serializeCoordinateSystem(out);
+#define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(out);
+#define SerializePartDefinition( value ) (value)->serializePartDefinition(out);
+#define SerializeProductOccurrence( value ) (value)->serializeProductOccurrence(out);
+#define SerializeContextAndBodies( value ) (fileStructure->value)->serializeContextAndBodies(out);
+#define SerializeGeometrySummary( value ) (fileStructure->value)->serializeGeometrySummary(out);
+#define SerializeContextGraphics( value ) (fileStructure->value)->serializeContextGraphics(out);
using std::string;
+using namespace std;
+using namespace std::tr1;
-uint32_t PRCentity::getGraphicsIndex()
-{
- if(useMaterial)
- return parent->colourMap.size()+parent->getMaterialIndex(material);
- else
- return parent->getColourIndex(colour);
-}
-
-void PRCline::writeRepresentationItem(PRCbitStream &out,uint32_t index)
-{
- out << (uint32_t)(PRC_TYPE_RI_Curve);
- ContentPRCBase(&EMPTY_ATTRIBUTES,name,true,makeCADID(),0,makePRCID()).write(out);
- writeGraphics(out,m1,getGraphicsIndex(),1);
- out << (uint32_t)0 // index_local_coordinate_system+1
- << (uint32_t)0; // index_tessellation
-
- out << true // has wire body
- << (uint32_t)index+1 // index of context in geometry section
- << (uint32_t)1; // body index in topological context
- UserData(0,0).write(out);
-}
-
-void PRCline::writeTopologicalContext(PRCbitStream &out)
-{
- // topological context
- out << (uint32_t)(PRC_TYPE_TOPO_Context);
- EMPTY_CONTENTPRCBASE.write(out);
- out << (uint8_t)0 // behaviour
- << 0.0 // granularity
- << 0.0 // tolerance
- << false // have smallest face thickness
- << false; // have scale
-
- out << (uint32_t)1; // number of bodies
- // body
- out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody;
-
- out << false // base topology: no base information
- << (uint8_t)0; // content body: behaviour
- // Not sure what a 0 means, since it satisfies no #define,
- // but I think it means no bbox
-
- // wire edge
- out << false // not already stored
- << (uint32_t)PRC_TYPE_TOPO_WireEdge
- << false; // base topology: no base information
-
- // polyline
- out << false // not already stored
- << (uint32_t)PRC_TYPE_CRV_PolyLine
- << false // base topology: no base information
- << (uint32_t)KEPRCExtendTypeNone // extend info
- << true // is 3d
- << false // no transformation
- << 0.0 << static_cast<double>(numberOfPoints-1) // parameterization interval
- << 1.0 // no reparameterization
- << 0.0 // no reparameterization
- << (uint32_t)numberOfPoints;
-
- // points
- for(uint32_t i = 0; i < numberOfPoints; ++i)
- out << points[i][0]*scale << points[i][1]*scale << points[i][2]*scale;
-
- // ending of wire edge
- out << false; // trim surface domain
-}
-
-void PRCline::writeExtraGeometryContext(PRCbitStream &out)
-{
- //geometry summary
- out << (uint32_t)1; // number of bodies
- out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody; // body's serial type
- //context graphics
- out << (uint32_t)0; // number of treat types
-}
-
-void PRCcurve::writeRepresentationItem(PRCbitStream &out,uint32_t index)
-{
- out << (uint32_t)(PRC_TYPE_RI_Curve);
- ContentPRCBase(&EMPTY_ATTRIBUTES,name,true,makeCADID(),0,makePRCID()).write(out);
- writeGraphics(out,m1,getGraphicsIndex(),1);
- out << (uint32_t)0 // index_local_coordinate_system+1
- << (uint32_t)0; // index_tessellation
-
- out << true // has wire body
- << (uint32_t)index+1 // index of context in geometry section
- << (uint32_t)1; // body index in topological context
- UserData(0,0).write(out);
-}
-
-void PRCcurve::writeTopologicalContext(PRCbitStream &out)
-{
- // topological context
- out << (uint32_t)(PRC_TYPE_TOPO_Context);
- EMPTY_CONTENTPRCBASE.write(out);
- out << (uint8_t)0 // behaviour
- << 0.0 // granularity
- << 0.0 // tolerance
- << false // have smallest face thickness
- << false; // have scale
-
- out << (uint32_t)1; // number of bodies
- // body
- out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody;
-
- out << false // base topology: no base information
- << (uint8_t)0; // content body: behaviour
- // Not sure what a 0 means, since it satisfies no #define,
- // but I think it means no bbox
-
- // wire edge
- out << false // not already stored
- << (uint32_t)PRC_TYPE_TOPO_WireEdge
- << false; // base topology: no base information
-
- // curve
- out << false // not already stored
- << (uint32_t)PRC_TYPE_CRV_NURBS
- << false // base topology: no base information
- << (uint32_t)KEPRCExtendTypeNone // extend info
- << true // is 3D
- << isRational
- << (uint32_t)degree // degree
- << (uint32_t)numberOfControlPoints-1 // control points - 1
- << (uint32_t)degree+numberOfControlPoints; // knots - 1
-
- // control points
- for(uint32_t i = 0; i < numberOfControlPoints; ++i)
- {
- double Scale=scale;
- if(isRational) Scale *= weights[i];
- out << controlPoints[i][0]*Scale << controlPoints[i][1]*Scale
- << controlPoints[i][2]*Scale;
- if(isRational)
- out << weights[i];
- }
-
- writeKnots(out);
-
- out << (uint32_t)KEPRCKnotTypeUnspecified // KEPRCKnotTypePiecewiseBezierKnots
- << (uint32_t)KEPRCBSplineCurveFormUnspecified; // curve form
-
- // ending of wire edge
- out << false; // trim surface domain
-
-}
-
-void PRCcurve::writeExtraGeometryContext(PRCbitStream &out)
-{
- //geometry summary
- out << (uint32_t)1; // number of bodies
- out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody; // body's serial type
- //context graphics
- out << (uint32_t)0; // number of treat types
-}
-
-void PRCsurface::writeRepresentationItem(PRCbitStream &out,uint32_t index)
-{
- out << (uint32_t)(PRC_TYPE_RI_BrepModel);
- ContentPRCBase(&EMPTY_ATTRIBUTES,name,true,makeCADID(),0,makePRCID()).write(out);
- writeGraphics(out,0,getGraphicsIndex(),1);
- out << (uint32_t)0 // index_local_coordinate_system+1
- << (uint32_t)0; // index_tessellation
-
- out << true // has brep data
- << (uint32_t)index+1 // index of context in geometry section
- << (uint32_t)1 // body index in topological context
- << false; // is closed???? when is it closed?
- UserData(0,0).write(out);
-}
-
-void PRCsurface::writeTopologicalContext(PRCbitStream &out)
-{
- // topological context
- out << (uint32_t)(PRC_TYPE_TOPO_Context);
- EMPTY_CONTENTPRCBASE.write(out);
- out << (uint8_t)0 // behaviour
- << granularity // granularity
- << 0.0 // tolerance
- << false // have smallest face thickness
- << false; // have scale
-
- out << (uint32_t)1; // number of bodies
- // body
- out << (uint32_t)PRC_TYPE_TOPO_BrepData;
-
- out << false // base topology: no base information
- << (uint8_t)0 // content body: behaviour. Not sure what a 0 means, since it satisfies no #define, but I think it means no bbox
- << (uint32_t)1; // number of connex
-
- // connex
- out << false // not already stored
- << (uint32_t)PRC_TYPE_TOPO_Connex
- << false // base topology: no base information
- << (uint32_t)1; // number of shells
-
- // shell
- out << false // not already stored
- << (uint32_t)PRC_TYPE_TOPO_Shell
- << false // base topology: no base information
- << false // shell is closed
- << (uint32_t)1; // number of faces
-
- // face
- out << false // not already stored
- << (uint32_t)PRC_TYPE_TOPO_Face
- << false; // base topology: no base information
-
- // NURBS
- out << false // not already stored
- << (uint32_t)PRC_TYPE_SURF_NURBS
- << false // base topology: no base information
- << (uint32_t)KEPRCExtendTypeNone // Extend Info
- << isRational // is rational
- << (uint32_t)degreeU // degree in u
- << (uint32_t)degreeV // degree in v
- << (uint32_t)numberOfControlPointsU-1 // control points in u - 1
- << (uint32_t)numberOfControlPointsV-1 // control points in v - 1
- << (uint32_t)degreeU+numberOfControlPointsU // knots in u - 1
- << (uint32_t)degreeV+numberOfControlPointsV; // knots in v -1
-
- // control points
- for(uint32_t i = 0; i < numberOfControlPointsU*numberOfControlPointsV; ++i)
- {
- double Scale=scale;
- if(isRational) Scale *= weights[i];
- out << controlPoints[i][0]*Scale << controlPoints[i][1]*Scale
- << controlPoints[i][2]*Scale;
- if(isRational)
- out << weights[i];
- }
-
- writeKnots(out);
-
- out << (uint32_t)KEPRCKnotTypeUnspecified // KEPRCKnotTypePiecewiseBezierKnots
- << (uint32_t)KEPRCBSplineSurfaceFormUnspecified; // surface form
-
- // ending of face
- out << false // trim surface domain
- << false // have tolerance
- << (uint32_t)0 // number of loops
- << (int32_t)-1; // outer loop index
-
- // ending of shell
- out << (uint8_t)1;
- // orientation of surface normal w.r.t. face normal:
- // 0: same, 1: opposite, 2: unknown, 1 used in example
-}
-
-void PRCsurface::writeExtraGeometryContext(PRCbitStream &out)
-{
- //geometry summary
- out << (uint32_t)1; // number of bodies
- out << (uint32_t)PRC_TYPE_TOPO_BrepData; // body's serial type
- //context graphics
- out << (uint32_t)0; // number of treat types
-}
-
-
-void PRCCompressedSection::write(std::ostream &out)
+void PRCCompressedSection::write(ostream &out)
{
if(prepared)
out.write((char*)data,getSize());
@@ -309,6 +78,7 @@ void PRCGlobalsSection::writeData()
// even though this is technically not part of this section,
// it is handled here for convenience
out << (uint32_t)(0); // number of schemas
+ uint32_t i=0; // universal index for PRC standard compatibility
out << (uint32_t)PRC_TYPE_ASM_FileStructureGlobals;
SingleAttributeData value = {PRCVersion};
@@ -322,29 +92,33 @@ void PRCGlobalsSection::writeData()
out << tessellationAngleDegrees;
out << defaultFontFamilyName; // markup serialization helper
- out << numberOfFonts
- << (uint32_t)parent->colourMap.size();
- for(std::vector<RGBAColour>::iterator i = parent->colourMap.begin(); i != parent->colourMap.end(); i++)
+ const uint32_t number_of_fonts = font_keys_of_font.size();
+ WriteUnsignedInteger (number_of_fonts)
+ for (i=0;i<number_of_fonts;i++)
{
- out << i->R << i->G << i->B;
+ SerializeFontKeysSameFont (font_keys_of_font[i])
}
- out << numberOfPictures << numberOfTextureDefinitions;
- out << (uint32_t)parent->materialMap.size(); // number of materials
- for(std::vector<PRCMaterial>::iterator i = parent->materialMap.begin(); i != parent->materialMap.end(); i++)
- {
- out << (uint32_t)PRC_TYPE_GRAPH_Material;
- ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
- out << 3*parent->getColourIndex(i->ambient)+1 // ambient + 1
- << 3*parent->getColourIndex(i->diffuse)+1 // diffuse + 1
- << 3*parent->getColourIndex(i->emissive)+1 // emissive + 1
- << 3*parent->getColourIndex(i->specular)+1 // specular + 1
- << i->shininess // shininess
- << i->ambient.A // ambient_alpha
- << i->diffuse.A // diffuse_alpha
- << i->emissive.A // emissive_alpha
- << i->specular.A; // specular_alpha
- }
+
+ const uint32_t number_of_colors = colors.size();
+ WriteUnsignedInteger (number_of_colors)
+ for (i=0;i<number_of_colors;i++)
+ SerializeRgbColor (colors[i])
+
+ const uint32_t number_of_pictures = pictures.size();
+ WriteUnsignedInteger (number_of_pictures)
+ for (i=0;i<number_of_pictures;i++)
+ SerializePicture (pictures[i])
+
+ const uint32_t number_of_texture_definitions = texture_definitions.size();
+ WriteUnsignedInteger (number_of_texture_definitions)
+ for (i=0;i<number_of_texture_definitions;i++)
+ SerializeTextureDefinition (texture_definitions[i])
+
+ const uint32_t number_of_materials = materials.size();
+ WriteUnsignedInteger (number_of_materials)
+ for (i=0;i<number_of_materials;i++)
+ SerializeMaterial (materials[i])
out << (uint32_t)1 // number of line patterns hard coded for now
<< (uint32_t)PRC_TYPE_GRAPH_LinePattern;
@@ -353,47 +127,18 @@ void PRCGlobalsSection::writeData()
<< 0.0 // phase
<< false; // is real length
- out << (uint32_t)(parent->colourMap.size()+parent->materialMap.size()); // number of styles
- uint32_t index = 0;
- // colours are written first
- for(std::vector<RGBAColour>::iterator i = parent->colourMap.begin(); i != parent->colourMap.end(); i++, ++index)
- {
- out << (uint32_t)PRC_TYPE_GRAPH_Style;
- ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
- out << 0.0 // line width in mm
- << false // is vpicture
- << (uint32_t)1 // line pattern index+1
- << false // is material
- << (uint32_t)(3*index+1); // 3*color_index+1
- if(i->A < 1.0)
- out << true << (uint8_t)(i->A * 256);
- else
- out << false;
- out << false // additional 1 not defined
- << false // additional 2 not defined
- << false; // additional 3 not defined
- }
- // materials are after colours
- index = 0;
- for(std::vector<PRCMaterial>::iterator i = parent->materialMap.begin(); i != parent->materialMap.end(); i++, ++index)
- {
- out << (uint32_t)PRC_TYPE_GRAPH_Style;
- ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
- out << 0.0 // line width in mm
- << false // is vpicture
- << (uint32_t)1 // line pattern index+1
- << true // is material
- << index+1; // material_index+1
- if(i->alpha < 1.0)
- out << true << (uint8_t)(i->alpha * 256);
- else
- out << false;
- out << false // additional 1 not defined
- << false // additional 2 not defined
- << false; // additional 3 not defined
- }
- out << numberOfFillPatterns
- << numberOfReferenceCoordinateSystems;
+ const uint32_t number_of_styles = styles.size();
+ WriteUnsignedInteger (number_of_styles)
+ for (i=0;i<number_of_styles;i++)
+ SerializeCategory1LineStyle (styles[i])
+
+ out << numberOfFillPatterns;
+
+ const uint32_t number_of_reference_coordinate_systems = reference_coordinate_systems.size();
+ WriteUnsignedInteger (number_of_reference_coordinate_systems)
+ for (i=0;i<number_of_reference_coordinate_systems;i++)
+ SerializeCoordinateSystem (reference_coordinate_systems[i])
+
userData.write(out);
}
@@ -403,68 +148,20 @@ void PRCTreeSection::writeData()
EMPTY_CONTENTPRCBASE.write(out);
- out << (uint32_t)1; // number of part definitions
- // part definitions
- out << (uint32_t)(PRC_TYPE_ASM_PartDefinition);
- ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
- writeGraphics(out,m1,m1,1,true);
- Point3d M=Point3d(1e20,1e20,1e20);
- Point3d m=Point3d(-1e20,-1e20,-1e20);
- Extent3d(M,m).write(out);
-
- out << (uint32_t)parent->fileEntities.size(); // number of representation items
- for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
+ uint32_t number_of_part_definitions = part_definitions.size();
+ WriteUnsignedInteger (number_of_part_definitions)
+ for (uint32_t i=0;i<number_of_part_definitions;i++)
+ SerializePartDefinition (part_definitions[i])
+
+ uint32_t number_of_product_occurrences = product_occurrences.size();
+ WriteUnsignedInteger (number_of_product_occurrences)
+ for (uint32_t i=0;i<number_of_product_occurrences;i++)
{
- parent->fileEntities[i]->writeRepresentationItem(out,i);
+ product_occurrences[i]->unit_information.unit_from_CAD_file = true;
+ product_occurrences[i]->unit_information.unit = unit;
+ SerializeProductOccurrence (product_occurrences[i])
}
- writeEmptyMarkups(out);
-
- out << (uint32_t)0; // no views
-
- UserData(0,0).write(out);
- out << (uint32_t)1; // number of product occurrences
- // only one product occurrence
- out << (uint32_t)(PRC_TYPE_ASM_ProductOccurence);
- SingleAttribute sas[3];
- SingleAttributeData sad;
- AttributeTitle at;
-
- at.text = "FilePath";
- sad.text = "file name not specified";
- sas[0] = SingleAttribute(false,at,KEPRCModellerAttributeTypeString,sad);
-
- at.text = "FileSize";
- sad.integer = 1234;
- sas[1] = SingleAttribute(false,at,KEPRCModellerAttributeTypeInt,sad);
-
- at.text = "FileModificationTime";
- sad.time = time(NULL);
- sas[2] = SingleAttribute(false,at,KEPRCModellerAttributeTypeInt,sad);
-
- at.text = "__PRC_RESERVED_ATTRIBUTE_A3DF_ProductInformation";
- Attribute attr(false,at,3,sas);
- Attributes attrs(1,&attr);
- ContentPRCBase(&attrs,"root",true,makeCADID(),0,makePRCID()).write(out);
-
- writeGraphics(out,m1,m1,1,true);
- out << (uint32_t)1 // index_part+1
- << (uint32_t)0 // index_prototype+1
- << (uint32_t)0 // index_external_data+1
- << (uint32_t)0 // number of son product occurrences
- << (uint8_t)0; // product behaviour
- writeUnit(out,true,10.0);
- out << (uint8_t)0 // product information flags
- << (uint32_t)KEPRCProductLoadStatus_Loaded; // product_load_status
- out << false // has location
- << (uint32_t)0; // number of references
- writeEmptyMarkups(out);
- out << (uint32_t)0 // number_of_views
- << false // has entity filter
- << (uint32_t)0 // number_of_display_filters
- << (uint32_t)0; // number_of_scene_display_parameters
- UserData(0,0).write(out);
-
// File Structure Internal Data
out << (uint32_t)(PRC_TYPE_ASM_FileStructure);
EMPTY_CONTENTPRCBASE.write(out);
@@ -479,34 +176,38 @@ void PRCTessellationSection::writeData()
out << (uint32_t)(PRC_TYPE_ASM_FileStructureTessellation);
EMPTY_CONTENTPRCBASE.write(out);
- out << (uint32_t)0; // number of tessellations
+ const uint32_t number_of_tessellations = tessellations.size();
+ WriteUnsignedInteger (number_of_tessellations)
+ for (uint32_t i=0;i<number_of_tessellations;i++)
+ tessellations[i]->serializeBaseTessData(out);
UserData(0,0).write(out); // no user data
}
void PRCGeometrySection::writeData()
{
- out << (uint32_t)(PRC_TYPE_ASM_FileStructureGeometry);
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry)
EMPTY_CONTENTPRCBASE.write(out);
- out << (uint32_t)parent->fileEntities.size(); // number of topological contexts
- for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
- {
- parent->fileEntities[i]->writeTopologicalContext(out);
- }
+ const uint32_t number_of_contexts = fileStructure->contexts.size();
+ WriteUnsignedInteger (number_of_contexts)
+ for (uint32_t i=0;i<number_of_contexts;i++)
+ SerializeContextAndBodies (contexts[i])
UserData(0,0).write(out);
}
void PRCExtraGeometrySection::writeData()
{
- out << (uint32_t)(PRC_TYPE_ASM_FileStructureExtraGeometry);
+ WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureExtraGeometry)
EMPTY_CONTENTPRCBASE.write(out);
- out << (uint32_t)parent->fileEntities.size(); // number of contexts
- for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
- {
- parent->fileEntities[i]->writeExtraGeometryContext(out);
- }
+ const uint32_t number_of_contexts = fileStructure->contexts.size();
+ WriteUnsignedInteger (number_of_contexts)
+ for (uint32_t i=0;i<number_of_contexts;i++)
+ {
+ SerializeGeometrySummary (contexts[i])
+ SerializeContextGraphics (contexts[i])
+ }
UserData(0,0).write(out);
}
@@ -525,7 +226,7 @@ void PRCModelFile::writeData()
Attributes as(1,&a);
ContentPRCBase(&as,"PRC file").write(out);
- writeUnit(out,true,10); // unit is 10 mm, and happens to come from a CAD file
+ writeUnit(out,true,unit); // unit is specified, and happens to come from a CAD file
out << (uint32_t)1; // 1 product occurrence
//UUID
@@ -534,7 +235,7 @@ void PRCModelFile::writeData()
<< parent->fileStructures[0]->header.fileStructureUUID[2]
<< parent->fileStructures[0]->header.fileStructureUUID[3];
// index+1
- out << (uint32_t)1;
+ out << (uint32_t)parent->fileStructures[0]->tree.product_occurrences.size();
// active
out << true;
out << (uint32_t)0; // index in model file
@@ -562,7 +263,7 @@ void makeAppUUID(uint32_t *UUID)
UUID[0] = UUID[1] = UUID[2] = UUID[3] = 0;
}
-void writeUINT32_T(std::ostream &out, uint32_t data)
+void writeUINT32_T(ostream &out, uint32_t data)
{
#ifdef WORDS_BIGENDIAN
out.write(((char*)&data)+3,1);
@@ -577,10 +278,13 @@ void writeUINT32_T(std::ostream &out, uint32_t data)
#endif
}
-void PRCUncompressedFile::write(std::ostream &out)
+void PRCUncompressedFile::write(ostream &out)
{
- writeUINT32_T(out,file_size);
- out.write((char*)data,file_size);
+ if(data!=NULL)
+ {
+ writeUINT32_T(out,file_size);
+ out.write((char*)data,file_size);
+ }
}
uint32_t PRCUncompressedFile::getSize()
@@ -589,7 +293,7 @@ uint32_t PRCUncompressedFile::getSize()
}
-void PRCStartHeader::write(std::ostream &out)
+void PRCStartHeader::write(ostream &out)
{
out.write("PRC",3);
writeUINT32_T(out,minimal_version_for_read);
@@ -611,14 +315,13 @@ uint32_t PRCStartHeader::getSize()
}
-void PRCFileStructure::write(std::ostream &out)
+void PRCFileStructure::write(ostream &out)
{
header.write(out);
+ uint32_t number_of_uncompressed_files = uncompressedFiles.size();
writeUINT32_T(out,number_of_uncompressed_files);
- for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
- {
- uncompressedFiles[i].write(out);
- }
+ for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
+ i->write(out);
globals.write(out);
tree.write(out);
tessellations.write(out);
@@ -649,8 +352,8 @@ uint32_t PRCFileStructure::getSize()
uint32_t size = 0;
size += header.getSize();
size += sizeof(uint32_t);
- for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
- size += uncompressedFiles[i].getSize();
+ for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
+ size += i->getSize();
size += globals.getSize();
size += tree.getSize();
size += tessellations.getSize();
@@ -660,7 +363,7 @@ uint32_t PRCFileStructure::getSize()
}
-void PRCFileStructureInformation::write(std::ostream &out)
+void PRCFileStructureInformation::write(ostream &out)
{
writeUINT32_T(out,UUID[0]);
writeUINT32_T(out,UUID[1]);
@@ -680,7 +383,7 @@ uint32_t PRCFileStructureInformation::getSize()
return (4+2+number_of_offsets)*sizeof(uint32_t);
}
-void PRCHeader::write(std::ostream &out)
+void PRCHeader::write(ostream &out)
{
startHeader.write(out);
writeUINT32_T(out,number_of_file_structures);
@@ -690,11 +393,10 @@ void PRCHeader::write(std::ostream &out)
}
writeUINT32_T(out,model_file_offset);
writeUINT32_T(out,file_size);
+ uint32_t number_of_uncompressed_files = uncompressedFiles.size();
writeUINT32_T(out,number_of_uncompressed_files);
- for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
- {
- uncompressedFiles[i].write(out);
- }
+ for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
+ i->write(out);
}
uint32_t PRCHeader::getSize()
@@ -703,53 +405,361 @@ uint32_t PRCHeader::getSize()
for(uint32_t i = 0; i < number_of_file_structures; ++i)
size += fileStructureInformation[i].getSize();
size += 3*sizeof(uint32_t);
- for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
- size += uncompressedFiles[i].getSize();
+ for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
+ size += i->getSize();
return size;
}
-bool oPRCFile::add(PRCentity *p)
+void oPRCFile::doGroup(const PRCgroup& group, PRCPartDefinition *parent_part_definition, PRCProductOccurrence *parent_product_occurrence)
{
- fileEntities.push_back(p);
- if(p->useMaterial)
- {
- if(getMaterialIndex(p->material) == m1)
+ const string& name = group.name;
+
+ PRCPartDefinition *part_definition = new PRCPartDefinition;
+
+ if(group.options.tess)
+ {
+ if(!group.lines.empty())
+ {
+ bool same_color = true;
+ const PRCRgbColor &color = group.lines.front().color;
+ for(PRCtesslineList::const_iterator lit=group.lines.begin(); lit!=group.lines.end(); lit++)
+ if(color!=lit->color)
+ {
+ same_color = false;
+ break;
+ }
+ map<PRCVector3d,uint32_t> points;
+ PRC3DWireTess *tess = new PRC3DWireTess();
+ if(!same_color)
+ {
+ tess->is_segment_color = true;
+ tess->is_rgba = false;
+ }
+ for(PRCtesslineList::const_iterator lit=group.lines.begin(); lit!=group.lines.end(); lit++)
+ {
+ tess->wire_indexes.push_back(lit->point.size());
+ for(uint32_t i=0; i<lit->point.size(); i++)
+ {
+ map<PRCVector3d,uint32_t>::iterator pPoint = points.find(lit->point[i]);
+ if(pPoint!=points.end())
+ tess->wire_indexes.push_back(pPoint->second);
+ else
+ {
+ uint32_t point_index = m1;
+ points.insert(make_pair(lit->point[i],(point_index = tess->coordinates.size())));
+ tess->wire_indexes.push_back(point_index);
+ tess->coordinates.push_back(lit->point[i].x);
+ tess->coordinates.push_back(lit->point[i].y);
+ tess->coordinates.push_back(lit->point[i].z);
+ }
+ if(!same_color && i>0)
+ {
+ tess->rgba_vertices.push_back((uint8_t)(255*lit->color.red));
+ tess->rgba_vertices.push_back((uint8_t)(255*lit->color.green));
+ tess->rgba_vertices.push_back((uint8_t)(255*lit->color.blue));
+ }
+ }
+ }
+ const uint32_t tess_index = add3DWireTess(tess);
+ PRCPolyWire *polyWire = new PRCPolyWire();
+ polyWire->index_tessellation = tess_index;
+ if(same_color)
+ polyWire->index_of_line_style = addColour(RGBAColour(color.red,color.green,color.blue));
+ part_definition->addPolyWire(polyWire);
+ }
+// make rectangles pairs of triangles in a tesselation
+ if(!group.rectangles.empty())
+ {
+ bool same_color = true;
+ const uint32_t &style = group.rectangles.front().style;
+ for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+ if(style!=rit->style)
+ {
+ same_color = false;
+ break;
+ }
+ map<PRCVector3d,uint32_t> points;
+ PRC3DTess *tess = new PRC3DTess();
+ PRCTessFace *tessFace = new PRCTessFace();
+ tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+ uint32_t triangles = 0;
+ for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+ {
+ const bool degenerate = (rit->vertices[0]==rit->vertices[1]);
+ uint32_t vertex_indices[4];
+ for(size_t i = (degenerate?1:0); i < 4; ++i)
+ {
+ map<PRCVector3d,uint32_t>::iterator pPoint = points.find(rit->vertices[i]);
+ if(pPoint!=points.end())
+ vertex_indices[i] = pPoint->second;
+ else
+ {
+ points.insert(make_pair(rit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+ tess->coordinates.push_back(rit->vertices[i].x);
+ tess->coordinates.push_back(rit->vertices[i].y);
+ tess->coordinates.push_back(rit->vertices[i].z);
+ }
+ }
+ if(degenerate)
+ {
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ }
+ else
+ {
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ tess->triangulated_index.push_back(vertex_indices[2]);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ tess->triangulated_index.push_back(vertex_indices[3]);
+ tess->triangulated_index.push_back(vertex_indices[1]);
+ tess->triangulated_index.push_back(vertex_indices[0]);
+ triangles++;
+ if(!same_color)
+ tessFace->line_attributes.push_back(rit->style);
+ }
+ }
+ tessFace->sizes_triangulated.push_back(triangles);
+ tess->addTessFace(tessFace);
+ const uint32_t tess_index = add3DTess(tess);
+ PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+ polyBrepModel->index_tessellation = tess_index;
+ polyBrepModel->is_closed = group.options.closed;
+ if(same_color)
+ polyBrepModel->index_of_line_style = style;
+ part_definition->addPolyBrepModel(polyBrepModel);
+ }
+ }
+
+ if(!group.points.empty())
+ {
+ for(PRCpointsetMap::const_iterator pit=group.points.begin(); pit!=group.points.end(); pit++)
+ {
+ PRCPointSet *pointset = new PRCPointSet();
+ pointset->index_of_line_style = pit->first;
+ pointset->point = pit->second;
+ part_definition->addPointSet(pointset);
+ }
+ }
+
+ if(!group.wires.empty())
{
- materialMap.push_back(p->material);
+ PRCTopoContext *wireContext = new PRCTopoContext;
+ uint32_t context_index = addTopoContext(wireContext);
+ for(PRCwireList::const_iterator wit=group.wires.begin(); wit!=group.wires.end(); wit++)
+ {
+ PRCSingleWireBody *wireBody = new PRCSingleWireBody;
+ const uint32_t wire_body_index = wireContext->addSingleWireBody(wireBody);
+ PRCWireEdge *wireEdge = new PRCWireEdge;
+ wireBody->setWireEdge(wireEdge);
+ wireEdge->setCurve(wit->curve);
+ PRCWire *wire = new PRCWire();
+ wire->index_of_line_style = wit->style;
+ wire->context_id = context_index;
+ wire->body_id = wire_body_index;
+ if(wit->transform)
+ wire->index_local_coordinate_system = addTransform(wit->transform);
+ part_definition->addWire(wire);
+ }
+ }
- if(getColourIndex(p->material.ambient) == m1)
- colourMap.push_back(p->material.ambient);
+ const PRCfaceList &faces = group.faces;
+ if(!faces.empty())
+ {
+ bool same_color = true;
+ uint32_t style = faces.front().style;
+ for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++)
+ if(style!=fit->style)
+ {
+ same_color = false;
+ break;
+ }
+ PRCTopoContext *context = new PRCTopoContext;
+ context->granularity = group.options.granularity;
+ const uint32_t context_index = addTopoContext(context);
+ PRCShell *shell = new PRCShell;
+
+ for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++)
+ {
+ if(fit->transform || group.options.do_break ||
+ (fit->transparent && !group.options.no_break))
+ {
+ PRCBrepData *body = new PRCBrepData;
+ const uint32_t body_index = context->addBrepData(body);
+ PRCConnex *connex = new PRCConnex;
+ body->addConnex(connex);
+ PRCShell *shell = new PRCShell;
+ connex->addShell(shell);
+ shell->addFace(fit->face);
+
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ brepmodel->index_of_line_style = fit->style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+
+ brepmodel->index_local_coordinate_system = addTransform(fit->transform);
+
+ part_definition->addBrepModel(brepmodel);
+ }
+ else
+ {
+ if(!same_color)
+ fit->face->index_of_line_style = fit->style;
+ shell->addFace(fit->face);
+ }
+ }
+ if(shell->face.empty())
+ {
+ delete shell;
+ }
+ else
+ {
+ PRCBrepData *body = new PRCBrepData;
+ const uint32_t body_index = context->addBrepData(body);
+ PRCConnex *connex = new PRCConnex;
+ body->addConnex(connex);
+ connex->addShell(shell);
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ if(same_color)
+ brepmodel->index_of_line_style = style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+ part_definition->addBrepModel(brepmodel);
+ }
+ }
- if(getColourIndex(p->material.diffuse) == m1)
- colourMap.push_back(p->material.diffuse);
+ const PRCcompfaceList &compfaces = group.compfaces;
+ if(!compfaces.empty())
+ {
+ bool same_color = true;
+ uint32_t style = compfaces.front().style;
+ for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+ if(style!=fit->style)
+ {
+ same_color = false;
+ break;
+ }
+ PRCTopoContext *context = new PRCTopoContext;
+ context->granularity = group.options.granularity;
+ const uint32_t context_index = addTopoContext(context);
+ PRCCompressedBrepData *body = new PRCCompressedBrepData;
+
+ body->serial_tolerance=group.options.compression;
+ body->brep_data_compressed_tolerance=0.1*group.options.compression;
+
+ for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+ {
+ if(group.options.do_break ||
+ (fit->transparent && !group.options.no_break))
+ {
+ PRCCompressedBrepData *body = new PRCCompressedBrepData;
+ const uint32_t body_index = context->addCompressedBrepData(body);
+ body->face.push_back(fit->face);
+
+ body->serial_tolerance=group.options.compression;
+ body->brep_data_compressed_tolerance=2.8346456*
+ group.options.compression;
+
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ brepmodel->index_of_line_style = fit->style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+
+ part_definition->addBrepModel(brepmodel);
+ }
+ else
+ {
+ if(!same_color)
+ fit->face->index_of_line_style = fit->style;
+ body->face.push_back(fit->face);
+ }
+ }
+ if(body->face.empty())
+ {
+ delete body;
+ }
+ else
+ {
+ const uint32_t body_index = context->addCompressedBrepData(body);
+ PRCBrepModel *brepmodel = new PRCBrepModel();
+ if(same_color)
+ brepmodel->index_of_line_style = style;
+ brepmodel->context_id = context_index;
+ brepmodel->body_id = body_index;
+ brepmodel->is_closed = group.options.closed;
+ part_definition->addBrepModel(brepmodel);
+ }
+ }
- if(getColourIndex(p->material.emissive) == m1)
- colourMap.push_back(p->material.emissive);
+ PRCProductOccurrence *product_occurrence = new PRCProductOccurrence(name);
- if(getColourIndex(p->material.specular) == m1)
- colourMap.push_back(p->material.specular);
+ for(PRCgroupList::const_iterator it=group.groupList.begin(); it!=group.groupList.end(); it++)
+ {
+ doGroup(*it, part_definition, product_occurrence);
}
- }
- else
- {
- if(getColourIndex(p->colour) == m1)
+
+ // Simplify and reduce to as simple entities as possible
+ // First option - reduce to one element in parent
+ if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+ part_definition->representation_item.size() == 1 &&
+ ( name.empty() || part_definition->representation_item.front()->name.empty() ) &&
+ ( !group.transform || part_definition->representation_item.front()->index_local_coordinate_system==m1) )
{
- colourMap.push_back(p->colour);
+ if(part_definition->representation_item.front()->name.empty() )
+ part_definition->representation_item.front()->name = name;
+ if(part_definition->representation_item.front()->index_local_coordinate_system==m1)
+ part_definition->representation_item.front()->index_local_coordinate_system = addTransform(group.transform);
+ parent_part_definition->addRepresentationItem(part_definition->representation_item.front());
+ delete product_occurrence;
+ delete part_definition;
}
- }
- return true;
+ // Second option - reduce to a set
+ else if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+ !part_definition->representation_item.empty() &&
+ !group.options.do_break )
+ {
+ PRCSet *set = new PRCSet(name);
+ set->index_local_coordinate_system = addTransform(group.transform);
+ for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+ set->addRepresentationItem(*it);
+ parent_part_definition->addSet(set);
+ delete product_occurrence;
+ delete part_definition;
+ }
+ // Third option - create product
+ else
+ {
+ if (part_definition->representation_item.empty())
+ delete part_definition;
+ else
+ product_occurrence->index_part = addPartDefinition(part_definition);
+ if (group.transform) {
+ product_occurrence->location = group.transform;
+ product_occurrence->has_location = true;
+ }
+ if (parent_product_occurrence) {
+ parent_product_occurrence->index_son_occurrence.push_back(addProductOccurrence(product_occurrence));
+ }
+ else {
+ addProductOccurrence(product_occurrence);
+ }
+ }
+
}
bool oPRCFile::finish()
{
- // only one file structure is currently used
- // prepare data
- fileStructures[0] = new PRCFileStructure(this,0);
- fileStructures[0]->header.minimal_version_for_read = PRCVersion;
- fileStructures[0]->header.authoring_version = PRCVersion;
- makeFileUUID(fileStructures[0]->header.fileStructureUUID);
- makeAppUUID(fileStructures[0]->header.applicationUUID);
- fileStructures[0]->number_of_uncompressed_files = 0;
+ rootGroup.name = "root";
+ doGroup(rootGroup, NULL, NULL);
// write each section's bit data
fileStructures[0]->prepare();
@@ -758,7 +768,6 @@ bool oPRCFile::finish()
// create the header
// fill out enough info so that sizes can be computed correctly
- header.number_of_uncompressed_files = 0;
header.number_of_file_structures = number_of_file_structures;
header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures];
for(uint32_t i = 0; i < number_of_file_structures; ++i)
@@ -786,8 +795,8 @@ bool oPRCFile::finish()
{
header.fileStructureInformation[i].offsets[0] = currentOffset; // header offset
currentOffset += fileStructures[i]->header.getSize() + sizeof(uint32_t);
- for(uint32_t j = 0; j < fileStructures[i]->number_of_uncompressed_files; ++j)
- currentOffset += fileStructures[i]->uncompressedFiles[j].getSize();
+ for(list<PRCUncompressedFile>::iterator j = fileStructures[i]->uncompressedFiles.begin(); j != fileStructures[i]->uncompressedFiles.end(); j++)
+ currentOffset += j->getSize();
header.fileStructureInformation[i].offsets[1] = currentOffset; // globals offset
currentOffset += fileStructures[i]->globals.getSize();
header.fileStructureInformation[i].offsets[2] = currentOffset; // tree offset
@@ -818,35 +827,695 @@ bool oPRCFile::finish()
return true;
}
-uint32_t oPRCFile::getColourIndex(const RGBAColour &c)
+uint32_t oPRCFile::getSize()
{
- for(uint32_t i = 0; i < colourMap.size(); ++i)
+ uint32_t size = header.getSize();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
{
- if(colourMap[i] == c)
- return i;
+ size += fileStructures[i]->getSize();
}
- return m1;
+
+ size += modelFile.getSize();
+ return size;
}
-uint32_t oPRCFile::getMaterialIndex(const PRCMaterial &m)
+#define REPORT_ERROR( value ) { cerr << value << endl; return m1; }
+
+uint32_t PRCFileStructure::addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *p, uint32_t width, uint32_t height, string name)
{
- for(uint32_t i = 0; i < materialMap.size(); ++i)
+ if(size==0 || p==NULL)
+ REPORT_ERROR( "image not set" )
+ PRCPicture picture(name);
+ PRCUncompressedFile uncompressedFile;
+ uint32_t components=0;
+ uint8_t *data = NULL;
+ switch(format)
{
- if(materialMap[i] == m)
- return i;
+ case KEPRCPicture_BITMAP_RGB_BYTE:
+ components = 3;
+ case KEPRCPicture_BITMAP_RGBA_BYTE:
+ components = 4;
+ case KEPRCPicture_BITMAP_GREY_BYTE:
+ components = 1;
+ case KEPRCPicture_BITMAP_GREYA_BYTE:
+ components = 2;
+ if(width==0 || height==0)
+ REPORT_ERROR( "width or height parameter not set" )
+ if (size < width*height*components)
+ REPORT_ERROR( "image too small" )
+
+ {
+ uint32_t compressedDataSize = 0;
+ const int CHUNK= 1024; // is this reasonable?
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+ REPORT_ERROR ( "Compression initialization failed" )
+ unsigned int sizeAvailable = deflateBound(&strm,size);
+ uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+ strm.avail_in = size;
+ strm.next_in = (unsigned char*)p;
+ strm.next_out = (unsigned char*)compressedData;
+ strm.avail_out = sizeAvailable;
+
+ int code;
+ unsigned int chunks = 0;
+ while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+ {
+ ++chunks;
+ // strm.avail_out should be 0 if we got Z_OK
+ compressedDataSize = sizeAvailable - strm.avail_out;
+ compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+ strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+ strm.avail_out += CHUNK;
+ sizeAvailable += CHUNK;
+ }
+ compressedDataSize = sizeAvailable-strm.avail_out;
+
+ if(code != Z_STREAM_END)
+ {
+ deflateEnd(&strm);
+ free(compressedData);
+ REPORT_ERROR ( "Compression error" )
+ }
+
+ deflateEnd(&strm);
+ size = compressedDataSize;
+ data = new uint8_t[compressedDataSize];
+ memcpy(data, compressedData, compressedDataSize);
+ free(compressedData);
+ }
+ uncompressedFiles.push_back(uncompressedFile);
+ uncompressedFiles.back().file_size = size;
+ uncompressedFiles.back().data = data;
+ picture.format = format;
+ picture.uncompressed_file_index = uncompressedFiles.size()-1;
+ picture.pixel_width = width;
+ picture.pixel_height = height;
+ globals.pictures.push_back(picture);
+ return globals.pictures.size()-1;
+ break;
+
+ case KEPRCPicture_PNG:
+ case KEPRCPicture_JPG:
+ data = new uint8_t[size];
+ memcpy(data, p, size);
+ uncompressedFiles.push_back(uncompressedFile);
+ uncompressedFiles.back().file_size = size;
+ uncompressedFiles.back().data = data;
+ picture.format = format;
+ picture.uncompressed_file_index = uncompressedFiles.size()-1;
+ picture.pixel_width = 0; // width and height are ignored for JPG and PNG pictures - but let us keep things clean
+ picture.pixel_height = 0;
+ globals.pictures.push_back(picture);
+ return globals.pictures.size()-1;
+ break;
+
+ default:
+ REPORT_ERROR( "unknown picture format" )
}
return m1;
}
+#undef REPORT_ERROR
-uint32_t oPRCFile::getSize()
+uint32_t PRCFileStructure::addTextureDefinition(PRCTextureDefinition *pTextureDefinition)
{
- uint32_t size = header.getSize();
+ globals.texture_definitions.push_back(PRCpTextureDefinition(pTextureDefinition));
+ return globals.texture_definitions.size()-1;
+}
- for(uint32_t i = 0; i < number_of_file_structures; ++i)
+uint32_t PRCFileStructure::addRgbColor(const PRCRgbColor &color)
+{
+ globals.colors.push_back(color);
+ return 3*(globals.colors.size()-1);
+}
+
+uint32_t PRCFileStructure::addRgbColorUnique(const PRCRgbColor &color)
+{
+ for(uint32_t i = 0; i < globals.colors.size(); ++i)
{
- size += fileStructures[i]->getSize();
+ if(globals.colors[i] == color)
+ return 3*i;
}
+ globals.colors.push_back(color);
+ return 3*(globals.colors.size()-1);
+}
- size += modelFile.getSize();
- return size;
+uint32_t oPRCFile::addColor(const PRCRgbColor &color)
+{
+ PRCcolorMap::iterator pColor = colorMap.find(color);
+ uint32_t color_index = m1;
+ if(pColor!=colorMap.end())
+ return pColor->second;
+// color_index = addRgbColorUnique(color);
+ color_index = fileStructures[0]->addRgbColor(color);
+ colorMap.insert(make_pair(color,color_index));
+ return color_index;
+}
+
+uint32_t oPRCFile::addColour(const RGBAColour &colour)
+{
+ PRCcolourMap::iterator pColour = colourMap.find(colour);
+ if(pColour!=colourMap.end())
+ return pColour->second;
+ const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+ PRCStyle *style = new PRCStyle();
+ style->line_width = 1.0;
+ style->is_vpicture = false;
+ style->line_pattern_vpicture_index = 0;
+ style->is_material = false;
+ style->color_material_index = color_index;
+ style->is_transparency_defined = (colour.A < 1.0);
+ style->transparency = (uint8_t)(colour.A * 256);
+ style->additional = 0;
+ const uint32_t style_index = fileStructures[0]->addStyle(style);
+ colourMap.insert(make_pair(colour,style_index));
+ return style_index;
+}
+
+uint32_t oPRCFile::addTransform(const PRCpGeneralTransformation3d &transform)
+{
+ if(!transform)
+ return m1;
+ PRCtransformMap::iterator pTransform = transformMap.find(*transform);
+ if(pTransform!=transformMap.end())
+ return pTransform->second;
+ PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+ coordinateSystem->axis_set = transform;
+ const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+ transformMap.insert(make_pair(*transform,coordinate_system_index));
+ return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addMaterial(const PRCmaterial &material)
+{
+ PRCmaterialMap::iterator pMaterial = materialMap.find(material);
+ if(pMaterial!=materialMap.end())
+ return pMaterial->second;
+ PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric();
+ const PRCRgbColor ambient(material.ambient.R, material.ambient.G, material.ambient.B);
+ materialGeneric->ambient = addColor(ambient);
+ const PRCRgbColor diffuse(material.diffuse.R, material.diffuse.G, material.diffuse.B);
+ materialGeneric->diffuse = addColor(diffuse);
+ const PRCRgbColor emissive(material.emissive.R, material.emissive.G, material.emissive.B);
+ materialGeneric->emissive = addColor(emissive);
+ const PRCRgbColor specular(material.specular.R, material.specular.G, material.specular.B);
+ materialGeneric->specular = addColor(specular);
+ materialGeneric->shininess = material.shininess;
+ materialGeneric->ambient_alpha = material.ambient.A;
+ materialGeneric->diffuse_alpha = material.diffuse.A;
+ materialGeneric->emissive_alpha = material.emissive.A;
+ materialGeneric->specular_alpha = material.specular.A;
+ const uint32_t material_index = fileStructures[0]->addMaterialGeneric(materialGeneric);
+ PRCStyle *style = new PRCStyle();
+ style->line_width = 0.0;
+ style->is_vpicture = false;
+ style->line_pattern_vpicture_index = 0;
+ style->is_material = true;
+ style->color_material_index = material_index;
+ style->is_transparency_defined = (material.alpha < 1.0);
+ style->transparency = (uint8_t)(material.alpha * 256);
+ style->additional = 0;
+ const uint32_t style_index = fileStructures[0]->addStyle(style);
+ materialMap.insert(make_pair(material,style_index)).first;
+ return style_index;
+}
+
+bool isid(const double t[][4])
+{
+ return(
+ t[0][0]==1 && t[0][1]==0 && t[0][2]==0 && t[0][3]==0 &&
+ t[1][0]==0 && t[1][1]==1 && t[1][2]==0 && t[1][3]==0 &&
+ t[2][0]==0 && t[2][1]==0 && t[2][2]==1 && t[2][3]==0 &&
+ t[3][0]==0 && t[3][1]==0 && t[3][2]==0 && t[3][3]==1 );
+}
+
+void oPRCFile::begingroup(const char *name, PRCoptions *options,
+ const double t[][4])
+{
+ if(currentGroups.empty())
+ currentGroups.push(rootGroup.groupList.insert(rootGroup.groupList.end(),PRCgroup()));
+ else
+ currentGroups.push(currentGroups.top()->groupList.insert(currentGroups.top()->groupList.end(),PRCgroup()));
+ PRCgroup &group = *(currentGroups.top());
+ group.name=name;
+ if(options) group.options=*options;
+ if(t&&!isid(t))
+ group.transform.reset(new PRCGeneralTransformation3d(t));
+}
+
+void oPRCFile::endgroup()
+{
+ if(!currentGroups.empty())
+ currentGroups.pop();
+}
+
+PRCgroup& oPRCFile::findGroup()
+{
+ if(!currentGroups.empty())
+ return *(currentGroups.top());
+ else
+ return rootGroup;
+}
+
+#define ADDWIRE(curvtype) \
+ PRCgroup &group = findGroup(); \
+ group.wires.push_back(PRCwire()); \
+ PRCwire &wire = group.wires.back(); \
+ curvtype *curve = new curvtype; \
+ wire.curve.reset(curve); \
+ wire.style = addColour(c);
+
+#define ADDFACE(surftype) \
+ PRCgroup &group = findGroup(); \
+ group.faces.push_back(PRCface()); \
+ PRCface& face = group.faces.back(); \
+ surftype *surface = new surftype; \
+ face.face.reset(new PRCFace); \
+ face.face->setSurface(surface); \
+ face.transparent = m.alpha < 1.0; \
+ face.style = addMaterial(m);
+
+#define ADDCOMPFACE \
+ PRCgroup &group = findGroup(); \
+ group.compfaces.push_back(PRCcompface()); \
+ PRCcompface& face = group.compfaces.back(); \
+ PRCCompressedFace *compface = new PRCCompressedFace; \
+ face.face.reset(compface); \
+ face.transparent = m.alpha < 1.0; \
+ face.style = addMaterial(m);
+
+void oPRCFile::addPoint(const double P[3], const RGBAColour &c)
+{
+ PRCgroup &group = findGroup();
+ group.points[addColour(c)].push_back(PRCVector3d(P[0],P[1],P[2]));
+}
+
+void oPRCFile::addLine(uint32_t n, const double P[][3], const RGBAColour &c)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.tess)
+ {
+ group.lines.push_back(PRCtessline());
+ group.lines.back().color.red = c.R;
+ group.lines.back().color.green = c.G;
+ group.lines.back().color.blue = c.B;
+ for(uint32_t i=0; i<n; i++)
+ group.lines.back().point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
+ }
+ else
+ {
+ ADDWIRE(PRCPolyLine)
+ curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ curve->point[i].Set(P[i][0],P[i][1],P[i][2]);
+ curve->interval.min = 0;
+ curve->interval.max = curve->point.size()-1;
+ }
+}
+
+void oPRCFile::addBezierCurve(uint32_t n, const double cP[][3],
+ const RGBAColour &c)
+{
+ ADDWIRE(PRCNURBSCurve)
+ curve->is_rational = false;
+ curve->degree = 3;
+ const size_t NUMBER_OF_POINTS = n;
+ curve->control_point.resize(NUMBER_OF_POINTS);
+ for(size_t i = 0; i < NUMBER_OF_POINTS; ++i)
+ curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+ curve->knot.resize(3+NUMBER_OF_POINTS+1);
+ curve->knot[0] = 1;
+ for(size_t i = 1; i < 3+NUMBER_OF_POINTS; ++i)
+ curve->knot[i] = (i+2)/3; // integer division is intentional
+ curve->knot[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3;
+}
+
+void oPRCFile::addCurve(uint32_t d, uint32_t n, const double cP[][3], const double *k, const RGBAColour &c, const double w[])
+{
+ ADDWIRE(PRCNURBSCurve)
+ curve->is_rational = w;
+ curve->degree = d;
+ curve->control_point.resize(n);
+ for(uint32_t i = 0; i < n; i++)
+ if(w)
+ curve->control_point[i].Set(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]);
+ else
+ curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+ curve->knot.resize(d+n+1);
+ for(uint32_t i = 0; i < d+n+1; i++)
+ curve->knot[i] = k[i];
+}
+
+void oPRCFile::addRectangle(const double P[][3], const PRCmaterial &m)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.tess)
+ {
+ PRCgroup &group = findGroup();
+ group.rectangles.push_back(PRCtessrectangle());
+ PRCtessrectangle &rectangle = group.rectangles.back();
+ rectangle.style = addMaterial(m);
+ for(size_t i = 0; i < 4; i++)
+ {
+ rectangle.vertices[i].x = P[i][0];
+ rectangle.vertices[i].y = P[i][1];
+ rectangle.vertices[i].z = P[i][2];
+ }
+ }
+ else if(group.options.compression == 0.0)
+ {
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = false;
+ surface->degree_in_u = 1;
+ surface->degree_in_v = 1;
+ surface->control_point.resize(4);
+ for(size_t i = 0; i < 4; ++i)
+ {
+ surface->control_point[i].x = P[i][0];
+ surface->control_point[i].y = P[i][1];
+ surface->control_point[i].z = P[i][2];
+ }
+ surface->knot_u.resize(4);
+ surface->knot_v.resize(4);
+ surface->knot_v[0] = surface->knot_u[0] = 1;
+ surface->knot_v[1] = surface->knot_u[1] = 3;
+ surface->knot_v[2] = surface->knot_u[2] = 4;
+ surface->knot_v[3] = surface->knot_u[3] = 4;
+ }
+ else
+ {
+ ADDCOMPFACE
+
+ compface->degree = 1;
+ compface->control_point.resize(4);
+ for(size_t i = 0; i < 4; ++i)
+ {
+ compface->control_point[i].x = P[i][0];
+ compface->control_point[i].y = P[i][1];
+ compface->control_point[i].z = P[i][2];
+ }
+ }
+}
+
+void oPRCFile::addPatch(const double cP[][3], const PRCmaterial &m)
+{
+ PRCgroup &group = findGroup();
+ if(group.options.compression == 0.0)
+ {
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = false;
+ surface->degree_in_u = 3;
+ surface->degree_in_v = 3;
+ surface->control_point.resize(16);
+ for(size_t i = 0; i < 16; ++i)
+ {
+ surface->control_point[i].x = cP[i][0];
+ surface->control_point[i].y = cP[i][1];
+ surface->control_point[i].z = cP[i][2];
+ }
+ surface->knot_u.resize(8);
+ surface->knot_v.resize(8);
+ surface->knot_v[0] = surface->knot_u[0] = 1;
+ surface->knot_v[1] = surface->knot_u[1] = 1;
+ surface->knot_v[2] = surface->knot_u[2] = 1;
+ surface->knot_v[3] = surface->knot_u[3] = 1;
+ surface->knot_v[4] = surface->knot_u[4] = 2;
+ surface->knot_v[5] = surface->knot_u[5] = 2;
+ surface->knot_v[6] = surface->knot_u[6] = 2;
+ surface->knot_v[7] = surface->knot_u[7] = 2;
+ }
+ else
+ {
+ ADDCOMPFACE
+
+ compface->degree = 3;
+ compface->control_point.resize(16);
+ for(size_t i = 0; i < 16; ++i)
+ {
+ compface->control_point[i].x = cP[i][0];
+ compface->control_point[i].y = cP[i][1];
+ compface->control_point[i].z = cP[i][2];
+ }
+ }
+}
+
+void oPRCFile::addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+ const double cP[][3], const double *kU,
+ const double *kV, const PRCmaterial &m,
+ const double w[])
+{
+ ADDFACE(PRCNURBSSurface)
+
+ surface->is_rational = w;
+ surface->degree_in_u = dU;
+ surface->degree_in_v = dV;
+ surface->control_point.resize(nU*nV);
+ for(size_t i = 0; i < nU*nV; i++)
+ if(w)
+ surface->control_point[i]=PRCControlPoint(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]);
+ else
+ surface->control_point[i]=PRCControlPoint(cP[i][0],cP[i][1],cP[i][2]);
+ surface->knot_u.insert(surface->knot_u.end(), kU, kU+(dU+nU+1));
+ surface->knot_v.insert(surface->knot_v.end(), kV, kV+(dV+nV+1));
+}
+
+#define SETTRANSF \
+ if(t&&!isid(t)) \
+ face.transform.reset(new PRCGeneralTransformation3d(t)); \
+ if(origin) surface->origin.Set(origin[0],origin[1],origin[2]); \
+ if(x_axis) surface->x_axis.Set(x_axis[0],x_axis[1],x_axis[2]); \
+ if(y_axis) surface->y_axis.Set(y_axis[0],y_axis[1],y_axis[2]); \
+ surface->scale = scale; \
+ surface->geometry_is_2D = false; \
+ if(surface->origin!=PRCVector3d(0,0,0)) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Translate; \
+ if(surface->x_axis!=PRCVector3d(1,0,0)||surface->y_axis!=PRCVector3d(0,1,0)) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Rotate; \
+ if(surface->scale!=1) \
+ surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Scale; \
+ surface->has_transformation = (surface->behaviour != PRC_TRANSFORMATION_Identity);
+
+#define PRCFACETRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale, const double t[][4]
+
+void oPRCFile::addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCBlend01)
+ SETTRANSF
+ if(straight)
+ {
+ PRCPolyLine *center_curve = new PRCPolyLine;
+ center_curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ center_curve->point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+ center_curve->interval.min = 0;
+ center_curve->interval.max = center_curve->point.size()-1;
+ surface->setCenterCurve(center_curve);
+
+ PRCPolyLine *origin_curve = new PRCPolyLine;
+ origin_curve->point.resize(n);
+ for(uint32_t i=0; i<n; i++)
+ origin_curve->point[i].Set(oP[i][0],oP[i][1],oP[i][2]);
+ origin_curve->interval.min = 0;
+ origin_curve->interval.max = origin_curve->point.size()-1;
+ surface->setOriginCurve(origin_curve);
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = center_curve->interval.min;
+ surface->uv_domain.max.y = center_curve->interval.max;
+ }
+ else
+ {
+ PRCNURBSCurve *center_curve = new PRCNURBSCurve;
+ center_curve->is_rational = false;
+ center_curve->degree = 3;
+ const uint32_t CENTER_NUMBER_OF_POINTS = n;
+ center_curve->control_point.resize(CENTER_NUMBER_OF_POINTS);
+ for(uint32_t i = 0; i < CENTER_NUMBER_OF_POINTS; ++i)
+ center_curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+ center_curve->knot.resize(3+CENTER_NUMBER_OF_POINTS+1);
+ center_curve->knot[0] = 1;
+ for(uint32_t i = 1; i < 3+CENTER_NUMBER_OF_POINTS; ++i)
+ center_curve->knot[i] = (i+2)/3; // integer division is intentional
+ center_curve->knot[3+CENTER_NUMBER_OF_POINTS] = (3+CENTER_NUMBER_OF_POINTS+1)/3;
+ surface->setCenterCurve(center_curve);
+
+ PRCNURBSCurve *origin_curve = new PRCNURBSCurve;
+ origin_curve->is_rational = false;
+ origin_curve->degree = 3;
+ const uint32_t ORIGIN_NUMBER_OF_POINTS = n;
+ origin_curve->control_point.resize(ORIGIN_NUMBER_OF_POINTS);
+ for(uint32_t i = 0; i < ORIGIN_NUMBER_OF_POINTS; ++i)
+ origin_curve->control_point[i].Set(oP[i][0],oP[i][1],oP[i][2]);
+ origin_curve->knot.resize(3+ORIGIN_NUMBER_OF_POINTS+1);
+ origin_curve->knot[0] = 1;
+ for(size_t i = 1; i < 3+ORIGIN_NUMBER_OF_POINTS; ++i)
+ origin_curve->knot[i] = (i+2)/3; // integer division is intentional
+ origin_curve->knot[3+ORIGIN_NUMBER_OF_POINTS] = (3+ORIGIN_NUMBER_OF_POINTS+1)/3;
+ surface->setOriginCurve(origin_curve);
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = 1; // first knot
+ surface->uv_domain.max.y = (3+CENTER_NUMBER_OF_POINTS+1)/3; // last knot
+ }
+}
+
+void oPRCFile::addHemisphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCSphere)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 0.5*pi;
+ surface->radius = radius;
+}
+
+void oPRCFile::addSphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCSphere)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y =-0.5*pi;
+ surface->uv_domain.max.y = 0.5*pi;
+ surface->radius = radius;
+}
+
+void oPRCFile::addDisk(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCRuled)
+ SETTRANSF
+ PRCCircle *first_curve = new PRCCircle;
+ first_curve->radius = radius;
+ surface->setFirstCurve(first_curve);
+ PRCCircle *second_curve = new PRCCircle;
+ second_curve->radius = 0;
+ surface->setSecondCurve(second_curve);
+
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 1;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 2*pi;
+ surface->parameterization_on_v_coeff_a = -1;
+ surface->parameterization_on_v_coeff_b = 2*pi;
+}
+
+void oPRCFile::addCylinder(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCCylinder)
+ SETTRANSF
+ surface->uv_domain.min.x = 0;
+ surface->uv_domain.max.x = 2*pi;
+ surface->uv_domain.min.y = (height>0)?0:height;
+ surface->uv_domain.max.y = (height>0)?height:0;
+ surface->radius = radius;
+}
+
+void oPRCFile::addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+ ADDFACE(PRCTorus)
+ SETTRANSF
+ surface->uv_domain.min.x = (angle1/180)*pi;
+ surface->uv_domain.max.x = (angle2/180)*pi;
+ surface->uv_domain.min.y = 0;
+ surface->uv_domain.max.y = 2*pi;
+ surface->major_radius = major_radius;
+ surface->minor_radius = minor_radius;
+}
+
+#undef PRCFACETRANSFORM
+#undef ADDFACE
+#undef ADDWIRE
+#undef SETTRANSF
+
+uint32_t PRCFileStructure::addMaterialGeneric(PRCMaterialGeneric *pMaterialGeneric)
+{
+ globals.materials.push_back(PRCpMaterial(pMaterialGeneric));
+ return globals.materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureApplication(PRCTextureApplication *pTextureApplication)
+{
+ globals.materials.push_back(PRCpMaterial(pTextureApplication));
+ return globals.materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addStyle(PRCStyle *pStyle)
+{
+ globals.styles.push_back(PRCpStyle(pStyle));
+ return globals.styles.size()-1;
+}
+
+uint32_t PRCFileStructure::addPartDefinition(PRCPartDefinition *pPartDefinition)
+{
+ tree.part_definitions.push_back(PRCpPartDefinition(pPartDefinition));
+ return tree.part_definitions.size()-1;
+}
+
+uint32_t PRCFileStructure::addProductOccurrence(PRCProductOccurrence *pProductOccurrence)
+{
+ tree.product_occurrences.push_back(PRCpProductOccurrence(pProductOccurrence));
+ return tree.product_occurrences.size()-1;
+}
+
+uint32_t PRCFileStructure::addTopoContext(PRCTopoContext *pTopoContext)
+{
+ contexts.push_back(PRCpTopoContext(pTopoContext));
+ return contexts.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DTess(PRC3DTess *p3DTess)
+{
+ tessellations.tessellations.push_back(PRCpTess(p3DTess));
+ return tessellations.tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DWireTess(PRC3DWireTess *p3DWireTess)
+{
+ tessellations.tessellations.push_back(PRCpTess(p3DWireTess));
+ return tessellations.tessellations.size()-1;
+}
+/*
+uint32_t PRCFileStructure::addMarkupTess(PRCMarkupTess *pMarkupTess)
+{
+ tessellations.tessellations.push_back(PRCpTess(pMarkupTess));
+ return tessellations.tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::addMarkup(PRCMarkup *pMarkup)
+{
+ tree.markups.push_back(PRCpMarkup(pMarkup));
+ return tree.markups.size()-1;
+}
+
+uint32_t PRCFileStructure::addAnnotationItem(PRCAnnotationItem *pAnnotationItem)
+{
+ tree.annotation_entities.push_back(PRCpAnnotationItem(pAnnotationItem));
+ return tree.annotation_entities.size()-1;
+}
+*/
+uint32_t PRCFileStructure::addCoordinateSystem(PRCCoordinateSystem *pCoordinateSystem)
+{
+ globals.reference_coordinate_systems.push_back(PRCpCoordinateSystem(pCoordinateSystem));
+ return globals.reference_coordinate_systems.size()-1;
+}
+
+uint32_t PRCFileStructure::addCoordinateSystemUnique(PRCCoordinateSystem *pCoordinateSystem)
+{
+ for(uint32_t i = 0; i < globals.reference_coordinate_systems.size(); ++i)
+ {
+ if(*(globals.reference_coordinate_systems[i])==*pCoordinateSystem)
+ return i;
+ }
+ globals.reference_coordinate_systems.push_back(PRCpCoordinateSystem(pCoordinateSystem));
+ return globals.reference_coordinate_systems.size()-1;
}