X3DImporter_Rendering.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. /*
  2. Open Asset Import Library (assimp)
  3. ----------------------------------------------------------------------
  4. Copyright (c) 2006-2016, assimp team
  5. All rights reserved.
  6. Redistribution and use of this software in source and binary forms,
  7. with or without modification, are permitted provided that the
  8. following conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the
  11. following disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the
  14. following disclaimer in the documentation and/or other
  15. materials provided with the distribution.
  16. * Neither the name of the assimp team, nor the names of its
  17. contributors may be used to endorse or promote products
  18. derived from this software without specific prior
  19. written permission of the assimp team.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ----------------------------------------------------------------------
  32. */
  33. /// \file X3DImporter_Rendering.cpp
  34. /// \brief Parsing data from nodes of "Rendering" set of X3D.
  35. /// \date 2015-2016
  36. /// \author [email protected]
  37. #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
  38. #include "X3DImporter.hpp"
  39. #include "X3DImporter_Macro.hpp"
  40. namespace Assimp
  41. {
  42. // <Color
  43. // DEF="" ID
  44. // USE="" IDREF
  45. // color="" MFColor [inputOutput]
  46. // />
  47. void X3DImporter::ParseNode_Rendering_Color()
  48. {
  49. std::string use, def;
  50. std::list<aiColor3D> color;
  51. CX3DImporter_NodeElement* ne( nullptr );
  52. MACRO_ATTRREAD_LOOPBEG;
  53. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  54. MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol3f);
  55. MACRO_ATTRREAD_LOOPEND;
  56. // if "USE" defined then find already defined element.
  57. if(!use.empty())
  58. {
  59. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Color, ne);
  60. }
  61. else
  62. {
  63. // create and if needed - define new geometry object.
  64. ne = new CX3DImporter_NodeElement_Color(NodeElement_Cur);
  65. if(!def.empty()) ne->ID = def;
  66. ((CX3DImporter_NodeElement_Color*)ne)->Value = color;
  67. // check for X3DMetadataObject childs.
  68. if(!mReader->isEmptyElement())
  69. ParseNode_Metadata(ne, "Color");
  70. else
  71. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  72. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  73. }// if(!use.empty()) else
  74. }
  75. // <ColorRGBA
  76. // DEF="" ID
  77. // USE="" IDREF
  78. // color="" MFColorRGBA [inputOutput]
  79. // />
  80. void X3DImporter::ParseNode_Rendering_ColorRGBA()
  81. {
  82. std::string use, def;
  83. std::list<aiColor4D> color;
  84. CX3DImporter_NodeElement* ne( nullptr );
  85. MACRO_ATTRREAD_LOOPBEG;
  86. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  87. MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol4f);
  88. MACRO_ATTRREAD_LOOPEND;
  89. // if "USE" defined then find already defined element.
  90. if(!use.empty())
  91. {
  92. MACRO_USE_CHECKANDAPPLY(def, use, ENET_ColorRGBA, ne);
  93. }
  94. else
  95. {
  96. // create and if needed - define new geometry object.
  97. ne = new CX3DImporter_NodeElement_ColorRGBA(NodeElement_Cur);
  98. if(!def.empty()) ne->ID = def;
  99. ((CX3DImporter_NodeElement_ColorRGBA*)ne)->Value = color;
  100. // check for X3DMetadataObject childs.
  101. if(!mReader->isEmptyElement())
  102. ParseNode_Metadata(ne, "ColorRGBA");
  103. else
  104. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  105. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  106. }// if(!use.empty()) else
  107. }
  108. // <Coordinate
  109. // DEF="" ID
  110. // USE="" IDREF
  111. // point="" MFVec3f [inputOutput]
  112. // />
  113. void X3DImporter::ParseNode_Rendering_Coordinate()
  114. {
  115. std::string use, def;
  116. std::list<aiVector3D> point;
  117. CX3DImporter_NodeElement* ne( nullptr );
  118. MACRO_ATTRREAD_LOOPBEG;
  119. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  120. MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec3f);
  121. MACRO_ATTRREAD_LOOPEND;
  122. // if "USE" defined then find already defined element.
  123. if(!use.empty())
  124. {
  125. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Coordinate, ne);
  126. }
  127. else
  128. {
  129. // create and if needed - define new geometry object.
  130. ne = new CX3DImporter_NodeElement_Coordinate(NodeElement_Cur);
  131. if(!def.empty()) ne->ID = def;
  132. ((CX3DImporter_NodeElement_Coordinate*)ne)->Value = point;
  133. // check for X3DMetadataObject childs.
  134. if(!mReader->isEmptyElement())
  135. ParseNode_Metadata(ne, "Coordinate");
  136. else
  137. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  138. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  139. }// if(!use.empty()) else
  140. }
  141. // <IndexedLineSet
  142. // DEF="" ID
  143. // USE="" IDREF
  144. // colorIndex="" MFInt32 [initializeOnly]
  145. // colorPerVertex="true" SFBool [initializeOnly]
  146. // coordIndex="" MFInt32 [initializeOnly]
  147. // >
  148. // <!-- ColorCoordinateContentModel -->
  149. // ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
  150. // contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
  151. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  152. // </IndexedLineSet>
  153. void X3DImporter::ParseNode_Rendering_IndexedLineSet()
  154. {
  155. std::string use, def;
  156. std::list<int32_t> colorIndex;
  157. bool colorPerVertex = true;
  158. std::list<int32_t> coordIndex;
  159. CX3DImporter_NodeElement* ne( nullptr );
  160. MACRO_ATTRREAD_LOOPBEG;
  161. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  162. MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsListI32);
  163. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  164. MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsListI32);
  165. MACRO_ATTRREAD_LOOPEND;
  166. // if "USE" defined then find already defined element.
  167. if(!use.empty())
  168. {
  169. MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedLineSet, ne);
  170. }
  171. else
  172. {
  173. // check data
  174. if((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3)))
  175. throw DeadlyImportError("IndexedLineSet must contain not empty \"coordIndex\" attribute.");
  176. // create and if needed - define new geometry object.
  177. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedLineSet, NodeElement_Cur);
  178. if(!def.empty()) ne->ID = def;
  179. CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
  180. ne_alias.ColorIndex = colorIndex;
  181. ne_alias.ColorPerVertex = colorPerVertex;
  182. ne_alias.CoordIndex = coordIndex;
  183. // check for child nodes
  184. if(!mReader->isEmptyElement())
  185. {
  186. ParseHelper_Node_Enter(ne);
  187. MACRO_NODECHECK_LOOPBEGIN("IndexedLineSet");
  188. // check for Color and Coordinate nodes
  189. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  190. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  191. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  192. // check for X3DMetadataObject
  193. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedLineSet");
  194. MACRO_NODECHECK_LOOPEND("IndexedLineSet");
  195. ParseHelper_Node_Exit();
  196. }// if(!mReader->isEmptyElement())
  197. else
  198. {
  199. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  200. }
  201. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  202. }// if(!use.empty()) else
  203. }
  204. // <IndexedTriangleFanSet
  205. // DEF="" ID
  206. // USE="" IDREF
  207. // ccw="true" SFBool [initializeOnly]
  208. // colorPerVertex="true" SFBool [initializeOnly]
  209. // index="" MFInt32 [initializeOnly]
  210. // normalPerVertex="true" SFBool [initializeOnly]
  211. // solid="true" SFBool [initializeOnly]
  212. // >
  213. // <!-- ComposedGeometryContentModel -->
  214. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  215. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  216. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  217. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  218. // </IndexedTriangleFanSet>
  219. void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
  220. {
  221. std::string use, def;
  222. bool ccw = true;
  223. bool colorPerVertex = true;
  224. std::list<int32_t> index;
  225. bool normalPerVertex = true;
  226. bool solid = true;
  227. CX3DImporter_NodeElement* ne( nullptr );
  228. MACRO_ATTRREAD_LOOPBEG;
  229. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  230. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  231. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  232. MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
  233. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  234. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  235. MACRO_ATTRREAD_LOOPEND;
  236. // if "USE" defined then find already defined element.
  237. if(!use.empty())
  238. {
  239. MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleFanSet, ne);
  240. }
  241. else
  242. {
  243. // check data
  244. if(index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute.");
  245. // create and if needed - define new geometry object.
  246. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet, NodeElement_Cur);
  247. if(!def.empty()) ne->ID = def;
  248. CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
  249. ne_alias.CCW = ccw;
  250. ne_alias.ColorPerVertex = colorPerVertex;
  251. ne_alias.CoordIndex = index;
  252. ne_alias.NormalPerVertex = normalPerVertex;
  253. ne_alias.Solid = solid;
  254. // check for child nodes
  255. if(!mReader->isEmptyElement())
  256. {
  257. ParseHelper_Node_Enter(ne);
  258. MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleFanSet");
  259. // check for X3DComposedGeometryNodes
  260. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  261. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  262. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  263. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  264. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  265. // check for X3DMetadataObject
  266. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleFanSet");
  267. MACRO_NODECHECK_LOOPEND("IndexedTriangleFanSet");
  268. ParseHelper_Node_Exit();
  269. }// if(!mReader->isEmptyElement())
  270. else
  271. {
  272. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  273. }
  274. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  275. }// if(!use.empty()) else
  276. }
  277. // <IndexedTriangleSet
  278. // DEF="" ID
  279. // USE="" IDREF
  280. // ccw="true" SFBool [initializeOnly]
  281. // colorPerVertex="true" SFBool [initializeOnly]
  282. // index="" MFInt32 [initializeOnly]
  283. // normalPerVertex="true" SFBool [initializeOnly]
  284. // solid="true" SFBool [initializeOnly]
  285. // >
  286. // <!-- ComposedGeometryContentModel -->
  287. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  288. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  289. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  290. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  291. // </IndexedTriangleSet>
  292. void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
  293. {
  294. std::string use, def;
  295. bool ccw = true;
  296. bool colorPerVertex = true;
  297. std::list<int32_t> index;
  298. bool normalPerVertex = true;
  299. bool solid = true;
  300. CX3DImporter_NodeElement* ne( nullptr );
  301. MACRO_ATTRREAD_LOOPBEG;
  302. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  303. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  304. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  305. MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
  306. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  307. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  308. MACRO_ATTRREAD_LOOPEND;
  309. // if "USE" defined then find already defined element.
  310. if(!use.empty())
  311. {
  312. MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleSet, ne);
  313. }
  314. else
  315. {
  316. // check data
  317. if(index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute.");
  318. // create and if needed - define new geometry object.
  319. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleSet, NodeElement_Cur);
  320. if(!def.empty()) ne->ID = def;
  321. CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
  322. ne_alias.CCW = ccw;
  323. ne_alias.ColorPerVertex = colorPerVertex;
  324. ne_alias.CoordIndex = index;
  325. ne_alias.NormalPerVertex = normalPerVertex;
  326. ne_alias.Solid = solid;
  327. // check for child nodes
  328. if(!mReader->isEmptyElement())
  329. {
  330. ParseHelper_Node_Enter(ne);
  331. MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleSet");
  332. // check for X3DComposedGeometryNodes
  333. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  334. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  335. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  336. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  337. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  338. // check for X3DMetadataObject
  339. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleSet");
  340. MACRO_NODECHECK_LOOPEND("IndexedTriangleSet");
  341. ParseHelper_Node_Exit();
  342. }// if(!mReader->isEmptyElement())
  343. else
  344. {
  345. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  346. }
  347. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  348. }// if(!use.empty()) else
  349. }
  350. // <IndexedTriangleStripSet
  351. // DEF="" ID
  352. // USE="" IDREF
  353. // ccw="true" SFBool [initializeOnly]
  354. // colorPerVertex="true" SFBool [initializeOnly]
  355. // index="" MFInt32 [initializeOnly]
  356. // normalPerVertex="true" SFBool [initializeOnly]
  357. // solid="true" SFBool [initializeOnly]
  358. // >
  359. // <!-- ComposedGeometryContentModel -->
  360. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  361. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  362. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  363. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  364. // </IndexedTriangleStripSet>
  365. void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
  366. {
  367. std::string use, def;
  368. bool ccw = true;
  369. bool colorPerVertex = true;
  370. std::list<int32_t> index;
  371. bool normalPerVertex = true;
  372. bool solid = true;
  373. CX3DImporter_NodeElement* ne( nullptr );
  374. MACRO_ATTRREAD_LOOPBEG;
  375. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  376. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  377. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  378. MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsListI32);
  379. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  380. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  381. MACRO_ATTRREAD_LOOPEND;
  382. // if "USE" defined then find already defined element.
  383. if(!use.empty())
  384. {
  385. MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleStripSet, ne);
  386. }
  387. else
  388. {
  389. // check data
  390. if(index.size() == 0) throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute.");
  391. // create and if needed - define new geometry object.
  392. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet, NodeElement_Cur);
  393. if(!def.empty()) ne->ID = def;
  394. CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
  395. ne_alias.CCW = ccw;
  396. ne_alias.ColorPerVertex = colorPerVertex;
  397. ne_alias.CoordIndex = index;
  398. ne_alias.NormalPerVertex = normalPerVertex;
  399. ne_alias.Solid = solid;
  400. // check for child nodes
  401. if(!mReader->isEmptyElement())
  402. {
  403. ParseHelper_Node_Enter(ne);
  404. MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleStripSet");
  405. // check for X3DComposedGeometryNodes
  406. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  407. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  408. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  409. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  410. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  411. // check for X3DMetadataObject
  412. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleStripSet");
  413. MACRO_NODECHECK_LOOPEND("IndexedTriangleStripSet");
  414. ParseHelper_Node_Exit();
  415. }// if(!mReader->isEmptyElement())
  416. else
  417. {
  418. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  419. }
  420. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  421. }// if(!use.empty()) else
  422. }
  423. // <LineSet
  424. // DEF="" ID
  425. // USE="" IDREF
  426. // vertexCount="" MFInt32 [initializeOnly]
  427. // >
  428. // <!-- ColorCoordinateContentModel -->
  429. // ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
  430. // contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
  431. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  432. // </LineSet>
  433. void X3DImporter::ParseNode_Rendering_LineSet()
  434. {
  435. std::string use, def;
  436. std::list<int32_t> vertexCount;
  437. CX3DImporter_NodeElement* ne( nullptr );
  438. MACRO_ATTRREAD_LOOPBEG;
  439. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  440. MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsListI32);
  441. MACRO_ATTRREAD_LOOPEND;
  442. // if "USE" defined then find already defined element.
  443. if(!use.empty())
  444. {
  445. MACRO_USE_CHECKANDAPPLY(def, use, ENET_LineSet, ne);
  446. }
  447. else
  448. {
  449. // check data
  450. if(vertexCount.size() == 0) throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute.");
  451. // create and if needed - define new geometry object.
  452. ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_LineSet, NodeElement_Cur);
  453. if(!def.empty()) ne->ID = def;
  454. CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
  455. ne_alias.VertexCount = vertexCount;
  456. // create CoordIdx
  457. size_t coord_num = 0;
  458. ne_alias.CoordIndex.clear();
  459. for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
  460. {
  461. if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
  462. for(int32_t i = 0; i < *vc_it; i++) ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num++));// add vertices indices
  463. ne_alias.CoordIndex.push_back(-1);// add face delimiter.
  464. }
  465. // check for child nodes
  466. if(!mReader->isEmptyElement())
  467. {
  468. ParseHelper_Node_Enter(ne);
  469. MACRO_NODECHECK_LOOPBEGIN("LineSet");
  470. // check for X3DComposedGeometryNodes
  471. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  472. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  473. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  474. // check for X3DMetadataObject
  475. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("LineSet");
  476. MACRO_NODECHECK_LOOPEND("LineSet");
  477. ParseHelper_Node_Exit();
  478. }// if(!mReader->isEmptyElement())
  479. else
  480. {
  481. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  482. }
  483. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  484. }// if(!use.empty()) else
  485. }
  486. // <PointSet
  487. // DEF="" ID
  488. // USE="" IDREF
  489. // >
  490. // <!-- ColorCoordinateContentModel -->
  491. // ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
  492. // contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
  493. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  494. // </PointSet>
  495. void X3DImporter::ParseNode_Rendering_PointSet()
  496. {
  497. std::string use, def;
  498. CX3DImporter_NodeElement* ne( nullptr );
  499. MACRO_ATTRREAD_LOOPBEG;
  500. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  501. MACRO_ATTRREAD_LOOPEND;
  502. // if "USE" defined then find already defined element.
  503. if(!use.empty())
  504. {
  505. MACRO_USE_CHECKANDAPPLY(def, use, ENET_PointSet, ne);
  506. }
  507. else
  508. {
  509. // create and if needed - define new geometry object.
  510. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_PointSet, NodeElement_Cur);
  511. if(!def.empty()) ne->ID = def;
  512. // check for child nodes
  513. if(!mReader->isEmptyElement())
  514. {
  515. ParseHelper_Node_Enter(ne);
  516. MACRO_NODECHECK_LOOPBEGIN("PointSet");
  517. // check for X3DComposedGeometryNodes
  518. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  519. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  520. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  521. // check for X3DMetadataObject
  522. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("PointSet");
  523. MACRO_NODECHECK_LOOPEND("PointSet");
  524. ParseHelper_Node_Exit();
  525. }// if(!mReader->isEmptyElement())
  526. else
  527. {
  528. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  529. }
  530. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  531. }// if(!use.empty()) else
  532. }
  533. // <TriangleFanSet
  534. // DEF="" ID
  535. // USE="" IDREF
  536. // ccw="true" SFBool [initializeOnly]
  537. // colorPerVertex="true" SFBool [initializeOnly]
  538. // fanCount="" MFInt32 [inputOutput]
  539. // normalPerVertex="true" SFBool [initializeOnly]
  540. // solid="true" SFBool [initializeOnly]
  541. // >
  542. // <!-- ComposedGeometryContentModel -->
  543. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  544. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  545. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  546. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  547. // </TriangleFanSet>
  548. void X3DImporter::ParseNode_Rendering_TriangleFanSet()
  549. {
  550. std::string use, def;
  551. bool ccw = true;
  552. bool colorPerVertex = true;
  553. std::list<int32_t> fanCount;
  554. bool normalPerVertex = true;
  555. bool solid = true;
  556. CX3DImporter_NodeElement* ne( nullptr );
  557. MACRO_ATTRREAD_LOOPBEG;
  558. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  559. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  560. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  561. MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsListI32);
  562. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  563. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  564. MACRO_ATTRREAD_LOOPEND;
  565. // if "USE" defined then find already defined element.
  566. if(!use.empty())
  567. {
  568. MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleFanSet, ne);
  569. }
  570. else
  571. {
  572. // check data
  573. if(fanCount.size() == 0) throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute.");
  574. // create and if needed - define new geometry object.
  575. ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_TriangleFanSet, NodeElement_Cur);
  576. if(!def.empty()) ne->ID = def;
  577. CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
  578. ne_alias.CCW = ccw;
  579. ne_alias.ColorPerVertex = colorPerVertex;
  580. ne_alias.VertexCount = fanCount;
  581. ne_alias.NormalPerVertex = normalPerVertex;
  582. ne_alias.Solid = solid;
  583. // create CoordIdx
  584. size_t coord_num_first, coord_num_prev;
  585. ne_alias.CoordIndex.clear();
  586. // assign indices for first triangle
  587. coord_num_first = 0;
  588. coord_num_prev = 1;
  589. for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
  590. {
  591. if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
  592. for(int32_t vc = 2; vc < *vc_it; vc++)
  593. {
  594. if(ccw)
  595. {
  596. // 2 1
  597. // 0
  598. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_first));// first vertex is a center and always is [0].
  599. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev++));
  600. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev));
  601. }
  602. else
  603. {
  604. // 1 2
  605. // 0
  606. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_first));// first vertex is a center and always is [0].
  607. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev + 1));
  608. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev++));
  609. }// if(ccw) else
  610. ne_alias.CoordIndex.push_back(-1);// add face delimiter.
  611. }// for(int32_t vc = 2; vc < *vc_it; vc++)
  612. coord_num_prev++;// that index will be center of next fan
  613. coord_num_first = coord_num_prev++;// forward to next point - second point of fan
  614. }// for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
  615. // check for child nodes
  616. if(!mReader->isEmptyElement())
  617. {
  618. ParseHelper_Node_Enter(ne);
  619. MACRO_NODECHECK_LOOPBEGIN("TriangleFanSet");
  620. // check for X3DComposedGeometryNodes
  621. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  622. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  623. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  624. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  625. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  626. // check for X3DMetadataObject
  627. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleFanSet");
  628. MACRO_NODECHECK_LOOPEND("TriangleFanSet");
  629. ParseHelper_Node_Exit();
  630. }// if(!mReader->isEmptyElement())
  631. else
  632. {
  633. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  634. }
  635. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  636. }// if(!use.empty()) else
  637. }
  638. // <TriangleSet
  639. // DEF="" ID
  640. // USE="" IDREF
  641. // ccw="true" SFBool [initializeOnly]
  642. // colorPerVertex="true" SFBool [initializeOnly]
  643. // normalPerVertex="true" SFBool [initializeOnly]
  644. // solid="true" SFBool [initializeOnly]
  645. // >
  646. // <!-- ComposedGeometryContentModel -->
  647. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  648. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  649. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  650. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  651. // </TriangleSet>
  652. void X3DImporter::ParseNode_Rendering_TriangleSet()
  653. {
  654. std::string use, def;
  655. bool ccw = true;
  656. bool colorPerVertex = true;
  657. bool normalPerVertex = true;
  658. bool solid = true;
  659. CX3DImporter_NodeElement* ne( nullptr );
  660. MACRO_ATTRREAD_LOOPBEG;
  661. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  662. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  663. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  664. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  665. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  666. MACRO_ATTRREAD_LOOPEND;
  667. // if "USE" defined then find already defined element.
  668. if(!use.empty())
  669. {
  670. MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet, ne);
  671. }
  672. else
  673. {
  674. // create and if needed - define new geometry object.
  675. ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_TriangleSet, NodeElement_Cur);
  676. if(!def.empty()) ne->ID = def;
  677. CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
  678. ne_alias.CCW = ccw;
  679. ne_alias.ColorPerVertex = colorPerVertex;
  680. ne_alias.NormalPerVertex = normalPerVertex;
  681. ne_alias.Solid = solid;
  682. // check for child nodes
  683. if(!mReader->isEmptyElement())
  684. {
  685. ParseHelper_Node_Enter(ne);
  686. MACRO_NODECHECK_LOOPBEGIN("TriangleSet");
  687. // check for X3DComposedGeometryNodes
  688. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  689. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  690. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  691. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  692. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  693. // check for X3DMetadataObject
  694. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleSet");
  695. MACRO_NODECHECK_LOOPEND("TriangleSet");
  696. ParseHelper_Node_Exit();
  697. }// if(!mReader->isEmptyElement())
  698. else
  699. {
  700. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  701. }
  702. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  703. }// if(!use.empty()) else
  704. }
  705. // <TriangleStripSet
  706. // DEF="" ID
  707. // USE="" IDREF
  708. // ccw="true" SFBool [initializeOnly]
  709. // colorPerVertex="true" SFBool [initializeOnly]
  710. // normalPerVertex="true" SFBool [initializeOnly]
  711. // solid="true" SFBool [initializeOnly]
  712. // stripCount="" MFInt32 [inputOutput]
  713. // >
  714. // <!-- ComposedGeometryContentModel -->
  715. // ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
  716. // Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
  717. // Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
  718. // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
  719. // </TriangleStripSet>
  720. void X3DImporter::ParseNode_Rendering_TriangleStripSet()
  721. {
  722. std::string use, def;
  723. bool ccw = true;
  724. bool colorPerVertex = true;
  725. std::list<int32_t> stripCount;
  726. bool normalPerVertex = true;
  727. bool solid = true;
  728. CX3DImporter_NodeElement* ne( nullptr );
  729. MACRO_ATTRREAD_LOOPBEG;
  730. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  731. MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
  732. MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  733. MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsListI32);
  734. MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
  735. MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
  736. MACRO_ATTRREAD_LOOPEND;
  737. // if "USE" defined then find already defined element.
  738. if(!use.empty())
  739. {
  740. MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleStripSet, ne);
  741. }
  742. else
  743. {
  744. // check data
  745. if(stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute.");
  746. // create and if needed - define new geometry object.
  747. ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_TriangleStripSet, NodeElement_Cur);
  748. if(!def.empty()) ne->ID = def;
  749. CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
  750. ne_alias.CCW = ccw;
  751. ne_alias.ColorPerVertex = colorPerVertex;
  752. ne_alias.VertexCount = stripCount;
  753. ne_alias.NormalPerVertex = normalPerVertex;
  754. ne_alias.Solid = solid;
  755. // create CoordIdx
  756. size_t coord_num0, coord_num1, coord_num2;// indices of current triangle
  757. bool odd_tri;// sequence of current triangle
  758. size_t coord_num_sb;// index of first point of strip
  759. ne_alias.CoordIndex.clear();
  760. coord_num_sb = 0;
  761. for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
  762. {
  763. if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");
  764. // set initial values for first triangle
  765. coord_num0 = coord_num_sb;
  766. coord_num1 = coord_num_sb + 1;
  767. coord_num2 = coord_num_sb + 2;
  768. odd_tri = true;
  769. for(int32_t vc = 2; vc < *vc_it; vc++)
  770. {
  771. if(ccw)
  772. {
  773. // 0 2
  774. // 1
  775. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num0));
  776. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num1));
  777. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num2));
  778. }
  779. else
  780. {
  781. // 0 1
  782. // 2
  783. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num0));
  784. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num2));
  785. ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num1));
  786. }// if(ccw) else
  787. ne_alias.CoordIndex.push_back(-1);// add face delimiter.
  788. // prepare values for next triangle
  789. if(odd_tri)
  790. {
  791. coord_num0 = coord_num2;
  792. coord_num2++;
  793. }
  794. else
  795. {
  796. coord_num1 = coord_num2;
  797. coord_num2 = coord_num1 + 1;
  798. }
  799. odd_tri = !odd_tri;
  800. coord_num_sb = coord_num2;// that index will be start of next strip
  801. }// for(int32_t vc = 2; vc < *vc_it; vc++)
  802. }// for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
  803. // check for child nodes
  804. if(!mReader->isEmptyElement())
  805. {
  806. ParseHelper_Node_Enter(ne);
  807. MACRO_NODECHECK_LOOPBEGIN("TriangleStripSet");
  808. // check for X3DComposedGeometryNodes
  809. if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
  810. if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
  811. if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
  812. if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
  813. if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
  814. // check for X3DMetadataObject
  815. if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleStripSet");
  816. MACRO_NODECHECK_LOOPEND("TriangleStripSet");
  817. ParseHelper_Node_Exit();
  818. }// if(!mReader->isEmptyElement())
  819. else
  820. {
  821. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  822. }
  823. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  824. }// if(!use.empty()) else
  825. }
  826. // <Normal
  827. // DEF="" ID
  828. // USE="" IDREF
  829. // vector="" MFVec3f [inputOutput]
  830. // />
  831. void X3DImporter::ParseNode_Rendering_Normal()
  832. {
  833. std::string use, def;
  834. std::list<aiVector3D> vector;
  835. CX3DImporter_NodeElement* ne;
  836. MACRO_ATTRREAD_LOOPBEG;
  837. MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
  838. MACRO_ATTRREAD_CHECK_REF("vector", vector, XML_ReadNode_GetAttrVal_AsListVec3f);
  839. MACRO_ATTRREAD_LOOPEND;
  840. // if "USE" defined then find already defined element.
  841. if(!use.empty())
  842. {
  843. MACRO_USE_CHECKANDAPPLY(def, use, ENET_Normal, ne);
  844. }
  845. else
  846. {
  847. // create and if needed - define new geometry object.
  848. ne = new CX3DImporter_NodeElement_Normal(NodeElement_Cur);
  849. if(!def.empty()) ne->ID = def;
  850. ((CX3DImporter_NodeElement_Normal*)ne)->Value = vector;
  851. // check for X3DMetadataObject childs.
  852. if(!mReader->isEmptyElement())
  853. ParseNode_Metadata(ne, "Normal");
  854. else
  855. NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
  856. NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
  857. }// if(!use.empty()) else
  858. }
  859. }// namespace Assimp
  860. #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER