r17781 by fschmid - Updates for the PRC exporter:

scribus-commit scribus-commit at lists.scribus.net
Fri Sep 28 15:05:16 UTC 2012


Author: fschmid
Date: Fri Sep 28 15:05:16 2012
New Revision: 17781

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17781
Log:
Updates for the PRC exporter:
- updated prc exporter sources to the latest used by Asymtote
- fixed loading of 3-D Models.
- fixed incorrect export due to missing triangle strips.

Modified:
    trunk/Scribus/scribus/scribus.cpp
    trunk/Scribus/scribus/scribus.h
    trunk/Scribus/scribus/third_party/prc/PRC.h
    trunk/Scribus/scribus/third_party/prc/PRCbitStream.cc
    trunk/Scribus/scribus/third_party/prc/PRCbitStream.h
    trunk/Scribus/scribus/third_party/prc/PRCdouble.cc
    trunk/Scribus/scribus/third_party/prc/PRCdouble.h
    trunk/Scribus/scribus/third_party/prc/exportPRC.cpp
    trunk/Scribus/scribus/third_party/prc/oPRCFile.cc
    trunk/Scribus/scribus/third_party/prc/oPRCFile.h
    trunk/Scribus/scribus/third_party/prc/writePRC.cc
    trunk/Scribus/scribus/third_party/prc/writePRC.h
    trunk/Scribus/scribus/ui/osgeditor.cpp
    trunk/Scribus/scribus/ui/osgeditor.h

Modified: trunk/Scribus/scribus/scribus.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/scribus.cpp
==============================================================================
--- trunk/Scribus/scribus/scribus.cpp (original)
+++ trunk/Scribus/scribus/scribus.cpp Fri Sep 28 15:05:16 2012
@@ -176,6 +176,8 @@
 #include "ui/nodeeditpalette.h"
 #ifdef HAVE_OSG
 	#include "ui/osgeditor.h"
+	#include <osgDB/ReaderWriter>
+	#include <osgDB/PluginQuery>
 #endif
 #include "ui/outlinepalette.h"
 #include "ui/pageitemattributes.h"
@@ -476,6 +478,37 @@
 	ClipB = QApplication::clipboard();
 	palettesStatus[0] = false;
 	guidesStatus[0] = false;
+#ifdef HAVE_OSG
+	QStringList supportedExts;
+	supportedExts << "osg" << "dxf" << "flt" << "ive" << "geo" << "sta" << "stl" << "logo" << "3ds" << "ac" << "obj";
+	QStringList realSupportedExts;
+	QMap<QString, QString> formats;
+	osgDB::FileNameList plugins = osgDB::listAllAvailablePlugins();
+	for(osgDB::FileNameList::iterator itr = plugins.begin(); itr != plugins.end(); ++itr)
+	{
+		osgDB::ReaderWriterInfoList infoList;
+		if (osgDB::queryPlugin(*itr, infoList))
+		{
+			for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin(); rwi_itr != infoList.end(); ++rwi_itr)
+			{
+				osgDB::ReaderWriterInfo& info = *(*rwi_itr);
+				osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
+				for(fdm_itr = info.extensions.begin(); fdm_itr != info.extensions.end(); ++fdm_itr)
+				{
+					if (supportedExts.contains(QString::fromStdString(fdm_itr->first)))
+					{
+						formats.insert("*." + QString::fromStdString(fdm_itr->first) + " *." + QString::fromStdString(fdm_itr->first).toUpper(), QString::fromStdString(fdm_itr->second) + " (*." + QString::fromStdString(fdm_itr->first) + " *." + QString::fromStdString(fdm_itr->first).toUpper() + ")");
+					}
+				}
+			}
+		}
+	}
+	realSupportedExts = formats.keys();
+	QString docexts = realSupportedExts.join(" ");
+	QStringList longList = formats.values();
+	QString longDesc = longList.join(";;") + ";;";
+	osgFilterString = tr("All Supported Formats (%1);;%2All Files (*)").arg(docexts).arg(longDesc);
+#endif
 }
 
 
@@ -9577,7 +9610,7 @@
 #ifdef HAVE_OSG
 		if (currItem->asOSGFrame())
 		{
-			OSGEditorDialog *dia = new OSGEditorDialog(this, currItem->asOSGFrame());
+			OSGEditorDialog *dia = new OSGEditorDialog(this, currItem->asOSGFrame(), osgFilterString);
 			dia->exec();
 			return;
 		}

Modified: trunk/Scribus/scribus/scribus.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/scribus.h
==============================================================================
--- trunk/Scribus/scribus/scribus.h (original)
+++ trunk/Scribus/scribus/scribus.h Fri Sep 28 15:05:16 2012
@@ -610,6 +610,7 @@
 	FormatsManager *formatsManager;
 
 	QPointer<HelpBrowser> helpBrowser;
+	QString osgFilterString;
 };
 
 #endif

Modified: trunk/Scribus/scribus/third_party/prc/PRC.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/PRC.h
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/PRC.h (original)
+++ trunk/Scribus/scribus/third_party/prc/PRC.h Fri Sep 28 15:05:16 2012
@@ -1,7 +1,20 @@
 #ifndef __PRC_H
 #define __PRC_H
 
+#ifdef _MSC_VER
+#if _MSC_VER >= 1600
 #include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
 
 //const uint32_t PRCVersion=7094;   // For Adobe Reader 8 or later
 const uint32_t PRCVersion=8137; // For Adobe Reader 9 or later

Modified: trunk/Scribus/scribus/third_party/prc/PRCbitStream.cc
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/PRCbitStream.cc
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/PRCbitStream.cc (original)
+++ trunk/Scribus/scribus/third_party/prc/PRCbitStream.cc Fri Sep 28 15:05:16 2012
@@ -81,6 +81,19 @@
   deflateEnd(&strm);
 }
 
+void PRCbitStream::write(std::ostream &out) const
+{
+  if(compressed)
+  {
+    out.write((char*)data,compressedDataSize);
+  }
+  else
+  {
+     cerr << "Attempt to write stream before compression." << endl;
+     exit(1);
+  }
+}
+
 unsigned int PRCbitStream::getSize() const
 {
   if(compressed)

Modified: trunk/Scribus/scribus/third_party/prc/PRCbitStream.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/PRCbitStream.h
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/PRCbitStream.h (original)
+++ trunk/Scribus/scribus/third_party/prc/PRCbitStream.h Fri Sep 28 15:05:16 2012
@@ -21,9 +21,24 @@
 #ifndef __PRC_BIT_STREAM_H
 #define __PRC_BIT_STREAM_H
 
+#ifdef _MSC_VER
+#include <stdio.h>
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
 #include <string>
+#include <iostream>
 #include <stdlib.h>
-#include <stdint.h>
 
 #define CHUNK_SIZE (1024)
 // Is this a reasonable initial size?
@@ -52,6 +67,7 @@
     PRCbitStream& operator <<(const char*);
 
     void compress();
+    void write(std::ostream &out) const;
   private:
     void writeBit(bool);
     void writeBits(uint32_t,uint8_t);

Modified: trunk/Scribus/scribus/third_party/prc/PRCdouble.cc
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/PRCdouble.cc
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/PRCdouble.cc (original)
+++ trunk/Scribus/scribus/third_party/prc/PRCdouble.cc Fri Sep 28 15:05:16 2012
@@ -23,6 +23,7 @@
 }
 
 #ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
 void *memrchr(const void *buf,int c,size_t count)
 {
   unsigned char
@@ -35,6 +36,7 @@
 
                  return(NULL);
 }
+#endif
 #endif
 
 sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE] =

Modified: trunk/Scribus/scribus/third_party/prc/PRCdouble.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/PRCdouble.h
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/PRCdouble.h (original)
+++ trunk/Scribus/scribus/third_party/prc/PRCdouble.h Fri Sep 28 15:05:16 2012
@@ -3,6 +3,7 @@
 
 #include <cstdlib>
 #include <cmath>
+#include <cstring>
 
 #ifdef HAVE_CONFIG_H
 #include "scconfig.h"
@@ -131,8 +132,9 @@
 int stCOFDOECompare(const void*,const void*);
 
 #ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
 void *memrchr(const void *,int,size_t);
 #endif
-
+#endif
 
 #endif // __PRC_DOUBLE_H

Modified: trunk/Scribus/scribus/third_party/prc/exportPRC.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/exportPRC.cpp
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/exportPRC.cpp (original)
+++ trunk/Scribus/scribus/third_party/prc/exportPRC.cpp Fri Sep 28 15:05:16 2012
@@ -119,48 +119,42 @@
 	getCurrentMaterial ( geode );
 	for ( unsigned int i=0; i<geode->getNumDrawables(); i++ )
 	{
-		osg::Drawable *drawable=geode->getDrawable ( i );
-		osg::Geometry *geom=dynamic_cast<osg::Geometry *> ( drawable );
-		getCurrentMaterial ( drawable );
-		QString nam = QString::fromStdString(drawable->getName());
-		out->begingroup(nam.toLatin1());
-		for ( unsigned int ipr=0; ipr<geom->getNumPrimitiveSets(); ipr++ )
-		{
-			osg::PrimitiveSet* prset=geom->getPrimitiveSet ( ipr );
-			analysePrimSet ( prset, out, geom, dynamic_cast<const osg::Vec3Array*> ( geom->getVertexArray() ) );
-		}
-		out->endgroup();
+		osg::Drawable *drawable = geode->getDrawable ( i );
+		if (drawable)
+		{
+			osg::Geometry *geom = dynamic_cast<osg::Geometry *> ( drawable );
+			if (geom)
+			{
+				getCurrentMaterial ( drawable );
+				QString nam = QString::fromStdString(drawable->getName());
+				PRCoptions grpopt;
+				grpopt.no_break = true;
+				grpopt.do_break = false;
+				grpopt.tess = true;
+				out->begingroup(nam.toLatin1(), &grpopt);
+				for ( unsigned int ipr=0; ipr < geom->getNumPrimitiveSets(); ipr++ )
+				{
+					osg::PrimitiveSet* prset=geom->getPrimitiveSet ( ipr );
+					analysePrimSet ( prset, out, geom, dynamic_cast<const osg::Vec3Array*> ( geom->getVertexArray() ) );
+				}
+				out->endgroup();
+			}
+		}
 	}
 }
 
 void PRCExporter::analysePrimSet ( osg::PrimitiveSet*prset, oPRCFile *out, osg::Geometry *geom, const osg::Vec3Array *verts )
 {
 	unsigned int ic;
-//	const osg::Vec4Array *Diffuse = dynamic_cast<const osg::Vec4Array*> ( geom->getColorArray() );
-//	double r = ( *Diffuse ) [0].x();
-//	double g = ( *Diffuse ) [0].y();
-//	double b = ( *Diffuse ) [0].z();
-//	double a = ( *Diffuse ) [0].w();
-	// you might want to handle each type of primset differently: such as:
+	unsigned int evenodd=0;
 	switch ( prset->getMode() )
 	{
 		case osg::PrimitiveSet::TRIANGLES: // get vertices of triangle
-//			osg::notify ( osg::WARN ) << "Triangles " << std::endl;
 			for ( ic=0; ic<prset->getNumIndices()-2; ic+=3 )
 			{
 				double ( *points ) [3] = new double[4][3];
-//				double *knotsU = new double[4];
-//				double *knotsV = new double[4];
 				double knotsU[] = {1,1,2,2};
 				double knotsV[] = {1,1,2,2};
-//				knotsU[0] = 1.0;
-//				knotsU[1] = 1.0;
-//				knotsU[2] = 2.0;
-//				knotsU[3] = 2.0;
-//				knotsV[0] = 1.0;
-//				knotsV[1] = 1.0;
-//				knotsV[2] = 2.0;
-//				knotsV[3] = 2.0;
 				points[0][0] = ( * verts ) [prset->index ( ic ) ].x();
 				points[0][1] = ( * verts ) [prset->index ( ic ) ].y();
 				points[0][2] = ( * verts ) [prset->index ( ic ) ].z();
@@ -173,31 +167,113 @@
 				points[3][0] = ( * verts ) [prset->index ( ic+2 ) ].x();
 				points[3][1] = ( * verts ) [prset->index ( ic+2 ) ].y();
 				points[3][2] = ( * verts ) [prset->index ( ic+2 ) ].z();
-//				out->addRectangle(points, currentMaterial);
 				out->addSurface(1, 1, 2, 2, points, knotsU, knotsV, currentMaterial, NULL );
-//				out->add ( new PRCsurface ( out, 1, 1, 2, 2, points, knotsU, knotsV, *new RGBAColour ( r,g,b,a ) ) );
+				delete[] points;
 			}
 			break;
 		case osg::PrimitiveSet::TRIANGLE_STRIP: // look up how tristrips are coded
-//			osg::notify ( osg::WARN ) << "Triangle Strip " << std::endl;
+			if (prset->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
+			{
+				const osg::DrawArrayLengths* drawArrayLengths = static_cast<const osg::DrawArrayLengths*>(prset);
+				QList<uint> lenList;
+				for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr !=drawArrayLengths->end(); ++primItr)
+				{
+					unsigned int localPrimLength = *primItr;
+					lenList.append(localPrimLength);
+				}
+				int lenInd = 0;
+				int actLen = lenList[lenInd]-2;
+				int currLen = 0;
+				evenodd = 0;
+				for(unsigned int vindex = 0; vindex < prset->getNumIndices()-2; ++vindex, evenodd++)
+				{
+					double ( *points ) [3] = new double[4][3];
+					double knotsU[] = {1,1,2,2};
+					double knotsV[] = {1,1,2,2};
+					if (evenodd % 2 == 0)
+					{
+						points[0][0] = ( * verts ) [prset->index ( vindex ) ].x();
+						points[0][1] = ( * verts ) [prset->index ( vindex ) ].y();
+						points[0][2] = ( * verts ) [prset->index ( vindex ) ].z();
+						points[1][0] = ( * verts ) [prset->index ( vindex+1 ) ].x();
+						points[1][1] = ( * verts ) [prset->index ( vindex+1 ) ].y();
+						points[1][2] = ( * verts ) [prset->index ( vindex+1 ) ].z();
+					}
+					else
+					{
+						points[0][0] = ( * verts ) [prset->index ( vindex+1 ) ].x();
+						points[0][1] = ( * verts ) [prset->index ( vindex+1 ) ].y();
+						points[0][2] = ( * verts ) [prset->index ( vindex+1 ) ].z();
+						points[1][0] = ( * verts ) [prset->index ( vindex ) ].x();
+						points[1][1] = ( * verts ) [prset->index ( vindex ) ].y();
+						points[1][2] = ( * verts ) [prset->index ( vindex ) ].z();
+					}
+					points[2][0] = ( * verts ) [prset->index ( vindex+2 ) ].x();
+					points[2][1] = ( * verts ) [prset->index ( vindex+2 ) ].y();
+					points[2][2] = ( * verts ) [prset->index ( vindex+2 ) ].z();
+					points[3][0] = ( * verts ) [prset->index ( vindex+2 ) ].x();
+					points[3][1] = ( * verts ) [prset->index ( vindex+2 ) ].y();
+					points[3][2] = ( * verts ) [prset->index ( vindex+2 ) ].z();
+					out->addSurface(1, 1, 2, 2, points, knotsU, knotsV, currentMaterial, NULL );
+					currLen++;
+					if (currLen >= actLen)
+					{
+						lenInd++;
+						if (lenInd == lenList.count())
+							break;
+						actLen = lenList[lenInd]-2;
+						currLen = 0;
+						vindex += 2;
+						evenodd = 0;
+						if (vindex >= prset->getNumIndices())
+							break;
+					}
+					delete[] points;
+				}
+			}
+			else
+			{
+				evenodd = 0;
+				for(unsigned int vindex = 0; vindex < prset->getNumIndices()-2; ++vindex, evenodd++)
+				{
+					double ( *points ) [3] = new double[4][3];
+					double knotsU[] = {1,1,2,2};
+					double knotsV[] = {1,1,2,2};
+					if (evenodd % 2 == 0)
+					{
+						points[0][0] = ( * verts ) [prset->index ( vindex ) ].x();
+						points[0][1] = ( * verts ) [prset->index ( vindex ) ].y();
+						points[0][2] = ( * verts ) [prset->index ( vindex ) ].z();
+						points[1][0] = ( * verts ) [prset->index ( vindex+1 ) ].x();
+						points[1][1] = ( * verts ) [prset->index ( vindex+1 ) ].y();
+						points[1][2] = ( * verts ) [prset->index ( vindex+1 ) ].z();
+					}
+					else
+					{
+						points[0][0] = ( * verts ) [prset->index ( vindex+1 ) ].x();
+						points[0][1] = ( * verts ) [prset->index ( vindex+1 ) ].y();
+						points[0][2] = ( * verts ) [prset->index ( vindex+1 ) ].z();
+						points[1][0] = ( * verts ) [prset->index ( vindex ) ].x();
+						points[1][1] = ( * verts ) [prset->index ( vindex ) ].y();
+						points[1][2] = ( * verts ) [prset->index ( vindex ) ].z();
+					}
+					points[2][0] = ( * verts ) [prset->index ( vindex+2 ) ].x();
+					points[2][1] = ( * verts ) [prset->index ( vindex+2 ) ].y();
+					points[2][2] = ( * verts ) [prset->index ( vindex+2 ) ].z();
+					points[3][0] = ( * verts ) [prset->index ( vindex+2 ) ].x();
+					points[3][1] = ( * verts ) [prset->index ( vindex+2 ) ].y();
+					points[3][2] = ( * verts ) [prset->index ( vindex+2 ) ].z();
+					out->addSurface(1, 1, 2, 2, points, knotsU, knotsV, currentMaterial, NULL );
+					delete[] points;
+				}
+			}
 			break;
 		case osg::PrimitiveSet::QUADS: // get vertices of quad
-//			osg::notify ( osg::WARN ) << "Quad " << std::endl;
 			for ( ic=0; ic<prset->getNumIndices()-3; ic+=4 )
 			{
 				double ( *points ) [3] = new double[4][3];
-//				double *knotsU = new double[4];
-//				double *knotsV = new double[4];
 				double knotsU[] = {1,1,2,2};
 				double knotsV[] = {1,1,2,2};
-//				knotsU[0] = 1.0;
-//				knotsU[1] = 1.0;
-//				knotsU[2] = 2.0;
-//				knotsU[3] = 2.0;
-//				knotsV[0] = 1.0;
-//				knotsV[1] = 1.0;
-//				knotsV[2] = 2.0;
-//				knotsV[3] = 2.0;
 				points[0][0] = ( * verts ) [prset->index ( ic ) ].x();
 				points[0][1] = ( * verts ) [prset->index ( ic ) ].y();
 				points[0][2] = ( * verts ) [prset->index ( ic ) ].z();
@@ -210,9 +286,8 @@
 				points[3][0] = ( * verts ) [prset->index ( ic+2 ) ].x();
 				points[3][1] = ( * verts ) [prset->index ( ic+2 ) ].y();
 				points[3][2] = ( * verts ) [prset->index ( ic+2 ) ].z();
-//				out->addRectangle(points, currentMaterial);
 				out->addSurface(1, 1, 2, 2, points, knotsU, knotsV, currentMaterial, NULL );
-//				out->add ( new PRCsurface ( out, 1, 1, 2, 2, points, knotsU, knotsV, *new RGBAColour ( r,g,b,a ) ) );
+				delete[] points;
 			}
 			break;
 		case osg::PrimitiveSet::QUAD_STRIP: // look up how tristrips are coded

Modified: trunk/Scribus/scribus/third_party/prc/oPRCFile.cc
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/oPRCFile.cc
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/oPRCFile.cc (original)
+++ trunk/Scribus/scribus/third_party/prc/oPRCFile.cc Fri Sep 28 15:05:16 2012
@@ -24,12 +24,19 @@
 #include <sstream>
 #include <iostream>
 #include <fstream>
+#include <iomanip>
 #include <string>
 #include <zlib.h>
 #include <string.h>
 
 #define WriteUnsignedInteger( value ) out << (uint32_t)(value);
 #define WriteInteger( value ) out << (int32_t)(value);
+#define WriteDouble( value ) out << (double)(value);
+#define WriteString( value ) out << (value);
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define WriteUncompressedBlock( value, count ) out.write((char *)(value),(count));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+#define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(out);
 #define SerializeContentPRCBase write(out);
 #define SerializeRgbColor( value ) (value).serializeRgbColor(out);
 #define SerializePicture( value ) (value).serializePicture(out);
@@ -39,276 +46,261 @@
 #define SerializeFontKeysSameFont( value ) (value).serializeFontKeysSameFont(out);
 #define SerializeMaterial( value ) (value)->serializeMaterial(out);
 
+#define SerializeUserData UserData(0,0).write(out);
+#define SerializeEmptyContentPRCBase ContentPRCBase(PRC_TYPE_ROOT_PRCBase).serializeContentPRCBase(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);
+#define SerializeContextAndBodies( value ) (value)->serializeContextAndBodies(out);
+#define SerializeGeometrySummary( value ) (value)->serializeGeometrySummary(out);
+#define SerializeContextGraphics( value ) (value)->serializeContextGraphics(out);
+#define SerializeStartHeader serializeStartHeader(out);
+#define SerializeUncompressedFiles  \
+ { \
+  const uint32_t number_of_uncompressed_files = uncompressed_files.size(); \
+  WriteUncompressedUnsignedInteger (number_of_uncompressed_files) \
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++) \
+  { \
+    WriteUncompressedUnsignedInteger ((*it)->file_size) \
+    WriteUncompressedBlock ((*it)->data, (*it)->file_size) \
+  } \
+ }
+#define SerializeModelFileData serializeModelFileData(modelFile_out); modelFile_out.compress();
+#define SerializeUnit( value ) (value).serializeUnit(out);
 
 using std::string;
 using namespace std;
 
-void PRCCompressedSection::write(ostream &out)
-{
-  if(prepared)
-    out.write((char*)data,getSize());
-}
-
-void PRCCompressedSection::prepare()
-{
-  writeData();
-  compress();
-  prepared = true;
-}
-
-uint32_t PRCCompressedSection::getSize()
-{
-  if(!prepared)
-    return m1;
-  else
-    return out.getSize();
-}
-
-void PRCGlobalsSection::writeData()
+// Map [0,1] to [0,255]
+inline uint8_t byte(double r) 
+{
+  if(r < 0.0) r=0.0;
+  else if(r > 1.0) r=1.0;
+  int a=(int)(256.0*r);
+  if(a == 256) a=255;
+  return a;
+}
+
+void PRCFileStructure::serializeFileStructureGlobals(PRCbitStream &out)
 {
   // 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;
+  const uint32_t number_of_schema = 0;
+  WriteUnsignedInteger (number_of_schema)
+
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGlobals)
 
   PRCSingleAttribute sa((int32_t)PRCVersion);
   PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
   a.addKey(sa);
-  ContentPRCBase cb;
+  ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase);
   cb.addAttribute(a);
   cb.serializeContentPRCBase(out);
-  out << numberOfReferencedFileStructures; // no referencing of file structures
-  out << tessellationChordHeightRatio;
-  out << tessellationAngleDegrees;
-  out << defaultFontFamilyName; // markup serialization helper
+  WriteUnsignedInteger (number_of_referenced_file_structures)
+  // SerializeFileStructureInternalGlobalData
+  WriteDouble (tessellation_chord_height_ratio)
+  WriteDouble (tessellation_angle_degree)
+
+  // SerializeMarkupSerializationHelper
+  WriteString (default_font_family_name)
 
   const uint32_t number_of_fonts = font_keys_of_font.size();
   WriteUnsignedInteger (number_of_fonts)
-  for (i=0;i<number_of_fonts;i++)
+  for (uint32_t i=0;i<number_of_fonts;i++)
   {
     SerializeFontKeysSameFont (font_keys_of_font[i])
   }
 
-  
   const uint32_t number_of_colors = colors.size();
   WriteUnsignedInteger (number_of_colors)
-  for (i=0;i<number_of_colors;i++)
+  for (uint32_t 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++)
+  for (uint32_t 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++)
+  for (uint32_t 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++)
+  for (uint32_t 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;
-  ContentPRCBase("",true,makeCADID(),0,makePRCID()).serializeContentPRCBase(out);
-  out << (uint32_t)0 // number of lengths
-      << 0.0 // phase
-      << false; // is real length
+  // number of line patterns hard coded for now
+  const uint32_t number_of_line_patterns = 1;
+  WriteUnsignedInteger (number_of_line_patterns)
+  PRCLinePattern().serializeLinePattern(out);
 
   const uint32_t number_of_styles = styles.size();
   WriteUnsignedInteger (number_of_styles)
-  for (i=0;i<number_of_styles;i++)
+  for (uint32_t i=0;i<number_of_styles;i++)
      SerializeCategory1LineStyle (styles[i])
 
-  out << numberOfFillPatterns; 
+  const uint32_t number_of_fill_patterns = 0;
+  WriteUnsignedInteger (number_of_fill_patterns)
 
   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++)
+  for (uint32_t i=0;i<number_of_reference_coordinate_systems;i++)
      SerializeCoordinateSystem (reference_coordinate_systems[i])
 
-  userData.write(out);
-}
-
-void PRCTreeSection::writeData()
-{
-  out << (uint32_t)(PRC_TYPE_ASM_FileStructureTree);
-
-  EMPTY_CONTENTPRCBASE.serializeContentPRCBase(out);
-
-  uint32_t number_of_part_definitions = part_definitions.size();
-  WriteUnsignedInteger (number_of_part_definitions) 
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTree(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTree)
+
+  SerializeEmptyContentPRCBase
+
+  const 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]) 
+    SerializePartDefinition (part_definitions[i])
 	
-  uint32_t number_of_product_occurrences = product_occurrences.size();
-  WriteUnsignedInteger (number_of_product_occurrences) 
+  const 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++)
   {
     product_occurrences[i]->unit_information.unit_from_CAD_file = true;
     product_occurrences[i]->unit_information.unit = unit;
-    SerializeProductOccurrence (product_occurrences[i]) 
-  }
-
-  // File Structure Internal Data
-  out << (uint32_t)(PRC_TYPE_ASM_FileStructure);
-  EMPTY_CONTENTPRCBASE.serializeContentPRCBase(out);
-  out << makePRCID(); // next available index
-  out << (uint32_t)1; // product occurrence index
-
-  UserData(0,0).write(out);
-}
-
-void PRCTessellationSection::writeData()
-{
-  out << (uint32_t)(PRC_TYPE_ASM_FileStructureTessellation);
-
-  EMPTY_CONTENTPRCBASE.serializeContentPRCBase(out);
+    SerializeProductOccurrence (product_occurrences[i])
+  }
+
+  // SerializeFileStructureInternalData
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructure)
+  SerializeEmptyContentPRCBase
+  const uint32_t next_available_index = makePRCID();
+  WriteUnsignedInteger (next_available_index)
+  const uint32_t index_product_occurence = number_of_product_occurrences;  // Asymptote (oPRCFile) specific - we write the root product last
+  WriteUnsignedInteger (index_product_occurence)
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTessellation(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTessellation)
+
+  SerializeEmptyContentPRCBase
   const uint32_t number_of_tessellations = tessellations.size();
-  WriteUnsignedInteger (number_of_tessellations) 
+  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()
-{
-   WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry)
-
-  EMPTY_CONTENTPRCBASE.serializeContentPRCBase(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()
-{
-   WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureExtraGeometry)
-
-  EMPTY_CONTENTPRCBASE.serializeContentPRCBase(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);
-}
-
-void PRCModelFile::writeData()
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureGeometry(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry)
+
+  SerializeEmptyContentPRCBase
+  const uint32_t number_of_contexts = contexts.size();
+  WriteUnsignedInteger (number_of_contexts)
+  for (uint32_t i=0;i<number_of_contexts;i++)
+    SerializeContextAndBodies (contexts[i])
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureExtraGeometry(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureExtraGeometry)
+
+  SerializeEmptyContentPRCBase
+  const uint32_t number_of_contexts = contexts.size();
+  WriteUnsignedInteger (number_of_contexts)
+  for (uint32_t i=0;i<number_of_contexts;i++)
+  {
+     SerializeGeometrySummary (contexts[i])
+     SerializeContextGraphics (contexts[i])
+  }
+
+  SerializeUserData
+}
+
+void oPRCFile::serializeModelFileData(PRCbitStream &out)
 {
   // even though this is technically not part of this section,
   // it is handled here for convenience
-  out << (uint32_t)(0); // number of schemas
-  out << (uint32_t)(PRC_TYPE_ASM_ModelFile);
+  const uint32_t number_of_schema = 0;
+  WriteUnsignedInteger (number_of_schema)
+  WriteUnsignedInteger (PRC_TYPE_ASM_ModelFile)
 
   PRCSingleAttribute sa((int32_t)PRCVersion);
   PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
   a.addKey(sa);
-  ContentPRCBase cb("PRC file");
+  ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase,"PRC file");
   cb.addAttribute(a);
   cb.serializeContentPRCBase(out);
 
-  writeUnit(out,true,unit); // unit is specified, and happens to come from a CAD file
+  SerializeUnit (unit)
 
   out << (uint32_t)1; // 1 product occurrence
   //UUID
-  out << parent->fileStructures[0]->header.fileStructureUUID[0]
-      << parent->fileStructures[0]->header.fileStructureUUID[1]
-      << parent->fileStructures[0]->header.fileStructureUUID[2]
-      << parent->fileStructures[0]->header.fileStructureUUID[3];
+  SerializeCompressedUniqueId( fileStructures[0]->file_structure_uuid )
   // index+1
-  out << (uint32_t)parent->fileStructures[0]->tree.product_occurrences.size();
+  out << (uint32_t)fileStructures[0]->product_occurrences.size();
   // active
   out << true;
   out << (uint32_t)0; // index in model file
 
-  UserData(0,0).write(out);
-}
-
-void makeFileUUID(uint32_t *UUID)
+  SerializeUserData
+}
+
+void makeFileUUID(PRCUniqueId& UUID)
 {
   // make a UUID
   static uint32_t count = 0;
   ++count;
   // the minimum requirement on UUIDs is that all must be unique in the file
-  UUID[0] = 0x33595341; // some constant
-  UUID[1] = time(NULL); // the time
-  UUID[2] = count;
-  UUID[3] = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant
+  UUID.id0 = 0x33595341; // some constant
+  UUID.id1 = (uint32_t)time(NULL); // the time
+  UUID.id2 = count;
+  UUID.id3 = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant
   // maybe add something else to make it more unique
   // so multiple files can be combined
   // a hash of some data perhaps?
 }
 
-void makeAppUUID(uint32_t *UUID)
-{
-  UUID[0] = UUID[1] = UUID[2] = UUID[3] = 0;
-}
-
-void writeUINT32_T(ostream &out, uint32_t data)
-{
-#ifdef WORDS_BIGENDIAN
-  out.write(((char*)&data)+3,1);
-  out.write(((char*)&data)+2,1);
-  out.write(((char*)&data)+1,1);
-  out.write(((char*)&data)+0,1);
-#else
-  out.write(((char*)&data)+0,1);
-  out.write(((char*)&data)+1,1);
-  out.write(((char*)&data)+2,1);
-  out.write(((char*)&data)+3,1);
-#endif
-}
-
-void PRCUncompressedFile::write(ostream &out)
+void makeAppUUID(PRCUniqueId& UUID)
+{
+  UUID.id0 = UUID.id1 = UUID.id2 = UUID.id3 = 0;
+}
+
+void PRCUncompressedFile::write(ostream &out) const
 {
   if(data!=NULL)
   {
-    writeUINT32_T(out,file_size);
+    WriteUncompressedUnsignedInteger (file_size)
     out.write((char*)data,file_size);
   }
 }
 
-uint32_t PRCUncompressedFile::getSize()
+uint32_t PRCUncompressedFile::getSize() const
 {
   return sizeof(file_size)+file_size;
 }
 
 
-void PRCStartHeader::write(ostream &out)
-{
-  out.write("PRC",3);
-  writeUINT32_T(out,minimal_version_for_read);
-  writeUINT32_T(out,authoring_version);
-  writeUINT32_T(out,fileStructureUUID[0]);
-  writeUINT32_T(out,fileStructureUUID[1]);
-  writeUINT32_T(out,fileStructureUUID[2]);
-  writeUINT32_T(out,fileStructureUUID[3]);
-
-  writeUINT32_T(out,applicationUUID[0]);
-  writeUINT32_T(out,applicationUUID[1]);
-  writeUINT32_T(out,applicationUUID[2]);
-  writeUINT32_T(out,applicationUUID[3]);
-}
-
-uint32_t PRCStartHeader::getSize()
+void PRCStartHeader::serializeStartHeader(ostream &out) const
+{
+  WriteUncompressedBlock ("PRC",3)
+  WriteUncompressedUnsignedInteger (minimal_version_for_read)
+  WriteUncompressedUnsignedInteger (authoring_version)
+  SerializeFileStructureUncompressedUniqueId( file_structure_uuid );
+  SerializeFileStructureUncompressedUniqueId( application_uuid );
+}
+
+uint32_t PRCStartHeader::getStartHeaderSize() const
 {
   return 3+(2+2*4)*sizeof(uint32_t);
 }
@@ -316,64 +308,65 @@
 
 void PRCFileStructure::write(ostream &out)
 {
-  header.write(out);
-  uint32_t number_of_uncompressed_files = uncompressedFiles.size();
-  writeUINT32_T(out,number_of_uncompressed_files);
-  for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
-    i->write(out);
-  globals.write(out);
-  tree.write(out);
-  tessellations.write(out);
-  geometry.write(out);
-  extraGeometry.write(out);
-}
-
+  // SerializeFileStructureHeader
+  SerializeStartHeader
+  SerializeUncompressedFiles
+  globals_out.write(out);
+  tree_out.write(out);
+  tessellations_out.write(out);
+  geometry_out.write(out);
+  extraGeometry_out.write(out);
+}
+
+#define SerializeFileStructureGlobals serializeFileStructureGlobals(globals_out); globals_out.compress(); sizes[1]=globals_out.getSize();
+#define SerializeFileStructureTree serializeFileStructureTree(tree_out); tree_out.compress(); sizes[2]=tree_out.getSize();
+#define SerializeFileStructureTessellation serializeFileStructureTessellation(tessellations_out); tessellations_out.compress(); sizes[3]=tessellations_out.getSize();
+#define SerializeFileStructureGeometry serializeFileStructureGeometry(geometry_out); geometry_out.compress(); sizes[4]=geometry_out.getSize();
+#define SerializeFileStructureExtraGeometry serializeFileStructureExtraGeometry(extraGeometry_out); extraGeometry_out.compress(); sizes[5]=extraGeometry_out.getSize();
+#define FlushSerialization resetGraphicsAndName();
 void PRCFileStructure::prepare()
 {
-  globals.prepare();
-  resetGraphicsAndName();
-
-  tree.prepare();
-  resetGraphicsAndName();
-
-  tessellations.prepare();
-  resetGraphicsAndName();
-
-  geometry.prepare();
-  resetGraphicsAndName();
-
-  extraGeometry.prepare();
-  resetGraphicsAndName();
+  uint32_t size = 0;
+  size += getStartHeaderSize();
+  size += sizeof(uint32_t);
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+    size += (*it)->getSize();
+  sizes[0]=size;
+
+  SerializeFileStructureGlobals
+  FlushSerialization
+
+  SerializeFileStructureTree
+  FlushSerialization
+
+  SerializeFileStructureTessellation
+  FlushSerialization
+
+  SerializeFileStructureGeometry
+  FlushSerialization
+
+  SerializeFileStructureExtraGeometry
+  FlushSerialization
 }
 
 uint32_t PRCFileStructure::getSize()
 {
   uint32_t size = 0;
-  size += header.getSize();
-  size += sizeof(uint32_t);
-  for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
-    size += i->getSize();
-  size += globals.getSize();
-  size += tree.getSize();
-  size += tessellations.getSize();
-  size += geometry.getSize();
-  size += extraGeometry.getSize();
+  for(size_t i=0; i<6; i++)
+    size += sizes[i];
   return size;
 }
 
 
 void PRCFileStructureInformation::write(ostream &out)
 {
-  writeUINT32_T(out,UUID[0]);
-  writeUINT32_T(out,UUID[1]);
-  writeUINT32_T(out,UUID[2]);
-  writeUINT32_T(out,UUID[3]);
-
-  writeUINT32_T(out,reserved);
-  writeUINT32_T(out,number_of_offsets);
+  SerializeFileStructureUncompressedUniqueId( UUID );
+
+  WriteUncompressedUnsignedInteger (reserved)
+  WriteUncompressedUnsignedInteger (number_of_offsets)
   for(uint32_t i = 0; i < number_of_offsets; ++i)
   {
-    writeUINT32_T(out,offsets[i]);
+    WriteUncompressedUnsignedInteger (offsets[i])
   }
 }
 
@@ -384,87 +377,93 @@
 
 void PRCHeader::write(ostream &out)
 {
-  startHeader.write(out);
-  writeUINT32_T(out,number_of_file_structures);
+  SerializeStartHeader
+  WriteUncompressedUnsignedInteger (number_of_file_structures)
   for(uint32_t i = 0; i < number_of_file_structures; ++i)
   {
     fileStructureInformation[i].write(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(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
-    i->write(out);
+  WriteUncompressedUnsignedInteger (model_file_offset)
+  WriteUncompressedUnsignedInteger (file_size)
+  SerializeUncompressedFiles
 }
 
 uint32_t PRCHeader::getSize()
 {
-  uint32_t size = startHeader.getSize() + sizeof(uint32_t);
+  uint32_t size = getStartHeaderSize() + sizeof(uint32_t);
   for(uint32_t i = 0; i < number_of_file_structures; ++i)
     size += fileStructureInformation[i].getSize();
   size += 3*sizeof(uint32_t);
-  for(list<PRCUncompressedFile>::iterator i = uncompressedFiles.begin(); i != uncompressedFiles.end(); i++)
-    size += i->getSize();
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+    size += (*it)->getSize();
   return size;
 }
 
-void oPRCFile::doGroup(PRCgroup& group, PRCPartDefinition *parent_part_definition, PRCProductOccurrence *parent_product_occurrence)
+void oPRCFile::doGroup(PRCgroup& group)
 {
     const string& name = group.name;
 
-    PRCPartDefinition *part_definition = new PRCPartDefinition;
+    PRCProductOccurrence*& product_occurrence        = group.product_occurrence;
+    PRCProductOccurrence*& parent_product_occurrence = group.parent_product_occurrence;
+    PRCPartDefinition*& part_definition              = group.part_definition;
+    PRCPartDefinition*& parent_part_definition       = group.parent_part_definition;
 
     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)
+        for(PRCtesslineMap::const_iterator wit=group.lines.begin(); wit!=group.lines.end(); wit++)
+        {
+          bool same_color = true;
+          const PRCtesslineList& lines = wit->second;
+          const PRCRgbColor &color = lines.front().color;
+          for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
+            if(color!=lit->color)
+            {
+              same_color = false;
+              break;
+            }
+          map<PRCVector3d,uint32_t> points;
+          PRC3DWireTess *tess = new PRC3DWireTess();
+          if(!same_color)
           {
-            same_color = false;
-            break;
+            tess->is_segment_color = true;
+            tess->is_rgba = false;
           }
-        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++)
+          for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
           {
-            map<PRCVector3d,uint32_t>::iterator pPoint = points.find(lit->point[i]);
-            if(pPoint!=points.end())
-              tess->wire_indexes.push_back(pPoint->second);
-            else
+            tess->wire_indexes.push_back(lit->point.size());
+            for(uint32_t i=0; i<lit->point.size(); i++)
             {
-              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));
+              map<PRCVector3d,uint32_t>::iterator pPoint = points.find(lit->point[i]);
+              if(pPoint!=points.end())
+                tess->wire_indexes.push_back(pPoint->second);
+              else
+              {
+                const uint32_t point_index = tess->coordinates.size();
+                points.insert(make_pair(lit->point[i],point_index));
+                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(byte(lit->color.red));
+                tess->rgba_vertices.push_back(byte(lit->color.green));
+                tess->rgba_vertices.push_back(byte(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 = addColourWidth(RGBAColour(color.red,color.green,color.blue),wit->first);
+          else
+            polyWire->index_of_line_style = addColourWidth(RGBAColour(1,1,1),wit->first);
+          part_definition->addPolyWire(polyWire);
         }
-        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())
@@ -479,6 +478,7 @@
           }
         map<PRCVector3d,uint32_t> points;
         PRC3DTess *tess = new PRC3DTess();
+        tess->crease_angle = group.options.crease_angle;
         PRCTessFace *tessFace = new PRCTessFace();
         tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
         uint32_t triangles = 0;
@@ -488,7 +488,7 @@
           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]);
+            map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(rit->vertices[i]);
             if(pPoint!=points.end())
               vertex_indices[i] =  pPoint->second;
             else
@@ -535,7 +535,146 @@
         part_definition->addPolyBrepModel(polyBrepModel);
       }
     }
-   
+
+    if(!group.quads.empty())
+    {
+      map<PRCVector3d,uint32_t> points;
+      PRC3DTess *tess = new PRC3DTess();
+      tess->crease_angle = group.options.crease_angle;
+      PRCTessFace *tessFace = new PRCTessFace();
+      tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+      uint32_t triangles = 0;
+
+      tessFace->is_rgba = false;
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        if(C[0].A != 1.0 || C[1].A != 1.0 || C[2].A != 1.0 || C[3].A != 1.0)
+        {
+          tessFace->is_rgba = true;
+          break;
+        }
+      }
+      bool same_colour = true;
+      const RGBAColour& colour = group.quads.front().colours[0];
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        if(colour!=C[0] || colour!=C[1] || colour!=C[2] || colour!=C[3])
+        {
+          same_colour = false;
+          break;
+        }
+      }
+      
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        const bool degenerate = (qit->vertices[0]==qit->vertices[1]);
+        uint32_t vertex_indices[4];
+        for(size_t i = (degenerate?1:0); i < 4; ++i)
+        {
+          map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(qit->vertices[i]);
+          if(pPoint!=points.end())
+            vertex_indices[i] =  pPoint->second;
+          else
+          {
+            points.insert(make_pair(qit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+            tess->coordinates.push_back(qit->vertices[i].x);
+            tess->coordinates.push_back(qit->vertices[i].y);
+            tess->coordinates.push_back(qit->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_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[1].R));
+            tessFace->rgba_vertices.push_back(byte(C[1].G));
+            tessFace->rgba_vertices.push_back(byte(C[1].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[1].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[2].R));
+            tessFace->rgba_vertices.push_back(byte(C[2].G));
+            tessFace->rgba_vertices.push_back(byte(C[2].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[2].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          }
+        }
+        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_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[0].R));
+            tessFace->rgba_vertices.push_back(byte(C[0].G));
+            tessFace->rgba_vertices.push_back(byte(C[0].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[0].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[2].R));
+            tessFace->rgba_vertices.push_back(byte(C[2].G));
+            tessFace->rgba_vertices.push_back(byte(C[2].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[2].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          }
+          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_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          
+            tessFace->rgba_vertices.push_back(byte(C[1].R));
+            tessFace->rgba_vertices.push_back(byte(C[1].G));
+            tessFace->rgba_vertices.push_back(byte(C[1].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[1].A));
+          
+            tessFace->rgba_vertices.push_back(byte(C[0].R));
+            tessFace->rgba_vertices.push_back(byte(C[0].G));
+            tessFace->rgba_vertices.push_back(byte(C[0].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[0].A));
+          }
+        }
+      }
+      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_colour)
+        polyBrepModel->index_of_line_style = addColour(colour);
+      part_definition->addPolyBrepModel(polyBrepModel);
+    }
+
     if(!group.points.empty())
     {
       for(PRCpointsetMap::const_iterator pit=group.points.begin(); pit!=group.points.end(); pit++)
@@ -547,10 +686,35 @@
       }
     }
 
+    if(!group.pointsets.empty())
+    {
+      for(std::vector<PRCPointSet*>::iterator pit=group.pointsets.begin(); pit!=group.pointsets.end(); pit++)
+      {
+        part_definition->addPointSet(*pit);
+      }
+    }
+
+    if(!group.polymodels.empty())
+    {
+      for(std::vector<PRCPolyBrepModel*>::iterator pit=group.polymodels.begin(); pit!=group.polymodels.end(); pit++)
+      {
+        (*pit)->is_closed = group.options.closed;
+        part_definition->addPolyBrepModel(*pit);
+      }
+    }
+
+    if(!group.polywires.empty())
+    {
+      for(std::vector<PRCPolyWire*>::iterator pit=group.polywires.begin(); pit!=group.polywires.end(); pit++)
+      {
+        part_definition->addPolyWire(*pit);
+      }
+    }
+
     if(!group.wires.empty())
     {
       PRCTopoContext *wireContext = NULL;
-      uint32_t context_index = getTopoContext(wireContext);
+      const uint32_t context_index = getTopoContext(wireContext);
       for(PRCwireList::iterator wit=group.wires.begin(); wit!=group.wires.end(); wit++)
       {
         PRCWireEdge *wireEdge = new PRCWireEdge;
@@ -572,7 +736,7 @@
     if(!faces.empty())
     {
       bool same_color = true;
-      uint32_t style = faces.front().style;
+      const uint32_t style = faces.front().style;
       for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++)
         if(style!=fit->style)
         {
@@ -590,7 +754,7 @@
 
       for(PRCfaceList::iterator fit=faces.begin(); fit!=faces.end(); fit++)
       {
-        if(fit->transform || group.options.do_break || 
+        if(fit->transform || group.options.do_break ||
            (fit->transparent && !group.options.no_break))
         {
           PRCShell *shell = new PRCShell;
@@ -600,7 +764,7 @@
           PRCBrepData *body = new PRCBrepData;
           body->addConnex(connex);
           const uint32_t body_index = context->addBrepData(body);
-      
+
           PRCBrepModel *brepmodel = new PRCBrepModel();
           brepmodel->index_of_line_style = fit->style;
           brepmodel->context_id = context_index;
@@ -643,7 +807,7 @@
     if(!compfaces.empty())
     {
       bool same_color = true;
-      uint32_t style = compfaces.front().style;
+      const uint32_t style = compfaces.front().style;
       for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
         if(style!=fit->style)
         {
@@ -653,13 +817,13 @@
       PRCTopoContext *context = NULL;
       const uint32_t context_index = getTopoContext(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 || 
+        if(group.options.do_break ||
            (fit->transparent && !group.options.no_break))
         {
           PRCCompressedBrepData *body = new PRCCompressedBrepData;
@@ -702,14 +866,20 @@
       }
     }
 
-    PRCProductOccurrence *product_occurrence = new PRCProductOccurrence(name);
-
-    for(PRCgroupList::iterator it=group.groupList.begin(); it!=group.groupList.end(); it++)
-    {
-       doGroup(*it, part_definition, product_occurrence);
-    }
-
     // Simplify and reduce to as simple entities as possible
+    // products with named representation items can not be reduced to sets, since 
+    // outside references are already set
+    bool nonamedparts = true;
+    for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+    {
+      if (!(*it)->name.empty())
+      {
+        nonamedparts = false;
+        break;
+    }
+    }
+    lastgroupname.clear();
+    lastgroupnames.clear();
     // First option - reduce to one element in parent
     if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
         part_definition->representation_item.size() == 1 &&
@@ -720,32 +890,52 @@
         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);
+      lastgroupname = calculate_unique_name(part_definition->representation_item.front(), parent_product_occurrence);
       parent_part_definition->addRepresentationItem(part_definition->representation_item.front());
       part_definition->representation_item.clear();
-      delete product_occurrence;
-      delete part_definition;
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
     }
     // 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 )
+      !group.options.do_break && nonamedparts)
     {
       PRCSet *set = new PRCSet(name);
       set->index_local_coordinate_system = addTransform(group.transform);
+      lastgroupname = calculate_unique_name(set, parent_product_occurrence);
       for(PRCRepresentationItemList::iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+      {
+        lastgroupnames.push_back(calculate_unique_name(*it, parent_product_occurrence));
         set->addRepresentationItem(*it);
+      }
       part_definition->representation_item.clear();
       parent_part_definition->addSet(set);
-      delete product_occurrence;
-      delete part_definition;      
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
     }
     // Third option - create product
     else if ( !product_occurrence->index_son_occurrence.empty() || !part_definition->representation_item.empty())
     {
-      if (part_definition->representation_item.empty())
-        delete part_definition;
+      // if everything is enclosed in one group - drop the root group
+      if (parent_product_occurrence == NULL && group.transform == NULL &&
+          part_definition->representation_item.empty() && product_occurrence->index_son_occurrence.size()==1) {
+        delete part_definition; part_definition = NULL;
+        delete product_occurrence; product_occurrence = NULL;
+      }
       else
+      {
+        lastgroupname = calculate_unique_name(product_occurrence, NULL);
+        if (part_definition->representation_item.empty()) {
+          delete part_definition; part_definition = NULL;
+        }
+      else
+        {
+          for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+            if ((*it)->name.empty())
+              lastgroupnames.push_back(calculate_unique_name(*it, product_occurrence));
         product_occurrence->index_part = addPartDefinition(part_definition);
+        }
       if (group.transform) {
         product_occurrence->location = group.transform;
         group.transform = NULL;
@@ -757,23 +947,65 @@
         addProductOccurrence(product_occurrence);
       }
     }
+    }
     // Last case - absolutely nothing to do
     else
     {
-      delete product_occurrence;
-      delete part_definition;
-    }
-    
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
+    }
+
+}
+
+std::string oPRCFile::calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence)
+{
+  std::stringstream ss (std::stringstream::in | std::stringstream::out);
+  uint8_t *serialization_buffer = NULL;
+  PRCbitStream serialization(serialization_buffer,0u);
+  const PRCFileStructure *pfile_structure = fileStructures[0];
+  const PRCUniqueId& uuid = pfile_structure->file_structure_uuid;
+// ConvertUniqueIdentifierToString (prc_entity)
+// SerializeCompressedUniqueId (file_structure)
+  serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+  serialization << prc_entity->getType();
+// WriteUnsignedInteger (unique_identifier)
+  serialization << prc_entity->getPRCID();
+  if (prc_occurence)
+  {
+// serialization_buffer = Flush serialization (serialization) 
+  {
+    const uint32_t size_serialization = serialization.getSize();
+    while(size_serialization == serialization.getSize())
+      serialization << false;
+  }
+// ConvertUniqueIdentifierToString (prc_occurrence_unique_id)
+// SerializeCompressedUniqueId (file_structure)
+    serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+    serialization << (uint32_t)PRC_TYPE_ASM_ProductOccurence;
+// WriteUnsignedInteger (unique_identifier)
+    serialization << prc_occurence->getPRCID();
+  }
+  ss << (prc_entity->name.empty()?"node":prc_entity->name) << '.';
+  const uint32_t size_serialization = serialization.getSize();
+  for(size_t j=0; j<size_serialization; j++)
+    ss << hex << setfill('0') << setw(2) << (uint32_t)(serialization_buffer[j]);
+
+  return ss.str();
 }
 
 bool oPRCFile::finish()
 {
-  rootGroup.name = "root";
-  doGroup(rootGroup, NULL, NULL);
+  if(groups.size()!=1) {
+    fputs("begingroup without matching endgroup",stderr);
+    exit(1);
+  }
+  doGroup(groups.top());
 
   // write each section's bit data
   fileStructures[0]->prepare();
-  modelFile.prepare();
+  SerializeModelFileData
 
   // create the header
 
@@ -782,41 +1014,29 @@
   header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures];
   for(uint32_t i = 0; i < number_of_file_structures; ++i)
   {
-    header.fileStructureInformation[i].UUID[0] = fileStructures[i]->header.fileStructureUUID[0];
-    header.fileStructureInformation[i].UUID[1] = fileStructures[i]->header.fileStructureUUID[1];
-    header.fileStructureInformation[i].UUID[2] = fileStructures[i]->header.fileStructureUUID[2];
-    header.fileStructureInformation[i].UUID[3] = fileStructures[i]->header.fileStructureUUID[3];
+    header.fileStructureInformation[i].UUID = fileStructures[i]->file_structure_uuid;
     header.fileStructureInformation[i].reserved = 0;
     header.fileStructureInformation[i].number_of_offsets = 6;
     header.fileStructureInformation[i].offsets = new uint32_t[6];
   }
 
-  header.startHeader.minimal_version_for_read = PRCVersion;
-  header.startHeader.authoring_version = PRCVersion;
-  makeFileUUID(header.startHeader.fileStructureUUID);
-  makeAppUUID(header.startHeader.applicationUUID);
+  header.minimal_version_for_read = PRCVersion;
+  header.authoring_version = PRCVersion;
+  makeFileUUID(header.file_structure_uuid);
+  makeAppUUID(header.application_uuid);
 
   header.file_size = getSize();
-  header.model_file_offset = header.file_size - modelFile.getSize();
+  header.model_file_offset = header.file_size - modelFile_out.getSize();
 
   uint32_t currentOffset = header.getSize();
 
   for(uint32_t i = 0; i < number_of_file_structures; ++i)
   {
-    header.fileStructureInformation[i].offsets[0] = currentOffset; // header offset
-    currentOffset += fileStructures[i]->header.getSize() + sizeof(uint32_t);
-    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
-    currentOffset += fileStructures[i]->tree.getSize();
-    header.fileStructureInformation[i].offsets[3] = currentOffset; // tessellations offset
-    currentOffset += fileStructures[i]->tessellations.getSize();
-    header.fileStructureInformation[i].offsets[4] = currentOffset; // geometry offset
-    currentOffset += fileStructures[i]->geometry.getSize();
-    header.fileStructureInformation[i].offsets[5] = currentOffset; // extra geometry offset
-    currentOffset += fileStructures[i]->extraGeometry.getSize();
+    for(size_t j=0; j<6; j++)
+    {
+      header.fileStructureInformation[i].offsets[j] = currentOffset;
+      currentOffset += fileStructures[i]->sizes[j];
+    }
   }
 
   // write the data
@@ -827,7 +1047,7 @@
     fileStructures[i]->write(output);
   }
 
-  modelFile.write(output);
+  modelFile_out.write(output);
   output.flush();
 
   for(uint32_t i = 0; i < number_of_file_structures; ++i)
@@ -846,52 +1066,68 @@
     size += fileStructures[i]->getSize();
   }
 
-  size += modelFile.getSize();
+  size += modelFile_out.getSize();
   return size;
 }
 
-#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)
 {
+  uint8_t *data = NULL;
+  uint32_t components=0;
+  PRCPicture picture(name);
   if(size==0 || p==NULL)
-    REPORT_ERROR( "image not set" )
-  PRCPicture picture(name);
-  PRCUncompressedFile uncompressedFile;
-  uint32_t components=0;
-  uint8_t *data = NULL;
+    { cerr << "image not set" << endl; return m1; }
+  PRCUncompressedFile* uncompressed_file = new PRCUncompressedFile;
+  if(format==KEPRCPicture_PNG || format==KEPRCPicture_JPG)
+  {
+    data = new uint8_t[size];
+    memcpy(data, p, size);
+    uncompressed_files.push_back(uncompressed_file);
+    uncompressed_files.back()->file_size = size;
+    uncompressed_files.back()->data = data;
+    picture.format = format;
+    picture.uncompressed_file_index = uncompressed_files.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;
+    pictures.push_back(picture);
+    return pictures.size()-1;
+  }
+
   switch(format)
   {
     case KEPRCPicture_BITMAP_RGB_BYTE:
-      components = 3;
+      components = 3; break;
     case KEPRCPicture_BITMAP_RGBA_BYTE:
-      components = 4;
+      components = 4; break;
     case KEPRCPicture_BITMAP_GREY_BYTE:
-      components = 1;
+      components = 1; break;
     case KEPRCPicture_BITMAP_GREYA_BYTE:
-      components = 2;
+      components = 2; break;
+    default:
+      { cerr << "unknown picture format" << endl; return m1; }
+  }
       if(width==0 || height==0)
-        REPORT_ERROR( "width or height parameter not set" )
+        { cerr << "width or height parameter not set" << endl; return m1; }
       if (size < width*height*components)
-        REPORT_ERROR( "image too small" )
-   
+        { cerr << "image too small" << endl; return m1; }
+
       {
         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" )
+          { cerr << "Compression initialization failed" << endl; return m1; }
         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)
@@ -905,95 +1141,73 @@
           sizeAvailable += CHUNK;
         }
         compressedDataSize = sizeAvailable-strm.avail_out;
-       
+
         if(code != Z_STREAM_END)
         {
           deflateEnd(&strm);
           free(compressedData);
-          REPORT_ERROR ( "Compression error" )
+          { cerr << "Compression error" << endl; return m1; }
         }
-       
+
         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;
+      uncompressed_files.push_back(uncompressed_file);
+      uncompressed_files.back()->file_size = size;
+      uncompressed_files.back()->data = data;
       picture.format = format;
-      picture.uncompressed_file_index = uncompressedFiles.size()-1;
+      picture.uncompressed_file_index = uncompressed_files.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 PRCFileStructure::addTextureDefinition(PRCTextureDefinition *pTextureDefinition)
-{
-  globals.texture_definitions.push_back(pTextureDefinition);
-  return globals.texture_definitions.size()-1;
+      pictures.push_back(picture);
+      return pictures.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureDefinition(PRCTextureDefinition*& pTextureDefinition)
+{
+  texture_definitions.push_back(pTextureDefinition);
+  pTextureDefinition = NULL;
+  return texture_definitions.size()-1;
 }
 
 uint32_t PRCFileStructure::addRgbColor(const PRCRgbColor &color)
 {
-  globals.colors.push_back(color);
-  return 3*(globals.colors.size()-1);
+  colors.push_back(color);
+  return 3*(colors.size()-1);
 }
 
 uint32_t PRCFileStructure::addRgbColorUnique(const PRCRgbColor &color)
 {
-  for(uint32_t i = 0; i < globals.colors.size(); ++i)
-  {
-    if(globals.colors[i] == color)
+  for(uint32_t i = 0; i < colors.size(); ++i)
+  {
+    if(colors[i] == color)
       return 3*i;
   }
-  globals.colors.push_back(color);
-  return 3*(globals.colors.size()-1);
+  colors.push_back(color);
+  return 3*(colors.size()-1);
 }
 
 uint32_t oPRCFile::addColor(const PRCRgbColor &color)
 {
-  PRCcolorMap::iterator pColor = colorMap.find(color);
-  uint32_t color_index = m1;
+  PRCcolorMap::const_iterator pColor = colorMap.find(color);
   if(pColor!=colorMap.end())
     return pColor->second;
 //  color_index = addRgbColorUnique(color);
-  color_index = fileStructures[0]->addRgbColor(color);
+  const uint32_t 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);
+  PRCcolourMap::const_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();  
+  PRCStyle *style = new PRCStyle();
   style->line_width = 1.0;
   style->is_vpicture = false;
   style->line_pattern_vpicture_index = 0;
@@ -1007,95 +1221,242 @@
   return style_index;
 }
 
+uint32_t oPRCFile::addColourWidth(const RGBAColour &colour, double width)
+{
+  RGBAColourWidth colourwidth(colour.R, colour.G, colour.B, colour.A, width);
+  PRCcolourwidthMap::const_iterator pColour = colourwidthMap.find(colourwidth);
+  if(pColour!=colourwidthMap.end())
+    return pColour->second;
+  const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+  PRCStyle *style = new PRCStyle();
+  style->line_width = width;
+  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);
+  colourwidthMap.insert(make_pair(colourwidth,style_index));
+  return style_index;
+}
+
 uint32_t oPRCFile::addTransform(PRCGeneralTransformation3d*& transform)
 {
   if(!transform)
     return m1;
-  PRCtransformMap::iterator pTransform = transformMap.find(*transform);
+  PRCtransformMap::const_iterator pTransform = transformMap.find(*transform);
   if(pTransform!=transformMap.end())
     return pTransform->second;
   PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+  bool transform_replaced = false;
+  if(                            transform->M(0,1)==0 && transform->M(0,2)==0 &&
+      transform->M(1,0)==0 &&                            transform->M(1,2)==0 &&
+      transform->M(2,0)==0 && transform->M(2,1)==0 &&
+      transform->M(3,0)==0 && transform->M(3,1)==0 && transform->M(3,2)==0 && transform->M(3,3)==1 )
+  {
+    transform_replaced = true;
+    PRCCartesianTransformation3d *carttransform = new PRCCartesianTransformation3d;
+//  if(transform->M(0,3)==0 && transform->M(1,3)==0 && transform->M(1,3)==0 &&
+//     transform->M(0,0)==1 && transform->M(1,1)==1 && transform->M(2,2)==1 )
+//    carttransform->behaviour = PRC_TRANSFORMATION_Identity;
+    if(transform->M(0,3)!=0 || transform->M(1,3)!=0 || transform->M(2,3)!=0)
+    {
+      carttransform->behaviour |= PRC_TRANSFORMATION_Translate;
+      carttransform->origin.Set(transform->M(0,3),transform->M(1,3),transform->M(2,3));
+    }
+    if(transform->M(0,0)!=transform->M(1,1) || transform->M(0,0)!=transform->M(2,2))
+    {
+      carttransform->behaviour |= PRC_TRANSFORMATION_NonUniformScale;
+      carttransform->scale.Set(transform->M(0,0),transform->M(1,1),transform->M(2,2));
+    }
+    else
+      if(transform->M(0,0)!=1)
+      {
+        carttransform->behaviour |= PRC_TRANSFORMATION_Scale;
+        carttransform->uniform_scale=transform->M(0,0);
+      }
+    coordinateSystem->axis_set = carttransform;
+  }
+  else
   coordinateSystem->axis_set = transform;
   const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
   transformMap.insert(make_pair(*transform,coordinate_system_index));
+  if(transform_replaced)
+    delete transform;
   transform = NULL;
   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);
