vrshoot
diff libs/assimp/PlyParser.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/PlyParser.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,919 @@ 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 +/** @file Implementation of the PLY parser class */ 1.46 + 1.47 +#include "AssimpPCH.h" 1.48 +#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER 1.49 + 1.50 +#include "PlyLoader.h" 1.51 +#include "fast_atof.h" 1.52 + 1.53 +using namespace Assimp; 1.54 + 1.55 +// ------------------------------------------------------------------------------------------------ 1.56 +PLY::EDataType PLY::Property::ParseDataType(const char* pCur,const char** pCurOut) 1.57 +{ 1.58 + ai_assert(NULL != pCur && NULL != pCurOut); 1.59 + PLY::EDataType eOut = PLY::EDT_INVALID; 1.60 + 1.61 + if (TokenMatch(pCur,"char",4) || 1.62 + TokenMatch(pCur,"int8",4)) 1.63 + { 1.64 + eOut = PLY::EDT_Char; 1.65 + } 1.66 + else if (TokenMatch(pCur,"uchar",5) || 1.67 + TokenMatch(pCur,"uint8",5)) 1.68 + { 1.69 + eOut = PLY::EDT_UChar; 1.70 + } 1.71 + else if (TokenMatch(pCur,"short",5) || 1.72 + TokenMatch(pCur,"int16",5)) 1.73 + { 1.74 + eOut = PLY::EDT_Short; 1.75 + } 1.76 + else if (TokenMatch(pCur,"ushort",6) || 1.77 + TokenMatch(pCur,"uint16",6)) 1.78 + { 1.79 + eOut = PLY::EDT_UShort; 1.80 + } 1.81 + else if (TokenMatch(pCur,"int32",5) || TokenMatch(pCur,"int",3)) 1.82 + { 1.83 + eOut = PLY::EDT_Int; 1.84 + } 1.85 + else if (TokenMatch(pCur,"uint32",6) || TokenMatch(pCur,"uint",4)) 1.86 + { 1.87 + eOut = PLY::EDT_UInt; 1.88 + } 1.89 + else if (TokenMatch(pCur,"float",5) || TokenMatch(pCur,"float32",7)) 1.90 + { 1.91 + eOut = PLY::EDT_Float; 1.92 + } 1.93 + else if (TokenMatch(pCur,"double64",8) || TokenMatch(pCur,"double",6) || 1.94 + TokenMatch(pCur,"float64",7)) 1.95 + { 1.96 + eOut = PLY::EDT_Double; 1.97 + } 1.98 + if (PLY::EDT_INVALID == eOut) 1.99 + { 1.100 + DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK"); 1.101 + } 1.102 + *pCurOut = pCur; 1.103 + return eOut; 1.104 +} 1.105 + 1.106 +// ------------------------------------------------------------------------------------------------ 1.107 +PLY::ESemantic PLY::Property::ParseSemantic(const char* pCur,const char** pCurOut) 1.108 +{ 1.109 + ai_assert(NULL != pCur && NULL != pCurOut); 1.110 + 1.111 + PLY::ESemantic eOut = PLY::EST_INVALID; 1.112 + if (TokenMatch(pCur,"red",3)) 1.113 + { 1.114 + eOut = PLY::EST_Red; 1.115 + } 1.116 + else if (TokenMatch(pCur,"green",5)) 1.117 + { 1.118 + eOut = PLY::EST_Green; 1.119 + } 1.120 + else if (TokenMatch(pCur,"blue",4)) 1.121 + { 1.122 + eOut = PLY::EST_Blue; 1.123 + } 1.124 + else if (TokenMatch(pCur,"alpha",5)) 1.125 + { 1.126 + eOut = PLY::EST_Alpha; 1.127 + } 1.128 + else if (TokenMatch(pCur,"vertex_index",12) || TokenMatch(pCur,"vertex_indices",14)) 1.129 + { 1.130 + eOut = PLY::EST_VertexIndex; 1.131 + } 1.132 + else if (TokenMatch(pCur,"material_index",14)) 1.133 + { 1.134 + eOut = PLY::EST_MaterialIndex; 1.135 + } 1.136 + else if (TokenMatch(pCur,"ambient_red",11)) 1.137 + { 1.138 + eOut = PLY::EST_AmbientRed; 1.139 + } 1.140 + else if (TokenMatch(pCur,"ambient_green",13)) 1.141 + { 1.142 + eOut = PLY::EST_AmbientGreen; 1.143 + } 1.144 + else if (TokenMatch(pCur,"ambient_blue",12)) 1.145 + { 1.146 + eOut = PLY::EST_AmbientBlue; 1.147 + } 1.148 + else if (TokenMatch(pCur,"ambient_alpha",13)) 1.149 + { 1.150 + eOut = PLY::EST_AmbientAlpha; 1.151 + } 1.152 + else if (TokenMatch(pCur,"diffuse_red",11)) 1.153 + { 1.154 + eOut = PLY::EST_DiffuseRed; 1.155 + } 1.156 + else if (TokenMatch(pCur,"diffuse_green",13)) 1.157 + { 1.158 + eOut = PLY::EST_DiffuseGreen; 1.159 + } 1.160 + else if (TokenMatch(pCur,"diffuse_blue",12)) 1.161 + { 1.162 + eOut = PLY::EST_DiffuseBlue; 1.163 + } 1.164 + else if (TokenMatch(pCur,"diffuse_alpha",13)) 1.165 + { 1.166 + eOut = PLY::EST_DiffuseAlpha; 1.167 + } 1.168 + else if (TokenMatch(pCur,"specular_red",12)) 1.169 + { 1.170 + eOut = PLY::EST_SpecularRed; 1.171 + } 1.172 + else if (TokenMatch(pCur,"specular_green",14)) 1.173 + { 1.174 + eOut = PLY::EST_SpecularGreen; 1.175 + } 1.176 + else if (TokenMatch(pCur,"specular_blue",13)) 1.177 + { 1.178 + eOut = PLY::EST_SpecularBlue; 1.179 + } 1.180 + else if (TokenMatch(pCur,"specular_alpha",14)) 1.181 + { 1.182 + eOut = PLY::EST_SpecularAlpha; 1.183 + } 1.184 + else if (TokenMatch(pCur,"opacity",7)) 1.185 + { 1.186 + eOut = PLY::EST_Opacity; 1.187 + } 1.188 + else if (TokenMatch(pCur,"specular_power",6)) 1.189 + { 1.190 + eOut = PLY::EST_PhongPower; 1.191 + } 1.192 + else if (TokenMatch(pCur,"r",1)) 1.193 + { 1.194 + eOut = PLY::EST_Red; 1.195 + } 1.196 + else if (TokenMatch(pCur,"g",1)) 1.197 + { 1.198 + eOut = PLY::EST_Green; 1.199 + } 1.200 + else if (TokenMatch(pCur,"b",1)) 1.201 + { 1.202 + eOut = PLY::EST_Blue; 1.203 + } 1.204 + // NOTE: Blender3D exports texture coordinates as s,t tuples 1.205 + else if (TokenMatch(pCur,"u",1) || TokenMatch(pCur,"s",1) || TokenMatch(pCur,"tx",2)) 1.206 + { 1.207 + eOut = PLY::EST_UTextureCoord; 1.208 + } 1.209 + else if (TokenMatch(pCur,"v",1) || TokenMatch(pCur,"t",1) || TokenMatch(pCur,"ty",2)) 1.210 + { 1.211 + eOut = PLY::EST_VTextureCoord; 1.212 + } 1.213 + else if (TokenMatch(pCur,"x",1)) 1.214 + { 1.215 + eOut = PLY::EST_XCoord; 1.216 + } 1.217 + else if (TokenMatch(pCur,"y",1)) 1.218 + { 1.219 + eOut = PLY::EST_YCoord; 1.220 + } 1.221 + else if (TokenMatch(pCur,"z",1)) 1.222 + { 1.223 + eOut = PLY::EST_ZCoord; 1.224 + } 1.225 + else if (TokenMatch(pCur,"nx",2)) 1.226 + { 1.227 + eOut = PLY::EST_XNormal; 1.228 + } 1.229 + else if (TokenMatch(pCur,"ny",2)) 1.230 + { 1.231 + eOut = PLY::EST_YNormal; 1.232 + } 1.233 + else if (TokenMatch(pCur,"nz",2)) 1.234 + { 1.235 + eOut = PLY::EST_ZNormal; 1.236 + } 1.237 + else 1.238 + { 1.239 + DefaultLogger::get()->info("Found unknown property semantic in file. This is ok"); 1.240 + SkipLine(&pCur); 1.241 + } 1.242 + *pCurOut = pCur; 1.243 + return eOut; 1.244 +} 1.245 + 1.246 +// ------------------------------------------------------------------------------------------------ 1.247 +bool PLY::Property::ParseProperty (const char* pCur, 1.248 + const char** pCurOut, 1.249 + PLY::Property* pOut) 1.250 +{ 1.251 + ai_assert(NULL != pCur && NULL != pCurOut); 1.252 + 1.253 + // Forms supported: 1.254 + // "property float x" 1.255 + // "property list uchar int vertex_index" 1.256 + *pCurOut = pCur; 1.257 + 1.258 + // skip leading spaces 1.259 + if (!SkipSpaces(pCur,&pCur))return false; 1.260 + 1.261 + // skip the "property" string at the beginning 1.262 + if (!TokenMatch(pCur,"property",8)) 1.263 + { 1.264 + // seems not to be a valid property entry 1.265 + return false; 1.266 + } 1.267 + // get next word 1.268 + if (!SkipSpaces(pCur,&pCur))return false; 1.269 + if (TokenMatch(pCur,"list",4)) 1.270 + { 1.271 + pOut->bIsList = true; 1.272 + 1.273 + // seems to be a list. 1.274 + if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(pCur, &pCur))) 1.275 + { 1.276 + // unable to parse list size data type 1.277 + SkipLine(pCur,&pCur); 1.278 + *pCurOut = pCur; 1.279 + return false; 1.280 + } 1.281 + if (!SkipSpaces(pCur,&pCur))return false; 1.282 + if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur))) 1.283 + { 1.284 + // unable to parse list data type 1.285 + SkipLine(pCur,&pCur); 1.286 + *pCurOut = pCur; 1.287 + return false; 1.288 + } 1.289 + } 1.290 + else 1.291 + { 1.292 + if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur))) 1.293 + { 1.294 + // unable to parse data type. Skip the property 1.295 + SkipLine(pCur,&pCur); 1.296 + *pCurOut = pCur; 1.297 + return false; 1.298 + } 1.299 + } 1.300 + 1.301 + if (!SkipSpaces(pCur,&pCur))return false; 1.302 + const char* szCur = pCur; 1.303 + pOut->Semantic = PLY::Property::ParseSemantic(pCur, &pCur); 1.304 + 1.305 + if (PLY::EST_INVALID == pOut->Semantic) 1.306 + { 1.307 + // store the name of the semantic 1.308 + uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; 1.309 + 1.310 + DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK"); 1.311 + pOut->szName = std::string(szCur,iDiff); 1.312 + } 1.313 + 1.314 + SkipSpacesAndLineEnd(pCur,&pCur); 1.315 + *pCurOut = pCur; 1.316 + return true; 1.317 +} 1.318 + 1.319 +// ------------------------------------------------------------------------------------------------ 1.320 +PLY::EElementSemantic PLY::Element::ParseSemantic(const char* pCur, 1.321 + const char** pCurOut) 1.322 +{ 1.323 + ai_assert(NULL != pCur && NULL != pCurOut); 1.324 + PLY::EElementSemantic eOut = PLY::EEST_INVALID; 1.325 + if (TokenMatch(pCur,"vertex",6)) 1.326 + { 1.327 + eOut = PLY::EEST_Vertex; 1.328 + } 1.329 + else if (TokenMatch(pCur,"face",4)) 1.330 + { 1.331 + eOut = PLY::EEST_Face; 1.332 + } 1.333 +#if 0 1.334 + // TODO: maybe implement this? 1.335 + else if (TokenMatch(pCur,"range_grid",10)) 1.336 + { 1.337 + eOut = PLY::EEST_Face; 1.338 + } 1.339 +#endif 1.340 + else if (TokenMatch(pCur,"tristrips",9)) 1.341 + { 1.342 + eOut = PLY::EEST_TriStrip; 1.343 + } 1.344 + else if (TokenMatch(pCur,"edge",4)) 1.345 + { 1.346 + eOut = PLY::EEST_Edge; 1.347 + } 1.348 + else if (TokenMatch(pCur,"material",8)) 1.349 + { 1.350 + eOut = PLY::EEST_Material; 1.351 + } 1.352 + *pCurOut = pCur; 1.353 + return eOut; 1.354 +} 1.355 + 1.356 +// ------------------------------------------------------------------------------------------------ 1.357 +bool PLY::Element::ParseElement (const char* pCur, 1.358 + const char** pCurOut, 1.359 + PLY::Element* pOut) 1.360 +{ 1.361 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != pOut); 1.362 + 1.363 + // Example format: "element vertex 8" 1.364 + *pCurOut = pCur; 1.365 + 1.366 + // skip leading spaces 1.367 + if (!SkipSpaces(&pCur))return false; 1.368 + 1.369 + // skip the "element" string at the beginning 1.370 + if (!TokenMatch(pCur,"element",7)) 1.371 + { 1.372 + // seems not to be a valid property entry 1.373 + return false; 1.374 + } 1.375 + // get next word 1.376 + if (!SkipSpaces(&pCur))return false; 1.377 + 1.378 + // parse the semantic of the element 1.379 + const char* szCur = pCur; 1.380 + pOut->eSemantic = PLY::Element::ParseSemantic(pCur,&pCur); 1.381 + if (PLY::EEST_INVALID == pOut->eSemantic) 1.382 + { 1.383 + // if the exact semantic can't be determined, just store 1.384 + // the original string identifier 1.385 + uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur; 1.386 + pOut->szName = std::string(szCur,iDiff); 1.387 + } 1.388 + 1.389 + if (!SkipSpaces(&pCur))return false; 1.390 + 1.391 + //parse the number of occurences of this element 1.392 + pOut->NumOccur = strtoul10(pCur,&pCur); 1.393 + 1.394 + // go to the next line 1.395 + SkipSpacesAndLineEnd(pCur,&pCur); 1.396 + 1.397 + // now parse all properties of the element 1.398 + while(true) 1.399 + { 1.400 + // skip all comments 1.401 + PLY::DOM::SkipComments(pCur,&pCur); 1.402 + 1.403 + PLY::Property prop; 1.404 + if(!PLY::Property::ParseProperty(pCur,&pCur,&prop))break; 1.405 + pOut->alProperties.push_back(prop); 1.406 + } 1.407 + *pCurOut = pCur; 1.408 + return true; 1.409 +} 1.410 + 1.411 +// ------------------------------------------------------------------------------------------------ 1.412 +bool PLY::DOM::SkipComments (const char* pCur, 1.413 + const char** pCurOut) 1.414 +{ 1.415 + ai_assert(NULL != pCur && NULL != pCurOut); 1.416 + *pCurOut = pCur; 1.417 + 1.418 + // skip spaces 1.419 + if (!SkipSpaces(pCur,&pCur))return false; 1.420 + 1.421 + if (TokenMatch(pCur,"comment",7)) 1.422 + { 1.423 + SkipLine(pCur,&pCur); 1.424 + SkipComments(pCur,&pCur); 1.425 + *pCurOut = pCur; 1.426 + return true; 1.427 + } 1.428 + *pCurOut = pCur; 1.429 + return false; 1.430 +} 1.431 + 1.432 +// ------------------------------------------------------------------------------------------------ 1.433 +bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut) 1.434 +{ 1.435 + ai_assert(NULL != pCur && NULL != pCurOut); 1.436 + DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin"); 1.437 + 1.438 + // after ply and format line 1.439 + *pCurOut = pCur; 1.440 + 1.441 + // parse all elements 1.442 + while (true) 1.443 + { 1.444 + // skip all comments 1.445 + PLY::DOM::SkipComments(pCur,&pCur); 1.446 + 1.447 + PLY::Element out; 1.448 + if(PLY::Element::ParseElement(pCur,&pCur,&out)) 1.449 + { 1.450 + // add the element to the list of elements 1.451 + alElements.push_back(out); 1.452 + } 1.453 + else if (TokenMatch(pCur,"end_header",10)) 1.454 + { 1.455 + // we have reached the end of the header 1.456 + break; 1.457 + } 1.458 + else 1.459 + { 1.460 + // ignore unknown header elements 1.461 + SkipLine(&pCur); 1.462 + } 1.463 + } 1.464 + SkipSpacesAndLineEnd(pCur,&pCur); 1.465 + *pCurOut = pCur; 1.466 + 1.467 + DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded"); 1.468 + return true; 1.469 +} 1.470 + 1.471 +// ------------------------------------------------------------------------------------------------ 1.472 +bool PLY::DOM::ParseElementInstanceLists ( 1.473 + const char* pCur, 1.474 + const char** pCurOut) 1.475 +{ 1.476 + ai_assert(NULL != pCur && NULL != pCurOut); 1.477 + 1.478 + DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin"); 1.479 + *pCurOut = pCur; 1.480 + 1.481 + alElementData.resize(alElements.size()); 1.482 + 1.483 + std::vector<PLY::Element>::const_iterator i = alElements.begin(); 1.484 + std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin(); 1.485 + 1.486 + // parse all element instances 1.487 + for (;i != alElements.end();++i,++a) 1.488 + { 1.489 + (*a).alInstances.resize((*i).NumOccur); 1.490 + PLY::ElementInstanceList::ParseInstanceList(pCur,&pCur,&(*i),&(*a)); 1.491 + } 1.492 + 1.493 + DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded"); 1.494 + *pCurOut = pCur; 1.495 + return true; 1.496 +} 1.497 + 1.498 +// ------------------------------------------------------------------------------------------------ 1.499 +bool PLY::DOM::ParseElementInstanceListsBinary ( 1.500 + const char* pCur, 1.501 + const char** pCurOut, 1.502 + bool p_bBE) 1.503 +{ 1.504 + ai_assert(NULL != pCur && NULL != pCurOut); 1.505 + 1.506 + DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin"); 1.507 + *pCurOut = pCur; 1.508 + 1.509 + alElementData.resize(alElements.size()); 1.510 + 1.511 + std::vector<PLY::Element>::const_iterator i = alElements.begin(); 1.512 + std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin(); 1.513 + 1.514 + // parse all element instances 1.515 + for (;i != alElements.end();++i,++a) 1.516 + { 1.517 + (*a).alInstances.resize((*i).NumOccur); 1.518 + PLY::ElementInstanceList::ParseInstanceListBinary(pCur,&pCur,&(*i),&(*a),p_bBE); 1.519 + } 1.520 + 1.521 + DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded"); 1.522 + *pCurOut = pCur; 1.523 + return true; 1.524 +} 1.525 + 1.526 +// ------------------------------------------------------------------------------------------------ 1.527 +bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE) 1.528 +{ 1.529 + ai_assert(NULL != pCur && NULL != p_pcOut); 1.530 + 1.531 + DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin"); 1.532 + 1.533 + if(!p_pcOut->ParseHeader(pCur,&pCur)) 1.534 + { 1.535 + DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure"); 1.536 + return false; 1.537 + } 1.538 + if(!p_pcOut->ParseElementInstanceListsBinary(pCur,&pCur,p_bBE)) 1.539 + { 1.540 + DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure"); 1.541 + return false; 1.542 + } 1.543 + DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded"); 1.544 + return true; 1.545 +} 1.546 + 1.547 +// ------------------------------------------------------------------------------------------------ 1.548 +bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut) 1.549 +{ 1.550 + ai_assert(NULL != pCur); 1.551 + ai_assert(NULL != p_pcOut); 1.552 + 1.553 + DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin"); 1.554 + 1.555 + 1.556 + if(!p_pcOut->ParseHeader(pCur,&pCur)) 1.557 + { 1.558 + DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure"); 1.559 + return false; 1.560 + } 1.561 + if(!p_pcOut->ParseElementInstanceLists(pCur,&pCur)) 1.562 + { 1.563 + DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure"); 1.564 + return false; 1.565 + } 1.566 + DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded"); 1.567 + return true; 1.568 +} 1.569 + 1.570 +// ------------------------------------------------------------------------------------------------ 1.571 +bool PLY::ElementInstanceList::ParseInstanceList ( 1.572 + const char* pCur, 1.573 + const char** pCurOut, 1.574 + const PLY::Element* pcElement, 1.575 + PLY::ElementInstanceList* p_pcOut) 1.576 +{ 1.577 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut); 1.578 + 1.579 + if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty()) 1.580 + { 1.581 + // if the element has an unknown semantic we can skip all lines 1.582 + // However, there could be comments 1.583 + for (unsigned int i = 0; i < pcElement->NumOccur;++i) 1.584 + { 1.585 + PLY::DOM::SkipComments(pCur,&pCur); 1.586 + SkipLine(pCur,&pCur); 1.587 + } 1.588 + } 1.589 + else 1.590 + { 1.591 + // be sure to have enough storage 1.592 + for (unsigned int i = 0; i < pcElement->NumOccur;++i) 1.593 + { 1.594 + PLY::DOM::SkipComments(pCur,&pCur); 1.595 + PLY::ElementInstance::ParseInstance(pCur, &pCur,pcElement, 1.596 + &p_pcOut->alInstances[i]); 1.597 + } 1.598 + } 1.599 + *pCurOut = pCur; 1.600 + return true; 1.601 +} 1.602 + 1.603 +// ------------------------------------------------------------------------------------------------ 1.604 +bool PLY::ElementInstanceList::ParseInstanceListBinary ( 1.605 + const char* pCur, 1.606 + const char** pCurOut, 1.607 + const PLY::Element* pcElement, 1.608 + PLY::ElementInstanceList* p_pcOut, 1.609 + bool p_bBE /* = false */) 1.610 +{ 1.611 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut); 1.612 + 1.613 + // we can add special handling code for unknown element semantics since 1.614 + // we can't skip it as a whole block (we don't know its exact size 1.615 + // due to the fact that lists could be contained in the property list 1.616 + // of the unknown element) 1.617 + for (unsigned int i = 0; i < pcElement->NumOccur;++i) 1.618 + { 1.619 + PLY::ElementInstance::ParseInstanceBinary(pCur, &pCur,pcElement, 1.620 + &p_pcOut->alInstances[i], p_bBE); 1.621 + } 1.622 + *pCurOut = pCur; 1.623 + return true; 1.624 +} 1.625 + 1.626 +// ------------------------------------------------------------------------------------------------ 1.627 +bool PLY::ElementInstance::ParseInstance ( 1.628 + const char* pCur, 1.629 + const char** pCurOut, 1.630 + const PLY::Element* pcElement, 1.631 + PLY::ElementInstance* p_pcOut) 1.632 +{ 1.633 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut); 1.634 + 1.635 + if (!SkipSpaces(pCur, &pCur))return false; 1.636 + 1.637 + // allocate enough storage 1.638 + p_pcOut->alProperties.resize(pcElement->alProperties.size()); 1.639 + 1.640 + std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin(); 1.641 + std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); 1.642 + for (;i != p_pcOut->alProperties.end();++i,++a) 1.643 + { 1.644 + if(!(PLY::PropertyInstance::ParseInstance(pCur, &pCur,&(*a),&(*i)))) 1.645 + { 1.646 + DefaultLogger::get()->warn("Unable to parse property instance. " 1.647 + "Skipping this element instance"); 1.648 + 1.649 + // skip the rest of the instance 1.650 + SkipLine(pCur, &pCur); 1.651 + 1.652 + PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType); 1.653 + (*i).avList.push_back(v); 1.654 + } 1.655 + } 1.656 + *pCurOut = pCur; 1.657 + return true; 1.658 +} 1.659 + 1.660 +// ------------------------------------------------------------------------------------------------ 1.661 +bool PLY::ElementInstance::ParseInstanceBinary ( 1.662 + const char* pCur, 1.663 + const char** pCurOut, 1.664 + const PLY::Element* pcElement, 1.665 + PLY::ElementInstance* p_pcOut, 1.666 + bool p_bBE /* = false */) 1.667 +{ 1.668 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut); 1.669 + 1.670 + // allocate enough storage 1.671 + p_pcOut->alProperties.resize(pcElement->alProperties.size()); 1.672 + 1.673 + std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin(); 1.674 + std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin(); 1.675 + for (;i != p_pcOut->alProperties.end();++i,++a) 1.676 + { 1.677 + if(!(PLY::PropertyInstance::ParseInstanceBinary(pCur, &pCur,&(*a),&(*i),p_bBE))) 1.678 + { 1.679 + DefaultLogger::get()->warn("Unable to parse binary property instance. " 1.680 + "Skipping this element instance"); 1.681 + 1.682 + (*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType)); 1.683 + } 1.684 + } 1.685 + *pCurOut = pCur; 1.686 + return true; 1.687 +} 1.688 + 1.689 +// ------------------------------------------------------------------------------------------------ 1.690 +bool PLY::PropertyInstance::ParseInstance (const char* pCur,const char** pCurOut, 1.691 + const PLY::Property* prop, PLY::PropertyInstance* p_pcOut) 1.692 +{ 1.693 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut); 1.694 + 1.695 + *pCurOut = pCur; 1.696 + 1.697 + // skip spaces at the beginning 1.698 + if (!SkipSpaces(pCur, &pCur))return false; 1.699 + 1.700 + if (prop->bIsList) 1.701 + { 1.702 + // parse the number of elements in the list 1.703 + PLY::PropertyInstance::ValueUnion v; 1.704 + PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eFirstType,&v); 1.705 + 1.706 + // convert to unsigned int 1.707 + unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType); 1.708 + 1.709 + // parse all list elements 1.710 + p_pcOut->avList.resize(iNum); 1.711 + for (unsigned int i = 0; i < iNum;++i) 1.712 + { 1.713 + if (!SkipSpaces(pCur, &pCur))return false; 1.714 + PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&p_pcOut->avList[i]); 1.715 + } 1.716 + } 1.717 + else 1.718 + { 1.719 + // parse the property 1.720 + PLY::PropertyInstance::ValueUnion v; 1.721 + 1.722 + PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&v); 1.723 + p_pcOut->avList.push_back(v); 1.724 + } 1.725 + SkipSpacesAndLineEnd(pCur, &pCur); 1.726 + *pCurOut = pCur; 1.727 + return true; 1.728 +} 1.729 + 1.730 +// ------------------------------------------------------------------------------------------------ 1.731 +bool PLY::PropertyInstance::ParseInstanceBinary ( 1.732 + const char* pCur, 1.733 + const char** pCurOut, 1.734 + const PLY::Property* prop, 1.735 + PLY::PropertyInstance* p_pcOut, 1.736 + bool p_bBE) 1.737 +{ 1.738 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut); 1.739 + 1.740 + if (prop->bIsList) 1.741 + { 1.742 + // parse the number of elements in the list 1.743 + PLY::PropertyInstance::ValueUnion v; 1.744 + PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eFirstType,&v,p_bBE); 1.745 + 1.746 + // convert to unsigned int 1.747 + unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType); 1.748 + 1.749 + // parse all list elements 1.750 + p_pcOut->avList.resize(iNum); 1.751 + for (unsigned int i = 0; i < iNum;++i){ 1.752 + PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&p_pcOut->avList[i],p_bBE); 1.753 + } 1.754 + } 1.755 + else 1.756 + { 1.757 + // parse the property 1.758 + PLY::PropertyInstance::ValueUnion v; 1.759 + PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&v,p_bBE); 1.760 + p_pcOut->avList.push_back(v); 1.761 + } 1.762 + *pCurOut = pCur; 1.763 + return true; 1.764 +} 1.765 + 1.766 +// ------------------------------------------------------------------------------------------------ 1.767 +PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue( 1.768 + PLY::EDataType eType) 1.769 +{ 1.770 + PLY::PropertyInstance::ValueUnion out; 1.771 + 1.772 + switch (eType) 1.773 + { 1.774 + case EDT_Float: 1.775 + out.fFloat = 0.f; 1.776 + return out; 1.777 + 1.778 + case EDT_Double: 1.779 + out.fDouble = 0.; 1.780 + return out; 1.781 + 1.782 + default: ; 1.783 + }; 1.784 + out.iUInt = 0; 1.785 + return out; 1.786 +} 1.787 + 1.788 +// ------------------------------------------------------------------------------------------------ 1.789 +bool PLY::PropertyInstance::ParseValue( 1.790 + const char* pCur, 1.791 + const char** pCurOut, 1.792 + PLY::EDataType eType, 1.793 + PLY::PropertyInstance::ValueUnion* out) 1.794 +{ 1.795 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != out); 1.796 + 1.797 + register bool ret = true; 1.798 + *pCurOut = pCur; 1.799 + switch (eType) 1.800 + { 1.801 + case EDT_UInt: 1.802 + case EDT_UShort: 1.803 + case EDT_UChar: 1.804 + 1.805 + out->iUInt = (uint32_t)strtoul10(pCur, &pCur); 1.806 + break; 1.807 + 1.808 + case EDT_Int: 1.809 + case EDT_Short: 1.810 + case EDT_Char: 1.811 + 1.812 + out->iInt = (int32_t)strtol10(pCur, &pCur); 1.813 + break; 1.814 + 1.815 + case EDT_Float: 1.816 + 1.817 + pCur = fast_atoreal_move<float>(pCur,out->fFloat); 1.818 + break; 1.819 + 1.820 + case EDT_Double: 1.821 + 1.822 + float f; 1.823 + pCur = fast_atoreal_move<float>(pCur,f); 1.824 + out->fDouble = (double)f; 1.825 + break; 1.826 + 1.827 + default: 1.828 + ret = false; 1.829 + } 1.830 + *pCurOut = pCur; 1.831 + return ret; 1.832 +} 1.833 + 1.834 +// ------------------------------------------------------------------------------------------------ 1.835 +bool PLY::PropertyInstance::ParseValueBinary( 1.836 + const char* pCur, 1.837 + const char** pCurOut, 1.838 + PLY::EDataType eType, 1.839 + PLY::PropertyInstance::ValueUnion* out, 1.840 + bool p_bBE) 1.841 +{ 1.842 + ai_assert(NULL != pCur && NULL != pCurOut && NULL != out); 1.843 + 1.844 + register bool ret = true; 1.845 + switch (eType) 1.846 + { 1.847 + case EDT_UInt: 1.848 + out->iUInt = (uint32_t)*((uint32_t*)pCur); 1.849 + pCur += 4; 1.850 + 1.851 + // Swap endianess 1.852 + if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt); 1.853 + break; 1.854 + 1.855 + case EDT_UShort: 1.856 + { 1.857 + int16_t i = *((uint16_t*)pCur); 1.858 + 1.859 + // Swap endianess 1.860 + if (p_bBE)ByteSwap::Swap(&i); 1.861 + out->iUInt = (uint32_t)i; 1.862 + pCur += 2; 1.863 + break; 1.864 + } 1.865 + 1.866 + case EDT_UChar: 1.867 + { 1.868 + out->iUInt = (uint32_t)(*((uint8_t*)pCur)); 1.869 + pCur ++; 1.870 + break; 1.871 + } 1.872 + 1.873 + case EDT_Int: 1.874 + out->iInt = *((int32_t*)pCur); 1.875 + pCur += 4; 1.876 + 1.877 + // Swap endianess 1.878 + if (p_bBE)ByteSwap::Swap(&out->iInt); 1.879 + break; 1.880 + 1.881 + case EDT_Short: 1.882 + { 1.883 + int16_t i = *((int16_t*)pCur); 1.884 + 1.885 + // Swap endianess 1.886 + if (p_bBE)ByteSwap::Swap(&i); 1.887 + out->iInt = (int32_t)i; 1.888 + pCur += 2; 1.889 + break; 1.890 + } 1.891 + 1.892 + case EDT_Char: 1.893 + out->iInt = (int32_t)*((int8_t*)pCur); 1.894 + pCur ++; 1.895 + break; 1.896 + 1.897 + case EDT_Float: 1.898 + { 1.899 + out->fFloat = *((float*)pCur); 1.900 + 1.901 + // Swap endianess 1.902 + if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat); 1.903 + pCur += 4; 1.904 + break; 1.905 + } 1.906 + case EDT_Double: 1.907 + { 1.908 + out->fDouble = *((double*)pCur); 1.909 + 1.910 + // Swap endianess 1.911 + if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble); 1.912 + pCur += 8; 1.913 + break; 1.914 + } 1.915 + default: 1.916 + ret = false; 1.917 + } 1.918 + *pCurOut = pCur; 1.919 + return ret; 1.920 +} 1.921 + 1.922 +#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER