23 #include <VirtualRobot/VirtualRobot.h>
32 #include <SemanticObjectRelations/SupportAnalysis/SupportGraph.h>
41 GraphvizLayoutedGraph layoutGraph(semrel::AttributedGraph
const& graph)
43 GraphvizLayout layout;
44 for (
auto vertex : graph.vertices())
46 auto desc = vertex.descriptor();
47 auto& attrs = vertex.attrib().json;
50 if (
auto style = attrs.find(
"style"); style != attrs.end())
52 auto label = style->find(
"label");
53 if (label != style->end() && label->is_string())
55 name = label->get<std::string>();
58 else if (
auto object = attrs.find(
"object");
object != attrs.end())
60 auto nameValue =
object->find(
"name");
61 if (nameValue != object->end() && nameValue->is_string())
63 name = nameValue->get<std::string>() +
std::to_string(object->at(
"id").get<
int>());
65 nameValue =
object->find(
"instance");
66 if (nameValue != object->end() && nameValue->is_string())
68 name = nameValue->get<std::string>();
71 layout.addNode(desc, name);
73 for (
auto edge : graph.edges())
75 auto& attrs = edge.attrib().json;
77 if (
auto style = attrs.find(
"style"); style != attrs.end())
79 auto label = style->find(
"label");
80 if (label != style->end() && label->is_string())
82 name = label->get<std::string>();
85 layout.addEdge(edge.sourceDescriptor(), edge.targetDescriptor(), name);
87 return layout.finish();
94 setlocale(LC_ALL,
"en_US.UTF-8");
97 timer =
new QTimer(
this);
98 widget.graphView->setScene(&graphicsScene);
99 widget.graphView->setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing);
101 int graphWidth = 750;
102 widget.splitter->setSizes({graphWidth, propWidth});
105 connect(widget.updatePushButton, SIGNAL(clicked()),
this, SLOT(
onUpdateGraphs()));
106 connect(widget.autoUpdateCheckBox, SIGNAL(stateChanged(
int)),
this, SLOT(
onAutoUpdateChanged()));
107 connect(widget.idComboBox, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
onUpdateGraphs()));
109 connect(widget.zoomSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
110 this, &SemanticRelationViewerWidgetController::onZoomChanged);
130 static const std::string STORAGE_NAME_KEY =
"SemanticGraphStorage";
137 configDialog->addProxyFinder<armarx::semantic::GraphStorageInterfacePrx>({STORAGE_NAME_KEY,
"SemanticGraphStorage",
"SemanticGraphStorage"});
139 return qobject_cast<SimpleConfigDialog*>(configDialog);
147 template <
typename T>
150 object->usingProxy(name);
151 proxy =
object->getProxy<
T>(name);
156 std::string storageName = configDialog->getProxyName(STORAGE_NAME_KEY);
157 setProxy(
this, storage, storageName);
168 semantic::data::GraphMap allGraphs = storage->getAll();
169 for (
auto& pair : allGraphs)
171 std::string
const&
id = pair.first;
175 std::string selectedID = widget.idComboBox->currentText().toStdString();
177 widget.idComboBox->blockSignals(
true);
178 widget.idComboBox->clear();
179 widget.idComboBox->blockSignals(
false);
181 if (allGraphs.empty())
186 widget.idComboBox->blockSignals(
true);
187 for (
auto& pair : allGraphs)
189 std::string
const&
id = pair.first;
190 widget.idComboBox->addItem(QString::fromStdString(
id));
193 int selectedIndex = widget.idComboBox->findText(QString::fromStdString(selectedID));
194 if (selectedIndex < 0)
198 widget.idComboBox->setCurrentIndex(selectedIndex);
199 widget.idComboBox->blockSignals(
false);
201 selectedID = widget.idComboBox->currentText().toStdString();
203 if (graphMap.count(selectedID))
205 semrel::AttributedGraph
const& graph = graphMap[selectedID];
208 drawGraph(&graphicsScene, layoutedGraph, graph);
209 widget.graphView->viewport()->update();
211 setPropertyView(nlohmann::json::object());
215 std::vector<std::string> ids;
216 for (
auto& entry : graphMap)
218 ids.push_back(entry.first);
221 <<
"\nExisting IDs: " << ids;
227 if (widget.autoUpdateCheckBox->checkState() == Qt::Checked)
239 std::string
id = widget.idComboBox->currentText().toStdString();
240 if (graphMap.count(
id) == 0)
245 auto& graph = graphMap[id];
246 auto vertex = graph.vertex(selected->
descriptor);
248 << vertex.attrib().json.dump(4);
250 setPropertyView(vertex.attrib().json);
251 highlightSelected(selected);
256 std::string
id = widget.idComboBox->currentText().toStdString();
257 if (graphMap.count(
id) == 0)
261 auto& graph = graphMap[id];
266 edge.attrib().json.is_null();
267 setPropertyView(edge.attrib().json);
268 highlightSelected(selected);
273 std::string
id = widget.idComboBox->currentText().toStdString();
274 if (graphMap.count(
id) == 0)
280 auto& graph = graphMap[id];
281 setPropertyView(graph.attrib().json);
282 highlightSelected(selected);
285 void SemanticRelationViewerWidgetController::drawGraph(QGraphicsScene* graphicsScene,
287 semrel::AttributedGraph
const& graph)
289 graphicsScene->clear();
291 float minX = FLT_MAX;
292 float minY = FLT_MAX;
294 for (
auto& pair : layoutedGraph.
nodes)
300 ellipse->setRect(layoutedNode.
posX, layoutedNode.
posY, layoutedNode.
width, layoutedNode.
height);
301 ellipse->
text = QString::fromStdString(layoutedNode.
label);
308 auto vertex = graph.vertex(semrel::ShapeID{
id});
309 auto& json = vertex.attrib().json;
310 if (json.count(
"style"))
312 auto& style = json[
"style"];
313 auto setColor = [&](std::string
const & colorName, QColor * output)
315 if (style.count(colorName))
317 Eigen::Vector4i scolor = style[colorName];
318 QColor qcolor(scolor(0), scolor(1), scolor(2), scolor(3));
322 setColor(
"fill-color", &ellipse->
fillColor);
324 setColor(
"font-color", &ellipse->
fontColor);
334 graphicsScene->addItem(ellipse);
339 for (
auto& pair : layoutedGraph.
edges)
341 int sourceID = pair.first.first;
342 int targetID = pair.first.second;
343 GraphvizLayoutedEdge
const& layoutedEdge = pair.second;
346 if (layoutedEdge.startPoint)
348 path.lineTo(*layoutedEdge.startPoint);
351 if (layoutedEdge.endPoint)
353 path.lineTo(*layoutedEdge.endPoint);
356 for (
int i = 0; i <= 10; ++i)
359 QPointF point = path.pointAtPercent(t);
361 minX =
std::min(
float(point.x()), minX);
362 minY =
std::min(
float(point.y()), minY);
365 SemanticGraphEdgeItem* item =
new SemanticGraphEdgeItem();
366 item->sourceDescriptor = sourceID;
367 item->targetDescriptor = targetID;
371 auto sourceVertex = graph.vertex(item->sourceDescriptor);
372 auto targetVertex = graph.vertex(item->targetDescriptor);
373 auto edge = graph.edge(sourceVertex, targetVertex);
374 auto& json = edge.attrib().json;
375 if (json.count(
"style"))
377 auto& style = json[
"style"];
378 if (style.count(
"color"))
380 Eigen::Vector4i scolor = style[
"color"];
381 QColor qcolor(scolor(0), scolor(1), scolor(2), scolor(3));
382 item->color = qcolor;
385 if (layoutedEdge.label.size() > 0)
387 item->label = QString::fromStdString(layoutedEdge.label);
388 item->labelPosition.setX(
double(layoutedEdge.labelPosX));
389 item->labelPosition.setY(
double(layoutedEdge.labelPosY));
399 graphicsScene->addItem(item);
402 SemanticGraphGlobalItem* global =
new SemanticGraphGlobalItem();
403 global->setRect(minX - 60.0f, minY - 40.0f, 100.0f, 30.0f);
410 graphicsScene->addItem(global);
413 void SemanticRelationViewerWidgetController::setPropertyView(nlohmann::json
const& attrs)
417 widget.propertiesView->setModel(&propertyModel);
418 widget.propertiesView->expandAll();
419 widget.propertiesView->resizeColumnToContents(0);
422 void SemanticRelationViewerWidgetController::highlightSelected(QGraphicsItem* selected)
424 for (QGraphicsItem* item : graphicsScene.items())
426 if (
auto* edge =
dynamic_cast<SemanticGraphEdgeItem*
>(item))
428 edge->selected = (edge == selected);
430 else if (
auto* vertex =
dynamic_cast<SemanticGraphVertexItem*
>(item))
432 vertex->selected = (vertex == selected);
434 else if (
auto* global =
dynamic_cast<SemanticGraphGlobalItem*
>(item))
436 global->selected = (global == selected);
439 graphicsScene.update();
442 void SemanticRelationViewerWidgetController::onZoomChanged(
double newZoom)
444 double inverseScale = 1.0 / graphicsSceneScale;
445 double zoom = inverseScale * newZoom;
446 widget.graphView->scale(zoom, zoom);
447 graphicsSceneScale = newZoom;