+uint32_t oPRCFile::addTransform(const double* t)
+{
+  if(!t)
+    return m1;
+  PRCGeneralTransformation3d* transform = new PRCGeneralTransformation3d(t);
+  return addTransform(transform);
+}
+
+uint32_t oPRCFile::addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCCartesianTransformation3d* transform = new PRCCartesianTransformation3d(origin, x_axis, y_axis, scale);
+  if(transform->behaviour==PRC_TRANSFORMATION_Identity)
+    return m1;
+  PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+  coordinateSystem->axis_set = transform;
+  const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+  return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addMaterial(const PRCmaterial& m)
+{
+  uint32_t material_index = m1;
+  const PRCmaterialgeneric materialgeneric(m);
+  PRCmaterialgenericMap::const_iterator pMaterialgeneric = materialgenericMap.find(materialgeneric);
+  if(pMaterialgeneric!=materialgenericMap.end())
+    material_index = pMaterialgeneric->second;
+  else
+{
+  PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric();
+  const PRCRgbColor ambient(m.ambient.R, m.ambient.G, m.ambient.B);
   materialGeneric->ambient = addColor(ambient);
-  const PRCRgbColor diffuse(material.diffuse.R, material.diffuse.G, material.diffuse.B);
+    const PRCRgbColor diffuse(m.diffuse.R, m.diffuse.G, m.diffuse.B);
   materialGeneric->diffuse = addColor(diffuse);
-  const PRCRgbColor emissive(material.emissive.R, material.emissive.G, material.emissive.B);
+    const PRCRgbColor emissive(m.emissive.R, m.emissive.G, m.emissive.B);
+
   materialGeneric->emissive = addColor(emissive);
-  const PRCRgbColor specular(material.specular.R, material.specular.G, material.specular.B);
+    const PRCRgbColor specular(m.specular.R, m.specular.G, m.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 == NULL ||
-    (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);
-}
-bool isid(const double t[])
-{
-  return(isid((double (*)[4])t));
-}
-
+
+    materialGeneric->shininess = m.shininess;
+    materialGeneric->ambient_alpha = m.ambient.A;
+    materialGeneric->diffuse_alpha = m.diffuse.A;
+    materialGeneric->emissive_alpha = m.emissive.A;
+    materialGeneric->specular_alpha = m.specular.A;
+    material_index = addMaterialGeneric(materialGeneric);
+    materialgenericMap.insert(make_pair(materialgeneric,material_index));
+  }
+  uint32_t color_material_index = m1;
+  if(m.picture_data!=NULL)
+  {
+    uint32_t picture_index = m1;
+    PRCpicture picture(m);
+    PRCpictureMap::const_iterator pPicture = pictureMap.find(picture);
+    if(pPicture!=pictureMap.end())
+      picture_index = pPicture->second;
+    else
+    {
+      picture_index = addPicture(picture);
+      uint8_t* data = new uint8_t[picture.size];
+      memcpy(data,picture.data,picture.size);
+      picture.data = data;
+      pictureMap.insert(make_pair(picture,picture_index));
+    }
+
+    uint32_t texture_definition_index = m1;
+    PRCtexturedefinition texturedefinition(picture_index, m);
+    PRCtexturedefinitionMap::const_iterator pTexturedefinition = texturedefinitionMap.find(texturedefinition);
+    if(pTexturedefinition!=texturedefinitionMap.end())
+      texture_definition_index = pTexturedefinition->second;
+    else
+    {
+      PRCTextureDefinition *TextureDefinition = new PRCTextureDefinition;
+      if (m.picture_size==216688 && m.picture_format==KEPRCPicture_JPG)
+        TextureDefinition->texture_mapping_attribute=PRC_TEXTURE_MAPPING_OPACITY;
+      TextureDefinition->picture_index = picture_index;
+      TextureDefinition->texture_function = m.picture_replace ? KEPRCTextureFunction_Replace : KEPRCTextureFunction_Modulate;
+      TextureDefinition->texture_wrapping_mode_S = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+      TextureDefinition->texture_wrapping_mode_T = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+      TextureDefinition->texture_mapping_attribute_components = (m.picture_format==KEPRCPicture_BITMAP_RGB_BYTE || m.picture_format==KEPRCPicture_JPG) ? PRC_TEXTURE_MAPPING_COMPONENTS_RGB : PRC_TEXTURE_MAPPING_COMPONENTS_RGBA;
+      texture_definition_index = addTextureDefinition(TextureDefinition);
+      texturedefinitionMap.insert(make_pair(texturedefinition,texture_definition_index));
+    }
+
+    uint32_t texture_application_index = m1;
+    const PRCtextureapplication textureapplication(material_index, texture_definition_index);
+    PRCtextureapplicationMap::const_iterator pTextureapplication = textureapplicationMap.find(textureapplication);
+    if(pTextureapplication!=textureapplicationMap.end())
+      texture_application_index = pTextureapplication->second;
+    else
+    {
+      PRCTextureApplication *TextureApplication = new PRCTextureApplication;
+      TextureApplication->material_generic_index = material_index;
+      TextureApplication->texture_definition_index = texture_definition_index;
+      texture_application_index = addTextureApplication(TextureApplication);
+      textureapplicationMap.insert(make_pair(textureapplication,texture_application_index));
+    }
+
+    color_material_index = texture_application_index;
+  }
+  else
+    color_material_index = material_index;
+
+  uint32_t style_index = m1;
+  PRCstyle style(0,m.alpha,true,color_material_index);
+  PRCstyleMap::const_iterator pStyle = styleMap.find(style);
+  if(pStyle!=styleMap.end())
+    style_index = pStyle->second;
+  else
+  {
+    PRCStyle *Style = new PRCStyle();
+    Style->line_width = 0.0;
+    Style->is_vpicture = false;
+    Style->line_pattern_vpicture_index = 0;
+    Style->is_material = true;
+    Style->is_transparency_defined = (m.alpha < 1.0);
+    Style->transparency = (uint8_t)(m.alpha * 256);
+    Style->additional = 0;
+    Style->color_material_index = color_material_index;
+    style_index = addStyle(Style);
+    styleMap.insert(make_pair(style,style_index));
+  }
+//  materialMap.insert(make_pair(material,style_index));
+   return style_index;
+}
+
+bool isid(const double* t)
+{
+  return(
+         t[0]==1 && t[4]==0 && t[ 8]==0 && t[12]==0 &&
+         t[1]==0 && t[5]==1 && t[ 9]==0 && t[13]==0 &&
+         t[2]==0 && t[6]==0 && t[10]==1 && t[14]==0 &&
+         t[3]==0 && t[7]==0 && t[11]==0 && t[15]==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());
+                          const double* t)
+{
+  const PRCgroup &parent_group = groups.top();
+  groups.push(PRCgroup());
+  PRCgroup &group = groups.top();
   group.name=name;
   if(options) group.options=*options;
   if(t&&!isid(t))
     group.transform = new PRCGeneralTransformation3d(t);
+  group.product_occurrence = new PRCProductOccurrence(name);
+  group.parent_product_occurrence = parent_group.product_occurrence;
+  group.part_definition = new PRCPartDefinition;
+  group.parent_part_definition = parent_group.part_definition;
 }
 
 void oPRCFile::endgroup()
 {
-  if(!currentGroups.empty())
-    currentGroups.pop();
+  if(groups.size()<2) {
+    fputs("begingroup without matching endgroup",stderr);
+    exit(1);
+  }
+  doGroup(groups.top());
+  groups.pop();
+
+// std::cout << lastgroupname << std::endl;
+// for(std::vector<std::string>::const_iterator it=lastgroupnames.begin(); it!=lastgroupnames.end(); it++)
+//   std::cout << " " << *it << std::endl;
+
 }
 
 PRCgroup& oPRCFile::findGroup()
 {
-  if(!currentGroups.empty())
-    return *(currentGroups.top());
-  else
-    return rootGroup;
+  return groups.top();
 }
 
 #define ADDWIRE(curvtype)                                 \
@@ -1125,23 +1486,453 @@
   face.transparent = m.alpha < 1.0;                       \
   face.style = addMaterial(m);
 
-void oPRCFile::addPoint(const double P[3], const RGBAColour &c)
+void oPRCFile::addPoint(const double P[3], const RGBAColour &c, double w)
 {
   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)
+  group.points[addColourWidth(c,w)].push_back(PRCVector3d(P[0],P[1],P[2]));
+}
+
+void oPRCFile::addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w)
+{
+  if(n==0 || P==NULL)
+     return;
+  PRCgroup &group = findGroup();
+  PRCPointSet *pointset = new PRCPointSet();
+  group.pointsets.push_back(pointset);
+  pointset->index_of_line_style = addColourWidth(c,w);
+  pointset->point.reserve(n);
+  for(uint32_t i=0; i<n; i++)
+    pointset->point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+  polyBrepModel->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+  polyBrepModel->index_tessellation = tess_index;
+  polyBrepModel->is_closed = group.options.closed;
+  polyBrepModel->index_of_line_style = style_index;
+  group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+  polyBrepModel->index_local_coordinate_system = addTransform(t);
+  polyBrepModel->index_tessellation = tess_index;
+  polyBrepModel->is_closed = group.options.closed;
+  polyBrepModel->index_of_line_style = style_index;
+  group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyWire *polyWire = new PRCPolyWire();
+  polyWire->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+  polyWire->index_tessellation = tess_index;
+  polyWire->index_of_line_style = style_index;
+  group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyWire *polyWire = new PRCPolyWire();
+  polyWire->index_local_coordinate_system = addTransform(t);
+  polyWire->index_tessellation = tess_index;
+  polyWire->index_of_line_style = style_index;
+  group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial &m,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return;
+  const uint32_t tess_index = createTriangleMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca);
+  useMesh(tess_index,m1);
+}
+
+uint32_t oPRCFile::createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const uint32_t style_index,
+ uint32_t nN, const double N[][3],  const uint32_t NI[][3],
+ uint32_t nT, const double T[][2],  const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
+ uint32_t nS, const uint32_t S[],   const uint32_t SI[], double ca)
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return m1;
+
+  const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+  const bool vertex_color   = (nC != 0 && C != NULL && CI != NULL);
+  const bool has_normals    = (nN != 0 && N != NULL && NI != NULL);
+  const bool textured       = (nT != 0 && T != NULL && TI != NULL);
+
+  PRC3DTess *tess = new PRC3DTess();
+  PRCTessFace *tessFace = new PRCTessFace();
+  tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+  tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  if(has_normals)
+  {
+    tess->normal_coordinate.reserve(3*nN);
+  for(uint32_t i=0; i<nN; i++)
+  {
+    tess->normal_coordinate.push_back(N[i][0]);
+    tess->normal_coordinate.push_back(N[i][1]);
+    tess->normal_coordinate.push_back(N[i][2]);
+  }
+  }
+  else
+    tess->crease_angle = ca;
+  if(textured)
+  {
+    tess->texture_coordinate.reserve(2*nT);
+  for(uint32_t i=0; i<nT; i++)
+  {
+    tess->texture_coordinate.push_back(T[i][0]);
+    tess->texture_coordinate.push_back(T[i][1]);
+  }
+  }
+  tess->triangulated_index.reserve(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI);
+  for(uint32_t i=0; i<nI; i++)
+  {
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][0]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][0]);
+    tess->triangulated_index.push_back(3*PI[i][0]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][2]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][2]);
+    tess->triangulated_index.push_back(3*PI[i][2]);
+  }
+  tessFace->sizes_triangulated.push_back(nI);
+  if(triangle_color)
+  {
+    tessFace->line_attributes.reserve(nI);
+    for(uint32_t i=0; i<nI; i++)
+       tessFace->line_attributes.push_back(SI[i]);
+  }
+  else if (style_index != m1 )
+  {
+      tessFace->line_attributes.push_back(style_index);
+  }
+  if(vertex_color)
+  {
+    tessFace->is_rgba=false;
+    for(uint32_t i=0; i<nI; i++)
+      if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+      {
+         tessFace->is_rgba=true;
+         break;
+      }
+
+    tessFace->rgba_vertices.reserve((tessFace->is_rgba?4:3)*3*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+    }
+  }
+  tess->addTessFace(tessFace);
+  const uint32_t tess_index = add3DTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial &m,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return;
+  const uint32_t tess_index = createQuadMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI, ca);
+  useMesh(tess_index,m1);
+}
+
+uint32_t oPRCFile::createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+ uint32_t nS, const uint32_t S[],    const uint32_t SI[], double ca)
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return m1;
+
+  const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+  const bool vertex_color   = (nC != 0 && C != NULL && CI != NULL);
+  const bool has_normals    = (nN != 0 && N != NULL && NI != NULL);
+  const bool textured       = (nT != 0 && T != NULL && TI != NULL);
+
+  PRC3DTess *tess = new PRC3DTess();
+  PRCTessFace *tessFace = new PRCTessFace();
+  tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+  tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  if(has_normals)
+  {
+    tess->normal_coordinate.reserve(3*nN);
+  for(uint32_t i=0; i<nN; i++)
+  {
+    tess->normal_coordinate.push_back(N[i][0]);
+    tess->normal_coordinate.push_back(N[i][1]);
+    tess->normal_coordinate.push_back(N[i][2]);
+  }
+  }
+  else
+    tess->crease_angle = ca;
+  if(textured)
+  {
+    tess->texture_coordinate.reserve(2*nT);
+  for(uint32_t i=0; i<nT; i++)
+  {
+    tess->texture_coordinate.push_back(T[i][0]);
+    tess->texture_coordinate.push_back(T[i][1]);
+  }
+  }
+  tess->triangulated_index.reserve(2*(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI));
+  for(uint32_t i=0; i<nI; i++)
+  {
+    // first triangle
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][0]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][0]);
+    tess->triangulated_index.push_back(3*PI[i][0]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][3]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][3]);
+    tess->triangulated_index.push_back(3*PI[i][3]);
+    // second triangle
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][2]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][2]);
+    tess->triangulated_index.push_back(3*PI[i][2]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][3]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][3]);
+    tess->triangulated_index.push_back(3*PI[i][3]);
+  }
+  tessFace->sizes_triangulated.push_back(2*nI);
+  if(triangle_color)
+  {
+    tessFace->line_attributes.reserve(2*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       tessFace->line_attributes.push_back(SI[i]);
+       tessFace->line_attributes.push_back(SI[i]);
+    }
+  }
+  else
+  {
+      tessFace->line_attributes.push_back(style_index);
+  }
+  if(vertex_color)
+  {
+    tessFace->is_rgba=false;
+    for(uint32_t i=0; i<nI; i++)
+      if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+      {
+         tessFace->is_rgba=true;
+         break;
+      }
+
+    tessFace->rgba_vertices.reserve(2*(tessFace->is_rgba?4:3)*3*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       // first triangle
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+       // second triangle
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+    }
+  }
+  tess->addTessFace(tessFace);
+  const uint32_t tess_index = add3DTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addQuad(const double P[][3], const RGBAColour C[])
+{
+  PRCgroup &group = findGroup();
+
+  group.quads.push_back(PRCtessquad());
+  PRCtessquad &quad = group.quads.back();
+  for(size_t i = 0; i < 4; i++)
+  {
+    quad.vertices[i].x = P[i][0];
+    quad.vertices[i].y = P[i][1];
+    quad.vertices[i].z = P[i][2];
+    quad.colours[i] = C[i];
+  }
+}
+/*
+void oPRCFile::addTriangle(const double P[][3], const double T[][2], uint32_t style_index)
+{
+  PRCgroup &group = findGroup();
+
+  group.triangles.push_back(PRCtesstriangle());
+  PRCtesstriangle &triangle = group.triangles.back();
+  for(size_t i = 0; i < 3; i++)
+  {
+    triangle.vertices[i].x = P[i][0];
+    triangle.vertices[i].y = P[i][1];
+    triangle.vertices[i].z = P[i][2];
+    triangle.texcoords[i].x = T[i][0];
+    triangle.texcoords[i].y = T[i][1];
+  }
+  triangle.style = style_index;
+}
+*/
+
+void oPRCFile::addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ const RGBAColour& c, double w,
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+    return;
+  const uint32_t tess_index = createLines(nP, P, nI, PI, segment_color, nC, C, nCI, CI);
+  useLines(tess_index, c, w);
+}
+
+uint32_t oPRCFile::createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+    return m1;
+
+  const bool vertex_color  = (nC != 0 && C != NULL && CI != NULL);
+
+  PRC3DWireTess *tess = new PRC3DWireTess();
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  tess->wire_indexes.reserve(nI);
+  for(uint32_t i=0; i<nI;)
+  {
+    tess->wire_indexes.push_back(PI[i]);
+    const uint32_t ni = i+PI[i]+1;
+    for(i++; i<ni; i++)
+      tess->wire_indexes.push_back(3*PI[i]);
+  }
+  if(vertex_color)
+  {
+    tess->is_segment_color = segment_color;
+    tess->is_rgba=false;
+    for(uint32_t i=0; i<nCI; i++)
+      if(1.0 != C[CI[i]].A)
+      {
+         tess->is_rgba=true;
+         break;
+      }
+    tess->rgba_vertices.reserve((tess->is_rgba?4:3)*nCI);
+    for(uint32_t i=0; i<nCI; i++)
+    {
+       tess->rgba_vertices.push_back(byte(C[CI[i]].R));
+       tess->rgba_vertices.push_back(byte(C[CI[i]].G));
+       tess->rgba_vertices.push_back(byte(C[CI[i]].B));
+       if(tess->is_rgba)
+       tess->rgba_vertices.push_back(byte(C[CI[i]].A));
+    }
+  }
+  const uint32_t tess_index = add3DWireTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addLine(uint32_t n, const double P[][3], const RGBAColour &c, double w)
 {
   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;
+    group.lines[w].push_back(PRCtessline());
+    PRCtessline& line = group.lines[w].back();
+    line.color.red   = c.R;
+    line.color.green = c.G;
+    line.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]));
+      line.point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
   }
   else
   {
@@ -1174,7 +1965,7 @@
 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->is_rational = (w!=NULL);
   curve->degree = d;
   curve->control_point.resize(n);
   for(uint32_t i = 0; i < n; i++)
@@ -1192,7 +1983,6 @@
   PRCgroup &group = findGroup();
   if(group.options.tess)
   {
-    PRCgroup &group = findGroup();
     group.rectangles.push_back(PRCtessrectangle());
     PRCtessrectangle &rectangle = group.rectangles.back();
     rectangle.style = addMaterial(m);
@@ -1245,7 +2035,7 @@
   if(group.options.compression == 0.0)
   {
     ADDFACE(PRCNURBSSurface)
-   
+
     surface->is_rational = false;
     surface->degree_in_u = 3;
     surface->degree_in_v = 3;
@@ -1289,7 +2079,7 @@
 {
   ADDFACE(PRCNURBSSurface)
 
-  surface->is_rational = w;
+  surface->is_rational = (w!=NULL);
   surface->degree_in_u = dU;
   surface->degree_in_v = dV;
   surface->control_point.resize(nU*nV);
@@ -1310,15 +2100,15 @@
   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))                                     \
+  if(surface->origin!=PRCVector3d(0.0,0.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)) \
+  if(surface->x_axis!=PRCVector3d(1.0,0.0,0.0)||surface->y_axis!=PRCVector3d(0.0,1.0,0.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]
+#define PRCFACETRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale, const double* t
 
 void oPRCFile::addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial &m, PRCFACETRANSFORM)
 {
@@ -1436,6 +2226,18 @@
   surface->radius = radius;
 }
 
+void oPRCFile::addCone(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCCone)
+  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->bottom_radius = radius;
+  surface->semi_angle = -atan(radius/height);;
+}
+
 void oPRCFile::addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM)
 {
   ADDFACE(PRCTorus)
@@ -1455,37 +2257,37 @@
 
 uint32_t PRCFileStructure::addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric)
 {
-  globals.materials.push_back(pMaterialGeneric);
+  materials.push_back(pMaterialGeneric);
   pMaterialGeneric = NULL;
-  return globals.materials.size()-1;
+  return materials.size()-1;
 }
 
 uint32_t PRCFileStructure::addTextureApplication(PRCTextureApplication*& pTextureApplication)
 {
-  globals.materials.push_back(pTextureApplication);
+  materials.push_back(pTextureApplication);
   pTextureApplication = NULL;
-  return globals.materials.size()-1;
+  return materials.size()-1;
 }
 
 uint32_t PRCFileStructure::addStyle(PRCStyle*& pStyle)
 {
-  globals.styles.push_back(pStyle);
+  styles.push_back(pStyle);
   pStyle = NULL;
-  return globals.styles.size()-1;
+  return styles.size()-1;
 }
 
 uint32_t PRCFileStructure::addPartDefinition(PRCPartDefinition*& pPartDefinition)
 {
-  tree.part_definitions.push_back(pPartDefinition);
-  pPartDefinition = NULL;  
-  return tree.part_definitions.size()-1;
+  part_definitions.push_back(pPartDefinition);
+  pPartDefinition = NULL;
+  return part_definitions.size()-1;
 }
 
 uint32_t PRCFileStructure::addProductOccurrence(PRCProductOccurrence*& pProductOccurrence)
 {
-  tree.product_occurrences.push_back(pProductOccurrence);
+  product_occurrences.push_back(pProductOccurrence);
   pProductOccurrence = NULL;
-  return tree.product_occurrences.size()-1;
+  return product_occurrences.size()-1;
 }
 
 uint32_t PRCFileStructure::addTopoContext(PRCTopoContext*& pTopoContext)
