1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14copyright notice, this list of conditions and the
15following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18copyright notice, this list of conditions and the
19following disclaimer in the documentation and/or other
20materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23contributors may be used to endorse or promote products
24derived from this software without specific prior
25written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41/// \file X3DImporter_Metadata.cpp
42/// \brief Parsing data from nodes of "Metadata" set of X3D.
43/// \date 2015-2016
44/// \author smal.root@gmail.com
45
46#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
47
48#include "X3DImporter.hpp"
49#include "X3DImporter_Macro.hpp"
50
51namespace Assimp
52{
53
54/// \def MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaName)
55/// Find element by "USE" or create new one.
56/// \param [in] pDEF_Var - variable name with "DEF" value.
57/// \param [in] pUSE_Var - variable name with "USE" value.
58/// \param [in] pReference - variable name with "reference" value.
59/// \param [in] pValue - variable name with "value" value.
60/// \param [in, out] pNE - pointer to node element.
61/// \param [in] pMetaClass - Class of node.
62/// \param [in] pMetaName - Name of node.
63/// \param [in] pType - type of element to find.
64#define MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \
65 /* if "USE" defined then find already defined element. */ \
66 if(!pUSE_Var.empty()) \
67 { \
68 MACRO_USE_CHECKANDAPPLY(pDEF_Var, pUSE_Var, pType, pNE); \
69 } \
70 else \
71 { \
72 pNE = new pMetaClass(NodeElement_Cur); \
73 if(!pDEF_Var.empty()) pNE->ID = pDEF_Var; \
74 \
75 ((pMetaClass*)pNE)->Reference = pReference; \
76 ((pMetaClass*)pNE)->Value = pValue; \
77 /* also metadata node can contain childs */ \
78 if(!mReader->isEmptyElement()) \
79 ParseNode_Metadata(pNE, pMetaName);/* in that case node element will be added to child elements list of current node. */ \
80 else \
81 NodeElement_Cur->Child.push_back(pNE);/* else - add element to child list manualy */ \
82 \
83 NodeElement_List.push_back(pNE);/* add new element to elements list. */ \
84 }/* if(!pUSE_Var.empty()) else */ \
85 \
86 do {} while(false)
87
88bool X3DImporter::ParseHelper_CheckRead_X3DMetadataObject()
89{
90 if(XML_CheckNode_NameEqual("MetadataBoolean"))
91 ParseNode_MetadataBoolean();
92 else if(XML_CheckNode_NameEqual("MetadataDouble"))
93 ParseNode_MetadataDouble();
94 else if(XML_CheckNode_NameEqual("MetadataFloat"))
95 ParseNode_MetadataFloat();
96 else if(XML_CheckNode_NameEqual("MetadataInteger"))
97 ParseNode_MetadataInteger();
98 else if(XML_CheckNode_NameEqual("MetadataSet"))
99 ParseNode_MetadataSet();
100 else if(XML_CheckNode_NameEqual("MetadataString"))
101 ParseNode_MetadataString();
102 else
103 return false;
104
105 return true;
106}
107
108void X3DImporter::ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& /*pNodeName*/)
109{
110 ParseHelper_Node_Enter(pParentElement);
111 MACRO_NODECHECK_METADATA(mReader->getNodeName());
112 ParseHelper_Node_Exit();
113}
114
115// <MetadataBoolean
116// DEF="" ID
117// USE="" IDREF
118// name="" SFString [inputOutput]
119// reference="" SFString [inputOutput]
120// value="" MFBool [inputOutput]
121// />
122void X3DImporter::ParseNode_MetadataBoolean()
123{
124 std::string def, use;
125 std::string name, reference;
126 std::vector<bool> value;
127 CX3DImporter_NodeElement* ne( nullptr );
128
129 MACRO_ATTRREAD_LOOPBEG;
130 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
131 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
132 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
133 MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrB);
134 MACRO_ATTRREAD_LOOPEND;
135
136 MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaBoolean, "MetadataBoolean", ENET_MetaBoolean);
137}
138
139// <MetadataDouble
140// DEF="" ID
141// USE="" IDREF
142// name="" SFString [inputOutput]
143// reference="" SFString [inputOutput]
144// value="" MFDouble [inputOutput]
145// />
146void X3DImporter::ParseNode_MetadataDouble()
147{
148 std::string def, use;
149 std::string name, reference;
150 std::vector<double> value;
151 CX3DImporter_NodeElement* ne( nullptr );
152
153 MACRO_ATTRREAD_LOOPBEG;
154 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
155 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
156 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
157 MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrD);
158 MACRO_ATTRREAD_LOOPEND;
159
160 MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaDouble, "MetadataDouble", ENET_MetaDouble);
161}
162
163// <MetadataFloat
164// DEF="" ID
165// USE="" IDREF
166// name="" SFString [inputOutput]
167// reference="" SFString [inputOutput]
168// value="" MFFloat [inputOutput]
169// />
170void X3DImporter::ParseNode_MetadataFloat()
171{
172 std::string def, use;
173 std::string name, reference;
174 std::vector<float> value;
175 CX3DImporter_NodeElement* ne( nullptr );
176
177 MACRO_ATTRREAD_LOOPBEG;
178 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
179 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
180 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
181 MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrF);
182 MACRO_ATTRREAD_LOOPEND;
183
184 MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaFloat, "MetadataFloat", ENET_MetaFloat);
185}
186
187// <MetadataInteger
188// DEF="" ID
189// USE="" IDREF
190// name="" SFString [inputOutput]
191// reference="" SFString [inputOutput]
192// value="" MFInteger [inputOutput]
193// />
194void X3DImporter::ParseNode_MetadataInteger()
195{
196 std::string def, use;
197 std::string name, reference;
198 std::vector<int32_t> value;
199 CX3DImporter_NodeElement* ne( nullptr );
200
201 MACRO_ATTRREAD_LOOPBEG;
202 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
203 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
204 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
205 MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrI32);
206 MACRO_ATTRREAD_LOOPEND;
207
208 MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaInteger, "MetadataInteger", ENET_MetaInteger);
209}
210
211// <MetadataSet
212// DEF="" ID
213// USE="" IDREF
214// name="" SFString [inputOutput]
215// reference="" SFString [inputOutput]
216// />
217void X3DImporter::ParseNode_MetadataSet()
218{
219 std::string def, use;
220 std::string name, reference;
221 CX3DImporter_NodeElement* ne( nullptr );
222
223 MACRO_ATTRREAD_LOOPBEG;
224 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
225 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
226 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
227 MACRO_ATTRREAD_LOOPEND;
228
229 // if "USE" defined then find already defined element.
230 if(!use.empty())
231 {
232 MACRO_USE_CHECKANDAPPLY(def, use, ENET_MetaSet, ne);
233 }
234 else
235 {
236 ne = new CX3DImporter_NodeElement_MetaSet(NodeElement_Cur);
237 if(!def.empty()) ne->ID = def;
238
239 ((CX3DImporter_NodeElement_MetaSet*)ne)->Reference = reference;
240 // also metadata node can contain childs
241 if(!mReader->isEmptyElement())
242 ParseNode_Metadata(ne, "MetadataSet");
243 else
244 NodeElement_Cur->Child.push_back(ne);// made object as child to current element
245
246 NodeElement_List.push_back(ne);// add new element to elements list.
247 }// if(!use.empty()) else
248}
249
250// <MetadataString
251// DEF="" ID
252// USE="" IDREF
253// name="" SFString [inputOutput]
254// reference="" SFString [inputOutput]
255// value="" MFString [inputOutput]
256// />
257void X3DImporter::ParseNode_MetadataString()
258{
259 std::string def, use;
260 std::string name, reference;
261 std::list<std::string> value;
262 CX3DImporter_NodeElement* ne( nullptr );
263
264 MACRO_ATTRREAD_LOOPBEG;
265 MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
266 MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
267 MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
268 MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListS);
269 MACRO_ATTRREAD_LOOPEND;
270
271 MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaString, "MetadataString", ENET_MetaString);
272}
273
274}// namespace Assimp
275
276#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
277