glc_bsrep.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00023 
00024 #include "glc_bsrep.h"
00025 #include "../glc_fileformatexception.h"
00026 #include "../glc_tracelog.h"
00027 
00028 // The binary rep suffix
00029 const QString GLC_BSRep::m_Suffix("BSRep");
00030 
00031 // The binary rep magic number
00032 const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");
00033 
00034 // The binary rep version
00035 const quint32 GLC_BSRep::m_Version= 102;
00036 
00037 // Mutex used by compression
00038 QMutex GLC_BSRep::m_CompressionMutex;
00039 
00040 // Default constructor
00041 GLC_BSRep::GLC_BSRep(const QString& fileName, bool useCompression)
00042 : m_FileInfo()
00043 , m_pFile(NULL)
00044 , m_DataStream()
00045 , m_UseCompression(useCompression)
00046 , m_CompressionLevel(-1)
00047 {
00048         setAbsoluteFileName(fileName);
00049         m_DataStream.setVersion(QDataStream::Qt_4_6);
00050         m_DataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
00051 }
00052 
00053 // Copy constructor
00054 GLC_BSRep::GLC_BSRep(const GLC_BSRep& binaryRep)
00055 : m_FileInfo(binaryRep.m_FileInfo)
00056 , m_pFile(NULL)
00057 , m_DataStream()
00058 , m_UseCompression(binaryRep.m_UseCompression)
00059 , m_CompressionLevel(binaryRep.m_CompressionLevel)
00060 {
00061         m_DataStream.setVersion(QDataStream::Qt_4_6);
00062         m_DataStream.setFloatingPointPrecision(binaryRep.m_DataStream.floatingPointPrecision());
00063 }
00064 
00065 GLC_BSRep::~GLC_BSRep()
00066 {
00067         delete m_pFile;
00068 }
00069 
00070 // Return true if the binary rep is up to date
00071 bool GLC_BSRep::isUsable(const QDateTime& timeStamp)
00072 {
00073         bool isUpToDate= false;
00074         if (open(QIODevice::ReadOnly))
00075         {
00076                 if (headerIsOk())
00077                 {
00078                         isUpToDate= timeStampOk(timeStamp);
00079                         isUpToDate= isUpToDate && close();
00080                 }
00081         }
00082         else
00083         {
00084                 QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
00085                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
00086                 close();
00087                 throw(fileFormatException);
00088         }
00089 
00090         if (!isUpToDate && GLC_TraceLog::isEnable())
00091         {
00092                 QStringList stringList("GLC_BSRep::isUsable");
00093                 stringList.append("File " + m_FileInfo.filePath() + " not Usable");
00094                 GLC_TraceLog::addTrace(stringList);
00095         }
00096         return isUpToDate;
00097 }
00098 
00100 // name Get Functions
00102 // Load the binary rep
00103 GLC_3DRep GLC_BSRep::loadRep()
00104 {
00105         GLC_3DRep loadedRep;
00106 
00107         if (open(QIODevice::ReadOnly))
00108         {
00109                 if (headerIsOk())
00110                 {
00111                         timeStampOk(QDateTime());
00112                         GLC_BoundingBox boundingBox;
00113                         m_DataStream >> boundingBox;
00114                         bool useCompression;
00115                         m_DataStream >> useCompression;
00116                         if (useCompression)
00117                         {
00118                                 QByteArray CompresseBuffer;
00119                                 m_DataStream >> CompresseBuffer;
00120                                 QByteArray uncompressedBuffer= qUncompress(CompresseBuffer);
00121                                 uncompressedBuffer.squeeze();
00122                                 CompresseBuffer.clear();
00123                                 CompresseBuffer.squeeze();
00124                                 QDataStream bufferStream(uncompressedBuffer);
00125                                 bufferStream >> loadedRep;
00126                         }
00127                         else
00128                         {
00129                                 m_DataStream >> loadedRep;
00130                         }
00131                         loadedRep.setFileName(m_FileInfo.filePath());
00132 
00133                         if (!close())
00134                         {
00135                                 QString message(QString("GLC_BSRep::loadRep An error occur when loading file ") + m_FileInfo.fileName());
00136                                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
00137                                 throw(fileFormatException);
00138                         }
00139                 }
00140                 else
00141                 {
00142                         QString message(QString("GLC_BSRep::loadRep File not supported ") + m_FileInfo.fileName());
00143                         GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotSupported);
00144                         close();
00145                         throw(fileFormatException);
00146                 }
00147         }
00148         else
00149         {
00150                 QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
00151                 GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
00152                 close();
00153                 throw(fileFormatException);
00154         }
00155 
00156 
00157         return loadedRep;
00158 }
00159 
00160 // Return the bounding box of the binary representation
00161 GLC_BoundingBox GLC_BSRep::boundingBox()
00162 {
00163         GLC_BoundingBox boundingBox;
00164 
00165         if (open(QIODevice::ReadOnly))
00166         {
00167                 if (headerIsOk())
00168                 {
00169                         timeStampOk(QDateTime());
00170 
00171                         m_DataStream >> boundingBox;
00172                 }
00173                 close();
00174         }
00175         return boundingBox;
00176 }
00177 
00178 // Return bsrep suffix
00179 QString GLC_BSRep::suffix()
00180 {
00181         return m_Suffix;
00182 }
00183 
00185 //name Set Functions
00187 // Set the binary representation file name
00188 void GLC_BSRep::setAbsoluteFileName(const QString& fileName)
00189 {
00190         m_FileInfo.setFile(fileName);
00191         if (m_FileInfo.suffix() != m_Suffix)
00192         {
00193                 m_FileInfo.setFile(fileName + '.' + m_Suffix);
00194         }
00195 
00196 }
00197 
00198 // Save the GLC_3DRep in serialised binary
00199 bool GLC_BSRep::save(const GLC_3DRep& rep)
00200 {
00201 
00203         bool saveOk= open(QIODevice::WriteOnly);
00204         if (saveOk)
00205         {
00206                 writeHeader(rep.lastModified());
00207 
00208                 // Representation Bounding Box
00209                 m_DataStream << rep.boundingBox();
00210 
00211                 // Compression usage
00212 
00213                 if (m_UseCompression && (rep.faceCount() < 1000000))
00214                 {
00215                         m_DataStream << true;
00216                         QByteArray uncompressedBuffer;
00217                         {
00218                                 QBuffer buffer(&uncompressedBuffer);
00219                                 buffer.open(QIODevice::WriteOnly);
00220                                 QDataStream bufferStream(&buffer);
00221                                 bufferStream << rep;
00222                         }
00223                         m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel);
00224                 }
00225                 else
00226                 {
00227                         m_DataStream << false;
00228                         // Binary representation geometry
00229                         // Add the rep
00230                         m_DataStream << rep;
00231                 }
00232 
00233                 // Flag the file
00234                 qint64 offset= sizeof(QUuid);
00235                 offset+= sizeof(quint32);
00236 
00237                 m_pFile->seek(offset);
00238                 bool writeOk= true;
00239                 m_DataStream << writeOk;
00240                 // Close the file
00241                 saveOk= close();
00242         }
00243         return saveOk;
00244 }
00245 
00246 
00247 // Open the file
00248 bool GLC_BSRep::open(QIODevice::OpenMode mode)
00249 {
00250         bool openOk= m_FileInfo.exists();
00251         if (openOk || (mode == QIODevice::WriteOnly))
00252         {
00253                 m_DataStream.setDevice(NULL);
00254                 delete m_pFile;
00255                 m_pFile= new QFile(m_FileInfo.filePath());
00256                 openOk= m_pFile->open(mode);
00257                 if (openOk)
00258                 {
00259                         m_DataStream.setDevice(m_pFile);
00260                 }
00261         }
00262         else if (GLC_TraceLog::isEnable())
00263         {
00264                 QStringList stringList("GLC_BSRep::open");
00265                 stringList.append("File " + m_FileInfo.filePath() + " doesn't exists");
00266                 GLC_TraceLog::addTrace(stringList);
00267         }
00268 
00269         return openOk;
00270 }
00271 
00272 // Close the file
00273 bool GLC_BSRep::close()
00274 {
00275         Q_ASSERT(m_pFile != NULL);
00276         Q_ASSERT(m_DataStream.device() != NULL);
00277         bool closeOk= m_DataStream.status() == QDataStream::Ok;
00278         m_DataStream.setDevice(NULL);
00279         m_pFile->close();
00280         delete m_pFile;
00281         m_pFile= NULL;
00282 
00283         return closeOk;
00284 }
00285 
00286 // Write the header
00287 void GLC_BSRep::writeHeader(const QDateTime& dateTime)
00288 {
00289         Q_ASSERT(m_pFile != NULL);
00290         Q_ASSERT(m_DataStream.device() != NULL);
00291 
00292         // Binary representation Header
00293         // Add the magic number
00294         m_DataStream << m_Uuid;
00295         // Add the version
00296         m_DataStream << m_Version;
00297         bool writeFinished= false;
00298         m_DataStream << writeFinished;
00299 
00300         // Set the version of the data stream
00301         m_DataStream.setVersion(QDataStream::Qt_4_6);
00302 
00303         // Add the time stamp
00304         m_DataStream << dateTime;
00305 }
00306 
00307 // Check the header
00308 bool GLC_BSRep::headerIsOk()
00309 {
00310         Q_ASSERT(m_pFile != NULL);
00311         Q_ASSERT(m_DataStream.device() != NULL);
00312         Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00313 
00314         QUuid uuid;
00315         quint32 version;
00316         bool writeFinished;
00317 
00318         m_DataStream >> uuid;
00319         m_DataStream >> version;
00320         m_DataStream >> writeFinished;
00321 
00322         // Set the version of the data stream
00323         m_DataStream.setVersion(QDataStream::Qt_4_6);
00324 
00325         bool headerOk= (uuid == m_Uuid) && (version == m_Version) && writeFinished;
00326 
00327         return headerOk;
00328 }
00329 
00330 // Check the time Stamp
00331 bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp)
00332 {
00333         Q_ASSERT(m_pFile != NULL);
00334         Q_ASSERT(m_DataStream.device() != NULL);
00335         Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);
00336 
00337         QDateTime dateTime;
00338         m_DataStream >> dateTime;
00339 
00340         bool timeStampOk= !timeStamp.isValid() || (dateTime == timeStamp);
00341         return timeStampOk;
00342 }
00343 

SourceForge.net Logo

©2005-2011 Laurent Ribon