@@ -1504,56 +2306,56 @@
 
 uint32_t PRCFileStructure::add3DTess(PRC3DTess*& p3DTess)
 {
-  tessellations.tessellations.push_back(p3DTess);
+  tessellations.push_back(p3DTess);
   p3DTess = NULL;
-  return tessellations.tessellations.size()-1;
+  return tessellations.size()-1;
 }
 
 uint32_t PRCFileStructure::add3DWireTess(PRC3DWireTess*& p3DWireTess)
 {
-  tessellations.tessellations.push_back(p3DWireTess);
+  tessellations.push_back(p3DWireTess);
   p3DWireTess = NULL;
-  return tessellations.tessellations.size()-1;
+  return tessellations.size()-1;
 }
 /*
 uint32_t PRCFileStructure::addMarkupTess(PRCMarkupTess*& pMarkupTess)
 {
-  tessellations.tessellations.push_back(pMarkupTess);
+  tessellations.push_back(pMarkupTess);
   pMarkupTess = NULL;
-  return tessellations.tessellations.size()-1;
+  return tessellations.size()-1;
 }
 
 uint32_t PRCFileStructure::addMarkup(PRCMarkup*& pMarkup)
 {
-  tree.markups.push_back(pMarkup);
+  markups.push_back(pMarkup);
   pMarkup = NULL;
-  return tree.markups.size()-1;
+  return markups.size()-1;
 }
 
 uint32_t PRCFileStructure::addAnnotationItem(PRCAnnotationItem*& pAnnotationItem)
 {
-  tree.annotation_entities.push_back(pAnnotationItem);
+  annotation_entities.push_back(pAnnotationItem);
   pAnnotationItem = NULL;
-  return tree.annotation_entities.size()-1;
+  return annotation_entities.size()-1;
 }
 */
 uint32_t PRCFileStructure::addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem)
 {
-  globals.reference_coordinate_systems.push_back(pCoordinateSystem);
+  reference_coordinate_systems.push_back(pCoordinateSystem);
   pCoordinateSystem = NULL;
-  return globals.reference_coordinate_systems.size()-1;
+  return 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) {
+  for(uint32_t i = 0; i < reference_coordinate_systems.size(); ++i)
+  {
+    if(*(reference_coordinate_systems[i])==*pCoordinateSystem) {
       pCoordinateSystem = NULL;
       return i;
     }
   }
-  globals.reference_coordinate_systems.push_back(pCoordinateSystem);
+  reference_coordinate_systems.push_back(pCoordinateSystem);
   pCoordinateSystem = NULL;
-  return globals.reference_coordinate_systems.size()-1;
-}
+  return reference_coordinate_systems.size()-1;
+}

Modified: trunk/Scribus/scribus/third_party/prc/oPRCFile.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/oPRCFile.h
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/oPRCFile.h (original)
+++ trunk/Scribus/scribus/third_party/prc/oPRCFile.h Fri Sep 28 15:05:16 2012
@@ -25,9 +25,11 @@
 #include <fstream>
 #include <vector>
 #include <map>
+#include <set>
 #include <list>
 #include <stack>
 #include <string>
+#include <cstring>
 
 #ifdef HAVE_CONFIG_H
 #include "scconfig.h"
@@ -46,6 +48,10 @@
     R(r), G(g), B(b), A(a) {}
   double R,G,B,A;
 
+  void Set(double r, double g, double b, double a=1.0) 
+  {
+    R = r; G = g; B = b; A = a;
+  }
   bool operator==(const RGBAColour &c) const
   {
     return (R==c.R && G==c.G && B==c.B && A==c.A);
@@ -64,23 +70,87 @@
       return (B<c.B);
     return (A<c.A);
   }
+  friend RGBAColour operator * (const RGBAColour& a, const double d)
+  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+  friend RGBAColour operator * (const double d, const RGBAColour& a)
+  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+
 };
 typedef std::map<RGBAColour,uint32_t> PRCcolourMap;
+
+struct RGBAColourWidth
+{
+  RGBAColourWidth(double r=0.0, double g=0.0, double b=0.0, double a=1.0, double w=1.0) :
+    R(r), G(g), B(b), A(a), W(w) {}
+  double R,G,B,A,W;
+
+  bool operator==(const RGBAColourWidth &c) const
+  {
+    return (R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+  }
+  bool operator!=(const RGBAColourWidth &c) const
+  {
+    return !(R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+  }
+  bool operator<(const RGBAColourWidth &c) const
+  {
+    if(R!=c.R)
+      return (R<c.R);
+    if(G!=c.G)
+      return (G<c.G);
+    if(B!=c.B)
+      return (B<c.B);
+    if(A!=c.A)
+      return (A<c.A);
+    return (W<c.W);
+  }
+};
+typedef std::map<RGBAColourWidth,uint32_t> PRCcolourwidthMap;
+
 typedef std::map<PRCRgbColor,uint32_t> PRCcolorMap;
 
 struct PRCmaterial
 {
-  PRCmaterial() : alpha(1.0),shininess(1.0) {}
+  PRCmaterial() : alpha(1.0),shininess(1.0),
+      picture_data(NULL), picture_format(KEPRCPicture_BITMAP_RGB_BYTE), picture_width(0), picture_height(0), picture_size(0),
+      picture_replace(false), picture_repeat(false) {}
   PRCmaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e,
-              const RGBAColour &s, double p, double h) :
-      ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
+              const RGBAColour &s, double p, double h,
+              const uint8_t* pic=NULL, EPRCPictureDataFormat picf=KEPRCPicture_BITMAP_RGB_BYTE,
+              uint32_t picw=0, uint32_t pich=0, uint32_t pics=0, bool picreplace=false, bool picrepeat=false) :
+      ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h),
+      picture_data(pic), picture_format(picf), picture_width(picw), picture_height(pich), picture_size(pics),
+      picture_replace(picreplace), picture_repeat(picrepeat) {
+        if(picture_size==0)
+        {
+          if (picture_format==KEPRCPicture_BITMAP_RGB_BYTE)
+             picture_size = picture_width*picture_height*3;
+          if (picture_format==KEPRCPicture_BITMAP_RGBA_BYTE)
+             picture_size = picture_width*picture_height*4;
+          if (picture_format==KEPRCPicture_BITMAP_GREY_BYTE)
+             picture_size = picture_width*picture_height*1;
+          if (picture_format==KEPRCPicture_BITMAP_GREYA_BYTE)
+             picture_size = picture_width*picture_height*2;
+        }
+      }
   RGBAColour ambient,diffuse,emissive,specular;
   double alpha,shininess;
+  const uint8_t* picture_data;
+  EPRCPictureDataFormat picture_format;
+  uint32_t picture_width;
+  uint32_t picture_height;
+  uint32_t picture_size;
+  bool picture_replace; // replace material color with texture color? if false - just modify
+  bool picture_repeat;  // repeat texture? if false - clamp to edge
 
   bool operator==(const PRCmaterial &m) const
   {
     return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
-        && specular==m.specular && alpha==m.alpha && shininess==m.shininess);
+        && specular==m.specular && alpha==m.alpha && shininess==m.shininess
+        && picture_replace==m.picture_replace && picture_repeat==m.picture_repeat
+        && picture_format==m.picture_format
+        && picture_width==m.picture_width && picture_height==m.picture_height && picture_size==m.picture_size
+        && (picture_data==m.picture_data || memcmp(picture_data,m.picture_data,picture_size)==0) );
   }
   bool operator<(const PRCmaterial &m) const
   {
@@ -94,10 +164,202 @@
       return (specular<m.specular);
     if(alpha!=m.alpha)
       return (alpha<m.alpha);
-    return (shininess<m.shininess);
+    if(shininess!=m.shininess)
+      return (shininess<m.shininess);
+    if(picture_replace!=m.picture_replace)
+      return (picture_replace<m.picture_replace);
+    if(picture_repeat!=m.picture_repeat)
+      return (picture_repeat<m.picture_repeat);
+    if(picture_format!=m.picture_format)
+      return (picture_format<m.picture_format);
+    if(picture_width!=m.picture_width)
+      return (picture_width<m.picture_width);
+    if(picture_height!=m.picture_height)
+      return (picture_height<m.picture_height);
+    if(picture_size!=m.picture_size)
+      return (picture_size<m.picture_size);
+    if(picture_data!=m.picture_data)
+      return (memcmp(picture_data,m.picture_data,picture_size)<0);
+    return false;
   }
 };
 typedef std::map<PRCmaterial,uint32_t> PRCmaterialMap;
+
+struct PRCpicture
+{
+  PRCpicture() : 
+      data(NULL), format(KEPRCPicture_BITMAP_RGB_BYTE),
+      width(0), height(0), size(0) {}
+  PRCpicture(const uint8_t* pic, EPRCPictureDataFormat picf,
+             uint32_t picw, uint32_t pich, uint32_t pics=0) :
+      data(pic), format(picf),
+      width(picw), height(pich), size(pics)
+  {
+    if(size==0)
+    {
+      if (format==KEPRCPicture_BITMAP_RGB_BYTE)
+         size = width*height*3;
+      if (format==KEPRCPicture_BITMAP_RGBA_BYTE)
+         size = width*height*4;
+      if (format==KEPRCPicture_BITMAP_GREY_BYTE)
+         size = width*height*1;
+      if (format==KEPRCPicture_BITMAP_GREYA_BYTE)
+         size = width*height*2;
+    }
+  }
+  PRCpicture(const PRCmaterial& m) :
+      data(m.picture_data), format(m.picture_format),
+      width(m.picture_width), height(m.picture_height), size(m.picture_size) {}
+
+  const uint8_t* data;
+  EPRCPictureDataFormat format;
+  uint32_t width;
+  uint32_t height;
+  uint32_t size;
+  bool operator==(const PRCpicture& p) const
+  {
+    return ( format==p.format
+        && width==p.width && height==p.height && size==p.size
+        && (data==p.data || memcmp(data,p.data,size)==0) );
+  }
+  bool operator<(const PRCpicture& p) const
+  {
+    if(format!=p.format)
+      return (format<p.format);
+    if(width!=p.width)
+      return (width<p.width);
+    if(height!=p.height)
+      return (height<p.height);
+    if(size!=p.size)
+      return (size<p.size);
+    if(data!=p.data)
+      return (memcmp(data,p.data,size)<0);
+    return false;
+  }
+};
+
+typedef std::map<PRCpicture,uint32_t> PRCpictureMap;
+
+struct PRCmaterialgeneric
+{
+  PRCmaterialgeneric() : alpha(1.0),shininess(1.0) {}
+  PRCmaterialgeneric(const RGBAColour& a, const RGBAColour& d, const RGBAColour& e,
+              const RGBAColour& s, double p, double h) :
+      ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
+  PRCmaterialgeneric(const PRCmaterial& m) :
+      ambient(m.ambient), diffuse(m.diffuse), emissive(m.emissive), specular(m.specular), alpha(m.alpha), shininess(m.shininess) {}
+  RGBAColour ambient,diffuse,emissive,specular;
+  double alpha,shininess;
+
+  bool operator==(const PRCmaterialgeneric& m) const
+  {
+    return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+        && specular==m.specular && alpha==m.alpha && shininess==m.shininess);
+  }
+  bool operator<(const PRCmaterialgeneric& m) const
+  {
+    if(ambient!=m.ambient)
+      return (ambient<m.ambient);
+    if(diffuse!=m.diffuse)
+      return (diffuse<m.diffuse);
+    if(emissive!=m.emissive)
+      return (emissive<m.emissive);
+    if(specular!=m.specular)
+      return (specular<m.specular);
+    if(alpha!=m.alpha)
+      return (alpha<m.alpha);
+    if(shininess!=m.shininess)
+      return (shininess<m.shininess);
+    return false;
+  }
+};
+typedef std::map<PRCmaterialgeneric,uint32_t> PRCmaterialgenericMap;
+
+struct PRCtexturedefinition
+{
+  PRCtexturedefinition() : 
+      picture_index(m1), picture_replace(false), picture_repeat(false) {}
+  PRCtexturedefinition(uint32_t picindex, bool picreplace=false, bool picrepeat=false) :
+      picture_index(picindex), picture_replace(picreplace), picture_repeat(picrepeat) {}
+  PRCtexturedefinition(uint32_t picindex, const PRCmaterial& m) :
+      picture_index(picindex), picture_replace(m.picture_replace), picture_repeat(m.picture_repeat) {}
+  uint32_t picture_index;
+  bool picture_replace; // replace material color with texture color? if false - just modify
+  bool picture_repeat;  // repeat texture? if false - clamp to edge
+
+  bool operator==(const PRCtexturedefinition& t) const
+  {
+    return (picture_index==t.picture_index
+        && picture_replace==t.picture_replace && picture_repeat==t.picture_repeat);
+  }
+  bool operator<(const PRCtexturedefinition& t) const
+  {
+    if(picture_index!=t.picture_index)
+      return (picture_index<t.picture_index);
+    if(picture_replace!=t.picture_replace)
+      return (picture_replace<t.picture_replace);
+    if(picture_repeat!=t.picture_repeat)
+      return (picture_repeat<t.picture_repeat);
+    return false;
+  }
+};
+typedef std::map<PRCtexturedefinition,uint32_t> PRCtexturedefinitionMap;
+
+struct PRCtextureapplication
+{
+  PRCtextureapplication() : 
+      material_generic_index(m1), texture_definition_index(m1) {}
+  PRCtextureapplication(uint32_t matindex, uint32_t texindex) :
+      material_generic_index(matindex), texture_definition_index(texindex) {}
+  uint32_t material_generic_index;
+  uint32_t texture_definition_index;
+
+  bool operator==(const PRCtextureapplication& t) const
+  {
+    return (material_generic_index==t.material_generic_index
+        && texture_definition_index==t.texture_definition_index);
+  }
+  bool operator<(const PRCtextureapplication& t) const
+  {
+    if(material_generic_index!=t.material_generic_index)
+      return (material_generic_index<t.material_generic_index);
+    if(texture_definition_index!=t.texture_definition_index)
+      return (texture_definition_index<t.texture_definition_index);
+    return false;
+  }
+};
+typedef std::map<PRCtextureapplication,uint32_t> PRCtextureapplicationMap;
+
+struct PRCstyle
+{
+  PRCstyle() : 
+      line_width(0), alpha(1), is_material(false), color_material_index(m1) {}
+  PRCstyle(double linewidth, double alph, bool ismat, uint32_t colindex=m1) :
+      line_width(linewidth), alpha(alph), is_material(ismat), color_material_index(colindex) {}
+  double line_width;
+  double alpha;
+  bool is_material;
+  uint32_t color_material_index;
+
+  bool operator==(const PRCstyle& s) const
+  {
+    return (line_width==s.line_width && alpha==s.alpha && is_material==s.is_material
+        && color_material_index==s.color_material_index);
+  }
+  bool operator<(const PRCstyle& s) const
+  {
+    if(line_width!=s.line_width)
+      return (line_width<s.line_width);
+    if(alpha!=s.alpha)
+      return (alpha<s.alpha);
+    if(is_material!=s.is_material)
+      return (is_material<s.is_material);
+    if(color_material_index!=s.color_material_index)
+      return (color_material_index<s.color_material_index);
+    return false;
+  }
+};
+typedef std::map<PRCstyle,uint32_t> PRCstyleMap;
 
 struct PRCtessrectangle // rectangle
 {
@@ -106,12 +368,32 @@
 };
 typedef std::vector<PRCtessrectangle> PRCtessrectangleList;
 
+struct PRCtessquad // rectangle
+{
+  PRCVector3d vertices[4];
+  RGBAColour  colours[4];
+};
+typedef std::vector<PRCtessquad> PRCtessquadList;
+/*
+struct PRCtesstriangle // textured triangle
+{
+  PRCtesstriangle() : 
+  style(m1) {}
+  PRCVector3d vertices[3];
+// PRCVector3d normals[3];
+// RGBAColour  colors[3];
+  PRCVector2d texcoords[3];
+  uint32_t style;
+};
+typedef std::vector<PRCtesstriangle> PRCtesstriangleList;
+*/
 struct PRCtessline // polyline
 {
   std::vector<PRCVector3d> point;
   PRCRgbColor color;
 };
 typedef std::list<PRCtessline> PRCtesslineList;
+typedef std::map<double, PRCtesslineList> PRCtesslineMap;
 
 struct PRCface
 {
@@ -148,240 +430,151 @@
 public:
   double compression;
   double granularity;
-  
-  bool closed;   // render the surface as one-sided; may yield faster rendering 
+
+  bool closed;   // render the surface as one-sided; may yield faster rendering
   bool tess;     // use tessellated mesh to store straight patches
-  bool do_break; // 
+  bool do_break; //
   bool no_break; // do not render transparent patches as one-faced nodes
-  
+  double crease_angle; // crease angle for meshes
+
   PRCoptions(double compression=0.0, double granularity=0.0, bool closed=false,
-             bool tess=false, bool do_break=true, bool no_break=false)
+             bool tess=false, bool do_break=true, bool no_break=false, double crease_angle=25.8419)
     : compression(compression), granularity(granularity), closed(closed),
-      tess(tess), do_break(do_break), no_break(no_break) {}
+      tess(tess), do_break(do_break), no_break(no_break), crease_angle(crease_angle) {}
 };
 
 class PRCgroup
 {
  public:
-  PRCgroup() : transform(NULL) {}
-  PRCgroup(const std::string &name) : name(name), transform(NULL) {}
+  PRCgroup() : 
+    product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {}
+  PRCgroup(const std::string& name) : 
+    product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {}
+  PRCProductOccurrence *product_occurrence, *parent_product_occurrence;
+  PRCPartDefinition *part_definition, *parent_part_definition;
   PRCfaceList       faces;
   PRCcompfaceList   compfaces;
   PRCtessrectangleList  rectangles;
-  PRCtesslineList       lines;
+// PRCtesstriangleList   triangles;
+  PRCtessquadList       quads;
+  PRCtesslineMap        lines;
   PRCwireList           wires;
   PRCpointsetMap        points;
+  std::vector<PRCPointSet*>      pointsets;
+  std::vector<PRCPolyBrepModel*> polymodels;
+  std::vector<PRCPolyWire*>      polywires;
+  PRCGeneralTransformation3d*  transform;
   std::string name;
-  std::list<PRCgroup> groupList;
-  PRCGeneralTransformation3d*  transform;
   PRCoptions options;
 };
