X3DImporter_Rendering.cpp 36 KB

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