27 #include <VirtualRobot/VirtualRobot.h>
34 #include <SemanticObjectRelations/SupportAnalysis/SupportGraph.h>
42 layoutGraph(semrel::AttributedGraph
const& graph)
44 GraphvizLayout layout;
45 for (
auto vertex : graph.vertices())
47 auto desc = vertex.descriptor();
48 auto& attrs = vertex.attrib().json;
51 if (
auto style = attrs.find(
"style"); style != attrs.end())
53 auto label = style->find(
"label");
54 if (label != style->end() && label->is_string())
56 name = label->get<std::string>();
59 else if (
auto object = attrs.find(
"object");
object != attrs.end())
61 auto nameValue =
object->find(
"name");
62 if (nameValue != object->end() && nameValue->is_string())
64 name = nameValue->get<std::string>() +
67 nameValue =
object->find(
"instance");
68 if (nameValue != object->end() && nameValue->is_string())
70 name = nameValue->get<std::string>();
73 layout.addNode(desc, name);
75 for (
auto edge : graph.edges())
77 auto& attrs = edge.attrib().json;
79 if (
auto style = attrs.find(
"style"); style != attrs.end())
81 auto label = style->find(
"label");
82 if (label != style->end() && label->is_string())
84 name = label->get<std::string>();
87 layout.addEdge(edge.sourceDescriptor(), edge.targetDescriptor(), name);
89 return layout.finish();
96 setlocale(LC_ALL,
"en_US.UTF-8");
99 timer =
new QTimer(
this);
100 widget.graphView->setScene(&graphicsScene);
101 widget.graphView->setRenderHints(QPainter::Antialiasing |
102 QPainter::HighQualityAntialiasing);
104 int graphWidth = 750;
105 widget.splitter->setSizes({graphWidth, propWidth});
108 connect(widget.updatePushButton, SIGNAL(clicked()),
this, SLOT(
onUpdateGraphs()));
109 connect(widget.autoUpdateCheckBox,
110 SIGNAL(stateChanged(
int)),
113 connect(widget.idComboBox, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
onUpdateGraphs()));
115 connect(widget.zoomSpinBox,
116 QOverload<double>::of(&QDoubleSpinBox::valueChanged),
118 &SemanticRelationViewerWidgetController::onZoomChanged);
135 static const std::string STORAGE_NAME_KEY =
"SemanticGraphStorage";
143 configDialog->addProxyFinder<armarx::semantic::GraphStorageInterfacePrx>(
144 {STORAGE_NAME_KEY,
"SemanticGraphStorage",
"SemanticGraphStorage"});
146 return qobject_cast<SimpleConfigDialog*>(configDialog);
154 template <
typename T>
158 object->usingProxy(name);
159 proxy =
object->getProxy<
T>(name);
165 std::string storageName = configDialog->getProxyName(STORAGE_NAME_KEY);
166 setProxy(
this, storage, storageName);
179 semantic::data::GraphMap allGraphs = storage->getAll();
180 for (
auto& pair : allGraphs)
182 std::string
const&
id = pair.first;
186 std::string selectedID = widget.idComboBox->currentText().toStdString();
188 widget.idComboBox->blockSignals(
true);
189 widget.idComboBox->clear();
190 widget.idComboBox->blockSignals(
false);
192 if (allGraphs.empty())
197 widget.idComboBox->blockSignals(
true);
198 for (
auto& pair : allGraphs)
200 std::string
const&
id = pair.first;
201 widget.idComboBox->addItem(QString::fromStdString(
id));
204 int selectedIndex = widget.idComboBox->findText(QString::fromStdString(selectedID));
205 if (selectedIndex < 0)
209 widget.idComboBox->setCurrentIndex(selectedIndex);
210 widget.idComboBox->blockSignals(
false);
212 selectedID = widget.idComboBox->currentText().toStdString();
214 if (graphMap.count(selectedID))
216 semrel::AttributedGraph
const& graph = graphMap[selectedID];
219 drawGraph(&graphicsScene, layoutedGraph, graph);
220 widget.graphView->viewport()->update();
222 setPropertyView(nlohmann::json::object());
226 std::vector<std::string> ids;
227 for (
auto& entry : graphMap)
229 ids.push_back(entry.first);
232 <<
"\nExisting IDs: " << ids;
239 if (widget.autoUpdateCheckBox->checkState() == Qt::Checked)
252 std::string
id = widget.idComboBox->currentText().toStdString();
253 if (graphMap.count(
id) == 0)
258 auto& graph = graphMap[id];
259 auto vertex = graph.vertex(selected->
descriptor);
261 <<
"]: " << vertex.attrib().json.dump(4);
263 setPropertyView(vertex.attrib().json);
264 highlightSelected(selected);
270 std::string
id = widget.idComboBox->currentText().toStdString();
271 if (graphMap.count(
id) == 0)
275 auto& graph = graphMap[id];
281 edge.attrib().json.is_null();
282 setPropertyView(edge.attrib().json);
283 highlightSelected(selected);
289 std::string
id = widget.idComboBox->currentText().toStdString();
290 if (graphMap.count(
id) == 0)
296 auto& graph = graphMap[id];
297 setPropertyView(graph.attrib().json);
298 highlightSelected(selected);
302 SemanticRelationViewerWidgetController::drawGraph(QGraphicsScene* graphicsScene,
304 semrel::AttributedGraph
const& graph)
306 graphicsScene->clear();
308 float minX = FLT_MAX;
309 float minY = FLT_MAX;
311 for (
auto& pair : layoutedGraph.
nodes)
319 ellipse->
text = QString::fromStdString(layoutedNode.
label);
326 auto vertex = graph.vertex(semrel::ShapeID{
id});
327 auto& json = vertex.attrib().json;
328 if (json.count(
"style"))
330 auto& style = json[
"style"];
331 auto setColor = [&](std::string
const& colorName, QColor* output)
333 if (style.count(colorName))
335 Eigen::Vector4i scolor = style[colorName];
336 QColor qcolor(scolor(0), scolor(1), scolor(2), scolor(3));
340 setColor(
"fill-color", &ellipse->
fillColor);
342 setColor(
"font-color", &ellipse->
fontColor);
346 QObject::connect(ellipse,
355 graphicsScene->addItem(ellipse);
359 for (
auto& pair : layoutedGraph.
edges)
361 int sourceID = pair.first.first;
362 int targetID = pair.first.second;
363 GraphvizLayoutedEdge
const& layoutedEdge = pair.second;
366 if (layoutedEdge.startPoint)
368 path.lineTo(*layoutedEdge.startPoint);
371 if (layoutedEdge.endPoint)
373 path.lineTo(*layoutedEdge.endPoint);
376 for (
int i = 0; i <= 10; ++i)
379 QPointF point = path.pointAtPercent(t);
381 minX =
std::min(
float(point.x()), minX);
382 minY =
std::min(
float(point.y()), minY);
385 SemanticGraphEdgeItem* item =
new SemanticGraphEdgeItem();
386 item->sourceDescriptor = sourceID;
387 item->targetDescriptor = targetID;
391 auto sourceVertex = graph.vertex(item->sourceDescriptor);
392 auto targetVertex = graph.vertex(item->targetDescriptor);
393 auto edge = graph.edge(sourceVertex, targetVertex);
394 auto& json = edge.attrib().json;
395 if (json.count(
"style"))
397 auto& style = json[
"style"];
398 if (style.count(
"color"))
400 Eigen::Vector4i scolor = style[
"color"];
401 QColor qcolor(scolor(0), scolor(1), scolor(2), scolor(3));
402 item->color = qcolor;
405 if (layoutedEdge.label.size() > 0)
407 item->label = QString::fromStdString(layoutedEdge.label);
408 item->labelPosition.setX(
double(layoutedEdge.labelPosX));
409 item->labelPosition.setY(
double(layoutedEdge.labelPosY));
413 QObject::connect(item,
422 graphicsScene->addItem(item);
425 SemanticGraphGlobalItem* global =
new SemanticGraphGlobalItem();
426 global->setRect(minX - 60.0f, minY - 40.0f, 100.0f, 30.0f);
428 QObject::connect(global,
436 graphicsScene->addItem(global);
440 SemanticRelationViewerWidgetController::setPropertyView(nlohmann::json
const& attrs)
444 widget.propertiesView->setModel(&propertyModel);
445 widget.propertiesView->expandAll();
446 widget.propertiesView->resizeColumnToContents(0);
450 SemanticRelationViewerWidgetController::highlightSelected(QGraphicsItem* selected)
452 for (QGraphicsItem* item : graphicsScene.items())
454 if (
auto* edge =
dynamic_cast<SemanticGraphEdgeItem*
>(item))
456 edge->selected = (edge == selected);
458 else if (
auto* vertex =
dynamic_cast<SemanticGraphVertexItem*
>(item))
460 vertex->selected = (vertex == selected);
462 else if (
auto* global =
dynamic_cast<SemanticGraphGlobalItem*
>(item))
464 global->selected = (global == selected);
467 graphicsScene.update();
471 SemanticRelationViewerWidgetController::onZoomChanged(
double newZoom)
473 double inverseScale = 1.0 / graphicsSceneScale;
474 double zoom = inverseScale * newZoom;
475 widget.graphView->scale(zoom, zoom);
476 graphicsSceneScale = newZoom;