-typedef std::list<PRCgroup> PRCgroupList;
-
-class PRCCompressedSection
+
+void makeFileUUID(PRCUniqueId&);
+void makeAppUUID(PRCUniqueId&);
+
+class PRCUncompressedFile
 {
   public:
-    PRCCompressedSection(oPRCFile *p) : data(0),prepared(false),parent(p),fileStructure(NULL),
-        out(data,0) {}
-    PRCCompressedSection(PRCFileStructure *fs) : data(0),prepared(false),parent(NULL),fileStructure(fs),
-        out(data,0) {}
-    virtual ~PRCCompressedSection()
-    {
-      free(data);
+    PRCUncompressedFile() : file_size(0), data(NULL) {}
+    PRCUncompressedFile(uint32_t fs, uint8_t *d) : file_size(fs), data(d) {}
+    ~PRCUncompressedFile() { if(data != NULL) delete[] data; }
+    uint32_t file_size;
+    uint8_t *data;
+
+    void write(std::ostream&) const;
+
+    uint32_t getSize() const;
+};
+typedef std::deque <PRCUncompressedFile*>  PRCUncompressedFileList;
+
+class PRCStartHeader
+{
+  public:
+    uint32_t minimal_version_for_read; // PRCVersion
+    uint32_t authoring_version; // PRCVersion
+    PRCUniqueId file_structure_uuid;
+    PRCUniqueId application_uuid; // should be 0
+
+    PRCStartHeader() :
+      minimal_version_for_read(PRCVersion), authoring_version(PRCVersion) {}
+    void serializeStartHeader(std::ostream&) const;
+
+    uint32_t getStartHeaderSize() const;
+};
+
+class PRCFileStructure : public PRCStartHeader
+{
+  public:
+    uint32_t number_of_referenced_file_structures;
+    double tessellation_chord_height_ratio;
+    double tessellation_angle_degree;
+    std::string default_font_family_name;
+    std::vector<PRCRgbColor> colors;
+    std::vector<PRCPicture> pictures;
+    PRCUncompressedFileList uncompressed_files;
+    PRCTextureDefinitionList texture_definitions;
+    PRCMaterialList materials;
+    PRCStyleList styles;
+    PRCCoordinateSystemList reference_coordinate_systems;
+    std::vector<PRCFontKeysSameFont> font_keys_of_font;
+    PRCPartDefinitionList part_definitions;
+    PRCProductOccurrenceList product_occurrences;
+//  PRCMarkupList markups;
+//  PRCAnnotationItemList annotation_entities;
+    double unit;
+    PRCTopoContextList contexts;
+    PRCTessList tessellations;
+
+    uint32_t sizes[6];
+    uint8_t *globals_data;
+    PRCbitStream globals_out; // order matters: PRCbitStream must be initialized last
+    uint8_t *tree_data;
+    PRCbitStream tree_out;
+    uint8_t *tessellations_data;
+    PRCbitStream tessellations_out;
+    uint8_t *geometry_data;
+    PRCbitStream geometry_out;
+    uint8_t *extraGeometry_data;
+    PRCbitStream extraGeometry_out;
+
+    ~PRCFileStructure () {
+      for(PRCUncompressedFileList::iterator  it=uncompressed_files.begin();  it!=uncompressed_files.end();  ++it) delete *it;
+      for(PRCTextureDefinitionList::iterator it=texture_definitions.begin(); it!=texture_definitions.end(); ++it) delete *it;
+      for(PRCMaterialList::iterator          it=materials.begin();           it!=materials.end();           ++it) delete *it;
+      for(PRCStyleList::iterator             it=styles.begin();              it!=styles.end();              ++it) delete *it;
+      for(PRCTopoContextList::iterator       it=contexts.begin();            it!=contexts.end();            ++it) delete *it;
+      for(PRCTessList::iterator              it=tessellations.begin();       it!=tessellations.end();       ++it) delete *it;
+      for(PRCPartDefinitionList::iterator    it=part_definitions.begin();    it!=part_definitions.end();    ++it) delete *it;
+      for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it;
+      for(PRCCoordinateSystemList::iterator  it=reference_coordinate_systems.begin(); it!=reference_coordinate_systems.end(); it++)
+        delete *it;
+
+      free(globals_data);
+      free(tree_data);
+      free(tessellations_data);
+      free(geometry_data);
+      free(extraGeometry_data);
     }
+
+    PRCFileStructure() :
+      number_of_referenced_file_structures(0),
+      tessellation_chord_height_ratio(2000.0),tessellation_angle_degree(40.0),
+      default_font_family_name(""),
+      unit(1),
+      globals_data(NULL),globals_out(globals_data,0),
+      tree_data(NULL),tree_out(tree_data,0),
+      tessellations_data(NULL),tessellations_out(tessellations_data,0),
+      geometry_data(NULL),geometry_out(geometry_data,0),
+      extraGeometry_data(NULL),extraGeometry_out(extraGeometry_data,0) {}
     void write(std::ostream&);
     void prepare();
     uint32_t getSize();
-
-  private:
-    virtual void writeData() = 0;
-    uint8_t *data;
-  protected:
-    void compress()
-    {
-      out.compress();
-    }
-    bool prepared;
-    oPRCFile *parent;
-    PRCFileStructure *fileStructure;
-    PRCbitStream out; // order matters: PRCbitStream must be initialized last
-};
-
-class PRCGlobalsSection : public PRCCompressedSection
-{
-  public:
-    PRCGlobalsSection(PRCFileStructure *fs, uint32_t i) :
-      PRCCompressedSection(fs),numberOfReferencedFileStructures(0), 
-      tessellationChordHeightRatio(2000.0),tessellationAngleDegrees(40.0),
-      defaultFontFamilyName(""),
-      numberOfFillPatterns(0),
-      userData(0,0),index(i) {}
-  virtual ~PRCGlobalsSection() {
-      for(PRCTextureDefinitionList::iterator i = texture_definitions.begin();
-          i != texture_definitions.end(); i++)
-        delete *i;
-      for(PRCMaterialList::iterator i = materials.begin();
-          i != materials.end(); i++)
-        delete *i;
-      for(PRCStyleList::iterator i = styles.begin();
-          i != styles.end(); i++)
-        delete *i;
-      for(PRCCoordinateSystemList::iterator i = 
-            reference_coordinate_systems.begin();
-          i != reference_coordinate_systems.end(); i++)
-        delete *i;
-  }
-    uint32_t numberOfReferencedFileStructures;
-    double tessellationChordHeightRatio;
-    double tessellationAngleDegrees;
-    std::string defaultFontFamilyName;
-    std::vector<PRCRgbColor> colors;
-    std::vector<PRCPicture> pictures;
-    PRCTextureDefinitionList texture_definitions;
-    PRCMaterialList materials;
-    PRCStyleList styles;
-    uint32_t numberOfFillPatterns;
-    PRCCoordinateSystemList reference_coordinate_systems;
-    std::vector<PRCFontKeysSameFont> font_keys_of_font;
-    UserData userData;
-  private:
-    uint32_t index;
-    virtual void writeData();
-};
-
-class PRCTreeSection : public PRCCompressedSection
-{
-  public:
-    PRCTreeSection(PRCFileStructure *fs, uint32_t i) :
-      PRCCompressedSection(fs),unit(1),index(i) {}
-  virtual ~PRCTreeSection() 
-  {
-    for(PRCPartDefinitionList::iterator it=part_definitions.begin(); it!=part_definitions.end(); ++it) delete *it;
-    for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it;
-  }
-
-  PRCPartDefinitionList part_definitions;
-  PRCProductOccurrenceList product_occurrences;
-/*
-  PRCMarkupList markups;
-  PRCAnnotationItemList annotation_entities;
- */
-  double unit;
-  private:
-    uint32_t index;
-    virtual void writeData();
-};
-
-class PRCTessellationSection : public PRCCompressedSection
-{
-  public:
-    PRCTessellationSection(PRCFileStructure *fs, uint32_t i) :
-      PRCCompressedSection(fs),index(i) {}
-  virtual ~PRCTessellationSection() {
-    for(PRCTessList::iterator it=tessellations.begin();
-        it!=tessellations.end(); ++it)
-      delete *it;
-  }
-  PRCTessList tessellations;
-  private:
-    uint32_t index;
-    virtual void writeData();
-};
-
-class PRCGeometrySection : public PRCCompressedSection
-{
-  public:
-    PRCGeometrySection(PRCFileStructure *fs, uint32_t i) :
-      PRCCompressedSection(fs),index(i) {}
-  virtual ~PRCGeometrySection() {}
-  private:
-    uint32_t index;
-    virtual void writeData();
-};
-
-class PRCExtraGeometrySection : public PRCCompressedSection
-{
-  public:
-    PRCExtraGeometrySection(PRCFileStructure *fs, uint32_t i) :
-      PRCCompressedSection(fs),index(i) {}
-  virtual ~PRCExtraGeometrySection() {}
-  private:
-    uint32_t index;
-    virtual void writeData();
-};
-
-class PRCModelFile : public PRCCompressedSection
-{
-  public:
-    PRCModelFile(oPRCFile *p) : PRCCompressedSection(p), unit(1) {}
-    double unit;
-  virtual ~PRCModelFile() {}
-  private:
-    virtual void writeData();
-};
-
-void makeFileUUID(uint32_t*);
-void makeAppUUID(uint32_t*);
-
-class PRCUncompressedFile
-{
-  public:
-    PRCUncompressedFile() : file_size(0), data(NULL) {}
-    PRCUncompressedFile(uint32_t fs, uint8_t *d) : file_size(fs), data(d) {}
-//    PRCUncompressedFile(uint32_t fs, const std::string &fn) : file_size(fs), data(NULL), file_name(fn) {}
-    ~PRCUncompressedFile() { if(data != NULL) delete[] data; }
-    uint32_t file_size;
-    uint8_t *data;
-//    std::string file_name;
-
-    void write(std::ostream&);
-
-    uint32_t getSize();
-};
-
-class PRCStartHeader
-{
-  public:
-    uint32_t minimal_version_for_read; // PRCVersion
-    uint32_t authoring_version; // PRCVersion
-    uint32_t fileStructureUUID[4];
-    uint32_t applicationUUID[4]; // should be 0
-
-    void write(std::ostream&);
-
-    uint32_t getSize();
-};
-
-class PRCFileStructure
-{
-  private:
-    oPRCFile *parent;
-    uint32_t index;
-  public:
-    PRCStartHeader header;
-    std::list<PRCUncompressedFile> uncompressedFiles;
-    PRCTopoContextList contexts;
-
-    ~PRCFileStructure () {
-      for(PRCTopoContextList::iterator i = contexts.begin();
-          i != contexts.end(); i++)
-        delete *i;
-    }
-  
-    PRCGlobalsSection globals;
-    PRCTreeSection tree;
-    PRCTessellationSection tessellations;
-    PRCGeometrySection geometry;
-    PRCExtraGeometrySection extraGeometry;
-
-    PRCFileStructure(oPRCFile *p, uint32_t i) : parent(p),index(i),
-      globals(this,i),tree(this,i),tessellations(this,i),geometry(this,i),
-      extraGeometry(this,i) {}
-    void write(std::ostream&);
-    void prepare();
-    uint32_t getSize();
+    void serializeFileStructureGlobals(PRCbitStream&);
+    void serializeFileStructureTree(PRCbitStream&);
+    void serializeFileStructureTessellation(PRCbitStream&);
+    void serializeFileStructureGeometry(PRCbitStream&);
+    void serializeFileStructureExtraGeometry(PRCbitStream&);
     uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0, std::string name="");
-    uint32_t addTextureDefinition(PRCTextureDefinition *pTextureDefinition);
+    uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition);
     uint32_t addRgbColor(const PRCRgbColor &color);
     uint32_t addRgbColorUnique(const PRCRgbColor &color);
     uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric);
@@ -405,7 +598,7 @@
 class PRCFileStructureInformation
 {
   public:
-    uint32_t UUID[4];
+    PRCUniqueId UUID;
     uint32_t reserved; // 0
     uint32_t number_of_offsets;
     uint32_t *offsets;
@@ -415,15 +608,14 @@
     uint32_t getSize();
 };
 
-class PRCHeader
+class PRCHeader : public PRCStartHeader
 {
   public :
-    PRCStartHeader startHeader;
     uint32_t number_of_file_structures;
     PRCFileStructureInformation *fileStructureInformation;
     uint32_t model_file_offset;
     uint32_t file_size; // not documented
-    std::list<PRCUncompressedFile> uncompressedFiles;
+    PRCUncompressedFileList uncompressed_files;
 
     void write(std::ostream&);
     uint32_t getSize();
@@ -434,40 +626,60 @@
 class oPRCFile
 {
   public:
-    oPRCFile(std::ostream &os, double unit=1, uint32_t n=1) :
+    oPRCFile(std::ostream &os, double u=1, uint32_t n=1) :
       number_of_file_structures(n),
-      fileStructures(new PRCFileStructure*[n]),modelFile(this),
+      fileStructures(new PRCFileStructure*[n]),
+      unit(u),
+      modelFile_data(NULL),modelFile_out(modelFile_data,0),
       fout(NULL),output(os)
       {
         for(uint32_t i = 0; i < number_of_file_structures; ++i)
         {
-          fileStructures[i] = new PRCFileStructure(this,i);
-          fileStructures[i]->header.minimal_version_for_read = PRCVersion;
-          fileStructures[i]->header.authoring_version = PRCVersion;
-          makeFileUUID(fileStructures[i]->header.fileStructureUUID);
-          makeAppUUID(fileStructures[i]->header.applicationUUID);
-          fileStructures[i]->tree.unit = unit;
+          fileStructures[i] = new PRCFileStructure();
+          fileStructures[i]->minimal_version_for_read = PRCVersion;
+          fileStructures[i]->authoring_version = PRCVersion;
+          makeFileUUID(fileStructures[i]->file_structure_uuid);
+          makeAppUUID(fileStructures[i]->application_uuid);
+          fileStructures[i]->unit = u;
         }
-        modelFile.unit = unit;
-      }
-  
-    oPRCFile(const std::string &name, double unit=1, uint32_t n=1) :
+
+        groups.push(PRCgroup());
+        PRCgroup &group = groups.top();
+        group.name="root";
+        group.transform = NULL;
+        group.product_occurrence = new PRCProductOccurrence(group.name);
+        group.parent_product_occurrence = NULL;
+        group.part_definition = new PRCPartDefinition;
+        group.parent_part_definition = NULL;
+      }
+
+    oPRCFile(const std::string &name, double u=1, uint32_t n=1) :
       number_of_file_structures(n),
-      fileStructures(new PRCFileStructure*[n]),modelFile(this),
+      fileStructures(new PRCFileStructure*[n]),
+      unit(u),
+      modelFile_data(NULL),modelFile_out(modelFile_data,0),
       fout(new std::ofstream(name.c_str(),
                              std::ios::out|std::ios::binary|std::ios::trunc)),
       output(*fout)
       {
         for(uint32_t i = 0; i < number_of_file_structures; ++i)
         {
-          fileStructures[i] = new PRCFileStructure(this,i);
-          fileStructures[i]->header.minimal_version_for_read = PRCVersion;
-          fileStructures[i]->header.authoring_version = PRCVersion;
-          makeFileUUID(fileStructures[i]->header.fileStructureUUID);
-          makeAppUUID(fileStructures[i]->header.applicationUUID);
-          fileStructures[i]->tree.unit = unit;
+          fileStructures[i] = new PRCFileStructure();
+          fileStructures[i]->minimal_version_for_read = PRCVersion;
+          fileStructures[i]->authoring_version = PRCVersion;
+          makeFileUUID(fileStructures[i]->file_structure_uuid);
+          makeAppUUID(fileStructures[i]->application_uuid);
+          fileStructures[i]->unit = u;
         }
-        modelFile.unit = unit;
+
+        groups.push(PRCgroup());
+        PRCgroup &group = groups.top();
+        group.name="root";
+        group.transform = NULL;
+        group.product_occurrence = new PRCProductOccurrence(group.name);
+        group.parent_product_occurrence = NULL;
+        group.part_definition = new PRCPartDefinition;
+        group.parent_part_definition = NULL;
       }
 
     ~oPRCFile()
@@ -477,53 +689,162 @@
       delete[] fileStructures;
       if(fout != NULL)
         delete fout;
+      free(modelFile_data);
+      for(PRCpictureMap::iterator it=pictureMap.begin(); it!=pictureMap.end(); ++it) delete it->first.data;
     }
 
     void begingroup(const char *name, PRCoptions *options=NULL,
-                    const double t[][4]=NULL);
+                    const double* t=NULL);
     void endgroup();
-  
+
+    std::string lastgroupname;
+    std::vector<std::string> lastgroupnames;
+    std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence);
+    
     bool finish();
     uint32_t getSize();
-  
+
     const uint32_t number_of_file_structures;
     PRCFileStructure **fileStructures;
     PRCHeader header;
-    PRCModelFile modelFile;
+    PRCUnit unit;
+    uint8_t *modelFile_data;
+    PRCbitStream modelFile_out; // order matters: PRCbitStream must be initialized last
     PRCcolorMap colorMap;
     PRCcolourMap colourMap;
-    PRCmaterialMap materialMap;
+    PRCcolourwidthMap colourwidthMap;
+    PRCmaterialgenericMap materialgenericMap;
+    PRCtexturedefinitionMap texturedefinitionMap;
+    PRCtextureapplicationMap textureapplicationMap;
+    PRCstyleMap styleMap;
+    PRCpictureMap pictureMap;
     PRCgroup rootGroup;
     PRCtransformMap transformMap;
-    std::stack<PRCgroupList::iterator> currentGroups;
+    std::stack<PRCgroup> groups;
     PRCgroup& findGroup();
-    void doGroup(PRCgroup& group, PRCPartDefinition *parent_part_definition, PRCProductOccurrence *parent_product_occurrence);
+    void doGroup(PRCgroup& group);
     uint32_t addColor(const PRCRgbColor &color);
     uint32_t addColour(const RGBAColour &colour);
+    uint32_t addColourWidth(const RGBAColour &colour, double width);
+    uint32_t addLineMaterial(const RGBAColour& c, double width)
+               { return addColourWidth(c,width); }
     uint32_t addMaterial(const PRCmaterial &material);
     uint32_t addTransform(PRCGeneralTransformation3d*& transform);
-    void addPoint(const double P[3], const RGBAColour &c);
-    void addLine(uint32_t n, const double P[][3], const RGBAColour &c);
+    uint32_t addTransform(const double* t);
+    uint32_t addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale);
+    void addPoint(const double P[3], const RGBAColour &c, double w=1.0);
+    void addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0);
+    void addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+                      const RGBAColour& c, double w,
+                      bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+    uint32_t createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+                      bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+    void addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial &m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca);
+    uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], uint32_t style_index,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nS, const uint32_t S[], const uint32_t SI[], double ca);
+    uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+            {
+               const uint32_t style = addMaterial(m);
+               if(M!=NULL && nM>0)
+               {
+                 uint32_t* const styles = new uint32_t[nM];
+                 for(uint32_t i=0; i<nM; i++)
+                   styles[i]=addMaterial(M[i]);
+                 const uint32_t meshid =  createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
+                 delete[] styles;
+                 return meshid;
+               }
+               else
+                 return createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
+            }
+    void addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial &m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca);
+    uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nS, const uint32_t S[],    const uint32_t SI[], double ca);
+    uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[], double ca)
+            {
+               const uint32_t style = addMaterial(m);
+               if(M!=NULL && nM>0)
+               {
+                 uint32_t* const styles = new uint32_t[nM];
+                 for(uint32_t i=0; i<nM; i++)
+                   styles[i]=addMaterial(M[i]);
+                 const uint32_t meshid =  createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI, ca);
+                 delete[] styles;
+                 return meshid;
+               }
+               else
+                 return createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
+            }
+#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
+#define PRCCARTRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale
+#define PRCGENTRANSFORM const double* t=NULL
+#define PRCNOMATERIALINDEX m1
+    void useMesh(uint32_t tess_index, uint32_t style_index,            PRCGENTRANSFORM);
+    void useMesh(uint32_t tess_index, const PRCmaterial& m,            PRCGENTRANSFORM)
+           { useMesh(tess_index,addMaterial(m),t); }
+    void useMesh(uint32_t tess_index, uint32_t style_index,            PRCCARTRANSFORM);
+    void useMesh(uint32_t tess_index, const PRCmaterial& m,            PRCCARTRANSFORM)
+           { useMesh(tess_index,addMaterial(m),origin, x_axis, y_axis, scale); }
+
+    void useLines(uint32_t tess_index, uint32_t style_index,           PRCGENTRANSFORM);
+    void useLines(uint32_t tess_index, const RGBAColour& c,  double w, PRCGENTRANSFORM)
+           { useLines(tess_index, addLineMaterial(c,w), t); }
+    void useLines(uint32_t tess_index, uint32_t style_index,           PRCCARTRANSFORM);
+    void useLines(uint32_t tess_index, const RGBAColour& c,  double w, PRCCARTRANSFORM)
+           { useLines(tess_index,addLineMaterial(c,w),origin, x_axis, y_axis, scale); }
+
+//  void addTriangle(const double P[][3], const double T[][2], uint32_t style_index);
+  
+    void addLine(uint32_t n, const double P[][3], const RGBAColour &c, double w=1.0);
     void addBezierCurve(uint32_t n, const double cP[][3], const RGBAColour &c);
     void addCurve(uint32_t d, uint32_t n, const double cP[][3], const double *k, const RGBAColour &c, const double w[]);
+    void addQuad(const double P[][3], const RGBAColour C[]);
+
     void addRectangle(const double P[][3], const PRCmaterial &m);
     void addPatch(const double cP[][3], const PRCmaterial &m);
     void 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[]);
-#define PRCFACETRANSFORM const double origin[3]=NULL, const double x_axis[3]=NULL, const double y_axis[3]=NULL, double scale=1, const double t[][4]=NULL
-    void addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial &m, PRCFACETRANSFORM);
-    void addHemisphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM);
-    void addSphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM);
-    void addDisk(double radius, const PRCmaterial &m, PRCFACETRANSFORM);
-    void addCylinder(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM);
-    void addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM);
-#undef PRCFACETRANSFORM
+    void addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial& m, PRCTRANSFORM);
+    void addHemisphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addSphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addDisk(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addCylinder(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+    void addCone(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+    void addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial& m, PRCTRANSFORM);
+#undef PRCTRANSFORM
+#undef PRCCARTRANSFORM
+#undef PRCGENTRANSFORM
 
 
     uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *picture, uint32_t width=0, uint32_t height=0,
       std::string name="", uint32_t fileStructure=0)
       { return fileStructures[fileStructure]->addPicture(format, size, picture, width, height, name); }
+    uint32_t addPicture(const PRCpicture& pic,
+      std::string name="", uint32_t fileStructure=0)
+      { return fileStructures[fileStructure]->addPicture(pic.format, pic.size, pic.data, pic.width, pic.height, name); }
     uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition, uint32_t fileStructure=0)
       {
         return fileStructures[fileStructure]->addTextureDefinition(pTextureDefinition);
@@ -598,6 +919,7 @@
         return fileStructures[fileStructure]->addCoordinateSystemUnique(pCoordinateSystem);
       }
   private:
+    void serializeModelFileData(PRCbitStream&);
     std::ofstream *fout;
     std::ostream &output;
 };

Modified: trunk/Scribus/scribus/third_party/prc/writePRC.cc
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/writePRC.cc
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/writePRC.cc (original)
+++ trunk/Scribus/scribus/third_party/prc/writePRC.cc Fri Sep 28 15:05:16 2012
@@ -29,12 +29,20 @@
 #include <fstream>
 #include <sstream>
 
+#if !defined(__GNUC__) || defined(__clang__)
+#include <vector>
+#endif
+
 using namespace std;
+
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj, min) (0)
+#endif
 
 // Count leading zeros.
 uint32_t CLZ(uint32_t a) 
 {
-#ifdef __GNUC__
+#if __GNUC_PREREQ(3,4)
   return __builtin_clz(a);
 #else
 // find the log base 2 of a 32-bit integer
@@ -49,7 +57,7 @@
   a |= a >> 8;
   a |= a >> 16;
 
-  return 31-MultiplyDeBruijnBitPosition[(unsignedInt)(a * 0x07C4ACDDU) >> 27];
+  return 31-MultiplyDeBruijnBitPosition[(uint32_t)(a * 0x07C4ACDDU) >> 27];
 #endif
 }
 
@@ -108,7 +116,23 @@
 #define SerializeContentSingleAttribute( value ) (value).serializeSingleAttribute(pbs);
 #define SerializeAttribute( value ) (value).serializeAttribute(pbs);
 #define SerializeAttributeData serializeAttributes(pbs);
