vrshoot
diff libs/assimp/ObjFileParser.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/ObjFileParser.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,679 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2012, assimp team 1.10 + 1.11 +All rights reserved. 1.12 + 1.13 +Redistribution and use of this software in source and binary forms, 1.14 +with or without modification, are permitted provided that the following 1.15 +conditions are met: 1.16 + 1.17 +* Redistributions of source code must retain the above 1.18 + copyright notice, this list of conditions and the 1.19 + following disclaimer. 1.20 + 1.21 +* Redistributions in binary form must reproduce the above 1.22 + copyright notice, this list of conditions and the 1.23 + following disclaimer in the documentation and/or other 1.24 + materials provided with the distribution. 1.25 + 1.26 +* Neither the name of the assimp team, nor the names of its 1.27 + contributors may be used to endorse or promote products 1.28 + derived from this software without specific prior 1.29 + written permission of the assimp team. 1.30 + 1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.42 +--------------------------------------------------------------------------- 1.43 +*/ 1.44 + 1.45 +#include "AssimpPCH.h" 1.46 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER 1.47 + 1.48 +#include "ObjFileParser.h" 1.49 +#include "ObjFileMtlImporter.h" 1.50 +#include "ObjTools.h" 1.51 +#include "ObjFileData.h" 1.52 +#include "ParsingUtils.h" 1.53 +#include "assimp/types.h" 1.54 +#include "DefaultIOSystem.h" 1.55 + 1.56 +namespace Assimp 1.57 +{ 1.58 + 1.59 +// ------------------------------------------------------------------- 1.60 +const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; 1.61 + 1.62 +// ------------------------------------------------------------------- 1.63 +// Constructor with loaded data and directories. 1.64 +ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem *io ) : 1.65 + m_DataIt(Data.begin()), 1.66 + m_DataItEnd(Data.end()), 1.67 + m_pModel(NULL), 1.68 + m_uiLine(0), 1.69 + m_pIO( io ) 1.70 +{ 1.71 + std::fill_n(m_buffer,BUFFERSIZE,0); 1.72 + 1.73 + // Create the model instance to store all the data 1.74 + m_pModel = new ObjFile::Model(); 1.75 + m_pModel->m_ModelName = strModelName; 1.76 + 1.77 + m_pModel->m_pDefaultMaterial = new ObjFile::Material(); 1.78 + m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); 1.79 + m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); 1.80 + m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; 1.81 + 1.82 + // Start parsing the file 1.83 + parseFile(); 1.84 +} 1.85 + 1.86 +// ------------------------------------------------------------------- 1.87 +// Destructor 1.88 +ObjFileParser::~ObjFileParser() 1.89 +{ 1.90 + /*delete m_pModel->m_pDefaultMaterial; 1.91 + m_pModel->m_pDefaultMaterial = NULL;*/ 1.92 + 1.93 + delete m_pModel; 1.94 + m_pModel = NULL; 1.95 +} 1.96 + 1.97 +// ------------------------------------------------------------------- 1.98 +// Returns a pointer to the model instance. 1.99 +ObjFile::Model *ObjFileParser::GetModel() const 1.100 +{ 1.101 + return m_pModel; 1.102 +} 1.103 + 1.104 +// ------------------------------------------------------------------- 1.105 +// File parsing method. 1.106 +void ObjFileParser::parseFile() 1.107 +{ 1.108 + if (m_DataIt == m_DataItEnd) 1.109 + return; 1.110 + 1.111 + while (m_DataIt != m_DataItEnd) 1.112 + { 1.113 + switch (*m_DataIt) 1.114 + { 1.115 + case 'v': // Parse a vertex texture coordinate 1.116 + { 1.117 + ++m_DataIt; 1.118 + if (*m_DataIt == ' ') 1.119 + { 1.120 + // Read in vertex definition 1.121 + getVector3(m_pModel->m_Vertices); 1.122 + } 1.123 + else if (*m_DataIt == 't') 1.124 + { 1.125 + // Read in texture coordinate (2D) 1.126 + ++m_DataIt; 1.127 + getVector2(m_pModel->m_TextureCoord); 1.128 + } 1.129 + else if (*m_DataIt == 'n') 1.130 + { 1.131 + // Read in normal vector definition 1.132 + ++m_DataIt; 1.133 + getVector3( m_pModel->m_Normals ); 1.134 + } 1.135 + } 1.136 + break; 1.137 + 1.138 + case 'p': // Parse a face, line or point statement 1.139 + case 'l': 1.140 + case 'f': 1.141 + { 1.142 + getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' 1.143 + ? aiPrimitiveType_LINE : aiPrimitiveType_POINT)); 1.144 + } 1.145 + break; 1.146 + 1.147 + case '#': // Parse a comment 1.148 + { 1.149 + getComment(); 1.150 + } 1.151 + break; 1.152 + 1.153 + case 'u': // Parse a material desc. setter 1.154 + { 1.155 + getMaterialDesc(); 1.156 + } 1.157 + break; 1.158 + 1.159 + case 'm': // Parse a material library 1.160 + { 1.161 + getMaterialLib(); 1.162 + } 1.163 + break; 1.164 + 1.165 + case 'g': // Parse group name 1.166 + { 1.167 + getGroupName(); 1.168 + } 1.169 + break; 1.170 + 1.171 + case 's': // Parse group number 1.172 + { 1.173 + getGroupNumber(); 1.174 + } 1.175 + break; 1.176 + 1.177 + case 'o': // Parse object name 1.178 + { 1.179 + getObjectName(); 1.180 + } 1.181 + break; 1.182 + 1.183 + default: 1.184 + { 1.185 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.186 + } 1.187 + break; 1.188 + } 1.189 + } 1.190 +} 1.191 + 1.192 +// ------------------------------------------------------------------- 1.193 +// Copy the next word in a temporary buffer 1.194 +void ObjFileParser::copyNextWord(char *pBuffer, size_t length) 1.195 +{ 1.196 + size_t index = 0; 1.197 + m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); 1.198 + while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) ) 1.199 + { 1.200 + pBuffer[index] = *m_DataIt; 1.201 + index++; 1.202 + if (index == length-1) 1.203 + break; 1.204 + ++m_DataIt; 1.205 + } 1.206 + pBuffer[index] = '\0'; 1.207 +} 1.208 + 1.209 +// ------------------------------------------------------------------- 1.210 +// Copy the next line into a temporary buffer 1.211 +void ObjFileParser::copyNextLine(char *pBuffer, size_t length) 1.212 +{ 1.213 + size_t index = 0; 1.214 + while (m_DataIt != m_DataItEnd) 1.215 + { 1.216 + if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1) 1.217 + break; 1.218 + 1.219 + pBuffer[ index ] = *m_DataIt; 1.220 + ++index; 1.221 + ++m_DataIt; 1.222 + } 1.223 + pBuffer[ index ] = '\0'; 1.224 +} 1.225 + 1.226 +// ------------------------------------------------------------------- 1.227 +// Get values for a new 3D vector instance 1.228 +void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) 1.229 +{ 1.230 + float x, y, z; 1.231 + copyNextWord(m_buffer, BUFFERSIZE); 1.232 + x = (float) fast_atof(m_buffer); 1.233 + 1.234 + copyNextWord(m_buffer, BUFFERSIZE); 1.235 + y = (float) fast_atof(m_buffer); 1.236 + 1.237 + copyNextWord(m_buffer, BUFFERSIZE); 1.238 + z = (float) fast_atof(m_buffer); 1.239 + 1.240 + point3d_array.push_back( aiVector3D( x, y, z ) ); 1.241 + //skipLine(); 1.242 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.243 +} 1.244 + 1.245 +// ------------------------------------------------------------------- 1.246 +// Get values for a new 2D vector instance 1.247 +void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) 1.248 +{ 1.249 + float x, y; 1.250 + copyNextWord(m_buffer, BUFFERSIZE); 1.251 + x = (float) fast_atof(m_buffer); 1.252 + 1.253 + copyNextWord(m_buffer, BUFFERSIZE); 1.254 + y = (float) fast_atof(m_buffer); 1.255 + 1.256 + point2d_array.push_back(aiVector2D(x, y)); 1.257 + 1.258 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.259 +} 1.260 + 1.261 +// ------------------------------------------------------------------- 1.262 +// Get values for a new face instance 1.263 +void ObjFileParser::getFace(aiPrimitiveType type) 1.264 +{ 1.265 + copyNextLine(m_buffer, BUFFERSIZE); 1.266 + if (m_DataIt == m_DataItEnd) 1.267 + return; 1.268 + 1.269 + char *pPtr = m_buffer; 1.270 + char *pEnd = &pPtr[BUFFERSIZE]; 1.271 + pPtr = getNextToken<char*>(pPtr, pEnd); 1.272 + if (pPtr == pEnd || *pPtr == '\0') 1.273 + return; 1.274 + 1.275 + std::vector<unsigned int> *pIndices = new std::vector<unsigned int>; 1.276 + std::vector<unsigned int> *pTexID = new std::vector<unsigned int>; 1.277 + std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>; 1.278 + bool hasNormal = false; 1.279 + 1.280 + const bool vt = (!m_pModel->m_TextureCoord.empty()); 1.281 + const bool vn = (!m_pModel->m_Normals.empty()); 1.282 + int iStep = 0, iPos = 0; 1.283 + while (pPtr != pEnd) 1.284 + { 1.285 + iStep = 1; 1.286 + 1.287 + if (IsLineEnd(*pPtr)) 1.288 + break; 1.289 + 1.290 + if (*pPtr=='/' ) 1.291 + { 1.292 + if (type == aiPrimitiveType_POINT) { 1.293 + DefaultLogger::get()->error("Obj: Separator unexpected in point statement"); 1.294 + } 1.295 + if (iPos == 0) 1.296 + { 1.297 + //if there are no texture coordinates in the file, but normals 1.298 + if (!vt && vn) { 1.299 + iPos = 1; 1.300 + iStep++; 1.301 + } 1.302 + } 1.303 + iPos++; 1.304 + } 1.305 + else if ( isSeparator(*pPtr) ) 1.306 + { 1.307 + iPos = 0; 1.308 + } 1.309 + else 1.310 + { 1.311 + //OBJ USES 1 Base ARRAYS!!!! 1.312 + const int iVal = atoi( pPtr ); 1.313 + int tmp = iVal; 1.314 + while ( ( tmp = tmp / 10 )!=0 ) 1.315 + ++iStep; 1.316 + 1.317 + if ( iVal > 0 ) 1.318 + { 1.319 + // Store parsed index 1.320 + if ( 0 == iPos ) 1.321 + { 1.322 + pIndices->push_back( iVal-1 ); 1.323 + } 1.324 + else if ( 1 == iPos ) 1.325 + { 1.326 + pTexID->push_back( iVal-1 ); 1.327 + } 1.328 + else if ( 2 == iPos ) 1.329 + { 1.330 + pNormalID->push_back( iVal-1 ); 1.331 + hasNormal = true; 1.332 + } 1.333 + else 1.334 + { 1.335 + reportErrorTokenInFace(); 1.336 + } 1.337 + } 1.338 + } 1.339 + pPtr += iStep; 1.340 + } 1.341 + 1.342 + if ( pIndices->empty() ) 1.343 + { 1.344 + DefaultLogger::get()->error("Obj: Ignoring empty face"); 1.345 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.346 + return; 1.347 + } 1.348 + 1.349 + ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); 1.350 + 1.351 + // Set active material, if one set 1.352 + if (NULL != m_pModel->m_pCurrentMaterial) 1.353 + face->m_pMaterial = m_pModel->m_pCurrentMaterial; 1.354 + else 1.355 + face->m_pMaterial = m_pModel->m_pDefaultMaterial; 1.356 + 1.357 + // Create a default object, if nothing is there 1.358 + if ( NULL == m_pModel->m_pCurrent ) 1.359 + createObject( "defaultobject" ); 1.360 + 1.361 + // Assign face to mesh 1.362 + if ( NULL == m_pModel->m_pCurrentMesh ) 1.363 + { 1.364 + createMesh(); 1.365 + } 1.366 + 1.367 + // Store the face 1.368 + m_pModel->m_pCurrentMesh->m_Faces.push_back( face ); 1.369 + m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size(); 1.370 + m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); 1.371 + if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) 1.372 + { 1.373 + m_pModel->m_pCurrentMesh->m_hasNormals = true; 1.374 + } 1.375 + // Skip the rest of the line 1.376 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.377 +} 1.378 + 1.379 +// ------------------------------------------------------------------- 1.380 +// Get values for a new material description 1.381 +void ObjFileParser::getMaterialDesc() 1.382 +{ 1.383 + // Each material request a new object. 1.384 + // Sometimes the object is already created (see 'o' tag by example), but it is not initialized ! 1.385 + // So, we create a new object only if the current on is already initialized ! 1.386 + if (m_pModel->m_pCurrent != NULL && 1.387 + ( m_pModel->m_pCurrent->m_Meshes.size() > 1 || 1.388 + (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) ) 1.389 + ) 1.390 + m_pModel->m_pCurrent = NULL; 1.391 + 1.392 + // Get next data for material data 1.393 + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); 1.394 + if (m_DataIt == m_DataItEnd) 1.395 + return; 1.396 + 1.397 + char *pStart = &(*m_DataIt); 1.398 + while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) ) 1.399 + ++m_DataIt; 1.400 + 1.401 + // Get name 1.402 + std::string strName(pStart, &(*m_DataIt)); 1.403 + if ( strName.empty()) 1.404 + return; 1.405 + 1.406 + // Search for material 1.407 + std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName ); 1.408 + if ( it == m_pModel->m_MaterialMap.end() ) 1.409 + { 1.410 + // Not found, use default material 1.411 + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; 1.412 + DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); 1.413 + } 1.414 + else 1.415 + { 1.416 + // Found, using detected material 1.417 + m_pModel->m_pCurrentMaterial = (*it).second; 1.418 + if ( needsNewMesh( strName )) 1.419 + { 1.420 + createMesh(); 1.421 + } 1.422 + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); 1.423 + } 1.424 + 1.425 + // Skip rest of line 1.426 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.427 +} 1.428 + 1.429 +// ------------------------------------------------------------------- 1.430 +// Get a comment, values will be skipped 1.431 +void ObjFileParser::getComment() 1.432 +{ 1.433 + while (m_DataIt != m_DataItEnd) 1.434 + { 1.435 + if ( '\n' == (*m_DataIt)) 1.436 + { 1.437 + ++m_DataIt; 1.438 + break; 1.439 + } 1.440 + else 1.441 + { 1.442 + ++m_DataIt; 1.443 + } 1.444 + } 1.445 +} 1.446 + 1.447 +// ------------------------------------------------------------------- 1.448 +// Get material library from file. 1.449 +void ObjFileParser::getMaterialLib() 1.450 +{ 1.451 + // Translate tuple 1.452 + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); 1.453 + if (m_DataIt == m_DataItEnd) 1.454 + return; 1.455 + 1.456 + char *pStart = &(*m_DataIt); 1.457 + while (m_DataIt != m_DataItEnd && !isNewLine(*m_DataIt)) 1.458 + m_DataIt++; 1.459 + 1.460 + // Check for existence 1.461 + const std::string strMatName(pStart, &(*m_DataIt)); 1.462 + IOStream *pFile = m_pIO->Open(strMatName); 1.463 + 1.464 + if (!pFile ) 1.465 + { 1.466 + DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); 1.467 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.468 + return; 1.469 + } 1.470 + 1.471 + // Import material library data from file 1.472 + std::vector<char> buffer; 1.473 + BaseImporter::TextFileToBuffer(pFile,buffer); 1.474 + m_pIO->Close( pFile ); 1.475 + 1.476 + // Importing the material library 1.477 + ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel ); 1.478 +} 1.479 + 1.480 +// ------------------------------------------------------------------- 1.481 +// Set a new material definition as the current material. 1.482 +void ObjFileParser::getNewMaterial() 1.483 +{ 1.484 + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); 1.485 + m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); 1.486 + if ( m_DataIt == m_DataItEnd ) 1.487 + return; 1.488 + 1.489 + char *pStart = &(*m_DataIt); 1.490 + std::string strMat( pStart, *m_DataIt ); 1.491 + while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) 1.492 + m_DataIt++; 1.493 + std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat ); 1.494 + if ( it == m_pModel->m_MaterialMap.end() ) 1.495 + { 1.496 + // Show a warning, if material was not found 1.497 + DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat); 1.498 + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; 1.499 + } 1.500 + else 1.501 + { 1.502 + // Set new material 1.503 + if ( needsNewMesh( strMat ) ) 1.504 + { 1.505 + createMesh(); 1.506 + } 1.507 + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat ); 1.508 + } 1.509 + 1.510 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.511 +} 1.512 + 1.513 +// ------------------------------------------------------------------- 1.514 +int ObjFileParser::getMaterialIndex( const std::string &strMaterialName ) 1.515 +{ 1.516 + int mat_index = -1; 1.517 + if ( strMaterialName.empty() ) 1.518 + return mat_index; 1.519 + for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) 1.520 + { 1.521 + if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) 1.522 + { 1.523 + mat_index = (int)index; 1.524 + break; 1.525 + } 1.526 + } 1.527 + return mat_index; 1.528 +} 1.529 + 1.530 +// ------------------------------------------------------------------- 1.531 +// Getter for a group name. 1.532 +void ObjFileParser::getGroupName() 1.533 +{ 1.534 + std::string strGroupName; 1.535 + 1.536 + m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName); 1.537 + if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) 1.538 + return; 1.539 + 1.540 + // Change active group, if necessary 1.541 + if ( m_pModel->m_strActiveGroup != strGroupName ) 1.542 + { 1.543 + // Search for already existing entry 1.544 + ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); 1.545 + 1.546 + // We are mapping groups into the object structure 1.547 + createObject( strGroupName ); 1.548 + 1.549 + // New group name, creating a new entry 1.550 + if (it == m_pModel->m_Groups.end()) 1.551 + { 1.552 + std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>; 1.553 + m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; 1.554 + m_pModel->m_pGroupFaceIDs = (pFaceIDArray); 1.555 + } 1.556 + else 1.557 + { 1.558 + m_pModel->m_pGroupFaceIDs = (*it).second; 1.559 + } 1.560 + m_pModel->m_strActiveGroup = strGroupName; 1.561 + } 1.562 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.563 +} 1.564 + 1.565 +// ------------------------------------------------------------------- 1.566 +// Not supported 1.567 +void ObjFileParser::getGroupNumber() 1.568 +{ 1.569 + // Not used 1.570 + 1.571 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.572 +} 1.573 + 1.574 +// ------------------------------------------------------------------- 1.575 +// Stores values for a new object instance, name will be used to 1.576 +// identify it. 1.577 +void ObjFileParser::getObjectName() 1.578 +{ 1.579 + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); 1.580 + if (m_DataIt == m_DataItEnd) 1.581 + return; 1.582 + char *pStart = &(*m_DataIt); 1.583 + while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) 1.584 + ++m_DataIt; 1.585 + 1.586 + std::string strObjectName(pStart, &(*m_DataIt)); 1.587 + if (!strObjectName.empty()) 1.588 + { 1.589 + // Reset current object 1.590 + m_pModel->m_pCurrent = NULL; 1.591 + 1.592 + // Search for actual object 1.593 + for (std::vector<ObjFile::Object*>::const_iterator it = m_pModel->m_Objects.begin(); 1.594 + it != m_pModel->m_Objects.end(); 1.595 + ++it) 1.596 + { 1.597 + if ((*it)->m_strObjName == strObjectName) 1.598 + { 1.599 + m_pModel->m_pCurrent = *it; 1.600 + break; 1.601 + } 1.602 + } 1.603 + 1.604 + // Allocate a new object, if current one was not found before 1.605 + if ( NULL == m_pModel->m_pCurrent ) 1.606 + createObject(strObjectName); 1.607 + } 1.608 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.609 +} 1.610 +// ------------------------------------------------------------------- 1.611 +// Creates a new object instance 1.612 +void ObjFileParser::createObject(const std::string &strObjectName) 1.613 +{ 1.614 + ai_assert( NULL != m_pModel ); 1.615 + //ai_assert( !strObjectName.empty() ); 1.616 + 1.617 + m_pModel->m_pCurrent = new ObjFile::Object; 1.618 + m_pModel->m_pCurrent->m_strObjName = strObjectName; 1.619 + m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); 1.620 + 1.621 + 1.622 + createMesh(); 1.623 + 1.624 + if( m_pModel->m_pCurrentMaterial ) 1.625 + { 1.626 + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = 1.627 + getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data ); 1.628 + m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; 1.629 + } 1.630 +} 1.631 +// ------------------------------------------------------------------- 1.632 +// Creates a new mesh 1.633 +void ObjFileParser::createMesh() 1.634 +{ 1.635 + ai_assert( NULL != m_pModel ); 1.636 + m_pModel->m_pCurrentMesh = new ObjFile::Mesh; 1.637 + m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh ); 1.638 + unsigned int meshId = m_pModel->m_Meshes.size()-1; 1.639 + if ( NULL != m_pModel->m_pCurrent ) 1.640 + { 1.641 + m_pModel->m_pCurrent->m_Meshes.push_back( meshId ); 1.642 + } 1.643 + else 1.644 + { 1.645 + DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance."); 1.646 + } 1.647 +} 1.648 + 1.649 +// ------------------------------------------------------------------- 1.650 +// Returns true, if a new mesh must be created. 1.651 +bool ObjFileParser::needsNewMesh( const std::string &rMaterialName ) 1.652 +{ 1.653 + if(m_pModel->m_pCurrentMesh == 0) 1.654 + { 1.655 + // No mesh data yet 1.656 + return true; 1.657 + } 1.658 + bool newMat = false; 1.659 + int matIdx = getMaterialIndex( rMaterialName ); 1.660 + int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; 1.661 + if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx ) 1.662 + { 1.663 + // New material -> only one material per mesh, so we need to create a new 1.664 + // material 1.665 + newMat = true; 1.666 + } 1.667 + return newMat; 1.668 +} 1.669 + 1.670 +// ------------------------------------------------------------------- 1.671 +// Shows an error in parsing process. 1.672 +void ObjFileParser::reportErrorTokenInFace() 1.673 +{ 1.674 + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); 1.675 + DefaultLogger::get()->error("OBJ: Not supported token in face description detected"); 1.676 +} 1.677 + 1.678 +// ------------------------------------------------------------------- 1.679 + 1.680 +} // Namespace Assimp 1.681 + 1.682 +#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER