GraphvizConverter.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "GraphvizConverter.h"
25 
29 
30 #include <SimoxUtility/algorithm/string/string_tools.h>
31 
32 #include <QPainterPath>
33 #include <QPointF>
34 
35 #include <boost/lexical_cast.hpp>
36 
37 #include <cassert>
38 //#include <iomanip> //setprecision
39 #include <stdexcept>
40 //#include <sstream>
41 #include <string>
42 #include <vector>
43 
45 {
46 }
47 
48 //TODO: ggf. diese beiden Funktionen und deren includes löschen
49 float armarx::GraphvizConverter::convertToFloat(const std::string& graphvizNumber)
50 {
51  /*
52  //replace ',' by '.'
53  size_t pointPos = graphvizNumber.find_first_of(",");
54  graphvizNumber.replace(pointPos, 1, ".");
55  */
56  try
57  {
58  return boost::lexical_cast<float>(graphvizNumber);
59  }
60  catch (boost::bad_lexical_cast&)
61  {
62  ARMARX_WARNING_S << " bad lexical cast to float - value:" << graphvizNumber;
63  throw;
64  }
65 }
66 
68 {
69  std::string graphvizNumber = to_string(number);
70 
71  /*
72  //replace '.' by ','
73  size_t pointPos = graphvizNumber.find_first_of(".");
74  graphvizNumber.replace(pointPos, 1, ",");
75  */
76 
77  return graphvizNumber;
78 }
79 
80 QPointF armarx::GraphvizConverter::convertToPoint(std::string graphvizPoint)
81 {
82  auto pos = graphvizPoint.find('!');
83  if (pos != std::string::npos)
84  {
85  graphvizPoint.erase(pos, 1);
86  }
87  tokenVector tokens = splitBy(graphvizPoint, ",");
88  ARMARX_CHECK_EXPRESSION(tokens.size() == 2) << graphvizPoint;
89 
90  try
91  {
92  float y = boost::lexical_cast<float>(tokens.at(1));
93  return QPointF {boost::lexical_cast<float>(tokens.at(0)), y};
94  }
95  catch (boost::bad_lexical_cast&)
96  {
97  ARMARX_WARNING_S << " bad lexical cast to point - value:" << graphvizPoint;
98  throw;
99  }
100  catch (const std::invalid_argument& ia)
101  {
102  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " " << tokens.at(0) << ", " << tokens.at(1);
103  }
104  catch (const std::out_of_range& e)
105  {
106  ARMARX_ERROR_S << "Out of range: " << e.what();
107  }
108 
109  return QPointF(0, 0);
110 }
111 
113 {
114  std::string graphvizPoint = to_string(point.x());
115  graphvizPoint += ",";
116  graphvizPoint += to_string(point.y());
117 
118  /*
119  * might be neccessary to use this version because graphviz wants a comma instead of a
120  * decimal point
121  *
122  std::stringstream ss;
123  // setprecision + fixed that 4 post decimal positions are shown
124  ss << std::setprecision(4) << std::fixed;
125  ss << point.x() << "," << point.y();
126  std::string graphvizPoint = ss.str();
127 
128  //replace '.' by ','
129  size_t pointPos = graphvizPoint.find_first_of(".");
130  while(pointPos != std::string::npos)
131  {
132  graphvizPoint.replace(pointPos, 1, ",");
133  pointPos = graphvizPoint.find_first_of(".", pointPos + 1);
134  }
135  */
136 
137  return graphvizPoint;
138 }
139 
140 QRectF armarx::GraphvizConverter::convertToRectangle(const std::string& graphvizPoint)
141 {
142  tokenVector tokens = splitBy(graphvizPoint, ",");
143  ARMARX_CHECK_EXPRESSION(tokens.size() == 4);
144 
145  try
146  {
147  float y = boost::lexical_cast<float>(tokens.at(1));
148  float y2 = boost::lexical_cast<float>(tokens.at(3));
149  return QRectF {boost::lexical_cast<float>(tokens.at(0)), y,
150  boost::lexical_cast<float>(tokens.at(2)), y2
151  };
152  }
153  catch (boost::bad_lexical_cast&)
154  {
155  ARMARX_WARNING_S << " bad lexical cast to float - point:" << graphvizPoint;
156  throw;
157  }
158  catch (const std::invalid_argument& ia)
159  {
160  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " " << tokens.at(0) << ", " << tokens.at(1);
161  }
162  catch (const std::out_of_range& e)
163  {
164  ARMARX_ERROR_S << "Out of range: " << e.what();
165  }
166 
167  return QRectF(0, 0, 0, 0);
168 
169 }
170 
172 {
173  splineVector splines;
174 
175  tokenVector splineStrings = splitBy(graphVizSplineType, ";");
176  ARMARX_CHECK_EXPRESSION(splineStrings.size() > 0);
177 
178  for (auto spline : splineStrings)
179  {
180  splines.push_back(tokenize(spline));
181  }
182 
183  return mergeSplines(splines);
184 }
185 
187 {
188  //assert(spline.controlPoints.size() % 3 == 1);
189 
190  std::string graphvizSpline;
191 
192  if (spline.endPoint)
193  {
194  graphvizSpline += "e,";
195  graphvizSpline += convertFromPoint(*(spline.endPoint));
196  graphvizSpline += " ";
197  }
198 
199  if (spline.startPoint)
200  {
201  graphvizSpline += "s,";
202  graphvizSpline += convertFromPoint(*(spline.startPoint));
203  graphvizSpline += " ";
204  }
205 
206  for (auto point : spline.controlPoints)
207  {
208  graphvizSpline += convertFromPoint(point);
209  graphvizSpline += " ";
210  }
211 
212  ARMARX_CHECK_EXPRESSION(graphvizSpline.size() > 0);
213  simox::alg::trim(graphvizSpline); //remove trailing whitespace
214 
215  return graphvizSpline;
216 }
217 
218 
219 armarx::SupportPoints armarx::GraphvizConverter::tokenize(std::string graphVizSpline)
220 {
221  tokenVector points = splitBy(graphVizSpline, " ");
222  /* TODO: de-comment
223  assert(points.size() >= 4); //there has to be a starting control point and a triple of control points
224  */
225  SupportPoints spline;
226 
227  for (auto point : points)
228  {
229  tokenVector tokens = splitBy(point, ",");
230 
231  if (tokens.size() == 3)
232  {
233  ARMARX_CHECK_EXPRESSION((tokens.at(0) == "s") || (tokens.at(0) == "e"));
234 
235  try
236  {
237  QPointF floatPoint {boost::lexical_cast<float>(tokens.at(1)), boost::lexical_cast<float>(tokens.at(2))};
238 
239  if (tokens.at(0) == "s")
240  {
241  spline.startPoint = std::make_shared<QPointF>(floatPoint);
242  }
243  else
244  {
245  spline.endPoint = std::make_shared<QPointF>(floatPoint);
246  }
247  }
248  catch (boost::bad_lexical_cast&)
249  {
250  ARMARX_WARNING_S << " bad lexical cast to pointlist - value:" << graphVizSpline;
251  throw;
252  }
253  catch (const std::invalid_argument& ia)
254  {
255  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what();
256  }
257  catch (const std::out_of_range& e)
258  {
259  ARMARX_ERROR_S << "Out of range: " << e.what();
260  }
261  }
262  else if (tokens.size() == 2)
263  {
264  try
265  {
266  QPointF p {boost::lexical_cast<float>(tokens.at(0)), boost::lexical_cast<float>(tokens.at(1))};
267  spline.controlPoints.push_back(p);
268  }
269  catch (const std::invalid_argument& ia)
270  {
271  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " " << tokens.at(0) << ", " << tokens.at(1);
272  }
273  catch (const std::out_of_range& e)
274  {
275  ARMARX_ERROR_S << "Out of range: " << e.what();
276  }
277  }
278  else
279  {
280  ARMARX_ERROR_S << "Not a valid string to represent a spline control point: " << point;
281  }
282  }
283 
284  //assert(spline.controlPoints.size() % 3 == 1);
285 
286  return spline;
287 }
288 
289 armarx::tokenVector armarx::GraphvizConverter::splitBy(std::string toSplit, std::string divider)
290 {
291  tokenVector tokenVec;
292  size_t dividerPos = 0;
293 
294  while (dividerPos != std::string::npos)
295  {
296  dividerPos = toSplit.find_first_of(divider);
297  std::string token = toSplit.substr(0, dividerPos);
298  toSplit = toSplit.substr(dividerPos + 1);
299 
300  tokenVec.push_back(token);
301  }
302 
303  return tokenVec;
304 }
305 
306 armarx::SupportPoints armarx::GraphvizConverter::mergeSplines(armarx::splineVector toMerge)
307 {
308  if (toMerge.size() >= 1)
309  {
310  return toMerge.front();
311  }
312  SupportPoints merged;
313  merged.startPoint = toMerge.front().startPoint;
314  merged.endPoint = toMerge.back().endPoint;
315 
316  for (SupportPoints otherSpline : toMerge)
317  {
318  merged.controlPoints.append(otherSpline.controlPoints);
319  }
320 
321  return merged;
322 }
323 
324 /*
325 QPainterPath armarx::SplineConverter::calcArrowhead(QPointF start, QPointF destination)
326 {
327  QPointF directionVector = destination - start;
328  QPointF baseVector {- directionVector.y(), directionVector.x()}; //vector orthogonal to directionVector
329 
330  QPointF leftWingEnd = start + 0.5 * baseVector;
331  QPointF rightWingEnd = start - 0.5 * baseVector;
332 
333  QPolygonF triangle;
334  triangle << leftWingEnd << rightWingEnd << destination;
335 
336  QPainterPath arrowhead;
337  arrowhead.addPolygon(triangle);
338  arrowhead.closeSubpath();
339 
340  return arrowhead;
341 }
342 */
343 
344 
346 {
347  QList<QPointF> list;
348 
349  if (startPoint)
350  {
351  list.append(*startPoint.get());
352  }
353 
354  list.append(controlPointList());
355 
356  if (endPoint)
357  {
358  list.append(*endPoint.get());
359  }
360 
361  return list;
362 }
363 
365 {
366  QList<QPointF> list;
367 
368  for (QPointF point : controlPoints)
369  {
370  list.append(point);
371  }
372 
373  return list;
374 }
375 
377 {
378  controlPoints.clear();
379 
380  for (auto point : list)
381  {
382  controlPoints.push_back(point);
383  }
384 }
385 
386 void armarx::SupportPoints::append(const QPointF& point)
387 {
388  controlPoints.append(point);
389 }
armarx::GraphvizConverter::GraphvizConverter
GraphvizConverter()
Definition: GraphvizConverter.cpp:44
GraphvizConverter.h
armarx::GraphvizConverter::convertFromSpline
static std::string convertFromSpline(SupportPoints spline)
Definition: GraphvizConverter.cpp:186
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::GraphvizConverter::convertToPoint
static QPointF convertToPoint(std::string graphvizPoint)
Definition: GraphvizConverter.cpp:80
armarx::GraphvizConverter::convertToSpline
static SupportPoints convertToSpline(const std::string &graphVizSplineType)
Definition: GraphvizConverter.cpp:171
armarx::SupportPoints::append
void append(const QPointF &point)
Definition: GraphvizConverter.cpp:386
StringHelpers.h
armarx::SupportPoints::startPoint
QPointPtr startPoint
Definition: Transition.h:57
armarx::SupportPoints::setControlPoints
void setControlPoints(QList< QPointF > list)
Definition: GraphvizConverter.cpp:376
armarx::GraphvizConverter::convertToFloat
static float convertToFloat(const std::string &graphvizNumber)
Definition: GraphvizConverter.cpp:49
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
armarx::GraphvizConverter::convertToRectangle
static QRectF convertToRectangle(const std::string &graphvizPoint)
Definition: GraphvizConverter.cpp:140
armarx::SupportPoints::endPoint
QPointPtr endPoint
Definition: Transition.h:58
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::SupportPoints::controlPointList
QList< QPointF > controlPointList() const
Definition: GraphvizConverter.cpp:364
ExpressionException.h
armarx::splineVector
std::vector< SupportPoints > splineVector
Definition: GraphvizConverter.h:41
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::GraphvizConverter::convertFromFloat
static std::string convertFromFloat(float number)
Definition: GraphvizConverter.cpp:67
armarx::SupportPoints::controlPoints
QPointList controlPoints
Definition: Transition.h:59
armarx::GraphvizConverter::convertFromPoint
static std::string convertFromPoint(QPointF point)
Definition: GraphvizConverter.cpp:112
armarx::SupportPoints
Definition: Transition.h:43
Logging.h
armarx::tokenVector
std::vector< std::string > tokenVector
Definition: GraphvizConverter.h:40
armarx::SupportPoints::toPointList
QList< QPointF > toPointList() const
Definition: GraphvizConverter.cpp:345