1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4 
5 Copyright (c) 2006-2017, assimp team
6 
7 All rights reserved.
8 
9 Redistribution and use of this software in source and binary forms,
10 with or without modification, are permitted provided that the
11 following conditions are met:
12 
13 * Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16 
17 * Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21 
22 * Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26 
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF 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