2
0

PlyParser.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /** @file Implementation of the PLY parser class */
  2. #include "PLYLoader.h"
  3. #include "MaterialSystem.h"
  4. #include "fast_atof.h"
  5. #include "../include/IOStream.h"
  6. #include "../include/IOSystem.h"
  7. #include "../include/aiMesh.h"
  8. #include "../include/aiScene.h"
  9. #include "../include/aiAssert.h"
  10. #include <boost/scoped_ptr.hpp>
  11. using namespace Assimp;
  12. // ------------------------------------------------------------------------------------------------
  13. PLY::EDataType PLY::Property::ParseDataType(const char* p_szIn,const char** p_szOut)
  14. {
  15. PLY::EDataType eOut = PLY::EDT_INVALID;
  16. if (0 == ASSIMP_strincmp(p_szIn,"char",4) ||
  17. 0 == ASSIMP_strincmp(p_szIn,"int8",4))
  18. {
  19. p_szIn+=4;
  20. eOut = PLY::EDT_Char;
  21. }
  22. else if (0 == ASSIMP_strincmp(p_szIn,"uchar",5) ||
  23. 0 == ASSIMP_strincmp(p_szIn,"uint8",5))
  24. {
  25. p_szIn+=5;
  26. eOut = PLY::EDT_UChar;
  27. }
  28. else if (0 == ASSIMP_strincmp(p_szIn,"short",5) ||
  29. 0 == ASSIMP_strincmp(p_szIn,"int16",5))
  30. {
  31. p_szIn+=5;
  32. eOut = PLY::EDT_Short;
  33. }
  34. else if (0 == ASSIMP_strincmp(p_szIn,"ushort",6) ||
  35. 0 == ASSIMP_strincmp(p_szIn,"uint16",6))
  36. {
  37. p_szIn+=6;
  38. eOut = PLY::EDT_UShort;
  39. }
  40. else if (0 == ASSIMP_strincmp(p_szIn,"int32",5))
  41. {
  42. p_szIn+=5;
  43. eOut = PLY::EDT_Int;
  44. }
  45. else if (0 == ASSIMP_strincmp(p_szIn,"uint32",6))
  46. {
  47. p_szIn+=6;
  48. eOut = PLY::EDT_UInt;
  49. }
  50. else if (0 == ASSIMP_strincmp(p_szIn,"int",3))
  51. {
  52. p_szIn+=3;
  53. eOut = PLY::EDT_Int;
  54. }
  55. else if (0 == ASSIMP_strincmp(p_szIn,"uint",4))
  56. {
  57. p_szIn+=4;
  58. eOut = PLY::EDT_UInt;
  59. }
  60. else if (0 == ASSIMP_strincmp(p_szIn,"float32",7))
  61. {
  62. p_szIn+=7;
  63. eOut = PLY::EDT_Float;
  64. }
  65. else if (0 == ASSIMP_strincmp(p_szIn,"float",5))
  66. {
  67. p_szIn+=5;
  68. eOut = PLY::EDT_Float;
  69. }
  70. else if (0 == ASSIMP_strincmp(p_szIn,"float64",7))
  71. {
  72. p_szIn+=7;
  73. eOut = PLY::EDT_Double;
  74. }
  75. else if (0 == ASSIMP_strincmp(p_szIn,"double64",8))
  76. {
  77. p_szIn+=8;
  78. eOut = PLY::EDT_Double;
  79. }
  80. else if (0 == ASSIMP_strincmp(p_szIn,"double",6))
  81. {
  82. p_szIn+=6;
  83. eOut = PLY::EDT_Double;
  84. }
  85. // either end of line or space, but no other characters allowed
  86. if (!(IsSpace(*p_szIn) || IsLineEnd(*p_szIn)))
  87. {
  88. eOut = PLY::EDT_INVALID;
  89. }
  90. *p_szOut = p_szIn;
  91. return eOut;
  92. }
  93. // ------------------------------------------------------------------------------------------------
  94. PLY::ESemantic PLY::Property::ParseSemantic(const char* p_szIn,const char** p_szOut)
  95. {
  96. PLY::ESemantic eOut = PLY::EST_INVALID;
  97. if (0 == ASSIMP_strincmp(p_szIn,"x",1))
  98. {
  99. p_szIn++;
  100. eOut = PLY::EST_XCoord;
  101. }
  102. else if (0 == ASSIMP_strincmp(p_szIn,"y",1))
  103. {
  104. p_szIn++;
  105. eOut = PLY::EST_YCoord;
  106. }
  107. else if (0 == ASSIMP_strincmp(p_szIn,"z",1))
  108. {
  109. p_szIn++;
  110. eOut = PLY::EST_ZCoord;
  111. }
  112. else if (0 == ASSIMP_strincmp(p_szIn,"red",3))
  113. {
  114. p_szIn+=3;
  115. eOut = PLY::EST_Red;
  116. }
  117. else if (0 == ASSIMP_strincmp(p_szIn,"green",4))
  118. {
  119. p_szIn+=5;
  120. eOut = PLY::EST_Green;
  121. }
  122. else if (0 == ASSIMP_strincmp(p_szIn,"blue",4))
  123. {
  124. p_szIn+=4;
  125. eOut = PLY::EST_Blue;
  126. }
  127. else if (0 == ASSIMP_strincmp(p_szIn,"alpha",5))
  128. {
  129. p_szIn+=5;
  130. eOut = PLY::EST_Alpha;
  131. }
  132. else if (0 == ASSIMP_strincmp(p_szIn,"vertex_index",12))
  133. {
  134. p_szIn+=12;
  135. eOut = PLY::EST_VertexIndex;
  136. }
  137. else if (0 == ASSIMP_strincmp(p_szIn,"vertex_indices",14))
  138. {
  139. p_szIn+=14;
  140. eOut = PLY::EST_VertexIndex;
  141. }
  142. else if (0 == ASSIMP_strincmp(p_szIn,"material_index",14))
  143. {
  144. p_szIn+=14;
  145. eOut = PLY::EST_MaterialIndex;
  146. }
  147. else if (0 == ASSIMP_strincmp(p_szIn,"ambient_red",11))
  148. {
  149. p_szIn+=11;
  150. eOut = PLY::EST_AmbientRed;
  151. }
  152. else if (0 == ASSIMP_strincmp(p_szIn,"ambient_green",13))
  153. {
  154. p_szIn+=13;
  155. eOut = PLY::EST_AmbientGreen;
  156. }
  157. else if (0 == ASSIMP_strincmp(p_szIn,"ambient_blue",12))
  158. {
  159. p_szIn+=12;
  160. eOut = PLY::EST_AmbientBlue;
  161. }
  162. else if (0 == ASSIMP_strincmp(p_szIn,"ambient_alpha",13))
  163. {
  164. p_szIn+=13;
  165. eOut = PLY::EST_AmbientAlpha;
  166. }
  167. else if (0 == ASSIMP_strincmp(p_szIn,"diffuse_red",11))
  168. {
  169. p_szIn+=11;
  170. eOut = PLY::EST_DiffuseRed;
  171. }
  172. else if (0 == ASSIMP_strincmp(p_szIn,"diffuse_green",13))
  173. {
  174. p_szIn+=13;
  175. eOut = PLY::EST_DiffuseGreen;
  176. }
  177. else if (0 == ASSIMP_strincmp(p_szIn,"diffuse_blue",12))
  178. {
  179. p_szIn+=12;
  180. eOut = PLY::EST_DiffuseBlue;
  181. }
  182. else if (0 == ASSIMP_strincmp(p_szIn,"diffuse_alpha",13))
  183. {
  184. p_szIn+=13;
  185. eOut = PLY::EST_DiffuseAlpha;
  186. }
  187. else if (0 == ASSIMP_strincmp(p_szIn,"specular_red",12))
  188. {
  189. p_szIn+=12;
  190. eOut = PLY::EST_SpecularRed;
  191. }
  192. else if (0 == ASSIMP_strincmp(p_szIn,"specular_green",14))
  193. {
  194. p_szIn+=14;
  195. eOut = PLY::EST_SpecularGreen;
  196. }
  197. else if (0 == ASSIMP_strincmp(p_szIn,"specular_blue",13))
  198. {
  199. p_szIn+=13;
  200. eOut = PLY::EST_SpecularBlue;
  201. }
  202. else if (0 == ASSIMP_strincmp(p_szIn,"specular_alpha",14))
  203. {
  204. p_szIn+=14;
  205. eOut = PLY::EST_SpecularAlpha;
  206. }
  207. else if (0 == ASSIMP_strincmp(p_szIn,"opacity",7))
  208. {
  209. p_szIn+=7;
  210. eOut = PLY::EST_Opacity;
  211. }
  212. else if (0 == ASSIMP_strincmp(p_szIn,"specular_power",6))
  213. {
  214. p_szIn+=7;
  215. eOut = PLY::EST_PhongPower;
  216. }
  217. else if (0 == ASSIMP_strincmp(p_szIn,"r",1))
  218. {
  219. p_szIn++;
  220. eOut = PLY::EST_Red;
  221. }
  222. else if (0 == ASSIMP_strincmp(p_szIn,"g",1))
  223. {
  224. p_szIn++;
  225. eOut = PLY::EST_Green;
  226. }
  227. else if (0 == ASSIMP_strincmp(p_szIn,"b",1))
  228. {
  229. p_szIn++;
  230. eOut = PLY::EST_Blue;
  231. }
  232. else
  233. {
  234. // ... find the next space or new line
  235. while (*p_szIn != ' ' && *p_szIn != '\t' &&
  236. *p_szIn != '\r' && *p_szIn != '\0' && *p_szIn != '\n')p_szIn++;
  237. }
  238. // either end of line or space, but no other characters allowed
  239. if (!(IsSpace(*p_szIn) || IsLineEnd(*p_szIn)))
  240. {
  241. eOut = PLY::EST_INVALID;
  242. }
  243. *p_szOut = p_szIn;
  244. return eOut;
  245. }
  246. // ------------------------------------------------------------------------------------------------
  247. bool PLY::Property::ParseProperty (const char* p_szIn, const char** p_szOut, PLY::Property* pOut)
  248. {
  249. // Forms supported:
  250. // "property float x"
  251. // "property list uchar int vertex_index"
  252. *p_szOut = p_szIn;
  253. // skip leading spaces
  254. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  255. // skip the "property" string at the beginning
  256. if (0 != ASSIMP_strincmp(p_szIn,"property",8) || !IsSpace(*(p_szIn+8)))
  257. {
  258. // seems not to be a valid property entry
  259. return false;
  260. }
  261. // get next word
  262. p_szIn += 9;
  263. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  264. if (0 == ASSIMP_strincmp(p_szIn,"list",4) && IsSpace(*(p_szIn+4)))
  265. {
  266. pOut->bIsList = true;
  267. // seems to be a list.
  268. p_szIn += 5;
  269. if(EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
  270. {
  271. // unable to parse list size data type
  272. SkipLine(p_szIn,&p_szIn);
  273. *p_szOut = p_szIn;
  274. return false;
  275. }
  276. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  277. if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
  278. {
  279. // unable to parse list data type
  280. SkipLine(p_szIn,&p_szIn);
  281. *p_szOut = p_szIn;
  282. return false;
  283. }
  284. }
  285. else
  286. {
  287. if(EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(p_szIn, &p_szIn)))
  288. {
  289. // unable to parse data type. Skip the property
  290. SkipLine(p_szIn,&p_szIn);
  291. *p_szOut = p_szIn;
  292. return false;
  293. }
  294. }
  295. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  296. const char* szCur = p_szIn;
  297. pOut->Semantic = PLY::Property::ParseSemantic(p_szIn, &p_szIn);
  298. if (PLY::EST_INVALID == pOut->Semantic)
  299. {
  300. // store the name of the semantic
  301. uintptr_t iDiff = (uintptr_t)p_szIn - (uintptr_t)szCur;
  302. pOut->szName = std::string(szCur,iDiff);
  303. }
  304. SkipSpacesAndLineEnd(p_szIn,&p_szIn);
  305. *p_szOut = p_szIn;
  306. return true;
  307. }
  308. // ------------------------------------------------------------------------------------------------
  309. PLY::EElementSemantic PLY::Element::ParseSemantic(const char* p_szIn,const char** p_szOut)
  310. {
  311. PLY::EElementSemantic eOut = PLY::EEST_INVALID;
  312. if (0 == ASSIMP_strincmp(p_szIn,"vertex",6))
  313. {
  314. p_szIn+=6;
  315. eOut = PLY::EEST_Vertex;
  316. }
  317. else if (0 == ASSIMP_strincmp(p_szIn,"face",4))
  318. {
  319. p_szIn+=4;
  320. eOut = PLY::EEST_Face;
  321. }
  322. #if 0
  323. else if (0 == ASSIMP_strincmp(p_szIn,"range_grid",10))
  324. {
  325. p_szIn+=10;
  326. eOut = PLY::EEST_Face;
  327. }
  328. #endif
  329. else if (0 == ASSIMP_strincmp(p_szIn,"tristrips",9))
  330. {
  331. p_szIn+=9;
  332. eOut = PLY::EEST_TriStrip;
  333. }
  334. else if (0 == ASSIMP_strincmp(p_szIn,"edge",4))
  335. {
  336. p_szIn+=4;
  337. eOut = PLY::EEST_Edge;
  338. }
  339. else if (0 == ASSIMP_strincmp(p_szIn,"material",8))
  340. {
  341. p_szIn+=8;
  342. eOut = PLY::EEST_Material;
  343. }
  344. // either end of line or space, but no other characters allowed
  345. if (!(IsSpace(*p_szIn) || IsLineEnd(*p_szIn)))
  346. {
  347. eOut = PLY::EEST_INVALID;
  348. }
  349. *p_szOut = p_szIn;
  350. return eOut;
  351. }
  352. // ------------------------------------------------------------------------------------------------
  353. bool PLY::Element::ParseElement (const char* p_szIn, const char** p_szOut,
  354. PLY::Element* pOut)
  355. {
  356. // Example format: "element vertex 8"
  357. *p_szOut = p_szIn;
  358. // skip leading spaces
  359. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  360. // skip the "element" string at the beginning
  361. if (0 != ASSIMP_strincmp(p_szIn,"element",7) || !IsSpace(*(p_szIn+7)))
  362. {
  363. // seems not to be a valid property entry
  364. return false;
  365. }
  366. // get next word
  367. p_szIn += 8;
  368. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  369. // parse the semantic of the element
  370. const char* szCur = p_szIn;
  371. pOut->eSemantic = PLY::Element::ParseSemantic(p_szIn,&p_szIn);
  372. if (PLY::EEST_INVALID == pOut->eSemantic)
  373. {
  374. // store the name of the semantic
  375. uintptr_t iDiff = (uintptr_t)p_szIn - (uintptr_t)szCur;
  376. pOut->szName = std::string(szCur,iDiff);
  377. }
  378. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  379. //parse the number of occurences of this element
  380. pOut->NumOccur = strtol10(p_szIn,&p_szIn);
  381. // go to the next line
  382. SkipSpacesAndLineEnd(p_szIn,&p_szIn);
  383. // now parse all properties of the element
  384. while(true)
  385. {
  386. // skip all comments
  387. PLY::DOM::SkipComments(p_szIn,&p_szIn);
  388. Property prop;
  389. if(!PLY::Property::ParseProperty(p_szIn,&p_szIn,&prop))break;
  390. // add the property to the property list
  391. pOut->alProperties.push_back(prop);
  392. }
  393. *p_szOut = p_szIn;
  394. return true;
  395. }
  396. // ------------------------------------------------------------------------------------------------
  397. bool PLY::DOM::SkipComments (const char* p_szIn,const char** p_szOut)
  398. {
  399. *p_szOut = p_szIn;
  400. // skip spaces
  401. if (!SkipSpaces(p_szIn,&p_szIn))return false;
  402. if (0 == ASSIMP_strincmp(p_szIn,"comment",7))
  403. {
  404. p_szIn += 7;
  405. SkipLine(p_szIn,&p_szIn);
  406. SkipComments(p_szIn,&p_szIn);
  407. *p_szOut = p_szIn;
  408. return true;
  409. }
  410. return false;
  411. }
  412. // ------------------------------------------------------------------------------------------------
  413. bool PLY::DOM::ParseHeader (const char* p_szIn,const char** p_szOut)
  414. {
  415. // after ply and format line
  416. *p_szOut = p_szIn;
  417. // parse all elements
  418. while (true)
  419. {
  420. // skip all comments
  421. PLY::DOM::SkipComments(p_szIn,&p_szIn);
  422. Element out;
  423. if(PLY::Element::ParseElement(p_szIn,&p_szIn,&out))
  424. {
  425. // add the element to the list of elements
  426. this->alElements.push_back(out);
  427. }
  428. else if (0 == ASSIMP_strincmp(p_szIn,"end_header",10) && IsSpaceOrNewLine(*(p_szIn+10)))
  429. {
  430. // we have reached the end of the header
  431. p_szIn += 11;
  432. break;
  433. }
  434. // ignore unknown header elements
  435. }
  436. SkipSpacesAndLineEnd(p_szIn,&p_szIn);
  437. *p_szOut = p_szIn;
  438. return true;
  439. }
  440. // ------------------------------------------------------------------------------------------------
  441. bool PLY::DOM::ParseElementInstanceLists (const char* p_szIn,const char** p_szOut)
  442. {
  443. this->alElementData.resize(this->alElements.size());
  444. std::vector<PLY::Element>::const_iterator i = this->alElements.begin();
  445. std::vector<PLY::ElementInstanceList>::iterator a = this->alElementData.begin();
  446. // parse all element instances
  447. for (;i != this->alElements.end();++i,++a)
  448. {
  449. *a = PLY::ElementInstanceList(&(*i)); // reserve enough storage
  450. PLY::ElementInstanceList::ParseInstanceList(p_szIn,&p_szIn,&(*i),&(*a));
  451. }
  452. return true;
  453. }
  454. // ------------------------------------------------------------------------------------------------
  455. bool PLY::DOM::ParseElementInstanceListsBinary (const char* p_szIn,const char** p_szOut,bool p_bBE)
  456. {
  457. this->alElementData.resize(this->alElements.size());
  458. std::vector<PLY::Element>::const_iterator i = this->alElements.begin();
  459. std::vector<PLY::ElementInstanceList>::iterator a = this->alElementData.begin();
  460. // parse all element instances
  461. for (;i != this->alElements.end();++i,++a)
  462. {
  463. *a = PLY::ElementInstanceList(&(*i)); // reserve enough storage
  464. PLY::ElementInstanceList::ParseInstanceListBinary(p_szIn,&p_szIn,&(*i),&(*a),p_bBE);
  465. }
  466. return true;
  467. }
  468. // ------------------------------------------------------------------------------------------------
  469. bool PLY::DOM::ParseInstanceBinary (const char* p_szIn,DOM* p_pcOut,bool p_bBE)
  470. {
  471. if(!p_pcOut->ParseHeader(p_szIn,&p_szIn))
  472. {
  473. return false;
  474. }
  475. if(!p_pcOut->ParseElementInstanceListsBinary(p_szIn,&p_szIn,p_bBE))
  476. {
  477. return false;
  478. }
  479. return true;
  480. }
  481. // ------------------------------------------------------------------------------------------------
  482. bool PLY::DOM::ParseInstance (const char* p_szIn,DOM* p_pcOut)
  483. {
  484. if(!p_pcOut->ParseHeader(p_szIn,&p_szIn))
  485. {
  486. return false;
  487. }
  488. if(!p_pcOut->ParseElementInstanceLists(p_szIn,&p_szIn))
  489. {
  490. return false;
  491. }
  492. return true;
  493. }
  494. // ------------------------------------------------------------------------------------------------
  495. bool PLY::ElementInstanceList::ParseInstanceList (const char* p_szIn,const char** p_szOut,
  496. const PLY::Element* pcElement, PLY::ElementInstanceList* p_pcOut)
  497. {
  498. if (EEST_INVALID == pcElement->eSemantic)
  499. {
  500. // if the element has an unknown semantic we can skip all lines
  501. // However, there could be comments
  502. for (unsigned int i = 0; i < pcElement->NumOccur;++i)
  503. {
  504. PLY::DOM::SkipComments(p_szIn,&p_szIn);
  505. SkipLine(p_szIn,&p_szIn);
  506. }
  507. }
  508. else
  509. {
  510. // be sure to have enough storage
  511. p_pcOut->alInstances.resize(pcElement->NumOccur);
  512. for (unsigned int i = 0; i < pcElement->NumOccur;++i)
  513. {
  514. PLY::DOM::SkipComments(p_szIn,&p_szIn);
  515. PLY::ElementInstance out;
  516. PLY::ElementInstance::ParseInstance(p_szIn, &p_szIn,pcElement, &out);
  517. // add it to the list
  518. p_pcOut->alInstances[i] = out;
  519. }
  520. }
  521. *p_szOut = p_szIn;
  522. return true;
  523. }
  524. // ------------------------------------------------------------------------------------------------
  525. bool PLY::ElementInstanceList::ParseInstanceListBinary (const char* p_szIn,const char** p_szOut,
  526. const PLY::Element* pcElement, PLY::ElementInstanceList* p_pcOut,bool p_bBE)
  527. {
  528. // we can add special handling code for unknown element semantics since
  529. // we can't skip it as a whole block (we don't know its exact size
  530. // due to the fact that lists could be contained in the property list
  531. // of the unknown element)
  532. for (unsigned int i = 0; i < pcElement->NumOccur;++i)
  533. {
  534. PLY::ElementInstance out;
  535. PLY::ElementInstance::ParseInstanceBinary(p_szIn, &p_szIn,pcElement, &out, p_bBE);
  536. // add it to the list
  537. p_pcOut->alInstances[i] = out;
  538. }
  539. *p_szOut = p_szIn;
  540. return true;
  541. }
  542. // ------------------------------------------------------------------------------------------------
  543. bool PLY::ElementInstance::ParseInstance (const char* p_szIn,const char** p_szOut,
  544. const PLY::Element* pcElement, PLY::ElementInstance* p_pcOut)
  545. {
  546. if (!SkipSpaces(p_szIn, &p_szIn))return false;
  547. p_pcOut->alProperties.resize(pcElement->alProperties.size());
  548. *p_szOut = p_szIn;
  549. std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
  550. std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
  551. for (;i != p_pcOut->alProperties.end();++i,++a)
  552. {
  553. if(!(PLY::PropertyInstance::ParseInstance(p_szIn, &p_szIn,&(*a),&(*i))))
  554. {
  555. // skip the rest of the instance
  556. SkipLine(p_szIn, &p_szIn);
  557. PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
  558. (*i).avList.push_back(v);
  559. }
  560. }
  561. *p_szOut = p_szIn;
  562. return true;
  563. }
  564. // ------------------------------------------------------------------------------------------------
  565. bool PLY::ElementInstance::ParseInstanceBinary (const char* p_szIn,const char** p_szOut,
  566. const PLY::Element* pcElement, PLY::ElementInstance* p_pcOut, bool p_bBE)
  567. {
  568. p_pcOut->alProperties.resize(pcElement->alProperties.size());
  569. *p_szOut = p_szIn;
  570. std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
  571. std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
  572. for (;i != p_pcOut->alProperties.end();++i,++a)
  573. {
  574. if(!(PLY::PropertyInstance::ParseInstance(p_szIn, &p_szIn,&(*a),&(*i))))
  575. {
  576. PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
  577. (*i).avList.push_back(v);
  578. }
  579. }
  580. *p_szOut = p_szIn;
  581. return true;
  582. }
  583. // ------------------------------------------------------------------------------------------------
  584. bool PLY::PropertyInstance::ParseInstance (const char* p_szIn,const char** p_szOut,
  585. const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
  586. {
  587. *p_szOut = p_szIn;
  588. // skip spaces at the beginning
  589. if (!SkipSpaces(p_szIn, &p_szIn))return false;
  590. if (prop->bIsList)
  591. {
  592. // parse the number of elements in the list
  593. PLY::PropertyInstance::ValueUnion v;
  594. PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eFirstType,&v);
  595. // convert to unsigned int
  596. unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
  597. // parse all list elements
  598. for (unsigned int i = 0; i < iNum;++i)
  599. {
  600. if (!SkipSpaces(p_szIn, &p_szIn))return false;
  601. PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eType,&v);
  602. p_pcOut->avList.push_back(v);
  603. }
  604. }
  605. else
  606. {
  607. // parse the property
  608. PLY::PropertyInstance::ValueUnion v;
  609. PLY::PropertyInstance::ParseValue(p_szIn, &p_szIn,prop->eType,&v);
  610. p_pcOut->avList.push_back(v);
  611. }
  612. SkipSpacesAndLineEnd(p_szIn, &p_szIn);
  613. *p_szOut = p_szIn;
  614. return true;
  615. }
  616. // ------------------------------------------------------------------------------------------------
  617. bool PLY::PropertyInstance::ParseInstanceBinary (const char* p_szIn,const char** p_szOut,
  618. const PLY::Property* prop, PLY::PropertyInstance* p_pcOut,bool p_bBE)
  619. {
  620. *p_szOut = p_szIn;
  621. if (prop->bIsList)
  622. {
  623. // parse the number of elements in the list
  624. PLY::PropertyInstance::ValueUnion v;
  625. PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eFirstType,&v,p_bBE);
  626. // convert to unsigned int
  627. unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v,prop->eFirstType);
  628. // parse all list elements
  629. for (unsigned int i = 0; i < iNum;++i)
  630. {
  631. PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eType,&v,p_bBE);
  632. p_pcOut->avList.push_back(v);
  633. }
  634. }
  635. else
  636. {
  637. // parse the property
  638. PLY::PropertyInstance::ValueUnion v;
  639. PLY::PropertyInstance::ParseValueBinary(p_szIn, &p_szIn,prop->eType,&v,p_bBE);
  640. p_pcOut->avList.push_back(v);
  641. }
  642. *p_szOut = p_szIn;
  643. return true;
  644. }
  645. // ------------------------------------------------------------------------------------------------
  646. PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(
  647. PLY::EDataType eType)
  648. {
  649. PLY::PropertyInstance::ValueUnion out;
  650. switch (eType)
  651. {
  652. case EDT_Float:
  653. out.fFloat = 0.0f;
  654. return out;
  655. case EDT_Double:
  656. out.fDouble = 0.0;
  657. return out;
  658. };
  659. out.iUInt = 0;
  660. return out;
  661. }
  662. // ------------------------------------------------------------------------------------------------
  663. bool PLY::PropertyInstance::ParseValue(const char* p_szIn,const char** p_szOut,
  664. PLY::EDataType eType,PLY::PropertyInstance::ValueUnion* out)
  665. {
  666. *p_szOut = p_szIn;
  667. switch (eType)
  668. {
  669. case EDT_UInt:
  670. case EDT_UShort:
  671. case EDT_UChar:
  672. // simply parse in a full uint
  673. out->iUInt = (uint32_t)strtol10(p_szIn, &p_szIn);
  674. break;
  675. case EDT_Int:
  676. case EDT_Short:
  677. case EDT_Char:
  678. {
  679. // simply parse in a full int
  680. // Take care of the sign at the beginning
  681. bool bMinus = false;
  682. if (*p_szIn == '-')
  683. {
  684. p_szIn++;
  685. bMinus = true;
  686. }
  687. out->iInt = (int32_t)strtol10(p_szIn, &p_szIn);
  688. if (bMinus)out->iInt *= -1;
  689. break;
  690. }
  691. case EDT_Float:
  692. // parse a simple float
  693. p_szIn = fast_atof_move(p_szIn,out->fFloat);
  694. break;
  695. case EDT_Double:
  696. // Parse a double float. .. TODO: support this
  697. float f;
  698. p_szIn = fast_atof_move(p_szIn,f);
  699. out->fDouble = (double)f;
  700. default:
  701. return false;
  702. }
  703. *p_szOut = p_szIn;
  704. return true;
  705. }
  706. // ------------------------------------------------------------------------------------------------
  707. bool PLY::PropertyInstance::ParseValueBinary(const char* p_szIn,const char** p_szOut,
  708. PLY::EDataType eType,PLY::PropertyInstance::ValueUnion* out, bool p_bBE)
  709. {
  710. *p_szOut = p_szIn;
  711. switch (eType)
  712. {
  713. case EDT_UInt:
  714. out->iUInt = (uint32_t)*((uint32_t*)p_szIn);
  715. p_szIn += 4;
  716. if (p_bBE)
  717. {
  718. std::swap(((unsigned char*)(&out->iUInt))[0],((unsigned char*)(&out->iUInt))[3]);
  719. std::swap(((unsigned char*)(&out->iUInt))[1],((unsigned char*)(&out->iUInt))[2]);
  720. }
  721. break;
  722. case EDT_UShort:
  723. {
  724. uint16_t i = *((uint16_t*)p_szIn);
  725. if (p_bBE)
  726. {
  727. std::swap(((unsigned char*)(&i))[0],((unsigned char*)(&i))[1]);
  728. }
  729. out->iUInt = (uint32_t)i;
  730. p_szIn += 2;
  731. break;
  732. }
  733. case EDT_UChar:
  734. {
  735. uint8_t i = *((uint8_t*)p_szIn);
  736. out->iUInt = (uint32_t)i;
  737. p_szIn += 2;
  738. break;
  739. }
  740. case EDT_Int:
  741. out->iInt = *((int32_t*)p_szIn);
  742. p_szIn += 4;
  743. if (p_bBE)
  744. {
  745. std::swap(((unsigned char*)(&out->iInt))[0],((unsigned char*)(&out->iInt))[3]);
  746. std::swap(((unsigned char*)(&out->iInt))[1],((unsigned char*)(&out->iInt))[2]);
  747. }
  748. break;
  749. case EDT_Short:
  750. {
  751. int16_t i = *((int16_t*)p_szIn);
  752. if (p_bBE)
  753. {
  754. std::swap(((unsigned char*)(&i))[0],((unsigned char*)(&i))[1]);
  755. }
  756. out->iInt = (int32_t)i;
  757. p_szIn += 2;
  758. break;
  759. }
  760. case EDT_Char:
  761. out->iInt = (int32_t)*((int8_t*)p_szIn);
  762. p_szIn += 1;
  763. break;
  764. case EDT_Float:
  765. if (p_bBE)
  766. {
  767. union {char szArray[4]; float fValue; } _X;
  768. _X.szArray[0] = ((unsigned char*)p_szIn)[3];
  769. _X.szArray[1] = ((unsigned char*)p_szIn)[2];
  770. _X.szArray[2] = ((unsigned char*)p_szIn)[1];
  771. _X.szArray[3] = ((unsigned char*)p_szIn)[0];
  772. out->fFloat = _X.fValue;
  773. }
  774. else out->fFloat = *((float*)p_szIn);
  775. p_szIn += 4;
  776. break;
  777. case EDT_Double:
  778. if (p_bBE)
  779. {
  780. union {char szArray[8]; double fValue; } _X;
  781. _X.szArray[0] = ((unsigned char*)p_szIn)[7];
  782. _X.szArray[1] = ((unsigned char*)p_szIn)[6];
  783. _X.szArray[2] = ((unsigned char*)p_szIn)[5];
  784. _X.szArray[3] = ((unsigned char*)p_szIn)[4];
  785. _X.szArray[4] = ((unsigned char*)p_szIn)[3];
  786. _X.szArray[5] = ((unsigned char*)p_szIn)[2];
  787. _X.szArray[6] = ((unsigned char*)p_szIn)[1];
  788. _X.szArray[7] = ((unsigned char*)p_szIn)[0];
  789. out->fDouble = _X.fValue;
  790. }
  791. else out->fDouble = *((double*)p_szIn);
  792. p_szIn += 8;
  793. break;
  794. default:
  795. return false;
  796. }
  797. *p_szOut = p_szIn;
  798. return true;
  799. }