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 
26 #include <cassert>
27 
28 #include <boost/lexical_cast.hpp>
29 
30 #include <QPainterPath>
31 #include <QPointF>
32 
33 #include <SimoxUtility/algorithm/string/string_tools.h>
34 
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
50 armarx::GraphvizConverter::convertToFloat(const std::string& graphvizNumber)
51 {
52  /*
53  //replace ',' by '.'
54  size_t pointPos = graphvizNumber.find_first_of(",");
55  graphvizNumber.replace(pointPos, 1, ".");
56  */
57  try
58  {
59  return boost::lexical_cast<float>(graphvizNumber);
60  }
61  catch (boost::bad_lexical_cast&)
62  {
63  ARMARX_WARNING_S << " bad lexical cast to float - value:" << graphvizNumber;
64  throw;
65  }
66 }
67 
68 std::string
70 {
71  std::string graphvizNumber = to_string(number);
72 
73  /*
74  //replace '.' by ','
75  size_t pointPos = graphvizNumber.find_first_of(".");
76  graphvizNumber.replace(pointPos, 1, ",");
77  */
78 
79  return graphvizNumber;
80 }
81 
82 QPointF
84 {
85  auto pos = graphvizPoint.find('!');
86  if (pos != std::string::npos)
87  {
88  graphvizPoint.erase(pos, 1);
89  }
90  tokenVector tokens = splitBy(graphvizPoint, ",");
91  ARMARX_CHECK_EXPRESSION(tokens.size() == 2) << graphvizPoint;
92 
93  try
94  {
95  float y = boost::lexical_cast<float>(tokens.at(1));
96  return QPointF{boost::lexical_cast<float>(tokens.at(0)), y};
97  }
98  catch (boost::bad_lexical_cast&)
99  {
100  ARMARX_WARNING_S << " bad lexical cast to point - value:" << graphvizPoint;
101  throw;
102  }
103  catch (const std::invalid_argument& ia)
104  {
105  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " "
106  << tokens.at(0) << ", " << tokens.at(1);
107  }
108  catch (const std::out_of_range& e)
109  {
110  ARMARX_ERROR_S << "Out of range: " << e.what();
111  }
112 
113  return QPointF(0, 0);
114 }
115 
116 std::string
118 {
119  std::string graphvizPoint = to_string(point.x());
120  graphvizPoint += ",";
121  graphvizPoint += to_string(point.y());
122 
123  /*
124  * might be neccessary to use this version because graphviz wants a comma instead of a
125  * decimal point
126  *
127  std::stringstream ss;
128  // setprecision + fixed that 4 post decimal positions are shown
129  ss << std::setprecision(4) << std::fixed;
130  ss << point.x() << "," << point.y();
131  std::string graphvizPoint = ss.str();
132 
133  //replace '.' by ','
134  size_t pointPos = graphvizPoint.find_first_of(".");
135  while(pointPos != std::string::npos)
136  {
137  graphvizPoint.replace(pointPos, 1, ",");
138  pointPos = graphvizPoint.find_first_of(".", pointPos + 1);
139  }
140  */
141 
142  return graphvizPoint;
143 }
144 
145 QRectF
146 armarx::GraphvizConverter::convertToRectangle(const std::string& graphvizPoint)
147 {
148  tokenVector tokens = splitBy(graphvizPoint, ",");
149  ARMARX_CHECK_EXPRESSION(tokens.size() == 4);
150 
151  try
152  {
153  float y = boost::lexical_cast<float>(tokens.at(1));
154  float y2 = boost::lexical_cast<float>(tokens.at(3));
155  return QRectF{boost::lexical_cast<float>(tokens.at(0)),
156  y,
157  boost::lexical_cast<float>(tokens.at(2)),
158  y2};
159  }
160  catch (boost::bad_lexical_cast&)
161  {
162  ARMARX_WARNING_S << " bad lexical cast to float - point:" << graphvizPoint;
163  throw;
164  }
165  catch (const std::invalid_argument& ia)
166  {
167  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " "
168  << tokens.at(0) << ", " << tokens.at(1);
169  }
170  catch (const std::out_of_range& e)
171  {
172  ARMARX_ERROR_S << "Out of range: " << e.what();
173  }
174 
175  return QRectF(0, 0, 0, 0);
176 }
177 
179 armarx::GraphvizConverter::convertToSpline(const std::string& graphVizSplineType)
180 {
181  splineVector splines;
182 
183  tokenVector splineStrings = splitBy(graphVizSplineType, ";");
184  ARMARX_CHECK_EXPRESSION(splineStrings.size() > 0);
185 
186  for (auto spline : splineStrings)
187  {
188  splines.push_back(tokenize(spline));
189  }
190 
191  return mergeSplines(splines);
192 }
193 
194 std::string
196 {
197  //assert(spline.controlPoints.size() % 3 == 1);
198 
199  std::string graphvizSpline;
200 
201  if (spline.endPoint)
202  {
203  graphvizSpline += "e,";
204  graphvizSpline += convertFromPoint(*(spline.endPoint));
205  graphvizSpline += " ";
206  }
207 
208  if (spline.startPoint)
209  {
210  graphvizSpline += "s,";
211  graphvizSpline += convertFromPoint(*(spline.startPoint));
212  graphvizSpline += " ";
213  }
214 
215  for (auto point : spline.controlPoints)
216  {
217  graphvizSpline += convertFromPoint(point);
218  graphvizSpline += " ";
219  }
220 
221  ARMARX_CHECK_EXPRESSION(graphvizSpline.size() > 0);
222  simox::alg::trim(graphvizSpline); //remove trailing whitespace
223 
224  return graphvizSpline;
225 }
226 
228 armarx::GraphvizConverter::tokenize(std::string graphVizSpline)
229 {
230  tokenVector points = splitBy(graphVizSpline, " ");
231  /* TODO: de-comment
232  assert(points.size() >= 4); //there has to be a starting control point and a triple of control points
233  */
234  SupportPoints spline;
235 
236  for (auto point : points)
237  {
238  tokenVector tokens = splitBy(point, ",");
239 
240  if (tokens.size() == 3)
241  {
242  ARMARX_CHECK_EXPRESSION((tokens.at(0) == "s") || (tokens.at(0) == "e"));
243 
244  try
245  {
246  QPointF floatPoint{boost::lexical_cast<float>(tokens.at(1)),
247  boost::lexical_cast<float>(tokens.at(2))};
248 
249  if (tokens.at(0) == "s")
250  {
251  spline.startPoint = std::make_shared<QPointF>(floatPoint);
252  }
253  else
254  {
255  spline.endPoint = std::make_shared<QPointF>(floatPoint);
256  }
257  }
258  catch (boost::bad_lexical_cast&)
259  {
260  ARMARX_WARNING_S << " bad lexical cast to pointlist - value:" << graphVizSpline;
261  throw;
262  }
263  catch (const std::invalid_argument& ia)
264  {
265  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what();
266  }
267  catch (const std::out_of_range& e)
268  {
269  ARMARX_ERROR_S << "Out of range: " << e.what();
270  }
271  }
272  else if (tokens.size() == 2)
273  {
274  try
275  {
276  QPointF p{boost::lexical_cast<float>(tokens.at(0)),
277  boost::lexical_cast<float>(tokens.at(1))};
278  spline.controlPoints.push_back(p);
279  }
280  catch (const std::invalid_argument& ia)
281  {
282  ARMARX_ERROR_S << "Invalid argument for float conversion: " << ia.what() << " "
283  << tokens.at(0) << ", " << tokens.at(1);
284  }
285  catch (const std::out_of_range& e)
286  {
287  ARMARX_ERROR_S << "Out of range: " << e.what();
288  }
289  }
290  else
291  {
292  ARMARX_ERROR_S << "Not a valid string to represent a spline control point: " << point;
293  }
294  }
295 
296  //assert(spline.controlPoints.size() % 3 == 1);
297 
298  return spline;
299 }
300 
302 armarx::GraphvizConverter::splitBy(std::string toSplit, std::string divider)
303 {
304  tokenVector tokenVec;
305  size_t dividerPos = 0;
306 
307  while (dividerPos != std::string::npos)
308  {
309  dividerPos = toSplit.find_first_of(divider);
310  std::string token = toSplit.substr(0, dividerPos);
311  toSplit = toSplit.substr(dividerPos + 1);
312 
313  tokenVec.push_back(token);
314  }
315 
316  return tokenVec;
317 }
318 
320 armarx::GraphvizConverter::mergeSplines(armarx::splineVector toMerge)
321 {
322  if (toMerge.size() >= 1)
323  {
324  return toMerge.front();
325  }
326  SupportPoints merged;
327  merged.startPoint = toMerge.front().startPoint;
328  merged.endPoint = toMerge.back().endPoint;
329 
330  for (SupportPoints otherSpline : toMerge)
331  {
332  merged.controlPoints.append(otherSpline.controlPoints);
333  }
334 
335  return merged;
336 }
337 
338 /*
339 QPainterPath armarx::SplineConverter::calcArrowhead(QPointF start, QPointF destination)
340 {
341  QPointF directionVector = destination - start;
342  QPointF baseVector {- directionVector.y(), directionVector.x()}; //vector orthogonal to directionVector
343 
344  QPointF leftWingEnd = start + 0.5 * baseVector;
345  QPointF rightWingEnd = start - 0.5 * baseVector;
346 
347  QPolygonF triangle;
348  triangle << leftWingEnd << rightWingEnd << destination;
349 
350  QPainterPath arrowhead;
351  arrowhead.addPolygon(triangle);
352  arrowhead.closeSubpath();
353 
354  return arrowhead;
355 }
356 */
357 
358 
359 QList<QPointF>
361 {
362  QList<QPointF> list;
363 
364  if (startPoint)
365  {
366  list.append(*startPoint.get());
367  }
368 
369  list.append(controlPointList());
370 
371  if (endPoint)
372  {
373  list.append(*endPoint.get());
374  }
375 
376  return list;
377 }
378 
379 QList<QPointF>
381 {
382  QList<QPointF> list;
383 
384  for (QPointF point : controlPoints)
385  {
386  list.append(point);
387  }
388 
389  return list;
390 }
391 
392 void
394 {
395  controlPoints.clear();
396 
397  for (auto point : list)
398  {
399  controlPoints.push_back(point);
400  }
401 }
402 
403 void
404 armarx::SupportPoints::append(const QPointF& point)
405 {
406  controlPoints.append(point);
407 }
armarx::GraphvizConverter::GraphvizConverter
GraphvizConverter()
Definition: GraphvizConverter.cpp:44
GraphvizConverter.h
armarx::GraphvizConverter::convertFromSpline
static std::string convertFromSpline(SupportPoints spline)
Definition: GraphvizConverter.cpp:195
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:83
armarx::GraphvizConverter::convertToSpline
static SupportPoints convertToSpline(const std::string &graphVizSplineType)
Definition: GraphvizConverter.cpp:179
armarx::SupportPoints::append
void append(const QPointF &point)
Definition: GraphvizConverter.cpp:404
StringHelpers.h
armarx::SupportPoints::startPoint
QPointPtr startPoint
Definition: Transition.h:52
armarx::SupportPoints::setControlPoints
void setControlPoints(QList< QPointF > list)
Definition: GraphvizConverter.cpp:393
armarx::GraphvizConverter::convertToFloat
static float convertToFloat(const std::string &graphvizNumber)
Definition: GraphvizConverter.cpp:50
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:216
armarx::GraphvizConverter::convertToRectangle
static QRectF convertToRectangle(const std::string &graphvizPoint)
Definition: GraphvizConverter.cpp:146
armarx::SupportPoints::endPoint
QPointPtr endPoint
Definition: Transition.h:53
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::SupportPoints::controlPointList
QList< QPointF > controlPointList() const
Definition: GraphvizConverter.cpp:380
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:69
armarx::SupportPoints::controlPoints
QPointList controlPoints
Definition: Transition.h:54
armarx::GraphvizConverter::convertFromPoint
static std::string convertFromPoint(QPointF point)
Definition: GraphvizConverter.cpp:117
armarx::SupportPoints
Definition: Transition.h:42
Logging.h
armarx::tokenVector
std::vector< std::string > tokenVector
Definition: GraphvizConverter.h:40
armarx::SupportPoints::toPointList
QList< QPointF > toPointList() const
Definition: GraphvizConverter.cpp:360