vrshoot

annotate 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
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 /** @file Implementation of the PLY parser class */
nuclear@0 43
nuclear@0 44 #include "AssimpPCH.h"
nuclear@0 45 #ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
nuclear@0 46
nuclear@0 47 #include "PlyLoader.h"
nuclear@0 48 #include "fast_atof.h"
nuclear@0 49
nuclear@0 50 using namespace Assimp;
nuclear@0 51
nuclear@0 52 // ------------------------------------------------------------------------------------------------
nuclear@0 53 PLY::EDataType PLY::Property::ParseDataType(const char* pCur,const char** pCurOut)
nuclear@0 54 {
nuclear@0 55 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 56 PLY::EDataType eOut = PLY::EDT_INVALID;
nuclear@0 57
nuclear@0 58 if (TokenMatch(pCur,"char",4) ||
nuclear@0 59 TokenMatch(pCur,"int8",4))
nuclear@0 60 {
nuclear@0 61 eOut = PLY::EDT_Char;
nuclear@0 62 }
nuclear@0 63 else if (TokenMatch(pCur,"uchar",5) ||
nuclear@0 64 TokenMatch(pCur,"uint8",5))
nuclear@0 65 {
nuclear@0 66 eOut = PLY::EDT_UChar;
nuclear@0 67 }
nuclear@0 68 else if (TokenMatch(pCur,"short",5) ||
nuclear@0 69 TokenMatch(pCur,"int16",5))
nuclear@0 70 {
nuclear@0 71 eOut = PLY::EDT_Short;
nuclear@0 72 }
nuclear@0 73 else if (TokenMatch(pCur,"ushort",6) ||
nuclear@0 74 TokenMatch(pCur,"uint16",6))
nuclear@0 75 {
nuclear@0 76 eOut = PLY::EDT_UShort;
nuclear@0 77 }
nuclear@0 78 else if (TokenMatch(pCur,"int32",5) || TokenMatch(pCur,"int",3))
nuclear@0 79 {
nuclear@0 80 eOut = PLY::EDT_Int;
nuclear@0 81 }
nuclear@0 82 else if (TokenMatch(pCur,"uint32",6) || TokenMatch(pCur,"uint",4))
nuclear@0 83 {
nuclear@0 84 eOut = PLY::EDT_UInt;
nuclear@0 85 }
nuclear@0 86 else if (TokenMatch(pCur,"float",5) || TokenMatch(pCur,"float32",7))
nuclear@0 87 {
nuclear@0 88 eOut = PLY::EDT_Float;
nuclear@0 89 }
nuclear@0 90 else if (TokenMatch(pCur,"double64",8) || TokenMatch(pCur,"double",6) ||
nuclear@0 91 TokenMatch(pCur,"float64",7))
nuclear@0 92 {
nuclear@0 93 eOut = PLY::EDT_Double;
nuclear@0 94 }
nuclear@0 95 if (PLY::EDT_INVALID == eOut)
nuclear@0 96 {
nuclear@0 97 DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
nuclear@0 98 }
nuclear@0 99 *pCurOut = pCur;
nuclear@0 100 return eOut;
nuclear@0 101 }
nuclear@0 102
nuclear@0 103 // ------------------------------------------------------------------------------------------------
nuclear@0 104 PLY::ESemantic PLY::Property::ParseSemantic(const char* pCur,const char** pCurOut)
nuclear@0 105 {
nuclear@0 106 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 107
nuclear@0 108 PLY::ESemantic eOut = PLY::EST_INVALID;
nuclear@0 109 if (TokenMatch(pCur,"red",3))
nuclear@0 110 {
nuclear@0 111 eOut = PLY::EST_Red;
nuclear@0 112 }
nuclear@0 113 else if (TokenMatch(pCur,"green",5))
nuclear@0 114 {
nuclear@0 115 eOut = PLY::EST_Green;
nuclear@0 116 }
nuclear@0 117 else if (TokenMatch(pCur,"blue",4))
nuclear@0 118 {
nuclear@0 119 eOut = PLY::EST_Blue;
nuclear@0 120 }
nuclear@0 121 else if (TokenMatch(pCur,"alpha",5))
nuclear@0 122 {
nuclear@0 123 eOut = PLY::EST_Alpha;
nuclear@0 124 }
nuclear@0 125 else if (TokenMatch(pCur,"vertex_index",12) || TokenMatch(pCur,"vertex_indices",14))
nuclear@0 126 {
nuclear@0 127 eOut = PLY::EST_VertexIndex;
nuclear@0 128 }
nuclear@0 129 else if (TokenMatch(pCur,"material_index",14))
nuclear@0 130 {
nuclear@0 131 eOut = PLY::EST_MaterialIndex;
nuclear@0 132 }
nuclear@0 133 else if (TokenMatch(pCur,"ambient_red",11))
nuclear@0 134 {
nuclear@0 135 eOut = PLY::EST_AmbientRed;
nuclear@0 136 }
nuclear@0 137 else if (TokenMatch(pCur,"ambient_green",13))
nuclear@0 138 {
nuclear@0 139 eOut = PLY::EST_AmbientGreen;
nuclear@0 140 }
nuclear@0 141 else if (TokenMatch(pCur,"ambient_blue",12))
nuclear@0 142 {
nuclear@0 143 eOut = PLY::EST_AmbientBlue;
nuclear@0 144 }
nuclear@0 145 else if (TokenMatch(pCur,"ambient_alpha",13))
nuclear@0 146 {
nuclear@0 147 eOut = PLY::EST_AmbientAlpha;
nuclear@0 148 }
nuclear@0 149 else if (TokenMatch(pCur,"diffuse_red",11))
nuclear@0 150 {
nuclear@0 151 eOut = PLY::EST_DiffuseRed;
nuclear@0 152 }
nuclear@0 153 else if (TokenMatch(pCur,"diffuse_green",13))
nuclear@0 154 {
nuclear@0 155 eOut = PLY::EST_DiffuseGreen;
nuclear@0 156 }
nuclear@0 157 else if (TokenMatch(pCur,"diffuse_blue",12))
nuclear@0 158 {
nuclear@0 159 eOut = PLY::EST_DiffuseBlue;
nuclear@0 160 }
nuclear@0 161 else if (TokenMatch(pCur,"diffuse_alpha",13))
nuclear@0 162 {
nuclear@0 163 eOut = PLY::EST_DiffuseAlpha;
nuclear@0 164 }
nuclear@0 165 else if (TokenMatch(pCur,"specular_red",12))
nuclear@0 166 {
nuclear@0 167 eOut = PLY::EST_SpecularRed;
nuclear@0 168 }
nuclear@0 169 else if (TokenMatch(pCur,"specular_green",14))
nuclear@0 170 {
nuclear@0 171 eOut = PLY::EST_SpecularGreen;
nuclear@0 172 }
nuclear@0 173 else if (TokenMatch(pCur,"specular_blue",13))
nuclear@0 174 {
nuclear@0 175 eOut = PLY::EST_SpecularBlue;
nuclear@0 176 }
nuclear@0 177 else if (TokenMatch(pCur,"specular_alpha",14))
nuclear@0 178 {
nuclear@0 179 eOut = PLY::EST_SpecularAlpha;
nuclear@0 180 }
nuclear@0 181 else if (TokenMatch(pCur,"opacity",7))
nuclear@0 182 {
nuclear@0 183 eOut = PLY::EST_Opacity;
nuclear@0 184 }
nuclear@0 185 else if (TokenMatch(pCur,"specular_power",6))
nuclear@0 186 {
nuclear@0 187 eOut = PLY::EST_PhongPower;
nuclear@0 188 }
nuclear@0 189 else if (TokenMatch(pCur,"r",1))
nuclear@0 190 {
nuclear@0 191 eOut = PLY::EST_Red;
nuclear@0 192 }
nuclear@0 193 else if (TokenMatch(pCur,"g",1))
nuclear@0 194 {
nuclear@0 195 eOut = PLY::EST_Green;
nuclear@0 196 }
nuclear@0 197 else if (TokenMatch(pCur,"b",1))
nuclear@0 198 {
nuclear@0 199 eOut = PLY::EST_Blue;
nuclear@0 200 }
nuclear@0 201 // NOTE: Blender3D exports texture coordinates as s,t tuples
nuclear@0 202 else if (TokenMatch(pCur,"u",1) || TokenMatch(pCur,"s",1) || TokenMatch(pCur,"tx",2))
nuclear@0 203 {
nuclear@0 204 eOut = PLY::EST_UTextureCoord;
nuclear@0 205 }
nuclear@0 206 else if (TokenMatch(pCur,"v",1) || TokenMatch(pCur,"t",1) || TokenMatch(pCur,"ty",2))
nuclear@0 207 {
nuclear@0 208 eOut = PLY::EST_VTextureCoord;
nuclear@0 209 }
nuclear@0 210 else if (TokenMatch(pCur,"x",1))
nuclear@0 211 {
nuclear@0 212 eOut = PLY::EST_XCoord;
nuclear@0 213 }
nuclear@0 214 else if (TokenMatch(pCur,"y",1))
nuclear@0 215 {
nuclear@0 216 eOut = PLY::EST_YCoord;
nuclear@0 217 }
nuclear@0 218 else if (TokenMatch(pCur,"z",1))
nuclear@0 219 {
nuclear@0 220 eOut = PLY::EST_ZCoord;
nuclear@0 221 }
nuclear@0 222 else if (TokenMatch(pCur,"nx",2))
nuclear@0 223 {
nuclear@0 224 eOut = PLY::EST_XNormal;
nuclear@0 225 }
nuclear@0 226 else if (TokenMatch(pCur,"ny",2))
nuclear@0 227 {
nuclear@0 228 eOut = PLY::EST_YNormal;
nuclear@0 229 }
nuclear@0 230 else if (TokenMatch(pCur,"nz",2))
nuclear@0 231 {
nuclear@0 232 eOut = PLY::EST_ZNormal;
nuclear@0 233 }
nuclear@0 234 else
nuclear@0 235 {
nuclear@0 236 DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
nuclear@0 237 SkipLine(&pCur);
nuclear@0 238 }
nuclear@0 239 *pCurOut = pCur;
nuclear@0 240 return eOut;
nuclear@0 241 }
nuclear@0 242
nuclear@0 243 // ------------------------------------------------------------------------------------------------
nuclear@0 244 bool PLY::Property::ParseProperty (const char* pCur,
nuclear@0 245 const char** pCurOut,
nuclear@0 246 PLY::Property* pOut)
nuclear@0 247 {
nuclear@0 248 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 249
nuclear@0 250 // Forms supported:
nuclear@0 251 // "property float x"
nuclear@0 252 // "property list uchar int vertex_index"
nuclear@0 253 *pCurOut = pCur;
nuclear@0 254
nuclear@0 255 // skip leading spaces
nuclear@0 256 if (!SkipSpaces(pCur,&pCur))return false;
nuclear@0 257
nuclear@0 258 // skip the "property" string at the beginning
nuclear@0 259 if (!TokenMatch(pCur,"property",8))
nuclear@0 260 {
nuclear@0 261 // seems not to be a valid property entry
nuclear@0 262 return false;
nuclear@0 263 }
nuclear@0 264 // get next word
nuclear@0 265 if (!SkipSpaces(pCur,&pCur))return false;
nuclear@0 266 if (TokenMatch(pCur,"list",4))
nuclear@0 267 {
nuclear@0 268 pOut->bIsList = true;
nuclear@0 269
nuclear@0 270 // seems to be a list.
nuclear@0 271 if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(pCur, &pCur)))
nuclear@0 272 {
nuclear@0 273 // unable to parse list size data type
nuclear@0 274 SkipLine(pCur,&pCur);
nuclear@0 275 *pCurOut = pCur;
nuclear@0 276 return false;
nuclear@0 277 }
nuclear@0 278 if (!SkipSpaces(pCur,&pCur))return false;
nuclear@0 279 if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
nuclear@0 280 {
nuclear@0 281 // unable to parse list data type
nuclear@0 282 SkipLine(pCur,&pCur);
nuclear@0 283 *pCurOut = pCur;
nuclear@0 284 return false;
nuclear@0 285 }
nuclear@0 286 }
nuclear@0 287 else
nuclear@0 288 {
nuclear@0 289 if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(pCur, &pCur)))
nuclear@0 290 {
nuclear@0 291 // unable to parse data type. Skip the property
nuclear@0 292 SkipLine(pCur,&pCur);
nuclear@0 293 *pCurOut = pCur;
nuclear@0 294 return false;
nuclear@0 295 }
nuclear@0 296 }
nuclear@0 297
nuclear@0 298 if (!SkipSpaces(pCur,&pCur))return false;
nuclear@0 299 const char* szCur = pCur;
nuclear@0 300 pOut->Semantic = PLY::Property::ParseSemantic(pCur, &pCur);
nuclear@0 301
nuclear@0 302 if (PLY::EST_INVALID == pOut->Semantic)
nuclear@0 303 {
nuclear@0 304 // store the name of the semantic
nuclear@0 305 uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
nuclear@0 306
nuclear@0 307 DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
nuclear@0 308 pOut->szName = std::string(szCur,iDiff);
nuclear@0 309 }
nuclear@0 310
nuclear@0 311 SkipSpacesAndLineEnd(pCur,&pCur);
nuclear@0 312 *pCurOut = pCur;
nuclear@0 313 return true;
nuclear@0 314 }
nuclear@0 315
nuclear@0 316 // ------------------------------------------------------------------------------------------------
nuclear@0 317 PLY::EElementSemantic PLY::Element::ParseSemantic(const char* pCur,
nuclear@0 318 const char** pCurOut)
nuclear@0 319 {
nuclear@0 320 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 321 PLY::EElementSemantic eOut = PLY::EEST_INVALID;
nuclear@0 322 if (TokenMatch(pCur,"vertex",6))
nuclear@0 323 {
nuclear@0 324 eOut = PLY::EEST_Vertex;
nuclear@0 325 }
nuclear@0 326 else if (TokenMatch(pCur,"face",4))
nuclear@0 327 {
nuclear@0 328 eOut = PLY::EEST_Face;
nuclear@0 329 }
nuclear@0 330 #if 0
nuclear@0 331 // TODO: maybe implement this?
nuclear@0 332 else if (TokenMatch(pCur,"range_grid",10))
nuclear@0 333 {
nuclear@0 334 eOut = PLY::EEST_Face;
nuclear@0 335 }
nuclear@0 336 #endif
nuclear@0 337 else if (TokenMatch(pCur,"tristrips",9))
nuclear@0 338 {
nuclear@0 339 eOut = PLY::EEST_TriStrip;
nuclear@0 340 }
nuclear@0 341 else if (TokenMatch(pCur,"edge",4))
nuclear@0 342 {
nuclear@0 343 eOut = PLY::EEST_Edge;
nuclear@0 344 }
nuclear@0 345 else if (TokenMatch(pCur,"material",8))
nuclear@0 346 {
nuclear@0 347 eOut = PLY::EEST_Material;
nuclear@0 348 }
nuclear@0 349 *pCurOut = pCur;
nuclear@0 350 return eOut;
nuclear@0 351 }
nuclear@0 352
nuclear@0 353 // ------------------------------------------------------------------------------------------------
nuclear@0 354 bool PLY::Element::ParseElement (const char* pCur,
nuclear@0 355 const char** pCurOut,
nuclear@0 356 PLY::Element* pOut)
nuclear@0 357 {
nuclear@0 358 ai_assert(NULL != pCur && NULL != pCurOut && NULL != pOut);
nuclear@0 359
nuclear@0 360 // Example format: "element vertex 8"
nuclear@0 361 *pCurOut = pCur;
nuclear@0 362
nuclear@0 363 // skip leading spaces
nuclear@0 364 if (!SkipSpaces(&pCur))return false;
nuclear@0 365
nuclear@0 366 // skip the "element" string at the beginning
nuclear@0 367 if (!TokenMatch(pCur,"element",7))
nuclear@0 368 {
nuclear@0 369 // seems not to be a valid property entry
nuclear@0 370 return false;
nuclear@0 371 }
nuclear@0 372 // get next word
nuclear@0 373 if (!SkipSpaces(&pCur))return false;
nuclear@0 374
nuclear@0 375 // parse the semantic of the element
nuclear@0 376 const char* szCur = pCur;
nuclear@0 377 pOut->eSemantic = PLY::Element::ParseSemantic(pCur,&pCur);
nuclear@0 378 if (PLY::EEST_INVALID == pOut->eSemantic)
nuclear@0 379 {
nuclear@0 380 // if the exact semantic can't be determined, just store
nuclear@0 381 // the original string identifier
nuclear@0 382 uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
nuclear@0 383 pOut->szName = std::string(szCur,iDiff);
nuclear@0 384 }
nuclear@0 385
nuclear@0 386 if (!SkipSpaces(&pCur))return false;
nuclear@0 387
nuclear@0 388 //parse the number of occurences of this element
nuclear@0 389 pOut->NumOccur = strtoul10(pCur,&pCur);
nuclear@0 390
nuclear@0 391 // go to the next line
nuclear@0 392 SkipSpacesAndLineEnd(pCur,&pCur);
nuclear@0 393
nuclear@0 394 // now parse all properties of the element
nuclear@0 395 while(true)
nuclear@0 396 {
nuclear@0 397 // skip all comments
nuclear@0 398 PLY::DOM::SkipComments(pCur,&pCur);
nuclear@0 399
nuclear@0 400 PLY::Property prop;
nuclear@0 401 if(!PLY::Property::ParseProperty(pCur,&pCur,&prop))break;
nuclear@0 402 pOut->alProperties.push_back(prop);
nuclear@0 403 }
nuclear@0 404 *pCurOut = pCur;
nuclear@0 405 return true;
nuclear@0 406 }
nuclear@0 407
nuclear@0 408 // ------------------------------------------------------------------------------------------------
nuclear@0 409 bool PLY::DOM::SkipComments (const char* pCur,
nuclear@0 410 const char** pCurOut)
nuclear@0 411 {
nuclear@0 412 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 413 *pCurOut = pCur;
nuclear@0 414
nuclear@0 415 // skip spaces
nuclear@0 416 if (!SkipSpaces(pCur,&pCur))return false;
nuclear@0 417
nuclear@0 418 if (TokenMatch(pCur,"comment",7))
nuclear@0 419 {
nuclear@0 420 SkipLine(pCur,&pCur);
nuclear@0 421 SkipComments(pCur,&pCur);
nuclear@0 422 *pCurOut = pCur;
nuclear@0 423 return true;
nuclear@0 424 }
nuclear@0 425 *pCurOut = pCur;
nuclear@0 426 return false;
nuclear@0 427 }
nuclear@0 428
nuclear@0 429 // ------------------------------------------------------------------------------------------------
nuclear@0 430 bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut)
nuclear@0 431 {
nuclear@0 432 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 433 DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
nuclear@0 434
nuclear@0 435 // after ply and format line
nuclear@0 436 *pCurOut = pCur;
nuclear@0 437
nuclear@0 438 // parse all elements
nuclear@0 439 while (true)
nuclear@0 440 {
nuclear@0 441 // skip all comments
nuclear@0 442 PLY::DOM::SkipComments(pCur,&pCur);
nuclear@0 443
nuclear@0 444 PLY::Element out;
nuclear@0 445 if(PLY::Element::ParseElement(pCur,&pCur,&out))
nuclear@0 446 {
nuclear@0 447 // add the element to the list of elements
nuclear@0 448 alElements.push_back(out);
nuclear@0 449 }
nuclear@0 450 else if (TokenMatch(pCur,"end_header",10))
nuclear@0 451 {
nuclear@0 452 // we have reached the end of the header
nuclear@0 453 break;
nuclear@0 454 }
nuclear@0 455 else
nuclear@0 456 {
nuclear@0 457 // ignore unknown header elements
nuclear@0 458 SkipLine(&pCur);
nuclear@0 459 }
nuclear@0 460 }
nuclear@0 461 SkipSpacesAndLineEnd(pCur,&pCur);
nuclear@0 462 *pCurOut = pCur;
nuclear@0 463
nuclear@0 464 DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
nuclear@0 465 return true;
nuclear@0 466 }
nuclear@0 467
nuclear@0 468 // ------------------------------------------------------------------------------------------------
nuclear@0 469 bool PLY::DOM::ParseElementInstanceLists (
nuclear@0 470 const char* pCur,
nuclear@0 471 const char** pCurOut)
nuclear@0 472 {
nuclear@0 473 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 474
nuclear@0 475 DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
nuclear@0 476 *pCurOut = pCur;
nuclear@0 477
nuclear@0 478 alElementData.resize(alElements.size());
nuclear@0 479
nuclear@0 480 std::vector<PLY::Element>::const_iterator i = alElements.begin();
nuclear@0 481 std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
nuclear@0 482
nuclear@0 483 // parse all element instances
nuclear@0 484 for (;i != alElements.end();++i,++a)
nuclear@0 485 {
nuclear@0 486 (*a).alInstances.resize((*i).NumOccur);
nuclear@0 487 PLY::ElementInstanceList::ParseInstanceList(pCur,&pCur,&(*i),&(*a));
nuclear@0 488 }
nuclear@0 489
nuclear@0 490 DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
nuclear@0 491 *pCurOut = pCur;
nuclear@0 492 return true;
nuclear@0 493 }
nuclear@0 494
nuclear@0 495 // ------------------------------------------------------------------------------------------------
nuclear@0 496 bool PLY::DOM::ParseElementInstanceListsBinary (
nuclear@0 497 const char* pCur,
nuclear@0 498 const char** pCurOut,
nuclear@0 499 bool p_bBE)
nuclear@0 500 {
nuclear@0 501 ai_assert(NULL != pCur && NULL != pCurOut);
nuclear@0 502
nuclear@0 503 DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
nuclear@0 504 *pCurOut = pCur;
nuclear@0 505
nuclear@0 506 alElementData.resize(alElements.size());
nuclear@0 507
nuclear@0 508 std::vector<PLY::Element>::const_iterator i = alElements.begin();
nuclear@0 509 std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
nuclear@0 510
nuclear@0 511 // parse all element instances
nuclear@0 512 for (;i != alElements.end();++i,++a)
nuclear@0 513 {
nuclear@0 514 (*a).alInstances.resize((*i).NumOccur);
nuclear@0 515 PLY::ElementInstanceList::ParseInstanceListBinary(pCur,&pCur,&(*i),&(*a),p_bBE);
nuclear@0 516 }
nuclear@0 517
nuclear@0 518 DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
nuclear@0 519 *pCurOut = pCur;
nuclear@0 520 return true;
nuclear@0 521 }
nuclear@0 522
nuclear@0 523 // ------------------------------------------------------------------------------------------------
nuclear@0 524 bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE)
nuclear@0 525 {
nuclear@0 526 ai_assert(NULL != pCur && NULL != p_pcOut);
nuclear@0 527
nuclear@0 528 DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
nuclear@0 529
nuclear@0 530 if(!p_pcOut->ParseHeader(pCur,&pCur))
nuclear@0 531 {
nuclear@0 532 DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
nuclear@0 533 return false;
nuclear@0 534 }
nuclear@0 535 if(!p_pcOut->ParseElementInstanceListsBinary(pCur,&pCur,p_bBE))
nuclear@0 536 {
nuclear@0 537 DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
nuclear@0 538 return false;
nuclear@0 539 }
nuclear@0 540 DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
nuclear@0 541 return true;
nuclear@0 542 }
nuclear@0 543
nuclear@0 544 // ------------------------------------------------------------------------------------------------
nuclear@0 545 bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut)
nuclear@0 546 {
nuclear@0 547 ai_assert(NULL != pCur);
nuclear@0 548 ai_assert(NULL != p_pcOut);
nuclear@0 549
nuclear@0 550 DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
nuclear@0 551
nuclear@0 552
nuclear@0 553 if(!p_pcOut->ParseHeader(pCur,&pCur))
nuclear@0 554 {
nuclear@0 555 DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
nuclear@0 556 return false;
nuclear@0 557 }
nuclear@0 558 if(!p_pcOut->ParseElementInstanceLists(pCur,&pCur))
nuclear@0 559 {
nuclear@0 560 DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
nuclear@0 561 return false;
nuclear@0 562 }
nuclear@0 563 DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
nuclear@0 564 return true;
nuclear@0 565 }
nuclear@0 566
nuclear@0 567 // ------------------------------------------------------------------------------------------------
nuclear@0 568 bool PLY::ElementInstanceList::ParseInstanceList (
nuclear@0 569 const char* pCur,
nuclear@0 570 const char** pCurOut,
nuclear@0 571 const PLY::Element* pcElement,
nuclear@0 572 PLY::ElementInstanceList* p_pcOut)
nuclear@0 573 {
nuclear@0 574 ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
nuclear@0 575
nuclear@0 576 if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
nuclear@0 577 {
nuclear@0 578 // if the element has an unknown semantic we can skip all lines
nuclear@0 579 // However, there could be comments
nuclear@0 580 for (unsigned int i = 0; i < pcElement->NumOccur;++i)
nuclear@0 581 {
nuclear@0 582 PLY::DOM::SkipComments(pCur,&pCur);
nuclear@0 583 SkipLine(pCur,&pCur);
nuclear@0 584 }
nuclear@0 585 }
nuclear@0 586 else
nuclear@0 587 {
nuclear@0 588 // be sure to have enough storage
nuclear@0 589 for (unsigned int i = 0; i < pcElement->NumOccur;++i)
nuclear@0 590 {
nuclear@0 591 PLY::DOM::SkipComments(pCur,&pCur);
nuclear@0 592 PLY::ElementInstance::ParseInstance(pCur, &pCur,pcElement,
nuclear@0 593 &p_pcOut->alInstances[i]);
nuclear@0 594 }
nuclear@0 595 }
nuclear@0 596 *pCurOut = pCur;
nuclear@0 597 return true;
nuclear@0 598 }
nuclear@0 599
nuclear@0 600 // ------------------------------------------------------------------------------------------------
nuclear@0 601 bool PLY::ElementInstanceList::ParseInstanceListBinary (
nuclear@0 602 const char* pCur,
nuclear@0 603 const char** pCurOut,
nuclear@0 604 const PLY::Element* pcElement,
nuclear@0 605 PLY::ElementInstanceList* p_pcOut,
nuclear@0 606 bool p_bBE /* = false */)
nuclear@0 607 {
nuclear@0 608 ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
nuclear@0 609
nuclear@0 610 // we can add special handling code for unknown element semantics since
nuclear@0 611 // we can't skip it as a whole block (we don't know its exact size
nuclear@0 612 // due to the fact that lists could be contained in the property list
nuclear@0 613 // of the unknown element)
nuclear@0 614 for (unsigned int i = 0; i < pcElement->NumOccur;++i)
nuclear@0 615 {
nuclear@0 616 PLY::ElementInstance::ParseInstanceBinary(pCur, &pCur,pcElement,
nuclear@0 617 &p_pcOut->alInstances[i], p_bBE);
nuclear@0 618 }
nuclear@0 619 *pCurOut = pCur;
nuclear@0 620 return true;
nuclear@0 621 }
nuclear@0 622
nuclear@0 623 // ------------------------------------------------------------------------------------------------
nuclear@0 624 bool PLY::ElementInstance::ParseInstance (
nuclear@0 625 const char* pCur,
nuclear@0 626 const char** pCurOut,
nuclear@0 627 const PLY::Element* pcElement,
nuclear@0 628 PLY::ElementInstance* p_pcOut)
nuclear@0 629 {
nuclear@0 630 ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
nuclear@0 631
nuclear@0 632 if (!SkipSpaces(pCur, &pCur))return false;
nuclear@0 633
nuclear@0 634 // allocate enough storage
nuclear@0 635 p_pcOut->alProperties.resize(pcElement->alProperties.size());
nuclear@0 636
nuclear@0 637 std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
nuclear@0 638 std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
nuclear@0 639 for (;i != p_pcOut->alProperties.end();++i,++a)
nuclear@0 640 {
nuclear@0 641 if(!(PLY::PropertyInstance::ParseInstance(pCur, &pCur,&(*a),&(*i))))
nuclear@0 642 {
nuclear@0 643 DefaultLogger::get()->warn("Unable to parse property instance. "
nuclear@0 644 "Skipping this element instance");
nuclear@0 645
nuclear@0 646 // skip the rest of the instance
nuclear@0 647 SkipLine(pCur, &pCur);
nuclear@0 648
nuclear@0 649 PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
nuclear@0 650 (*i).avList.push_back(v);
nuclear@0 651 }
nuclear@0 652 }
nuclear@0 653 *pCurOut = pCur;
nuclear@0 654 return true;
nuclear@0 655 }
nuclear@0 656
nuclear@0 657 // ------------------------------------------------------------------------------------------------
nuclear@0 658 bool PLY::ElementInstance::ParseInstanceBinary (
nuclear@0 659 const char* pCur,
nuclear@0 660 const char** pCurOut,
nuclear@0 661 const PLY::Element* pcElement,
nuclear@0 662 PLY::ElementInstance* p_pcOut,
nuclear@0 663 bool p_bBE /* = false */)
nuclear@0 664 {
nuclear@0 665 ai_assert(NULL != pCur && NULL != pCurOut && NULL != pcElement && NULL != p_pcOut);
nuclear@0 666
nuclear@0 667 // allocate enough storage
nuclear@0 668 p_pcOut->alProperties.resize(pcElement->alProperties.size());
nuclear@0 669
nuclear@0 670 std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
nuclear@0 671 std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
nuclear@0 672 for (;i != p_pcOut->alProperties.end();++i,++a)
nuclear@0 673 {
nuclear@0 674 if(!(PLY::PropertyInstance::ParseInstanceBinary(pCur, &pCur,&(*a),&(*i),p_bBE)))
nuclear@0 675 {
nuclear@0 676 DefaultLogger::get()->warn("Unable to parse binary property instance. "
nuclear@0 677 "Skipping this element instance");
nuclear@0 678
nuclear@0 679 (*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType));
nuclear@0 680 }
nuclear@0 681 }
nuclear@0 682 *pCurOut = pCur;
nuclear@0 683 return true;
nuclear@0 684 }
nuclear@0 685
nuclear@0 686 // ------------------------------------------------------------------------------------------------
nuclear@0 687 bool PLY::PropertyInstance::ParseInstance (const char* pCur,const char** pCurOut,
nuclear@0 688 const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
nuclear@0 689 {
nuclear@0 690 ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut);
nuclear@0 691
nuclear@0 692 *pCurOut = pCur;
nuclear@0 693
nuclear@0 694 // skip spaces at the beginning
nuclear@0 695 if (!SkipSpaces(pCur, &pCur))return false;
nuclear@0 696
nuclear@0 697 if (prop->bIsList)
nuclear@0 698 {
nuclear@0 699 // parse the number of elements in the list
nuclear@0 700 PLY::PropertyInstance::ValueUnion v;
nuclear@0 701 PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eFirstType,&v);
nuclear@0 702
nuclear@0 703 // convert to unsigned int
nuclear@0 704 unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
nuclear@0 705
nuclear@0 706 // parse all list elements
nuclear@0 707 p_pcOut->avList.resize(iNum);
nuclear@0 708 for (unsigned int i = 0; i < iNum;++i)
nuclear@0 709 {
nuclear@0 710 if (!SkipSpaces(pCur, &pCur))return false;
nuclear@0 711 PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&p_pcOut->avList[i]);
nuclear@0 712 }
nuclear@0 713 }
nuclear@0 714 else
nuclear@0 715 {
nuclear@0 716 // parse the property
nuclear@0 717 PLY::PropertyInstance::ValueUnion v;
nuclear@0 718
nuclear@0 719 PLY::PropertyInstance::ParseValue(pCur, &pCur,prop->eType,&v);
nuclear@0 720 p_pcOut->avList.push_back(v);
nuclear@0 721 }
nuclear@0 722 SkipSpacesAndLineEnd(pCur, &pCur);
nuclear@0 723 *pCurOut = pCur;
nuclear@0 724 return true;
nuclear@0 725 }
nuclear@0 726
nuclear@0 727 // ------------------------------------------------------------------------------------------------
nuclear@0 728 bool PLY::PropertyInstance::ParseInstanceBinary (
nuclear@0 729 const char* pCur,
nuclear@0 730 const char** pCurOut,
nuclear@0 731 const PLY::Property* prop,
nuclear@0 732 PLY::PropertyInstance* p_pcOut,
nuclear@0 733 bool p_bBE)
nuclear@0 734 {
nuclear@0 735 ai_assert(NULL != pCur && NULL != pCurOut && NULL != prop && NULL != p_pcOut);
nuclear@0 736
nuclear@0 737 if (prop->bIsList)
nuclear@0 738 {
nuclear@0 739 // parse the number of elements in the list
nuclear@0 740 PLY::PropertyInstance::ValueUnion v;
nuclear@0 741 PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eFirstType,&v,p_bBE);
nuclear@0 742
nuclear@0 743 // convert to unsigned int
nuclear@0 744 unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
nuclear@0 745
nuclear@0 746 // parse all list elements
nuclear@0 747 p_pcOut->avList.resize(iNum);
nuclear@0 748 for (unsigned int i = 0; i < iNum;++i){
nuclear@0 749 PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&p_pcOut->avList[i],p_bBE);
nuclear@0 750 }
nuclear@0 751 }
nuclear@0 752 else
nuclear@0 753 {
nuclear@0 754 // parse the property
nuclear@0 755 PLY::PropertyInstance::ValueUnion v;
nuclear@0 756 PLY::PropertyInstance::ParseValueBinary(pCur, &pCur,prop->eType,&v,p_bBE);
nuclear@0 757 p_pcOut->avList.push_back(v);
nuclear@0 758 }
nuclear@0 759 *pCurOut = pCur;
nuclear@0 760 return true;
nuclear@0 761 }
nuclear@0 762
nuclear@0 763 // ------------------------------------------------------------------------------------------------
nuclear@0 764 PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(
nuclear@0 765 PLY::EDataType eType)
nuclear@0 766 {
nuclear@0 767 PLY::PropertyInstance::ValueUnion out;
nuclear@0 768
nuclear@0 769 switch (eType)
nuclear@0 770 {
nuclear@0 771 case EDT_Float:
nuclear@0 772 out.fFloat = 0.f;
nuclear@0 773 return out;
nuclear@0 774
nuclear@0 775 case EDT_Double:
nuclear@0 776 out.fDouble = 0.;
nuclear@0 777 return out;
nuclear@0 778
nuclear@0 779 default: ;
nuclear@0 780 };
nuclear@0 781 out.iUInt = 0;
nuclear@0 782 return out;
nuclear@0 783 }
nuclear@0 784
nuclear@0 785 // ------------------------------------------------------------------------------------------------
nuclear@0 786 bool PLY::PropertyInstance::ParseValue(
nuclear@0 787 const char* pCur,
nuclear@0 788 const char** pCurOut,
nuclear@0 789 PLY::EDataType eType,
nuclear@0 790 PLY::PropertyInstance::ValueUnion* out)
nuclear@0 791 {
nuclear@0 792 ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
nuclear@0 793
nuclear@0 794 register bool ret = true;
nuclear@0 795 *pCurOut = pCur;
nuclear@0 796 switch (eType)
nuclear@0 797 {
nuclear@0 798 case EDT_UInt:
nuclear@0 799 case EDT_UShort:
nuclear@0 800 case EDT_UChar:
nuclear@0 801
nuclear@0 802 out->iUInt = (uint32_t)strtoul10(pCur, &pCur);
nuclear@0 803 break;
nuclear@0 804
nuclear@0 805 case EDT_Int:
nuclear@0 806 case EDT_Short:
nuclear@0 807 case EDT_Char:
nuclear@0 808
nuclear@0 809 out->iInt = (int32_t)strtol10(pCur, &pCur);
nuclear@0 810 break;
nuclear@0 811
nuclear@0 812 case EDT_Float:
nuclear@0 813
nuclear@0 814 pCur = fast_atoreal_move<float>(pCur,out->fFloat);
nuclear@0 815 break;
nuclear@0 816
nuclear@0 817 case EDT_Double:
nuclear@0 818
nuclear@0 819 float f;
nuclear@0 820 pCur = fast_atoreal_move<float>(pCur,f);
nuclear@0 821 out->fDouble = (double)f;
nuclear@0 822 break;
nuclear@0 823
nuclear@0 824 default:
nuclear@0 825 ret = false;
nuclear@0 826 }
nuclear@0 827 *pCurOut = pCur;
nuclear@0 828 return ret;
nuclear@0 829 }
nuclear@0 830
nuclear@0 831 // ------------------------------------------------------------------------------------------------
nuclear@0 832 bool PLY::PropertyInstance::ParseValueBinary(
nuclear@0 833 const char* pCur,
nuclear@0 834 const char** pCurOut,
nuclear@0 835 PLY::EDataType eType,
nuclear@0 836 PLY::PropertyInstance::ValueUnion* out,
nuclear@0 837 bool p_bBE)
nuclear@0 838 {
nuclear@0 839 ai_assert(NULL != pCur && NULL != pCurOut && NULL != out);
nuclear@0 840
nuclear@0 841 register bool ret = true;
nuclear@0 842 switch (eType)
nuclear@0 843 {
nuclear@0 844 case EDT_UInt:
nuclear@0 845 out->iUInt = (uint32_t)*((uint32_t*)pCur);
nuclear@0 846 pCur += 4;
nuclear@0 847
nuclear@0 848 // Swap endianess
nuclear@0 849 if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt);
nuclear@0 850 break;
nuclear@0 851
nuclear@0 852 case EDT_UShort:
nuclear@0 853 {
nuclear@0 854 int16_t i = *((uint16_t*)pCur);
nuclear@0 855
nuclear@0 856 // Swap endianess
nuclear@0 857 if (p_bBE)ByteSwap::Swap(&i);
nuclear@0 858 out->iUInt = (uint32_t)i;
nuclear@0 859 pCur += 2;
nuclear@0 860 break;
nuclear@0 861 }
nuclear@0 862
nuclear@0 863 case EDT_UChar:
nuclear@0 864 {
nuclear@0 865 out->iUInt = (uint32_t)(*((uint8_t*)pCur));
nuclear@0 866 pCur ++;
nuclear@0 867 break;
nuclear@0 868 }
nuclear@0 869
nuclear@0 870 case EDT_Int:
nuclear@0 871 out->iInt = *((int32_t*)pCur);
nuclear@0 872 pCur += 4;
nuclear@0 873
nuclear@0 874 // Swap endianess
nuclear@0 875 if (p_bBE)ByteSwap::Swap(&out->iInt);
nuclear@0 876 break;
nuclear@0 877
nuclear@0 878 case EDT_Short:
nuclear@0 879 {
nuclear@0 880 int16_t i = *((int16_t*)pCur);
nuclear@0 881
nuclear@0 882 // Swap endianess
nuclear@0 883 if (p_bBE)ByteSwap::Swap(&i);
nuclear@0 884 out->iInt = (int32_t)i;
nuclear@0 885 pCur += 2;
nuclear@0 886 break;
nuclear@0 887 }
nuclear@0 888
nuclear@0 889 case EDT_Char:
nuclear@0 890 out->iInt = (int32_t)*((int8_t*)pCur);
nuclear@0 891 pCur ++;
nuclear@0 892 break;
nuclear@0 893
nuclear@0 894 case EDT_Float:
nuclear@0 895 {
nuclear@0 896 out->fFloat = *((float*)pCur);
nuclear@0 897
nuclear@0 898 // Swap endianess
nuclear@0 899 if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat);
nuclear@0 900 pCur += 4;
nuclear@0 901 break;
nuclear@0 902 }
nuclear@0 903 case EDT_Double:
nuclear@0 904 {
nuclear@0 905 out->fDouble = *((double*)pCur);
nuclear@0 906
nuclear@0 907 // Swap endianess
nuclear@0 908 if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble);
nuclear@0 909 pCur += 8;
nuclear@0 910 break;
nuclear@0 911 }
nuclear@0 912 default:
nuclear@0 913 ret = false;
nuclear@0 914 }
nuclear@0 915 *pCurOut = pCur;
nuclear@0 916 return ret;
nuclear@0 917 }
nuclear@0 918
nuclear@0 919 #endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER