31 #ifndef WFMATH_ATLAS_CONV_H
32 #define WFMATH_ATLAS_CONV_H
36 #include "quaternion.h"
47 #ifndef ATLAS_MESSAGE_ELEMENT_H
48 #error "You must include Atlas/Message/Element.h before wfmath/atlasconv.h"
51 typedef Atlas::Message::WrongTypeException _AtlasBadParse;
56 AtlasInType(
const Atlas::Message::Element& val) : m_val(val) {}
58 template<
class C>
AtlasInType(C c) : m_obj(c), m_val(m_obj) {}
59 operator const Atlas::Message::Element&()
const {
return m_val;}
60 bool IsList()
const {
return m_val.isList();}
61 const Atlas::Message::ListType& AsList()
const {
return m_val.asList();}
63 Atlas::Message::Element m_obj;
64 const Atlas::Message::Element& m_val;
70 AtlasOutType(
const Atlas::Message::ListType& l) : m_val(l) {}
71 AtlasOutType(
const Atlas::Message::MapType& l) : m_val(l) {}
72 operator Atlas::Message::Element&() {
return m_val;}
73 operator const Atlas::Message::Element&()
const {
return m_val;}
75 Atlas::Message::Element m_val;
80 Atlas::Message::ListType a(len);
82 for(
unsigned i = 0; i < len; ++i)
88 inline void _ArrayFromAtlas(
CoordType* array,
unsigned len,
const AtlasInType& a)
91 throw _AtlasBadParse();
93 const Atlas::Message::ListType& list(a.AsList());
95 if(list.size() != (
unsigned int) len)
96 throw _AtlasBadParse();
98 for(
unsigned i = 0; i < len; ++i)
99 array[i] =
static_cast<CoordType>(list[i].asNum());
111 _ArrayFromAtlas(m_elem, dim, a);
112 for (
int i = 0; i < dim; ++i) {
113 if (!std::isfinite(m_elem[i])) {
124 return _ArrayToAtlas(m_elem, dim);
130 throw _AtlasBadParse();
133 const Atlas::Message::ListType& list(a.AsList());
136 throw _AtlasBadParse();
139 for(
int i = 0; i < 3; ++i)
140 m_vec[i] =
static_cast<CoordType>(list[i].asNum());
142 for (
int i = 0; i < 3; ++i) {
143 if (!std::isfinite(m_vec[i])) {
150 m_w =
static_cast<CoordType>(list[3].asNum());
151 if (!std::isfinite(m_w)) {
174 Atlas::Message::ListType a(4);
176 for(
int i = 0; i < 3; ++i)
192 _ArrayFromAtlas(m_elem, dim, a);
193 for (
int i = 0; i < dim; ++i) {
194 if (!std::isfinite(m_elem[i])) {
205 return _ArrayToAtlas(m_elem, dim);
218 throw _AtlasBadParse();
220 const Atlas::Message::ListType& list(a.AsList());
222 switch(list.size()) {
228 for(
int i = 0; i < dim; ++i) {
229 m_low[i] = list[i].asNum();
230 if (!std::isfinite((m_low[i]))) {
231 m_low.setValid(
false);
234 m_high[i] = list[i+dim].asNum();
235 if (!std::isfinite((m_high[i]))) {
236 m_high.setValid(
false);
244 throw _AtlasBadParse();
247 for(
int i = 0; i < dim; ++i) {
248 if(m_low[i] > m_high[i]) {
250 m_low[i] = m_high[i];
261 for(i = 0; i < dim; ++i)
266 return m_high.toAtlas();
270 Atlas::Message::ListType a(2*dim);
271 for(i = 0; i < dim; ++i) {
273 a[dim+i] = m_high[i];
282 const Atlas::Message::Element& message(a);
283 if (message.isMap()) {
284 const Atlas::Message::MapType& shapeElement(message.asMap());
286 auto shape_I = shapeElement.find(
"radius");
287 if (shape_I != shapeElement.end()) {
288 const Atlas::Message::Element& shapeRadiusElem(shape_I->second);
289 if (shapeRadiusElem.isNum()) {
290 m_radius = shapeRadiusElem.asNum();
292 if (!std::isfinite(m_radius)) {
293 m_center.setValid(
false);
298 auto pos_I = shapeElement.find(
"position");
299 if (pos_I != shapeElement.end()) {
300 const Atlas::Message::Element& posElem(pos_I->second);
301 if (posElem.isList()) {
302 m_center.fromAtlas(posElem);
311 Atlas::Message::MapType map;
312 map.insert(Atlas::Message::MapType::value_type(
"radius", m_radius));
313 map.insert(Atlas::Message::MapType::value_type(
"position", m_center.toAtlas()));
324 inline bool _ListNumCheck(
const Atlas::Message::ListType & list,
int dim)
326 for(
int i = 0; i < dim; ++i) {
327 if (!list[i].isNum()) {
334 template<
template <
int>
class ShapeT>
335 inline void _AddCorner(ShapeT<3> & shape,
336 const Atlas::Message::ListType & point)
338 Point<3> wpt(point[0].asNum(), point[1].asNum(), point[2].asNum());
339 if (!std::isfinite(wpt.x()) || !std::isfinite(wpt.y()) || !std::isfinite(wpt.z())) {
342 shape.addCorner(shape.numCorners(), wpt);
345 template<
template <
int>
class ShapeT>
346 inline void _AddCorner(ShapeT<2> & shape,
347 const Atlas::Message::ListType & point)
349 Point<2> wpt(point[0].asNum(), point[1].asNum());
350 if (!std::isfinite(wpt.x()) || !std::isfinite(wpt.y())) {
353 shape.addCorner(shape.numCorners(), wpt);
356 template<
template <
int>
class ShapeT,
int dim>
357 inline void _CornersFromAtlas(ShapeT<dim> & shape,
358 const Atlas::Message::Element& message)
360 if (message.isList()) {
361 const Atlas::Message::ListType& pointsData(message.asList());
363 for (
const auto & p : pointsData) {
368 const Atlas::Message::ListType& point(p.asList());
369 if ((point.size() < dim) || !_ListNumCheck(point, dim)) {
373 _AddCorner(shape, point);
380 const Atlas::Message::Element& message(a);
381 if (message.isMap()) {
382 const Atlas::Message::MapType& shapeElement(message.asMap());
383 auto it = shapeElement.find(
"points");
384 if ((it != shapeElement.end()) && it->second.isList()) {
385 _CornersFromAtlas(*
this, it->second);
386 if (numCorners() > 2) {
390 }
else if (message.isList()) {
391 _CornersFromAtlas(*
this, message);
392 if (numCorners() > 2) {
396 throw _AtlasBadParse();
401 Atlas::Message::ListType points;
402 for (
const auto & point : m_points)
404 points.push_back(point.toAtlas());
406 Atlas::Message::MapType map;
407 map.insert(Atlas::Message::MapType::value_type(
"points", points));
414 const Atlas::Message::Element& message(a);
415 if (message.isMap()) {
416 const Atlas::Message::MapType& shapeElement(message.asMap());
417 auto it = shapeElement.find(
"points");
418 if ((it != shapeElement.end()) && it->second.isList()) {
419 _CornersFromAtlas(*
this, it->second);
420 if (numCorners() > 0) {
424 }
else if (message.isList()) {
425 _CornersFromAtlas(*
this, message);
426 if (numCorners() > 0) {
430 throw _AtlasBadParse();
436 Atlas::Message::ListType points;
437 for (const_iterator I = m_points.begin(); I != m_points.end(); ++I)
439 points.push_back(I->toAtlas());
441 Atlas::Message::MapType map;
442 map.insert(Atlas::Message::MapType::value_type(
"points", points));
454 const Atlas::Message::Element& message(a);
455 if (message.isMap()) {
456 const Atlas::Message::MapType& shapeElement(message.asMap());
458 auto shape_I = shapeElement.find(
"point");
459 if (shape_I != shapeElement.end()) {
460 const Atlas::Message::Element& shapePointElem(shape_I->second);
464 shape_I = shapeElement.find(
"size");
465 if (shape_I != shapeElement.end()) {
466 const Atlas::Message::Element& shapeVectorElem(shape_I->second);
469 m_corner0 = shapePoint;
470 m_size = shapeVector;
476 throw _AtlasBadParse();
482 Atlas::Message::MapType map;
483 map.insert(Atlas::Message::MapType::value_type(
"point", m_corner0.toAtlas()));
484 map.insert(Atlas::Message::MapType::value_type(
"size", m_size.toAtlas()));
496 #endif // WFMATH_ATLAS_CONV_H