glc_objmtlloader.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  Version 2.0.0 Beta 1, packaged on April 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023 *****************************************************************************/
00024 
00026 
00027 #include "glc_objmtlloader.h"
00028 #include "../glc_fileformatexception.h"
00029 #include <QDir>
00030 #include <QFile>
00031 #include <QTextStream>
00032 #include <QtDebug>
00033 #include <QGLContext>
00034 
00035 GLC_ObjMtlLoader::GLC_ObjMtlLoader(const QGLContext *pContext, const QString& fileName)
00036 : m_FileName(fileName)
00037 , m_pCurrentMaterial(NULL)
00038 , m_Materials()
00039 , m_LoadStatus()
00040 , m_pQGLContext(pContext)
00041 , m_ListOfAttachedFileName()
00042 {
00043 }
00044 
00045 GLC_ObjMtlLoader::~GLC_ObjMtlLoader()
00046 {
00047         // Remove unused material
00048         QHash<QString, GLC_Material*>::iterator i;
00049         for (i= m_Materials.begin(); i != m_Materials.end(); ++i)
00050         {
00051                 if (i.value()->isUnused()) delete i.value();
00052         }
00053         m_Materials.clear();
00054         m_ListOfAttachedFileName.clear();
00055 }
00057 // Get functions
00059 // Get a material from is name
00060 GLC_Material* GLC_ObjMtlLoader::material(const QString& materialName)
00061 {
00062         if (m_Materials.contains(materialName))
00063         {
00064                 return m_Materials[materialName];
00065         }
00066         else
00067         {
00068                 return NULL;
00069         }
00070 }
00071 
00073 // Set functions
00075 // Load the materials
00076 bool GLC_ObjMtlLoader::loadMaterials()
00077 {
00078 
00079         // Create the input file stream
00080         QFile mtlFile(m_FileName);
00081 
00082         if (!mtlFile.open(QIODevice::ReadOnly))
00083         {
00084                 qDebug() << "GLC_ObjMtlLoader::LoadMaterial File " << m_FileName << " doesn't exist";
00085                 return false;
00086         }
00087         else
00088         {
00089                 //qDebug() << "GLC_ObjMtlLoader::LoadMaterial OK File " << m_FileName << " exist";
00090         }
00091 
00092         QTextStream mtlStream(&mtlFile);
00093 
00094         QString lineBuff;
00095         QString header;
00096 
00097         while (!mtlStream.atEnd())
00098         {
00099                 lineBuff= mtlStream.readLine();
00100                 //qDebug() << lineBuff;
00101                 QTextStream streamLine(lineBuff.toAscii());
00102 
00103                 if ((streamLine >> header).status() ==QTextStream::Ok)
00104                 {
00105 
00106                         // Search New material
00107                         if (header =="newmtl")
00108                         {
00109                                 //qDebug() << "New material find";
00110 
00111                                 if (NULL != m_pCurrentMaterial)
00112                                 {       // It's not the first material
00113                                         //qDebug() << "Add material : " << m_pCurrentMaterial->name();
00114                                         processMayaSpecific();
00115                                         m_Materials.insert(m_pCurrentMaterial->name(), m_pCurrentMaterial);
00116                                         m_pCurrentMaterial= NULL;
00117                                 }
00118 
00119                                 m_pCurrentMaterial= new GLC_Material;
00120                                 if (!extractMaterialName(lineBuff)) return false;
00121                                 //qDebug() << "New Material " << m_pCurrentMaterial->name();
00122 
00123                         }
00124                         else if ((header == "Ka") || (header == "Kd") || (header == "Ks")) // ambiant, diffuse and specular color
00125                         {
00126                                 if (!extractRGBValue(lineBuff)) return false;
00127                         }
00128 
00129                         else if ((header == "Ns") || (header == "d"))   // shiness Or transparency
00130                         {
00131                                 if (!extractOneValue(lineBuff)) return false;
00132                         }
00133                         else if ((header == "map_Kd") || (header == "map_Ka"))  // Texture
00134                         {
00135                                 //qDebug() << "Texture detected";
00136                                 extractTextureFileName(lineBuff);
00137                         }
00138 
00139                 }
00140         }
00141 
00142         if (NULL != m_pCurrentMaterial)
00143         {
00144                 //qDebug() << "Add material : " << m_pCurrentMaterial->name();
00145                 m_Materials.insert(m_pCurrentMaterial->name(), m_pCurrentMaterial);
00146                 m_pCurrentMaterial= NULL;
00147         }
00148 
00149         mtlFile.close();
00150         return true;
00151 
00152 }
00154 // Private services functions
00156 
00157 // Extract the material name
00158 bool GLC_ObjMtlLoader::extractMaterialName(QString &ligne)
00159 {
00160         bool result= false;
00161         QTextStream stream(&ligne);
00162         QString valueString;
00163         QString header;
00164         if ((stream >> header >> valueString).status() == QTextStream::Ok)
00165         {
00166                 // If There is an space in the string to extracts
00167                 QString valueString2;
00168                 while ((stream >> valueString2).status() == QTextStream::Ok)
00169                 {
00170                         valueString.append(" ");
00171                         valueString.append(valueString2);
00172                 }
00173                 m_pCurrentMaterial->setName(valueString);
00174                 //qDebug() << "Material name is : " << valueString;
00175                 result= true;
00176         }
00177         else
00178         {
00179                 m_LoadStatus= "GLC_ObjMtlLoader::extractMaterialName : something is wrong!!";
00180                 result= false;
00181         }
00182         return result;
00183 }
00184 // Extract the texture file name
00185 void GLC_ObjMtlLoader::extractTextureFileName(QString &ligne)
00186 {
00187         QTextStream stream(&ligne);
00188         QString valueString;
00189         QString header;
00190         if ((stream >> header >> valueString).status() == QTextStream::Ok)
00191         {
00192                 // Retrieve the .obj file path
00193                 QFileInfo fileInfo(m_FileName);
00194 
00195                 QString textureFileName(fileInfo.absolutePath() + QDir::separator());
00196                 // concatenate File Path with texture filename
00197                 textureFileName.append(getTextureName(stream, valueString));
00198 
00199                 QFile textureFile(textureFileName);
00200 
00201                 if (!textureFile.open(QIODevice::ReadOnly) || (textureFileName.right(3).contains("TGA", Qt::CaseInsensitive)))
00202                 {
00203                         m_LoadStatus= "GLC_ObjMtlLoader::extractTextureFileName File ";
00204                         //qDebug() << m_LoadStatus;
00205                         // Skip texture and continu loading
00206                 }
00207                 else
00208                 {
00209                         m_ListOfAttachedFileName << textureFileName;
00210                         // Create the texture and assign it to current material
00211                         GLC_Texture *pTexture = new GLC_Texture(m_pQGLContext, textureFile);
00212                         m_pCurrentMaterial->setTexture(pTexture);
00213                         //qDebug() << "Texture File is : " << valueString;
00214                 }
00215                 textureFile.close();
00216         }
00217 }
00218 
00219 // Extract RGB value
00220 bool GLC_ObjMtlLoader::extractRGBValue(QString &ligne)
00221 {
00222         bool result= false;
00223         QTextStream stream(&ligne);
00224         QString header;
00225         QString rColor, gColor, bColor;
00226         QColor color(Qt::white);
00227 
00228         if ((stream >> header >> rColor >> gColor >> bColor).status() == QTextStream::Ok)
00229         {
00230                 bool okr, okg, okb;
00231                 color.setRedF(rColor.toDouble(&okr));
00232                 color.setGreenF(gColor.toDouble(&okg));
00233                 color.setBlueF(bColor.toDouble(&okb));
00234                 if (!(okr && okg && okb))
00235                 {
00236                         m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : Wrong format of rgb color value!!";
00237                         qDebug() << m_LoadStatus;
00238                         result= false;
00239                 }
00240                 else
00241                 {
00242                         color.setAlphaF(1.0);
00243                         if (header == "Ka") // Ambiant Color
00244                         {
00245                                 m_pCurrentMaterial->setAmbientColor(color);
00246                                 //qDebug() << "Ambiant Color : " <<  color.redF() << " " << color.greenF() << " " << color.blueF();
00247                                 result= true;
00248                         }
00249 
00250                         else if (header == "Kd") // Diffuse Color
00251                         {
00252                                 m_pCurrentMaterial->setDiffuseColor(color);
00253                                 //qDebug() << "Diffuse Color : " <<  color.redF() << " " << color.greenF() << " " << color.blueF();
00254                                 result= true;
00255                         }
00256 
00257                         else if (header == "Ks") // Specular Color
00258                         {
00259                                 m_pCurrentMaterial->setSpecularColor(color);
00260                                 //qDebug() << "Specular Color : " <<  color.redF() << " " << color.greenF() << " " << color.blueF();
00261                                 result= true;
00262                         }
00263 
00264                         else
00265                         {
00266                                 m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!";
00267                                 result= false;
00268                         }
00269                 }
00270 
00271         }else
00272         {
00273                 m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!";
00274                 qDebug() << m_LoadStatus;
00275                 result= false;
00276         }
00277 
00278         return result;
00279 
00280 }
00281 
00282 // Extract One value
00283 bool GLC_ObjMtlLoader::extractOneValue(QString &ligne)
00284 {
00285         QTextStream stream(&ligne);
00286         QString valueString;
00287         QString header;
00288         GLfloat value;
00289 
00290         if ((stream >> header >> valueString).status() == QTextStream::Ok)
00291         {
00292                 if (header == "Ns") // Ambient color
00293                 {
00294                         bool ok;
00295                         value= valueString.toFloat(&ok);
00296                         if (!ok)
00297                         {
00298                                 m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format of Shiness !";
00299                                 qDebug() << m_LoadStatus;
00300                                 return false;
00301                         }
00302                         m_pCurrentMaterial->setShininess(value);
00303                         return true;
00304                 }
00305                 else if (header == "d") // Transparancy
00306                 {
00307                         bool ok;
00308                         value= valueString.toFloat(&ok);
00309                         if (!ok)
00310                         {
00311                                 m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format Transparency!";
00312                                 qDebug() << m_LoadStatus;
00313                                 return false;
00314                         }
00315                         m_pCurrentMaterial->setOpacity(static_cast<qreal>(value));
00316                         return true;
00317                 }
00318 
00319                 else
00320                 {
00321                         m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Ambient Color not found!!";
00322                         qDebug() << m_LoadStatus;
00323                         return false;
00324                 }
00325         }
00326         else
00327         {
00328                 m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : something is wrong!!";
00329                 qDebug() << m_LoadStatus;
00330                 GLC_FileFormatException fileFormatException(m_LoadStatus, m_FileName, GLC_FileFormatException::WrongFileFormat);
00331                 return false;
00332         }
00333 
00334 }
00335 
00336 // Get texture file name without parameters
00337 QString GLC_ObjMtlLoader::getTextureName(QTextStream &inputStream, const QString &input)
00338 {
00339         QString textureName(input);
00340         int numberOfStringToSkip= 0;
00341         // Check if there is a map parameter and count
00342         if ((input == "-o") || (input == "-s") || (input == "-t"))
00343         {
00344                 numberOfStringToSkip= 3;
00345         }
00346         else if (input == "-mm")
00347         {
00348                 numberOfStringToSkip= 2;
00349         }
00350         else if ((input == "-blendu") || (input == "-blendv") || (input == "-cc")
00351                         || (input == "-clamp") || (input == "-texres"))
00352         {
00353                 numberOfStringToSkip= 1;
00354         }
00355 
00356         if (numberOfStringToSkip != 0)
00357         {
00358                 // Skip unread map parameters
00359                 for (int i= 0; i < numberOfStringToSkip; ++i)
00360                 {
00361                         inputStream >> textureName;
00362                 }
00363 
00364                 if ((inputStream >> textureName).status() == QTextStream::Ok)
00365                 {
00366                         textureName= getTextureName(inputStream, textureName);
00367                 }
00368                 else
00369                 {
00370                         m_LoadStatus== "GLC_ObjToMesh2::extractString : Error occur when trying to decode map option";
00371                         GLC_FileFormatException fileFormatException(m_LoadStatus, m_FileName, GLC_FileFormatException::WrongFileFormat);
00372                         throw(fileFormatException);
00373                 }
00374         }
00375         return textureName;
00376 }
00377 // Process Maya specific obj
00378 void GLC_ObjMtlLoader::processMayaSpecific()
00379 {
00380         // Test if the current material have a texture
00381         if (m_pCurrentMaterial->hasTexture())
00382         {
00383                 // Test if the diffuse color of material is black
00384                 if (m_pCurrentMaterial->diffuseColor() == Qt::black)
00385                 {
00386                         // Change the material's diffuse color in order to see the texture
00387                         m_pCurrentMaterial->setDiffuseColor(Qt::lightGray);
00388                 }
00389         }
00390 }

SourceForge.net Logo

©2005 Laurent Ribon