35 #include <json/value.h>
36 #include <json/reader.h>
37 #include <boost/algorithm/string.hpp>
38 #include <boost/range/algorithm/count_if.hpp>
46 static const char AXIS_NAMES[] =
"XYZ";
47 static const char MINUS[] =
"-";
48 template <
typename T = Eigen::Vector3d>
49 inline T vectorFromJson(Json::Value
const &v) {
52 std::string inVal = v.asString();
54 throw std::runtime_error(
55 "Empty string can't be turned into a vector!");
57 using boost::is_any_of;
58 std::string val(boost::to_upper_copy(inVal));
59 if ((!boost::algorithm::all(
60 val, is_any_of(AXIS_NAMES) || is_any_of(MINUS) ||
61 boost::algorithm::is_space())) ||
62 boost::count_if(val, is_any_of(AXIS_NAMES)) != 1 ||
63 boost::count_if(val, is_any_of(MINUS)) > 1) {
64 throw std::runtime_error(
65 "Cannot turn the specified string into a vector: " + inVal);
68 (val.find(MINUS[0]) == std::string::npos) ? 1.0 : -1.0;
69 const std::string axisnames(AXIS_NAMES);
70 for (
const char c : val) {
71 auto location = axisnames.find(c);
72 if (location != std::string::npos) {
73 ret[location] = factor;
77 BOOST_ASSERT_MSG(
false,
"Should never reach here!");
80 if (v.size() != T::RowsAtCompileTime) {
81 throw std::runtime_error(
82 "Vector size wrong when converting from JSON!");
84 for (Json::ArrayIndex i = 0, e = v.size(); i < e; ++i) {
85 ret[i] = v[i].asFloat();
89 throw std::runtime_error(
"Could not convert JSON to vector: " +
93 static const char DEGREES_KEY[] =
"degrees";
94 static const char RADIANS_KEY[] =
"radians";
95 static inline double angleAsRadians(Json::Value
const &rotation) {
97 if (rotation[DEGREES_KEY].isNumeric()) {
98 ret = degreesToRadians(rotation[DEGREES_KEY].asFloat());
99 }
else if (rotation[RADIANS_KEY].isNumeric()) {
100 ret = rotation[RADIANS_KEY].asFloat();
102 throw std::runtime_error(
103 "Cannot have a rotation with either degrees or radians!");
108 static const char TRANSLATE_KEY[] =
"posttranslate";
109 static const char PRETRANSLATE_KEY[] =
"translate";
110 static const char ROTATE_KEY[] =
"postrotate";
111 static const char PREROTATE_KEY[] =
"rotate";
112 static const char AXIS_KEY[] =
"axis";
113 static const char CHANGE_BASIS_KEY[] =
"changeBasis";
114 static const char X_KEY[] =
"x";
115 static const char Y_KEY[] =
"y";
116 static const char Z_KEY[] =
"z";
117 static inline void handleLevel(Transform &t, Json::Value
const &v) {
122 if (v.isMember(CHANGE_BASIS_KEY)) {
123 Json::Value changeBasis = v[CHANGE_BASIS_KEY];
125 cb.setNewX(vectorFromJson<>(changeBasis[X_KEY]));
126 cb.setNewY(vectorFromJson<>(changeBasis[Y_KEY]));
127 cb.setNewZ(vectorFromJson<>(changeBasis[Z_KEY]));
128 t.transform(cb.get());
131 Eigen::Vector3d position = Eigen::Vector3d::Zero();
132 Eigen::AngleAxisd orientation = Eigen::AngleAxisd::Identity();
133 Eigen::Vector3d preposition = Eigen::Vector3d::Zero();
134 Eigen::AngleAxisd preorientation = Eigen::AngleAxisd::Identity();
135 bool haveTransform =
false;
136 bool havePreTransform =
false;
137 if (v.isMember(TRANSLATE_KEY)) {
138 position = vectorFromJson<>(v[TRANSLATE_KEY]);
139 haveTransform =
true;
141 if (v.isMember(PRETRANSLATE_KEY)) {
142 preposition = vectorFromJson<>(v[PRETRANSLATE_KEY]);
143 havePreTransform =
true;
145 if (v.isMember(ROTATE_KEY)) {
146 Json::Value rotate = v[ROTATE_KEY];
147 orientation = Eigen::AngleAxisd(angleAsRadians(rotate),
148 vectorFromJson<>(rotate[AXIS_KEY]));
149 haveTransform =
true;
151 if (v.isMember(PREROTATE_KEY)) {
152 Json::Value rotate = v[PREROTATE_KEY];
153 preorientation = Eigen::AngleAxisd(
154 angleAsRadians(rotate), vectorFromJson<>(rotate[AXIS_KEY]));
155 havePreTransform =
true;
158 Eigen::Affine3d xform;
159 xform.fromPositionOrientationScale(position, orientation,
160 Eigen::Vector3d::Constant(1));
161 t.concatPost(xform.matrix());
163 if (havePreTransform) {
164 Eigen::Affine3d xform;
165 xform.fromPositionOrientationScale(preposition, preorientation,
166 Eigen::Vector3d::Constant(1));
167 t.concatPre(xform.matrix());
171 static const char CHILD_KEY[] =
"child";
173 std::vector<Json::Value> levels;
174 Json::Value current = root;
175 levels.push_back(current);
176 while (current.isObject() && current.isMember(CHILD_KEY)) {
177 current = current[CHILD_KEY];
178 levels.push_back(current);
181 while (!levels.empty()) {
182 handleLevel(m_transform, levels.back());
187 JSONTransformVisitor::~JSONTransformVisitor() {}
189 Transform
const &JSONTransformVisitor::getTransform()
const {
193 Json::Value
const &JSONTransformVisitor::getLeaf()
const {
return m_leaf; }
Header wrapping the C99 standard stdint header.