GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_objmtlloader.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  Version 2.0.0, packaged on July 2010.
6 
7  http://glc-lib.sourceforge.net
8 
9  GLC-lib is free software; you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13 
14  GLC-lib is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with GLC-lib; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 
23 *****************************************************************************/
24 
26 
27 #include "glc_objmtlloader.h"
28 #include "../glc_fileformatexception.h"
29 #include <QDir>
30 #include <QFile>
31 #include <QTextStream>
32 #include <QtDebug>
33 #include <QGLContext>
34 
35 GLC_ObjMtlLoader::GLC_ObjMtlLoader(const QString& fileName)
36 : m_FileName(fileName)
37 , m_pCurrentMaterial(NULL)
38 , m_Materials()
39 , m_LoadStatus()
40 , m_ListOfAttachedFileName()
41 {
42 }
43 
45 {
46  // Remove unused material
47  QHash<QString, GLC_Material*>::iterator i;
48  for (i= m_Materials.begin(); i != m_Materials.end(); ++i)
49  {
50  if (i.value()->isUnused()) delete i.value();
51  }
52  m_Materials.clear();
54 }
56 // Get functions
58 // Get a material from is name
59 GLC_Material* GLC_ObjMtlLoader::material(const QString& materialName)
60 {
61  if (m_Materials.contains(materialName))
62  {
63  return m_Materials[materialName];
64  }
65  else
66  {
67  return NULL;
68  }
69 }
70 
72 // Set functions
74 // Load the materials
76 {
77 
78  // Create the input file stream
79  QFile mtlFile(m_FileName);
80 
81  if (!mtlFile.open(QIODevice::ReadOnly))
82  {
83  qDebug() << "GLC_ObjMtlLoader::LoadMaterial File " << m_FileName << " doesn't exist";
84  return false;
85  }
86  else
87  {
88  //qDebug() << "GLC_ObjMtlLoader::LoadMaterial OK File " << m_FileName << " exist";
89  }
90 
91  QTextStream mtlStream(&mtlFile);
92 
93  QString lineBuff;
94  QString header;
95 
96  while (!mtlStream.atEnd())
97  {
98  lineBuff= mtlStream.readLine();
99  //qDebug() << lineBuff;
100  QTextStream streamLine(lineBuff.toLatin1());
101 
102  if ((streamLine >> header).status() ==QTextStream::Ok)
103  {
104 
105  // Search New material
106  if (header =="newmtl")
107  {
108  //qDebug() << "New material find";
109 
110  if (NULL != m_pCurrentMaterial)
111  { // It's not the first material
112  //qDebug() << "Add material : " << m_pCurrentMaterial->name();
115  m_pCurrentMaterial= NULL;
116  }
117 
119  if (!extractMaterialName(lineBuff)) return false;
120  //qDebug() << "New Material " << m_pCurrentMaterial->name();
121 
122  }
123  else if ((header == "Ka") || (header == "Kd") || (header == "Ks")) // ambiant, diffuse and specular color
124  {
125  if (!extractRGBValue(lineBuff)) return false;
126  }
127 
128  else if ((header == "Ns") || (header == "d")) // shiness Or transparency
129  {
130  if (!extractOneValue(lineBuff)) return false;
131  }
132  else if ((header == "map_Kd") || (header == "map_Ka")) // Texture
133  {
134  //qDebug() << "Texture detected";
135  extractTextureFileName(lineBuff);
136  }
137 
138  }
139  }
140 
141  if (NULL != m_pCurrentMaterial)
142  {
143  //qDebug() << "Add material : " << m_pCurrentMaterial->name();
145  m_pCurrentMaterial= NULL;
146  }
147 
148  mtlFile.close();
149  return true;
150 
151 }
153 // Private services functions
155 
156 // Extract the material name
158 {
159  bool result= false;
160  QTextStream stream(&ligne);
161  QString valueString;
162  QString header;
163  if ((stream >> header >> valueString).status() == QTextStream::Ok)
164  {
165  // If There is an space in the string to extracts
166  QString valueString2;
167  while ((stream >> valueString2).status() == QTextStream::Ok)
168  {
169  valueString.append(" ");
170  valueString.append(valueString2);
171  }
172  m_pCurrentMaterial->setName(valueString);
173  //qDebug() << "Material name is : " << valueString;
174  result= true;
175  }
176  else
177  {
178  m_LoadStatus= "GLC_ObjMtlLoader::extractMaterialName : something is wrong!!";
179  result= false;
180  }
181  return result;
182 }
183 // Extract the texture file name
185 {
186  QTextStream stream(&ligne);
187  QString valueString;
188  QString header;
189  if ((stream >> header >> valueString).status() == QTextStream::Ok)
190  {
191  // Retrieve the .obj file path
192  QFileInfo fileInfo(m_FileName);
193 
194  QString textureFileName(fileInfo.absolutePath() + QDir::separator());
195  // concatenate File Path with texture filename
196  textureFileName.append(getTextureName(stream, valueString));
197 
198  QFile textureFile(textureFileName);
199 
200  if (!textureFile.open(QIODevice::ReadOnly))
201  {
202  QStringList stringList(m_FileName);
203  stringList.append("Open File : " + textureFileName + " failed");
204  GLC_ErrorLog::addError(stringList);
205  }
206  else if ((textureFileName.right(3).contains("TGA", Qt::CaseInsensitive)))
207  {
208  QStringList stringList(m_FileName);
209  stringList.append("Image : " + textureFileName + " not suported");
210  GLC_ErrorLog::addError(stringList);
211  }
212  else
213  {
214  m_ListOfAttachedFileName << textureFileName;
215  // Create the texture and assign it to current material
216  GLC_Texture *pTexture = new GLC_Texture(textureFile);
217  m_pCurrentMaterial->setTexture(pTexture);
218  //qDebug() << "Texture File is : " << valueString;
219  }
220  textureFile.close();
221  }
222 }
223 
224 // Extract RGB value
226 {
227  bool result= false;
228  QTextStream stream(&ligne);
229  QString header;
230  QString rColor, gColor, bColor;
231  QColor color(Qt::white);
232 
233  if ((stream >> header >> rColor >> gColor >> bColor).status() == QTextStream::Ok)
234  {
235  bool okr, okg, okb;
236  color.setRedF(rColor.toDouble(&okr));
237  color.setGreenF(gColor.toDouble(&okg));
238  color.setBlueF(bColor.toDouble(&okb));
239  if (!(okr && okg && okb))
240  {
241  m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : Wrong format of rgb color value!!";
242  qDebug() << m_LoadStatus;
243  result= false;
244  }
245  else
246  {
247  color.setAlphaF(1.0);
248  if (header == "Ka") // Ambiant Color
249  {
251  //qDebug() << "Ambiant Color : " << color.redF() << " " << color.greenF() << " " << color.blueF();
252  result= true;
253  }
254 
255  else if (header == "Kd") // Diffuse Color
256  {
258  //qDebug() << "Diffuse Color : " << color.redF() << " " << color.greenF() << " " << color.blueF();
259  result= true;
260  }
261 
262  else if (header == "Ks") // Specular Color
263  {
265  //qDebug() << "Specular Color : " << color.redF() << " " << color.greenF() << " " << color.blueF();
266  result= true;
267  }
268 
269  else
270  {
271  m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!";
272  result= false;
273  }
274  }
275 
276  }else
277  {
278  m_LoadStatus= "GLC_ObjMtlLoader::ExtractRGBValue : something is wrong!!";
279  qDebug() << m_LoadStatus;
280  result= false;
281  }
282 
283  return result;
284 
285 }
286 
287 // Extract One value
289 {
290  QTextStream stream(&ligne);
291  QString valueString;
292  QString header;
293  GLfloat value;
294 
295  if ((stream >> header >> valueString).status() == QTextStream::Ok)
296  {
297  if (header == "Ns") // Ambient color
298  {
299  bool ok;
300  value= valueString.toFloat(&ok);
301  if (!ok)
302  {
303  m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format of Shiness !";
304  qDebug() << m_LoadStatus;
305  return false;
306  }
308  return true;
309  }
310  else if (header == "d") // Transparancy
311  {
312  bool ok;
313  value= valueString.toFloat(&ok);
314  if (!ok)
315  {
316  m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Wrong format Transparency!";
317  qDebug() << m_LoadStatus;
318  return false;
319  }
320  m_pCurrentMaterial->setOpacity(static_cast<qreal>(value));
321  return true;
322  }
323 
324  else
325  {
326  m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : Ambient Color not found!!";
327  qDebug() << m_LoadStatus;
328  return false;
329  }
330  }
331  else
332  {
333  m_LoadStatus= "GLC_ObjMtlLoader::ExtractOneValue : something is wrong!!";
334  qDebug() << m_LoadStatus;
336  return false;
337  }
338 
339 }
340 
341 // Get texture file name without parameters
342 QString GLC_ObjMtlLoader::getTextureName(QTextStream &inputStream, const QString &input)
343 {
344  QString textureName(input);
345  int numberOfStringToSkip= 0;
346  // Check if there is a map parameter and count
347  if ((input == "-o") || (input == "-s") || (input == "-t"))
348  {
349  numberOfStringToSkip= 3;
350  }
351  else if (input == "-mm")
352  {
353  numberOfStringToSkip= 2;
354  }
355  else if ((input == "-blendu") || (input == "-blendv") || (input == "-cc")
356  || (input == "-clamp") || (input == "-texres"))
357  {
358  numberOfStringToSkip= 1;
359  }
360 
361  if (numberOfStringToSkip != 0)
362  {
363  // Skip unread map parameters
364  for (int i= 0; i < numberOfStringToSkip; ++i)
365  {
366  inputStream >> textureName;
367  }
368 
369  if ((inputStream >> textureName).status() == QTextStream::Ok)
370  {
371  textureName= getTextureName(inputStream, textureName);
372  }
373  else
374  {
375  m_LoadStatus== "GLC_ObjToMesh2::extractString : Error occur when trying to decode map option";
377  throw(fileFormatException);
378  }
379  }
380  return textureName;
381 }
382 // Process Maya specific obj
384 {
385  // Test if the current material have a texture
387  {
388  // Test if the diffuse color of material is black
389  if (m_pCurrentMaterial->diffuseColor() == Qt::black)
390  {
391  // Change the material's diffuse color in order to see the texture
392  m_pCurrentMaterial->setDiffuseColor(Qt::lightGray);
393  }
394  }
395 }

©2005-2013 Laurent Ribon