1 #include "X3DXmlHelper.h"
2 #include "X3DImporter.hpp"
3 
4 #include <assimp/ParsingUtils.h>
5 
6 namespace Assimp {
7 
getColor3DAttribute(XmlNode & node,const char * attributeName,aiColor3D & color)8 bool X3DXmlHelper::getColor3DAttribute(XmlNode &node, const char *attributeName, aiColor3D &color) {
9     std::string val;
10     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
11         std::vector<std::string> values;
12         tokenize<std::string>(val, values, " ");
13         if (values.size() != 3) {
14             Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
15             return false;
16         }
17         auto it = values.begin();
18         color.r = stof(*it++);
19         color.g = stof(*it++);
20         color.b = stof(*it);
21         return true;
22     }
23     return false;
24 }
25 
getVector2DAttribute(XmlNode & node,const char * attributeName,aiVector2D & color)26 bool X3DXmlHelper::getVector2DAttribute(XmlNode &node, const char *attributeName, aiVector2D &color) {
27     std::string val;
28     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
29         std::vector<std::string> values;
30         tokenize<std::string>(val, values, " ");
31         if (values.size() != 2) {
32             Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
33             return false;
34         }
35         auto it = values.begin();
36         color.x = stof(*it++);
37         color.y = stof(*it);
38         return true;
39     }
40     return false;
41 }
42 
getVector3DAttribute(XmlNode & node,const char * attributeName,aiVector3D & color)43 bool X3DXmlHelper::getVector3DAttribute(XmlNode &node, const char *attributeName, aiVector3D &color) {
44     std::string val;
45     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
46         std::vector<std::string> values;
47         tokenize<std::string>(val, values, " ");
48         if (values.size() != 3) {
49             Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
50             return false;
51         }
52         auto it = values.begin();
53         color.x = stof(*it++);
54         color.y = stof(*it++);
55         color.z = stof(*it);
56         return true;
57     }
58     return false;
59 }
60 
getBooleanArrayAttribute(XmlNode & node,const char * attributeName,std::vector<bool> & boolArray)61 bool X3DXmlHelper::getBooleanArrayAttribute(XmlNode &node, const char *attributeName, std::vector<bool> &boolArray) {
62     std::string val;
63     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
64         std::vector<std::string> values;
65         tokenize<std::string>(val, values, " ");
66         auto it = values.begin();
67         while (it != values.end()) {
68             auto s = *it++;
69             if (!s.empty())
70                 boolArray.push_back(s[0] == 't' || s[0] == '1');
71             else
72                 Throw_ConvertFail_Str2ArrB(node.name(), attributeName);
73         }
74         return true;
75     }
76     return false;
77 }
78 
getDoubleArrayAttribute(XmlNode & node,const char * attributeName,std::vector<double> & doubleArray)79 bool X3DXmlHelper::getDoubleArrayAttribute(XmlNode &node, const char *attributeName, std::vector<double> &doubleArray) {
80     std::string val;
81     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
82         std::vector<std::string> values;
83         tokenize<std::string>(val, values, " ");
84         auto it = values.begin();
85         while (it != values.end()) {
86             auto s = *it++;
87             if (!s.empty())
88                 doubleArray.push_back(atof(s.c_str()));
89             else
90                 Throw_ConvertFail_Str2ArrD(node.name(), attributeName);
91         }
92         return true;
93     }
94     return false;
95 }
96 
getFloatArrayAttribute(XmlNode & node,const char * attributeName,std::vector<float> & floatArray)97 bool X3DXmlHelper::getFloatArrayAttribute(XmlNode &node, const char *attributeName, std::vector<float> &floatArray) {
98     std::string val;
99     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
100         std::vector<std::string> values;
101         tokenize<std::string>(val, values, " ");
102         auto it = values.begin();
103         while (it != values.end()) {
104             auto s = *it++;
105             if (!s.empty())
106                 floatArray.push_back((float)atof(s.c_str()));
107             else
108                 Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
109         }
110         return true;
111     }
112     return false;
113 }
114 
getInt32ArrayAttribute(XmlNode & node,const char * attributeName,std::vector<int32_t> & intArray)115 bool X3DXmlHelper::getInt32ArrayAttribute(XmlNode &node, const char *attributeName, std::vector<int32_t> &intArray) {
116     std::string val;
117     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
118         std::vector<std::string> values;
119         tokenize<std::string>(val, values, " ");
120         auto it = values.begin();
121         while (it != values.end()) {
122             auto s = *it++;
123             if (!s.empty())
124                 intArray.push_back((int32_t)atof(s.c_str()));
125             else
126                 Throw_ConvertFail_Str2ArrI(node.name(), attributeName);
127         }
128         return true;
129     }
130     return false;
131 }
132 
getStringListAttribute(XmlNode & node,const char * attributeName,std::list<std::string> & stringList)133 bool X3DXmlHelper::getStringListAttribute(XmlNode &node, const char *attributeName, std::list<std::string> &stringList) {
134     std::string val;
135     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
136         std::vector<std::string> values;
137         tokenize<std::string>(val, values, " ");
138         auto it = values.begin();
139         std::string currentConcat = "";
140         bool inQuotes = false;
141         while (it != values.end()) {
142             auto s = *it++;
143             if (!s.empty()) {
144                 if (inQuotes) {
145                     if (*(s.rbegin()) == '"') {
146                         stringList.push_back(currentConcat + s.substr(0, s.length() - 1));
147                         currentConcat = "";
148                         inQuotes = false;
149                     } else {
150                         currentConcat += " " + s;
151                     }
152                 } else {
153                     if (s[0] == '"') {
154                         currentConcat = s.substr(1);
155                         inQuotes = true;
156                     } else {
157                         stringList.push_back(s);
158                     }
159                 }
160             } else if (!inQuotes)
161                 Throw_ConvertFail_Str2ArrI(node.name(), attributeName);
162         }
163         if (inQuotes) Throw_ConvertFail_Str2ArrI(node.name(), attributeName);
164         return true;
165     }
166     return false;
167 }
168 
getStringArrayAttribute(XmlNode & node,const char * attributeName,std::vector<std::string> & stringArray)169 bool X3DXmlHelper::getStringArrayAttribute(XmlNode &node, const char *attributeName, std::vector<std::string> &stringArray) {
170     std::list<std::string> tlist;
171 
172     if (getStringListAttribute(node, attributeName, tlist)) {
173         if (!tlist.empty()) {
174             stringArray.reserve(tlist.size());
175             for (std::list<std::string>::iterator it = tlist.begin(); it != tlist.end(); ++it) {
176                 stringArray.push_back(*it);
177             }
178             return true;
179         }
180     }
181     return false;
182 }
183 
getVector2DListAttribute(XmlNode & node,const char * attributeName,std::list<aiVector2D> & vectorList)184 bool X3DXmlHelper::getVector2DListAttribute(XmlNode &node, const char *attributeName, std::list<aiVector2D> &vectorList) {
185     std::string val;
186     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
187         std::vector<std::string> values;
188         tokenize<std::string>(val, values, " ");
189         if (values.size() % 2) Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
190         auto it = values.begin();
191         while (it != values.end()) {
192             aiVector2D tvec;
193 
194             tvec.x = (float)atof((*it++).c_str());
195             tvec.y = (float)atof((*it++).c_str());
196             vectorList.push_back(tvec);
197         }
198         return true;
199     }
200     return false;
201 }
202 
getVector2DArrayAttribute(XmlNode & node,const char * attributeName,std::vector<aiVector2D> & vectorArray)203 bool X3DXmlHelper::getVector2DArrayAttribute(XmlNode &node, const char *attributeName, std::vector<aiVector2D> &vectorArray) {
204     std::list<aiVector2D> tlist;
205 
206     if (getVector2DListAttribute(node, attributeName, tlist)) {
207         if (!tlist.empty()) {
208             vectorArray.reserve(tlist.size());
209             for (std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); ++it) {
210                 vectorArray.push_back(*it);
211             }
212             return true;
213         }
214     }
215     return false;
216 }
217 
getVector3DListAttribute(XmlNode & node,const char * attributeName,std::list<aiVector3D> & vectorList)218 bool X3DXmlHelper::getVector3DListAttribute(XmlNode &node, const char *attributeName, std::list<aiVector3D> &vectorList) {
219     std::string val;
220     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
221         std::vector<std::string> values;
222         tokenize<std::string>(val, values, " ");
223         if (values.size() % 3 != 0) Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
224         auto it = values.begin();
225         while (it != values.end()) {
226             aiVector3D tvec;
227 
228             tvec.x = (float)atof((*it++).c_str());
229             tvec.y = (float)atof((*it++).c_str());
230             tvec.z = (float)atof((*it++).c_str());
231             vectorList.push_back(tvec);
232         }
233         return true;
234     }
235     return false;
236 }
237 
getVector3DArrayAttribute(XmlNode & node,const char * attributeName,std::vector<aiVector3D> & vectorArray)238 bool X3DXmlHelper::getVector3DArrayAttribute(XmlNode &node, const char *attributeName, std::vector<aiVector3D> &vectorArray) {
239     std::list<aiVector3D> tlist;
240 
241     if (getVector3DListAttribute(node, attributeName, tlist)) {
242         if (!tlist.empty()) {
243             vectorArray.reserve(tlist.size());
244             for (std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) {
245                 vectorArray.push_back(*it);
246             }
247             return true;
248         }
249     }
250     return false;
251 }
252 
getColor3DListAttribute(XmlNode & node,const char * attributeName,std::list<aiColor3D> & colorList)253 bool X3DXmlHelper::getColor3DListAttribute(XmlNode &node, const char *attributeName, std::list<aiColor3D> &colorList) {
254     std::string val;
255     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
256         std::vector<std::string> values;
257         tokenize<std::string>(val, values, " ");
258         if (values.size() % 3 != 0) Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
259         auto it = values.begin();
260         while (it != values.end()) {
261             aiColor3D tvec;
262 
263             tvec.r = (float)atof((*it++).c_str());
264             tvec.g = (float)atof((*it++).c_str());
265             tvec.b = (float)atof((*it++).c_str());
266             colorList.push_back(tvec);
267         }
268         return true;
269     }
270     return false;
271 }
272 
getColor4DListAttribute(XmlNode & node,const char * attributeName,std::list<aiColor4D> & colorList)273 bool X3DXmlHelper::getColor4DListAttribute(XmlNode &node, const char *attributeName, std::list<aiColor4D> &colorList) {
274     std::string val;
275     if (XmlParser::getStdStrAttribute(node, attributeName, val)) {
276         std::vector<std::string> values;
277         tokenize<std::string>(val, values, " ");
278         if (values.size() % 4 != 0) Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
279         auto it = values.begin();
280         while (it != values.end()) {
281             aiColor4D tvec;
282 
283             tvec.r = (float)atof((*it++).c_str());
284             tvec.g = (float)atof((*it++).c_str());
285             tvec.b = (float)atof((*it++).c_str());
286             tvec.a = (float)atof((*it++).c_str());
287             colorList.push_back(tvec);
288         }
289         return true;
290     }
291     return false;
292 }
293 
294 } // namespace Assimp
295