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_Macro.hpp
42/// \brief Useful macrodefines.
43/// \date 2015-2016
44/// \author smal.root@gmail.com
45
46#ifndef X3DIMPORTER_MACRO_HPP_INCLUDED
47#define X3DIMPORTER_MACRO_HPP_INCLUDED
48
49/// \def MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pNE)
50/// Used for regular checking while attribute "USE" is defined.
51/// \param [in] pDEF - string holding "DEF" value.
52/// \param [in] pUSE - string holding "USE" value.
53/// \param [in] pType - type of element to find.
54/// \param [out] pNE - pointer to found node element.
55#define MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pType, pNE) \
56 do { \
57 XML_CheckNode_MustBeEmpty(); \
58 if(!pDEF.empty()) Throw_DEF_And_USE(); \
59 if(!FindNodeElement(pUSE, CX3DImporter_NodeElement::pType, &pNE)) Throw_USE_NotFound(pUSE); \
60 \
61 NodeElement_Cur->Child.push_back(pNE);/* add found object as child to current element */ \
62 } while(false)
63
64/// \def MACRO_ATTRREAD_LOOPBEG
65/// Begin of loop that read attributes values.
66#define MACRO_ATTRREAD_LOOPBEG \
67 for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
68 { \
69 std::string an(mReader->getAttributeName(idx));
70
71/// \def MACRO_ATTRREAD_LOOPEND
72/// End of loop that read attributes values.
73#define MACRO_ATTRREAD_LOOPEND \
74 Throw_IncorrectAttr(an); \
75 }
76
77/// \def MACRO_ATTRREAD_CHECK_REF
78/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
79/// "continue" will called.
80/// \param [in] pAttrName - attribute name.
81/// \param [out] pVarName - output variable name.
82/// \param [in] pFunction - function which read attribute value and write it to pVarName.
83#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
84 if(an == pAttrName) \
85 { \
86 pFunction(idx, pVarName); \
87 continue; \
88 }
89
90/// \def MACRO_ATTRREAD_CHECK_RET
91/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
92/// If result was read then "continue" will called.
93/// \param [in] pAttrName - attribute name.
94/// \param [out] pVarName - output variable name.
95/// \param [in] pFunction - function which read attribute value and write it to pVarName.
96#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
97 if(an == pAttrName) \
98 { \
99 pVarName = pFunction(idx); \
100 continue; \
101 }
102
103/// \def MACRO_ATTRREAD_CHECKUSEDEF_RET
104/// Compact variant for checking "USE" and "DEF". Also skip bbox attributes: "bboxCenter", "bboxSize".
105/// If result was read then "continue" will called.
106/// \param [out] pDEF_Var - output variable name for "DEF" value.
107/// \param [out] pUSE_Var - output variable name for "USE" value.
108#define MACRO_ATTRREAD_CHECKUSEDEF_RET(pDEF_Var, pUSE_Var) \
109 MACRO_ATTRREAD_CHECK_RET("DEF", pDEF_Var, mReader->getAttributeValue); \
110 MACRO_ATTRREAD_CHECK_RET("USE", pUSE_Var, mReader->getAttributeValue); \
111 if(an == "bboxCenter") continue; \
112 if(an == "bboxSize") continue; \
113 if(an == "containerField") continue; \
114 do {} while(false)
115
116/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
117/// Begin of loop of parsing child nodes. Do not add ';' at end.
118/// \param [in] pNodeName - current node name.
119#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
120 do { \
121 bool close_found = false; \
122 \
123 while(mReader->read()) \
124 { \
125 if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
126 {
127
128/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
129/// End of loop of parsing child nodes.
130/// \param [in] pNodeName - current node name.
131#define MACRO_NODECHECK_LOOPEND(pNodeName) \
132 }/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
133 else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
134 { \
135 if(XML_CheckNode_NameEqual(pNodeName)) \
136 { \
137 close_found = true; \
138 \
139 break; \
140 } \
141 }/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
142 }/* while(mReader->read()) */ \
143 \
144 if(!close_found) Throw_CloseNotFound(pNodeName); \
145 \
146 } while(false)
147
148#define MACRO_NODECHECK_METADATA(pNodeName) \
149 MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
150 /* and childs must be metadata nodes */ \
151 if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported(pNodeName); \
152 MACRO_NODECHECK_LOOPEND(pNodeName)
153
154/// \def MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4)
155/// Add points as quad. Means that pP1..pP4 set in CCW order.
156#define MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4) \
157 do { \
158 if(pCCW) \
159 { \
160 pOut.push_back(pIn[pP1]); \
161 pOut.push_back(pIn[pP2]); \
162 pOut.push_back(pIn[pP3]); \
163 pOut.push_back(pIn[pP4]); \
164 } \
165 else \
166 { \
167 pOut.push_back(pIn[pP4]); \
168 pOut.push_back(pIn[pP3]); \
169 pOut.push_back(pIn[pP2]); \
170 pOut.push_back(pIn[pP1]); \
171 } \
172 } while(false)
173
174/// \def MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4)
175/// Add points as quad. Means that pP1..pP4 set in CCW order.
176#define MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4) \
177 do { \
178 if(pCCW) \
179 { \
180 pOut.push_back(pP1); \
181 pOut.push_back(pP2); \
182 pOut.push_back(pP3); \
183 pOut.push_back(pP4); \
184 } \
185 else \
186 { \
187 pOut.push_back(pP4); \
188 pOut.push_back(pP3); \
189 pOut.push_back(pP2); \
190 pOut.push_back(pP1); \
191 } \
192 } while(false)
193
194#endif // X3DIMPORTER_MACRO_HPP_INCLUDED
195