-
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+
+void writeUncompressedUnsignedInteger(ostream &out, uint32_t data)
+{
+#ifdef WORDS_BIGENDIAN
+  out.write(((char*)&data)+3,1);
+  out.write(((char*)&data)+2,1);
+  out.write(((char*)&data)+1,1);
+  out.write(((char*)&data)+0,1);
+#else
+  out.write(((char*)&data)+0,1);
+  out.write(((char*)&data)+1,1);
+  out.write(((char*)&data)+2,1);
+  out.write(((char*)&data)+3,1);
+#endif
+}
 
 double PRCVector3d::Length()
 {
@@ -126,6 +150,84 @@
  return true;
 }
 
+double PRCVector2d::Length()
+{
+  return sqrt(x*x+y*y);
+}
+
+bool PRCVector2d::Normalize()
+{
+  double fLength=Length();
+  if(fLength < FLT_EPSILON) return false;
+  double factor=1.0/fLength;
+  x *= factor;
+  y *= factor;
+
+  return true;
+}
+
+void PRCVector2d::serializeVector2d(PRCbitStream &pbs)
+{
+  WriteDouble (x)
+  WriteDouble (y)
+}
+
+uint32_t makeCADID()
+{
+  static uint32_t ID = 1;
+  return ID++;
+}
+
+uint32_t makePRCID()
+{
+  static uint32_t ID = 1;
+  return ID++;
+}
+
+bool type_eligible_for_reference(uint32_t type)
+{
+  if(
+     type == PRC_TYPE_MISC_EntityReference ||
+     type == PRC_TYPE_MISC_MarkupLinkedItem ||
+     type == PRC_TYPE_RI_BrepModel ||
+     type == PRC_TYPE_RI_Curve ||
+     type == PRC_TYPE_RI_Direction ||
+     type == PRC_TYPE_RI_Plane ||
+     type == PRC_TYPE_RI_PointSet ||
+     type == PRC_TYPE_RI_PolyBrepModel ||
+     type == PRC_TYPE_RI_PolyWire ||
+     type == PRC_TYPE_RI_Set ||
+     type == PRC_TYPE_RI_CoordinateSystem ||
+     type == PRC_TYPE_ASM_ProductOccurence ||
+     type == PRC_TYPE_ASM_PartDefinition ||
+     type == PRC_TYPE_ASM_Filter ||
+     type == PRC_TYPE_MKP_View ||
+     type == PRC_TYPE_MKP_Markup ||
+     type == PRC_TYPE_MKP_Leader ||
+     type == PRC_TYPE_MKP_AnnotationItem ||
+     type == PRC_TYPE_MKP_AnnotationSet ||
+     type == PRC_TYPE_MKP_AnnotationReference ||
+     type == PRC_TYPE_GRAPH_Style ||
+     type == PRC_TYPE_GRAPH_Material ||
+     type == PRC_TYPE_GRAPH_TextureApplication ||
+     type == PRC_TYPE_GRAPH_TextureDefinition ||
+     type == PRC_TYPE_GRAPH_LinePattern ||
+     type == PRC_TYPE_GRAPH_DottingPattern ||
+     type == PRC_TYPE_GRAPH_HatchingPattern ||
+     type == PRC_TYPE_GRAPH_SolidPattern ||
+     type == PRC_TYPE_GRAPH_VPicturePattern ||
+     type == PRC_TYPE_GRAPH_AmbientLight ||
+     type == PRC_TYPE_GRAPH_PointLight ||
+     type == PRC_TYPE_GRAPH_DirectionalLight ||
+     type == PRC_TYPE_GRAPH_SpotLight ||
+     type == PRC_TYPE_GRAPH_SceneDisplayParameters ||
+     type == PRC_TYPE_GRAPH_Camera
+    )
+    return true;
+  else
+    return false;
+}
+
 void UserData::write(PRCbitStream &pbs)
 {
   pbs << size;
@@ -135,7 +237,7 @@
     for(uint32_t i = 0; i < quot; ++i)
       pbs << data[i];
     for(uint32_t j = 0; j < rem; ++j) // 0-based, big endian bit counting
-      pbs << (bool)(data[quot] & (0x80 >> j));
+      pbs << (bool)((data[quot] & (0x80 >> j))!=0);
   }
 }
 
@@ -197,12 +299,12 @@
   }
 }
 
-void ContentPRCBase::serializeContentPRCBase(PRCbitStream &pbs)
+void ContentPRCBase::serializeContentPRCBase(PRCbitStream &pbs) const
 {
   SerializeAttributeData
 
   SerializeName (name)
-  if (type_eligible_for_reference)
+  if (type_eligible_for_reference(type))
   {
     WriteUnsignedInteger (CAD_identifier)
     WriteUnsignedInteger (CAD_persistent_identifier)
@@ -356,6 +458,21 @@
   WriteUnsignedInteger (next_texture_index+1) 
   WriteUnsignedInteger (UV_coordinates_index+1)
 }
+
+void PRCLinePattern::serializeLinePattern(PRCbitStream &pbs)
+{
+  uint32_t i = 0;
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_LinePattern)
+  SerializeContentPRCBase
+  
+  const uint32_t size_lengths = lengths.size();
+  WriteUnsignedInteger (size_lengths)
+  for (i=0;i<size_lengths;i++)
+    WriteDouble (lengths[i])
+  WriteDouble (phase)
+  WriteBoolean (is_real_length)
+}
+
 
 void PRCStyle::serializeCategory1LineStyle(PRCbitStream &pbs)
 {
@@ -386,9 +503,8 @@
      WriteCharacter (additional_3)
 }
 
-ContentPRCBase EMPTY_CONTENTPRCBASE;
-
 std::string currentName;
+
 void writeName(PRCbitStream &pbs,const std::string &name)
 {
   pbs << (name == currentName);
@@ -408,7 +524,7 @@
 uint32_t current_index_of_line_style = m1;
 uint16_t current_behaviour_bit_field = 1;
 
-void writeGraphics(PRCbitStream &pbs,uint32_t l,uint32_t i,uint32_t b,bool force)
+void writeGraphics(PRCbitStream &pbs,uint32_t l,uint32_t i,uint16_t b,bool force)
 {
   if(force || current_layer_index != l || current_index_of_line_style != i || current_behaviour_bit_field != b)
   {
@@ -648,9 +764,8 @@
 void  PRCGeneralTransformation3d::serializeGeneralTransformation3d(PRCbitStream &pbs) const
 {
   WriteUnsignedInteger (PRC_TYPE_MISC_GeneralTransformation)
-  for (int j=0;j<4;j++)
-    for (int i=0;i<4;i++)
-     WriteDouble(mat[i][j]); 
+  for (uint32_t i=0; i<16; i++)
+     WriteDouble(m_coef[i]); 
 }
 
 void  PRCCartesianTransformation3d::serializeCartesianTransformation3d(PRCbitStream &pbs) const
@@ -950,29 +1065,9 @@
   WriteCharacter (behaviour)
 }
 
-void PRCVector2d::serializeVector2d(PRCbitStream &pbs)
-{
-  WriteDouble (x)
-  WriteDouble (y)
-}
-
-uint32_t makeCADID()
-{
-  static uint32_t ID = 1;
-  return ID++;
-}
-
-uint32_t makePRCID()
-{
-  static uint32_t ID = 1;
-  return ID++;
-}
-
 void writeUnit(PRCbitStream &out,bool fromCAD,double unit)
 {
-  static const double inches=72;
-  static const double cm=inches/2.54;
-  out << fromCAD << 10.0/cm; // Use bp.
+  out << fromCAD << unit;
 }
 
 void writeEmptyMarkups(PRCbitStream &out)
@@ -1269,13 +1364,23 @@
 
    const uint32_t number_of_control_point_in_u = degree_in_u + 1;
    const uint32_t number_of_control_point_in_v = degree_in_v + 1;
+
+#if defined(__GNUC__) && !defined(__clang__)
    PRCVector3d P[number_of_control_point_in_u][number_of_control_point_in_v];
+#else
+   vector<vector<PRCVector3d> > P(number_of_control_point_in_u, vector<PRCVector3d>(number_of_control_point_in_v));
+#endif
    for(uint32_t i=0;i<number_of_control_point_in_u;i++)
    for(uint32_t j=0;j<number_of_control_point_in_v;j++)
       P[i][j] = control_point[i*number_of_control_point_in_v+j];
+#ifdef __GNUC__
    itriple compressed_control_point[number_of_control_point_in_u][number_of_control_point_in_v];
    uint32_t control_point_type[number_of_control_point_in_u][number_of_control_point_in_v];
-   
+#else
+   vector<vector<itriple> > compressed_control_point(number_of_control_point_in_u, vector<itriple>(number_of_control_point_in_v));
+   vector<vector<uint32_t> > control_point_type(number_of_control_point_in_u, vector<uint32_t>(number_of_control_point_in_v));
+#endif
+
    uint32_t number_of_bits_for_isomin = 1;
    uint32_t number_of_bits_for_rest = 1;
    
@@ -1335,7 +1440,7 @@
          if(x*x+y*y<nurbs_tolerance*nurbs_tolerance)
          {
            control_point_type[i][j] = 1;
-           compressed_control_point[i][j] = iroundto(PRCVector3d(0,0,z), nurbs_tolerance);
+           compressed_control_point[i][j] = iroundto(PRCVector3d(0.0,0.0,z), nurbs_tolerance);
            P[i][j] = P[i-1][j-1] + U + V + roundto(z, nurbs_tolerance)*Ne; // see above
          }
          else
@@ -1485,6 +1590,17 @@
    SerializeTransformation
    SerializeUVParameterization
    WriteDouble ( radius )
+}
+
+void  PRCCone::serializeCone(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Cone) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   WriteDouble ( bottom_radius )
+   WriteDouble ( semi_angle )
 }
 
 void  PRCCylinder::serializeCylinder(PRCbitStream &pbs)
@@ -1811,24 +1927,32 @@
 
 void PRCSingleWireBody::serializeSingleWireBody(PRCbitStream &pbs)
 {
-   WriteUnsignedInteger ( PRC_TYPE_TOPO_SingleWireBody) 
-
-   SerializeContentBody 
-   SerializePtrTopology ( wire_edge )
-}
-
-void PRCUniqueId::serializeCompressedUniqueId(PRCbitStream &pbs)
-{
-	WriteUnsignedInteger (unique_id0) 
-	WriteUnsignedInteger (unique_id1) 
-	WriteUnsignedInteger (unique_id2) 
-	WriteUnsignedInteger (unique_id3) 	
+  WriteUnsignedInteger ( PRC_TYPE_TOPO_SingleWireBody) 
+
+  SerializeContentBody 
+  SerializePtrTopology ( wire_edge )
+}
+
+void PRCUniqueId::serializeCompressedUniqueId(PRCbitStream &pbs) const
+{
+   WriteUnsignedInteger (id0) 
+   WriteUnsignedInteger (id1) 
+   WriteUnsignedInteger (id2) 
+   WriteUnsignedInteger (id3) 	
+}
+
+void PRCUniqueId::serializeFileStructureUncompressedUniqueId(std::ostream& out) const
+{
+   WriteUncompressedUnsignedInteger (id0) 
+   WriteUncompressedUnsignedInteger (id1) 
+   WriteUncompressedUnsignedInteger (id2) 
+   WriteUncompressedUnsignedInteger (id3) 
 }
 
 void PRCUnit::serializeUnit(PRCbitStream &pbs)
 {
-	WriteBoolean (unit_from_CAD_file)
-	WriteDouble (unit)
+   WriteBoolean (unit_from_CAD_file)
+   WriteDouble (unit)
 }
 
 void PRCProductOccurrence::serializeProductOccurrence(PRCbitStream &pbs)
@@ -1868,7 +1992,7 @@
    const bool has_location = location != NULL;
    WriteBit (has_location)
    if (has_location)
-	   location->serializeTransformation3d (pbs);
+     location->serializeTransformation3d (pbs);
    
    WriteUnsignedInteger (0) // number_of_references
    

Modified: trunk/Scribus/scribus/third_party/prc/writePRC.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/third_party/prc/writePRC.h
==============================================================================
--- trunk/Scribus/scribus/third_party/prc/writePRC.h (original)
+++ trunk/Scribus/scribus/third_party/prc/writePRC.h Fri Sep 28 15:05:16 2012
@@ -24,7 +24,9 @@
 #include <vector>
 #include <deque>
 #include <list>
+#ifdef __GNUC__
 #include <ext/slist>
+#endif
 #include <map>
 #include <iostream>
 #include "PRCbitStream.h"
@@ -33,7 +35,7 @@
 #include <math.h>
 
 static const uint32_t m1=(uint32_t)-1;
-static const double pi=acos(-1);
+static const double pi=acos(-1.0);
 
 class PRCVector3d
 {
@@ -41,11 +43,12 @@
  double x;
  double y;
  double z;
- PRCVector3d() {}
+ PRCVector3d() :
+ x(0), y(0), z(0) {}
  PRCVector3d(double fx, double fy, double fz) :
  x(fx), y(fy), z(fz) {}
- PRCVector3d(const double c[]) :
- x(c?c[0]:0), y(c?c[1]:0), z(c?c[2]:0) {}
+ PRCVector3d(const double c[], double fx=0, double fy=0, double fz=0) :
+ x(c?c[0]:fx), y(c?c[1]:fy), z(c?c[2]:fz) {}
  PRCVector3d(const PRCVector3d& sVector3d) :
  x(sVector3d.x), y(sVector3d.y), z(sVector3d.z) {}
 
@@ -100,7 +103,7 @@
    return out;
  }
 };
-
+/*
 class UUID
 {
   public:
@@ -112,10 +115,10 @@
     }
   private:
     uint32_t id0,id1,id2,id3;
-};
-
-uint32_t makeCADID();
-uint32_t makePRCID();
+}; */
+
+void writeUncompressedUnsignedInteger(std::ostream &out, uint32_t data);
+
 void writeUnit(PRCbitStream &,bool,double);
 
 void writeEmptyMarkups(PRCbitStream&);
@@ -235,17 +238,27 @@
   PRCAttributeList attributes;
 };
 
+bool type_eligible_for_reference(uint32_t type);
+uint32_t makeCADID();
+uint32_t makePRCID();
+
 class ContentPRCBase : public PRCAttributes
 {
   public:
-  ContentPRCBase(std::string n="",bool efr = false,
-                  uint32_t ci = 0, uint32_t cpi = 0, uint32_t pi = 0) :
-    name(n),type_eligible_for_reference(efr),CAD_identifier(ci),
-    CAD_persistent_identifier(cpi),PRC_unique_identifier(pi) {}
-  void serializeContentPRCBase(PRCbitStream&);
-  uint32_t getPRCID() { return PRC_unique_identifier; }
+  ContentPRCBase(uint32_t t, std::string n="") :
+    type(t),name(n),CAD_identifier(0), CAD_persistent_identifier(0), PRC_unique_identifier(0)
+  {
+    if(type_eligible_for_reference(type))
+    {
+      CAD_identifier = makeCADID();
+      PRC_unique_identifier = makePRCID();
+    }
+  }
+  void serializeContentPRCBase(PRCbitStream&) const;
+  uint32_t getPRCID() const { return PRC_unique_identifier; }
+  uint32_t getType() const { return type; }
+  uint32_t type;
   std::string name;
-  bool type_eligible_for_reference;
   uint32_t CAD_identifier, CAD_persistent_identifier, PRC_unique_identifier;
 };
 
@@ -261,8 +274,6 @@
   uint32_t unique_identifier;
 };
 
-extern ContentPRCBase EMPTY_CONTENTPRCBASE;
-
 extern std::string currentName;
 void writeName(PRCbitStream&,const std::string&);
 void resetName();
@@ -271,7 +282,7 @@
 extern uint32_t current_index_of_line_style;
 extern uint16_t current_behaviour_bit_field;
 
-void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint32_t=1,bool=false);
+void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint16_t=1,bool=false);
 void resetGraphics();
 
 void resetGraphicsAndName();
@@ -305,7 +316,7 @@
 {
 public:
   PRCPicture(std::string n="") :
-  ContentPRCBase(n), format(KEPRCPicture_PNG), uncompressed_file_index(m1), pixel_width(0), pixel_height(0) {}
+  ContentPRCBase(PRC_TYPE_GRAPH_Picture,n), format(KEPRCPicture_PNG), uncompressed_file_index(m1), pixel_width(0), pixel_height(0) {}
   void serializePicture(PRCbitStream&);
   EPRCPictureDataFormat format;
   uint32_t uncompressed_file_index;
@@ -315,20 +326,67 @@
 
 struct PRCVector2d
 {
- PRCVector2d() :
- x(0.0), y(0.0) {}
- PRCVector2d(double X, double Y) :
- x(X), y(Y) {}
- void serializeVector2d(PRCbitStream&);
- double x;
- double y;
+  PRCVector2d() :
+  x(0.0), y(0.0) {}
+  PRCVector2d(double X, double Y) :
+  x(X), y(Y) {}
+  void serializeVector2d(PRCbitStream&);
+  double x;
+  double y;
+  PRCVector2d(const double c[], double fx=0, double fy=0) :
+  x(c?c[0]:fx), y(c?c[1]:fy) {}
+  PRCVector2d(const PRCVector2d& sVector2d) :
+  x(sVector2d.x), y(sVector2d.y) {}
+  
+  void Set(double fx, double fy)
+  { x = fx; y = fy; }
+  double Dot(const PRCVector2d & sPt) const
+  { return(x*sPt.x)+(y*sPt.y); }
+  double LengthSquared()
+  { return(x*x+y*y); }
+  
+  friend PRCVector2d operator + (const PRCVector2d& a, const PRCVector2d& b)
+  { return PRCVector2d(a.x+b.x,a.y+b.y); }
+  friend PRCVector2d operator - (const PRCVector2d& a)
+  { return PRCVector2d(-a.x,-a.y); }
+  friend PRCVector2d operator - (const PRCVector2d& a, const PRCVector2d& b)
+  { return PRCVector2d(a.x-b.x,a.y-b.y); }
+  friend PRCVector2d operator * (const PRCVector2d& a, const double d)
+  { return PRCVector2d(a.x*d,a.y*d); }
+  friend PRCVector2d operator * (const double d, const PRCVector2d& a)
+  { return PRCVector2d(a.x*d,a.y*d); }
+  friend PRCVector2d operator / (const PRCVector2d& a, const double d)
+  { return PRCVector2d(a.x/d,a.y/d); }
+    
+  double Length();
+  bool Normalize();
+  
+  bool operator==(const PRCVector2d &v) const
+  {
+    return x==v.x && y==v.y;
+  }
+  bool operator!=(const PRCVector2d &v) const
+  {
+    return !(x==v.x && y==v.y);
+  }
+  bool operator<(const PRCVector2d &v) const
+  {
+    if(x!=v.x)
+      return (x<v.x);
+    return (y<v.y);
+  }
+  friend std::ostream& operator << (std::ostream& out, const PRCVector2d& v)
+  {
+    out << "(" << v.x << "," << v.y << ")";
+    return out;
+  }
 };
 
 class PRCTextureDefinition : public ContentPRCBase
 {
 public:
   PRCTextureDefinition(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()), picture_index(m1), texture_mapping_attribute(PRC_TEXTURE_MAPPING_DIFFUSE),
+    ContentPRCBase(PRC_TYPE_GRAPH_TextureDefinition,n), picture_index(m1), texture_mapping_attribute(PRC_TEXTURE_MAPPING_DIFFUSE),
     texture_mapping_attribute_intensity(1.0), texture_mapping_attribute_components(PRC_TEXTURE_MAPPING_COMPONENTS_RGBA),
     texture_function(KEPRCTextureFunction_Modulate), texture_applying_mode(PRC_TEXTURE_APPLYING_MODE_NONE),
     texture_wrapping_mode_S(KEPRCTextureWrappingMode_Unknown), texture_wrapping_mode_T(KEPRCTextureWrappingMode_Unknown) // ,
@@ -371,7 +429,7 @@
 {
 public:
   PRCMaterialGeneric(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()),
+    ContentPRCBase(PRC_TYPE_GRAPH_Material,n),
     ambient(m1), diffuse(m1), emissive(m1), specular(m1), 
     shininess(0.0),
     ambient_alpha(1.0), diffuse_alpha(1.0), emissive_alpha(1.0), specular_alpha(1.0)
@@ -400,7 +458,7 @@
 {
 public:
   PRCTextureApplication(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()),
+    ContentPRCBase(PRC_TYPE_GRAPH_TextureApplication,n),
     material_generic_index(m1), texture_definition_index(m1),
     next_texture_index(m1), UV_coordinates_index(0)
     {}
@@ -412,11 +470,24 @@
   uint32_t UV_coordinates_index;
 };
 
+class PRCLinePattern : public ContentPRCBase
+{
+public:
+  PRCLinePattern(std::string n="") :
+  ContentPRCBase(PRC_TYPE_GRAPH_LinePattern,n),
+  phase(0), is_real_length(false) {}
+  void serializeLinePattern(PRCbitStream&);
+  std::vector<double> lengths;
+  double phase;
+  bool is_real_length;
+};
+typedef std::deque <PRCLinePattern*>  PRCLinePatternList;
+
 class PRCStyle : public ContentPRCBase
 {
 public:
   PRCStyle(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()), line_width(0.0), is_vpicture(false), line_pattern_vpicture_index(m1),
+    ContentPRCBase(PRC_TYPE_GRAPH_Style,n), line_width(0.0), is_vpicture(false), line_pattern_vpicture_index(m1),
     is_material(false), color_material_index(m1), is_transparency_defined(false), transparency(255), additional(0)
     {}
   void serializeCategory1LineStyle(PRCbitStream&);
@@ -476,7 +547,7 @@
 public:
   PRC3DTess() :
   has_faces(false), has_loops(false),
-  crease_angle(25.8419)
+  crease_angle(25.8419)  // arccos(0.9), default found in Acrobat output
   {}
   ~PRC3DTess() { for(PRCTessFaceList::iterator it=face_tessellation.begin(); it!=face_tessellation.end(); ++it) delete *it; }
   void serialize3DTess(PRCbitStream&);
@@ -541,7 +612,7 @@
 {
 public:
   PRCMarkup(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()),
+    ContentPRCBase(PRC_TYPE_MKP_Markup,n),
     type(KEPRCMarkupType_Unknown), sub_type(KEPRCMarkupSubType_Unknown), index_tessellation(m1) {}
   void serializeMarkup(PRCbitStream&);
   EPRCMarkupType type;
@@ -556,7 +627,7 @@
 {
 public:
   PRCAnnotationItem(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()) {}
+    ContentPRCBase(PRC_TYPE_MKP_AnnotationItem,n) {}
   void serializeAnnotationItem(PRCbitStream&);
   void serializeAnnotationEntity(PRCbitStream &pbs) { serializeAnnotationItem(pbs); }
   PRCReferenceUniqueIdentifier markup;
@@ -566,8 +637,8 @@
 class PRCRepresentationItemContent: public PRCGraphics, public ContentPRCBase
 {
 public:
-  PRCRepresentationItemContent(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()),
+  PRCRepresentationItemContent(uint32_t t, std::string n="") :
+    ContentPRCBase(t,n),
     index_local_coordinate_system(m1), index_tessellation(m1) {}
   void serializeRepresentationItemContent(PRCbitStream&);
   uint32_t index_local_coordinate_system;
@@ -577,8 +648,8 @@
 class PRCRepresentationItem : public PRCRepresentationItemContent
 {
 public:
-  PRCRepresentationItem(std::string n="") :
-    PRCRepresentationItemContent(n) {}
+  PRCRepresentationItem(uint32_t t, std::string n="") :
+    PRCRepresentationItemContent(t,n) {}
   virtual ~PRCRepresentationItem() {}
   virtual void serializeRepresentationItem(PRCbitStream &pbs) = 0;
 };
@@ -588,7 +659,7 @@
 {
 public:
   PRCBrepModel(std::string n="") :
-    PRCRepresentationItem(n), has_brep_data(true), context_id(m1), body_id(m1), is_closed(false) {}
+    PRCRepresentationItem(PRC_TYPE_RI_BrepModel,n), has_brep_data(true), context_id(m1), body_id(m1), is_closed(false) {}
   void serializeBrepModel(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializeBrepModel(pbs); }
   bool has_brep_data;
@@ -601,7 +672,7 @@
 {
 public:
   PRCPolyBrepModel(std::string n="") :
-    PRCRepresentationItem(n), is_closed(false) {}
+    PRCRepresentationItem(PRC_TYPE_RI_PolyBrepModel,n), is_closed(false) {}
   void serializePolyBrepModel(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyBrepModel(pbs); }
   bool is_closed;
@@ -611,7 +682,7 @@
 {
 public:
   PRCPointSet(std::string n="") :
-    PRCRepresentationItem(n) {}
+    PRCRepresentationItem(PRC_TYPE_RI_PointSet,n) {}
   void serializePointSet(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializePointSet(pbs); }
   std::vector<PRCVector3d> point;
@@ -621,7 +692,7 @@
 {
 public:
   PRCWire(std::string n="") :
-    PRCRepresentationItem(n), has_wire_body(true), context_id(m1), body_id(m1) {}
+    PRCRepresentationItem(PRC_TYPE_RI_Curve,n), has_wire_body(true), context_id(m1), body_id(m1) {}
   void serializeWire(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializeWire(pbs); }
   bool has_wire_body;
@@ -633,7 +704,7 @@
 {
 public:
   PRCPolyWire(std::string n="") :
-    PRCRepresentationItem(n) {}
+    PRCRepresentationItem(PRC_TYPE_RI_PolyWire,n) {}
   void serializePolyWire(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyWire(pbs); }
 };
@@ -642,7 +713,7 @@
 {
 public:
   PRCSet(std::string n="") :
-    PRCRepresentationItem(n) {}
+    PRCRepresentationItem(PRC_TYPE_RI_Set,n) {}
   ~PRCSet() { for(PRCRepresentationItemList::iterator it=elements.begin(); it!=elements.end(); ++it) delete *it; }
   void serializeSet(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializeSet(pbs); }
@@ -669,88 +740,63 @@
 public:
   PRCGeneralTransformation3d()
   {
-    mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = 1.0;
-    mat[0][1] = mat[0][2] = mat[0][3] = 0.0;
-    mat[1][0] = mat[1][2] = mat[1][3] = 0.0;
-    mat[2][0] = mat[2][1] = mat[2][3] = 0.0;
-    mat[3][0] = mat[3][1] = mat[3][2] = 0.0;
-  }
-  PRCGeneralTransformation3d(const double t[][4])
-  {
-    if(t!=NULL)
-      for (size_t i=0;i<4;i++)
-        for (size_t j=0;j<4;j++)
-          mat[i][j]=t[i][j];
-    else
-    {
-      mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = 1.0;
-      mat[0][1] = mat[0][2] = mat[0][3] = 0.0;
-      mat[1][0] = mat[1][2] = mat[1][3] = 0.0;
-      mat[2][0] = mat[2][1] = mat[2][3] = 0.0;
-      mat[3][0] = mat[3][1] = mat[3][2] = 0.0;
-    }
-  }
-  PRCGeneralTransformation3d(const double t[][4], double scale)
-  {
-    if(t!=NULL)
-    {
-      for (size_t i=0;i<3;i++)
-        for (size_t j=0;j<4;j++)
-          mat[i][j]=scale*t[i][j];
-      for(size_t j= 0;j<4; j++)
-        mat[3][j] = scale*t[3][j];
-    }
-    else
-    {
-      mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = 1.0;
-      mat[0][1] = mat[0][2] = mat[0][3] = 0.0;
-      mat[1][0] = mat[1][2] = mat[1][3] = 0.0;
-      mat[2][0] = mat[2][1] = mat[2][3] = 0.0;
-      mat[3][0] = mat[3][1] = mat[3][2] = 0.0;
-    }
+    setidentity();
+  }
+  PRCGeneralTransformation3d(const double t[])
+  {
+    set(t);
   }
   
   void serializeGeneralTransformation3d(PRCbitStream&) const;
   void serializeTransformation3d(PRCbitStream& pbs)  const { serializeGeneralTransformation3d(pbs); }
-  double mat[4][4];
+  double m_coef[16];
   bool operator==(const PRCGeneralTransformation3d &t) const
   {
-    for (size_t i=0;i<4;i++)
-      for (size_t j=0;j<4;j++)
-        if(mat[i][j]!=t.mat[i][j])
+    for (size_t i=0;i<16;i++)
+        if(m_coef[i]!=t.m_coef[i])
          return false;
     return true;
   }
   bool operator<(const PRCGeneralTransformation3d &t) const
   {
-    for (size_t i=0;i<4;i++)
-      for (size_t j=0;j<4;j++)
-        if(mat[i][j]!=t.mat[i][j])
+    for (size_t i=0;i<16;i++)
+        if(m_coef[i]!=t.m_coef[i])
         {
-          return (mat[i][j]<t.mat[i][j]);
+          return (m_coef[i]<t.m_coef[i]);
         }
     return false;
   }
-  void set(const double t[][4])
+  void set(const double t[])
   {
     if(t!=NULL) 
-      for (size_t i=0;i<4;i++)
-        for (size_t j=0;j<4;j++)
-          mat[i][j]=t[i][j];
+      for (size_t i=0;i<16;i++)
+          m_coef[i]=t[i];
+    else
+      setidentity();
+  }
+  void setidentity()
+  {
+    m_coef[0]=1; m_coef[4]=0; m_coef[ 8]=0; m_coef[12]=0;
+    m_coef[1]=0; m_coef[5]=1; m_coef[ 9]=0; m_coef[13]=0;
+    m_coef[2]=0; m_coef[6]=0; m_coef[10]=1; m_coef[14]=0;
+    m_coef[3]=0; m_coef[7]=0; m_coef[11]=0; m_coef[15]=1;
   }
   bool isnotidtransform() const {
     return(
-    mat[0][0]!=1 || mat[0][1]!=0 || mat[0][2]!=0 || mat[0][3]!=0 ||
-    mat[1][0]!=0 || mat[1][1]!=1 || mat[1][2]!=0 || mat[1][3]!=0 ||
-    mat[2][0]!=0 || mat[2][1]!=0 || mat[2][2]!=1 || mat[2][3]!=0 ||
-    mat[3][0]!=0 || mat[3][1]!=0 || mat[3][2]!=0 || mat[3][3]!=1 );
+           m_coef[0]!=1 || m_coef[4]!=0 || m_coef[ 8]!=0 || m_coef[12]!=0 ||
+           m_coef[1]!=0 || m_coef[5]!=1 || m_coef[ 9]!=0 || m_coef[13]!=0 ||
+           m_coef[2]!=0 || m_coef[6]!=0 || m_coef[10]!=1 || m_coef[14]!=0 ||
+           m_coef[3]!=0 || m_coef[7]!=0 || m_coef[11]!=0 || m_coef[15]!=1 );
   }
   bool isidtransform() const {
     return(
-    mat[0][0]==1 && mat[0][1]==0 && mat[0][2]==0 && mat[0][3]==0 &&
-    mat[1][0]==0 && mat[1][1]==1 && mat[1][2]==0 && mat[1][3]==0 &&
-    mat[2][0]==0 && mat[2][1]==0 && mat[2][2]==1 && mat[2][3]==0 &&
-    mat[3][0]==0 && mat[3][1]==0 && mat[3][2]==0 && mat[3][3]==1 );
+           m_coef[0]==1 && m_coef[4]==0 && m_coef[ 8]==0 && m_coef[12]==0 &&
+           m_coef[1]==0 && m_coef[5]==1 && m_coef[ 9]==0 && m_coef[13]==0 &&
+           m_coef[2]==0 && m_coef[6]==0 && m_coef[10]==1 && m_coef[14]==0 &&
+           m_coef[3]==0 && m_coef[7]==0 && m_coef[11]==0 && m_coef[15]==1 );
+  }
+  double M(size_t i, size_t j) const {
+    return m_coef[i+j*4];
   }
 };
 typedef std::deque <PRCGeneralTransformation3d> PRCGeneralTransformation3dList;
@@ -762,6 +808,18 @@
     behaviour(PRC_TRANSFORMATION_Identity), origin(0.0,0.0,0.0), X(1.0,0.0,0.0), Y(0.0,1.0,0.0), Z(0.0,0.0,1.0),
     scale(1.0,1.0,1.0), uniform_scale(1.0),
     X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0) {}
+  PRCCartesianTransformation3d(const double o[3], const double x[3], const double y[3], double sc) :
+    behaviour(PRC_TRANSFORMATION_Identity), origin(o,0.0,0.0,0.0), X(x,1.0,0.0,0.0), Y(y,0.0,1.0,0.0), Z(0.0,0.0,1.0),
+    scale(1.0,1.0,1.0), uniform_scale(sc),
+    X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0)
+    {
+      if(origin!=PRCVector3d(0.0,0.0,0.0))
+        behaviour = behaviour | PRC_TRANSFORMATION_Translate;
+      if(X!=PRCVector3d(1.0,0.0,0.0) || Y!=PRCVector3d(0.0,1.0,0.0))
+        behaviour = behaviour | PRC_TRANSFORMATION_Rotate;
+      if(uniform_scale!=1)
+        behaviour = behaviour | PRC_TRANSFORMATION_Scale;
+    }
   void serializeCartesianTransformation3d(PRCbitStream& pbs) const;
   void serializeTransformation3d(PRCbitStream& pbs) const { serializeCartesianTransformation3d(pbs); }
   uint8_t behaviour;
@@ -788,7 +846,7 @@
 public:
   PRCTransformation() :
     has_transformation(false), geometry_is_2D(false), behaviour(PRC_TRANSFORMATION_Identity),
-    origin(0,0,0), x_axis(1,0,0), y_axis(0,1,0), scale(1) {}
+    origin(0.0,0.0,0.0), x_axis(1.0,0.0,0.0), y_axis(0.0,1.0,0.0), scale(1) {}
   void serializeTransformation(PRCbitStream&);
   bool has_transformation;
   bool geometry_is_2D;
@@ -803,11 +861,12 @@
 {
 public:
   PRCCoordinateSystem(std::string n="") :
-  PRCRepresentationItem(n), axis_set(NULL) {}
+  PRCRepresentationItem(PRC_TYPE_RI_CoordinateSystem,n), axis_set(NULL) {}
   ~PRCCoordinateSystem() { delete axis_set; }
   void serializeCoordinateSystem(PRCbitStream&);
   void serializeRepresentationItem(PRCbitStream &pbs) { serializeCoordinateSystem(pbs); }
-  void setAxisSet(PRCTransformation3d*& transform) { axis_set = transform; transform = NULL; } 
+  void setAxisSet(PRCGeneralTransformation3d*& transform) { axis_set = transform; transform = NULL; } 
+  void setAxisSet(PRCCartesianTransformation3d*& transform) { axis_set = transform; transform = NULL; } 
   PRCTransformation3d *axis_set;
   bool operator==(const PRCCoordinateSystem &t) const
   {
@@ -859,7 +918,7 @@
 class PRCBoundingBox
 {
 public:
-  PRCBoundingBox() : min(0,0,0), max(0,0,0) {}
+  PRCBoundingBox() : min(0.0,0.0,0.0), max(0.0,0.0,0.0) {}
   PRCBoundingBox(const PRCVector3d &m1, const PRCVector3d& m2) : min(m1),max(m2) {}
   void serializeBoundingBox(PRCbitStream &pbs);
   PRCVector3d min;
@@ -1091,6 +1150,19 @@
   void  serializeSphere(PRCbitStream &pbs);
   void  serializeSurface(PRCbitStream &pbs) { serializeSphere(pbs); }
   double radius;
+};
+
+class PRCCone : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCCone() :
+    PRCSurface() {}
+  PRCCone(std::string n) :
+    PRCSurface(n) {}
+  void  serializeCone(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeCone(pbs); }
+  double bottom_radius;
+  double semi_angle;
 };
 
 class PRCCylinder : public PRCSurface, public PRCTransformation, public PRCUVParameterization
@@ -1311,7 +1383,7 @@
 {
 public:
   PRCTopoContext(std::string n="") :
-  ContentPRCBase(n), behaviour(0), granularity(1), tolerance(0),
+  ContentPRCBase(PRC_TYPE_TOPO_Context,n), behaviour(0), granularity(1), tolerance(0),
    have_smallest_face_thickness(false), smallest_thickness(0), have_scale(false), scale(1) {}
   ~PRCTopoContext() { for(PRCBodyList::iterator it=body.begin(); it!=body.end(); ++it) delete *it; }
   void serializeTopoContext(PRCbitStream&);
@@ -1335,18 +1407,20 @@
 class PRCUniqueId
 {
 public:
-  PRCUniqueId() : unique_id0(0), unique_id1(0), unique_id2(0), unique_id3(0)  {}
-  void serializeCompressedUniqueId(PRCbitStream&);
-  uint32_t unique_id0;
-  uint32_t unique_id1;
-  uint32_t unique_id2;
-  uint32_t unique_id3;
+  PRCUniqueId() : id0(0), id1(0), id2(0), id3(0)  {}
+  void serializeCompressedUniqueId(PRCbitStream&) const;
+  void serializeFileStructureUncompressedUniqueId(std::ostream& out) const;
+  uint32_t id0;
+  uint32_t id1;
+  uint32_t id2;
+  uint32_t id3;
 };
 
 class PRCUnit
 {
 public:
   PRCUnit() : unit_from_CAD_file(false), unit(1) {}
+  PRCUnit(double u, bool ufcf=true) : unit_from_CAD_file(ufcf), unit(u) {}
   void serializeUnit(PRCbitStream&);
   bool unit_from_CAD_file;
   double unit;
@@ -1356,7 +1430,7 @@
 {
 public:
   PRCProductOccurrence(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()),
+    ContentPRCBase(PRC_TYPE_ASM_ProductOccurence,n),
     index_part(m1),
     index_prototype(m1), prototype_in_same_file_structure(true),
     index_external_data(m1), external_data_in_same_file_structure(true),
@@ -1385,7 +1459,7 @@
 {
 public:
 	PRCPartDefinition(std::string n="") :
-    ContentPRCBase(n,true,makeCADID(),0,makePRCID()) {}
+    ContentPRCBase(PRC_TYPE_ASM_PartDefinition,n) {}
   ~PRCPartDefinition() { for(PRCRepresentationItemList::iterator it=representation_item.begin(); it!=representation_item.end(); ++it) delete *it; }
 	void serializePartDefinition(PRCbitStream&);
 	uint32_t addBrepModel(PRCBrepModel*& pBrepModel);

Modified: trunk/Scribus/scribus/ui/osgeditor.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/ui/osgeditor.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/osgeditor.cpp (original)
+++ trunk/Scribus/scribus/ui/osgeditor.cpp Fri Sep 28 15:05:16 2012
@@ -47,11 +47,12 @@
 #include <QInputDialog>
 #include <QColorDialog>
 
-OSGEditorDialog::OSGEditorDialog(QWidget* parent, PageItem_OSGFrame *frame) : QDialog(parent)
+OSGEditorDialog::OSGEditorDialog(QWidget* parent, PageItem_OSGFrame *frame, QString osgFilterString) : QDialog(parent)
 {
 	setupUi(this);
 	setModal(true);
 	currItem = frame;
+	filterString = osgFilterString;
 	int wd = 300;
 	int hd = 300;
 	double asp = currItem->width() / currItem->height();
@@ -572,36 +573,7 @@
 	QString fileName;
 	PrefsContext* dirs = PrefsManager::instance()->prefsFile->getContext("dirs");
 	QString wdir = dirs->get("models", ".");
-	QStringList supportedExts;
-	supportedExts << "osg" << "dxf" << "flt" << "ive" << "geo" << "sta" << "stl" << "logo" << "3ds" << "ac" << "obj";
-	QStringList realSupportedExts;
-	QMap<QString, QString> formats;
-	osgDB::FileNameList plugins = osgDB::listAllAvailablePlugins();
-	for(osgDB::FileNameList::iterator itr = plugins.begin(); itr != plugins.end(); ++itr)
-	{
-		osgDB::ReaderWriterInfoList infoList;
-		if (osgDB::queryPlugin(*itr, infoList))
-		{
-			for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin(); rwi_itr != infoList.end(); ++rwi_itr)
-			{
-				osgDB::ReaderWriterInfo& info = *(*rwi_itr);
-				osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
-				for(fdm_itr = info.extensions.begin(); fdm_itr != info.extensions.end(); ++fdm_itr)
-				{
-					if (supportedExts.contains(QString::fromStdString(fdm_itr->first)))
-					{
-						formats.insert("*." + QString::fromStdString(fdm_itr->first) + " *." + QString::fromStdString(fdm_itr->first).toUpper(), QString::fromStdString(fdm_itr->second) + " (*." + QString::fromStdString(fdm_itr->first) + " *." + QString::fromStdString(fdm_itr->first).toUpper() + ")");
-					}
-				}
-			}
-		}
-	}
-	realSupportedExts = formats.keys();
-	QString docexts = realSupportedExts.join(" ");
-	QStringList longList = formats.values();
-	QString longDesc = longList.join(";;") + ";;";
-	QString filter = tr("All Supported Formats (%1);;%2All Files (*)").arg(docexts).arg(longDesc);
-	CustomFDialog dia(this, wdir, tr("Import 3-D Model"), filter, fdHidePreviewCheckBox);
+	CustomFDialog dia(this, wdir, tr("Import 3-D Model"), filterString, fdHidePreviewCheckBox);
 	if (dia.exec() == QDialog::Accepted)
 		fileName = dia.selectedFile();
 	else

Modified: trunk/Scribus/scribus/ui/osgeditor.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17781&path=/trunk/Scribus/scribus/ui/osgeditor.h
==============================================================================
--- trunk/Scribus/scribus/ui/osgeditor.h (original)
+++ trunk/Scribus/scribus/ui/osgeditor.h Fri Sep 28 15:05:16 2012
@@ -43,7 +43,7 @@
 	Q_OBJECT
 
 	public:
-		OSGEditorDialog(QWidget* parent, PageItem_OSGFrame *frame);
+		OSGEditorDialog(QWidget* parent, PageItem_OSGFrame *frame, QString osgFilterString);
 		~OSGEditorDialog() {};
 
 	public slots:
@@ -78,6 +78,7 @@
 		osg::ref_ptr<osg::Node> usedModel2;
 		osg::ref_ptr<osg::StateSet> default_stateset;
 		QString modelFile;
+		QString filterString;
 };
 
 #endif




More information about the scribus-commit mailing list