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