Controller.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-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 MemoryX::gui-plugins::SceneEditor
19 * @date 2015
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24#include "Controller.h"
25
26#include <fstream>
27#include <stdexcept>
28#include <vector>
29
30#include <QApplication>
31#include <QMetaObject>
32#include <QMetaType>
33#include <QThread>
34#include <QtDesigner/abstractpropertyeditor.h>
35
36#include <SimoxUtility/json.h>
37
40
42#include "DeselectOperation.h"
44#include "RemoveOperation.h"
45
46controller::Controller::Controller() : QObject(), lastSelected(NULL)
47{
48 qRegisterMetaType<OperationPtrListPtr>("OperationPtrListPtr");
49}
50
53{
54 controller::ControllerPtr controller(new Controller());
55
56 controller->undoRedoStack.reset(new controller::UndoRedoStack());
58 controller->memoryXController.reset(new memoryxcontroller::MemoryXController());
59 controller->shortcutController.reset(new gui::ShortcutController);
60
61 return controller;
62}
63
67
68void
69controller::Controller::execute(int flags, const OperationPtrListPtr& operations, bool blocking)
70{
71 QMetaObject::invokeMethod(
72 this,
73 "executeQtThread",
74 blocking ? (QApplication::instance()->thread() == QThread::currentThread() ||
75 QApplication::instance()->thread() == NULL
76 ? Qt::DirectConnection
77 : Qt::BlockingQueuedConnection)
78 : Qt::QueuedConnection,
79 Q_ARG(int, flags),
80 Q_ARG(OperationPtrListPtr, operations));
81}
82
83void
84controller::Controller::executeQtThread(int flags, const OperationPtrListPtr& operations)
85{
86 std::unique_lock lock(execute_mutex);
87 bool failed = false;
89 std::vector<controller::OperationPtr>::size_type i = 0;
90
91 for (; i != operations->size(); i++)
92 {
93 if (!operations->at(i)->isExecuteable())
94 {
95 std::unique_lock lock(queue_mutex);
96 queuedOperations.push_back(std::make_pair(flags, operations->at(i)));
97 continue;
98 }
99
101 {
102 std::string tmp = operations->at(i)->getObjectId();
103 OperationPtr op = operations->at(i);
104 try
105 {
106 op->executeOnWorkingMemory();
107 }
108 catch (std::exception& e)
109 {
110 ARMARX_ERROR_S << "executeOnWorkingMemory failed: " << op->getObjectId()
111 << e.what();
112 failed = true;
113 break;
114 }
115 catch (...)
116 {
117 failed = true;
118 break;
119 }
120
121 if (tmp != operations->at(i)->getObjectId())
122 {
123 if (getScene()->getObjectManager()->getObjectById(operations->at(i)->getObjectId()))
124 {
125 // the new id should never be used in the local scene
126 throw std::runtime_error("New id is already used in local scene.");
127 }
128
129 std::string newId = operations->at(i)->getObjectId();
130 undoRedoStack->updateObjectId(tmp, newId);
131
132 // if the current vector is not updated, update it
133 if (operations->at(i)->getObjectId() == newId)
134 {
135 for (auto ito = operations->begin(); ito != operations->end(); ito++)
136 {
137 if (ito->get()->getObjectId() == tmp)
138 {
139 ito->get()->setObjectId(newId);
140 }
141 else if (ito->get()->getObjectId() == newId)
142 {
143 ito->get()->setObjectId(tmp);
144 }
145 }
146 }
147
148 // The IDs of all operations in the vector were swapped.
149 // We have revert the swap on the current operation, because it was already the new ID.
150 operations->at(i)->setObjectId(newId);
151 }
152 }
153
155 {
156 std::string tmp = operations->at(i)->getObjectId();
157 OperationPtr op = operations->at(i);
158 try
159 {
160 op->executeOnScene();
161 }
162 catch (std::exception& e)
163 {
164 ARMARX_ERROR_S << "executeOnScene failed: " << op->getObjectId() << e.what();
165 failed = true;
166 break;
167 }
168 catch (...)
169 {
170 failed = true;
171 break;
172 }
173
174 if (tmp != operations->at(i)->getObjectId())
175 {
176 throw std::runtime_error("ID changed while execution on local Scene.");
177 }
178 }
179
180 objectIds.push_back(operations->at(i)->getObjectId());
181 }
182
183 if (failed)
184 {
185 std::cerr << "Could not execute operations. Trying to revert." << std::endl;
186
187 // try to revert operations
188 if (i > 0)
189 {
190 int j = i - 1; // i is the failed operation
191
192 for (; j >= 0; j--)
193 {
194 controller::OperationPtr inverse = operations->at(j)->createInverseOperation();
195
197 {
198 try
199 {
200 inverse->executeOnScene();
201 }
202 catch (...)
203 {
204 std::cerr << "Could not revert operation on the local scene. Trying to "
205 "revert the other operations."
206 << std::endl;
207 }
208 }
209
211 {
212 try
213 {
214 inverse->executeOnWorkingMemory();
215 }
216 catch (...)
217 {
218 std::cerr << "Could not revert operation on WorkingMemory. Trying to "
219 "revert the other operations."
220 << std::endl;
221 }
222 }
223 }
224 }
225 }
226 else if (controller::Controller::UNDOABLE & flags)
227 {
228 undoRedoStack->push(operations);
229 }
230
231 std::vector<scene3D::SceneObjectPtr> allSelected =
232 scene->getSelectionManager()->getAllSelected();
233 scene3D::SceneObjectPtr newSelected =
234 allSelected.size() == 0 ? NULL : allSelected[allSelected.size() - 1];
235
236 if (newSelected != lastSelected)
237 {
238 lastSelected = newSelected;
239 triggerSceneObjectSelected(newSelected);
240 }
241
242 qRegisterMetaType<controller::vector_string>("controller::vector_string");
243 emit operationExecuted(objectIds);
244}
245
246void
248{
249 {
250 std::unique_lock lock(queue_mutex);
251
252 for (auto it = queuedOperations.begin(); it != queuedOperations.end(); ++it)
253 {
254 controller::OperationPtrListPtr queuedOperationsTmp(
255 new std::vector<controller::OperationPtr>);
256 queuedOperationsTmp->push_back((*it).second);
257 this->execute((*it).first, queuedOperationsTmp, blocking);
258 }
259
260 queuedOperations.clear();
261 }
262}
263
264void
266{
267 if (!memoryXController->getWorkingMemoryController())
268 {
269 throw std::runtime_error("Not initialized");
270 }
271
272 // remove all local objects
273 std::vector<scene3D::SceneObjectPtr> currentLocalObjects =
274 scene->getObjectManager()->getAllObjects();
275
276 for (scene3D::SceneObjectPtr object : currentLocalObjects)
277 {
278 scene->getObjectManager()->removeObject(object);
279 }
280
281 // clear the UndoRedoStack
282 undoRedoStack->clear();
283 // load the current state of the WorkingMemory
284 memoryXController->getWorkingMemoryController()->addAllInstancesToLocalScene();
285 emit reloadScene();
286}
287
288const std::shared_ptr<scene3D::Scene>
290{
291 return scene;
292}
293
294const std::shared_ptr<memoryxcontroller::MemoryXController>
296{
297 return memoryXController;
298}
299
300const std::shared_ptr<gui::ShortcutController>
302{
303 return shortcutController;
304}
305
306void
312
313void
319
320void
322 const std::string& collection)
323{
324 emit objectClassSelected(objectClass, collection);
325}
326
327void
332
333void
338
339void
344
345void
347{
348 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
349 new std::vector<controller::OperationPtr>());
350 std::vector<scene3D::SceneObjectPtr> selectedObjects =
351 getScene()->getSelectionManager()->getAllSelected();
352
353 for (auto it = selectedObjects.rbegin(); it != selectedObjects.rend(); ++it)
354 {
356 getMemoryXController(), getScene(), (*it)->getObjectId()));
357 operations->push_back(operation);
358 }
359
360 std::vector<scene3D::SceneObjectPtr> allObjects =
361 getScene()->getObjectManager()->getAllObjects();
362 std::vector<scene3D::SceneGroupPtr> groups = getScene()->getGroupManager()->getAllGroups();
363
364 for (auto itG = groups.begin(); itG != groups.end(); ++itG)
365 {
366 std::vector<scene3D::SceneObjectPtr> groupObjects = (*itG)->getAllObjects();
367
368 for (auto it = groupObjects.rbegin(); it != groupObjects.rend(); ++it)
369 {
370 controller::OperationPtr removeFromGroupOperation(
372 getScene(),
373 (*itG)->getGroupId(),
374 (*it)->getObjectId()));
375 operations->push_back(removeFromGroupOperation);
376 }
377
379 getMemoryXController(), getScene(), (*itG)->getGroupId()));
380 operations->push_back(deleteGroupOperation);
381 }
382
383 for (auto it = allObjects.rbegin(); it != allObjects.rend(); ++it)
384 {
386 getMemoryXController(), getScene(), (*it)->getObjectId()));
387 operations->push_back(operation);
388 }
389
392 operations);
393}
394
395void
396controller::Controller::saveSnapshotAsJSON(std::string const& snapshotName)
397{
398 std::shared_ptr<scene3D::Scene> scene = getScene();
399 scene3D::SceneObjectManagerPtr objectManager = scene->getObjectManager();
400 std::vector<scene3D::SceneObjectPtr> objects = objectManager->getAllObjects();
401
403 for (scene3D::SceneObjectPtr const& object : objects)
404 {
405 armarx::objects::SceneObject& objData = data.objects.emplace_back();
406
407 SbVec3f translation = object->getTranslation();
408 objData.position.x() = translation[0];
409 objData.position.y() = translation[1];
410 objData.position.z() = translation[2];
411 objData.position *= 1000; // m to mm
412
413 SbRotation rotation = object->getRotation();
414 objData.orientation.x() = rotation[0];
415 objData.orientation.y() = rotation[1];
416 objData.orientation.z() = rotation[2];
417 objData.orientation.w() = rotation[3];
418
419 objData.collection = object->getCollection();
420
421 objData.className = object->getClassId();
422 }
423 nlohmann::json j = data;
424
425 // TODO: We have to be able to define the folder somehow
426 const std::string filename = snapshotName + ".json";
427 try
428 {
429 nlohmann::write_json(filename, j, 2);
430 ARMARX_INFO << "Saved snapshot as JSON at \n" << std::filesystem::absolute(filename);
431 }
432 catch (const std::ios_base::failure& e)
433 {
434 ARMARX_WARNING << "Failed to save snapshot as JSON at \n"
435 << std::filesystem::absolute(filename) << ":\n"
436 << e.what();
437 }
438}
uint8_t data[1]
auto newId
void execute(int flags, const OperationPtrListPtr &operations, bool blocking=true)
Executes multiple operations.
void undo()
Goes one step back in the history and undoes the corresponding Operations.
void triggerSceneObjectSelected(scene3D::SceneObjectPtr object)
Triggers signal controller:Controller::sceneObjectSelected with given parameter.
const std::shared_ptr< memoryxcontroller::MemoryXController > getMemoryXController() const
Returns the MemoryXController.
void triggerMinimapClicked()
Triggers signal controller:Controller::minimapClicked.
void triggerObjectsChanged(controller::vector_string objectIds)
Triggers signal controller:Controller::objectsChanged with given parameter.
void saveSnapshotAsJSON(std::string const &snapshotName)
void objectsChanged(controller::vector_string objectIds)
A signal which gets triggered, if objects are moved or rotated.
static const int UNDOABLE
A flag to save the executed operations to the history.
Definition Controller.h:80
void clearScene()
Deletes all objects in local scene and in WorkingMemory and deletes all groups.
void triggerObjectClassSelected(const std::string &objectClass, const std::string &collection)
Triggers signal controller:Controller::objectClassSelected with given parameter.
void reloadScene()
A signal which gets triggered, after the scene is reloaded.
const std::shared_ptr< gui::ShortcutController > getShortcutController() const
Returns the ShortcutController.
static const int EXECUTE_ON_WM
A Flag to execute operations on the WorkingMemory.
Definition Controller.h:66
const std::shared_ptr< scene3D::Scene > getScene() const
Returns the Scene.
void executeQueuedOperations(bool blocking=true)
Executes the Operations, which are queued because the object, which would be affected by this was bus...
void reloadLocalScene()
Deletes all objects in the local Scene and loads the current objects from the WorkingMemory in the Sc...
void redo()
Goes one step forward in the history and redoes the corresponding Operations.
static const int EXECUTE_ON_SCENE
A flag to execute operations on the Scene.
Definition Controller.h:73
static ControllerPtr create()
Creates a new instance of the Controller, initializes the Scene and the MemoryXController and returns...
void objectClassSelected(const std::string &objectClass, const std::string &collection)
A signal which gets triggered, after a class gets selected.
void minimapClicked()
A signal which gets triggered, after a click was performed on the minimap.
void sceneObjectSelected(scene3D::SceneObjectPtr object)
A signal which gets triggered, after a object gets selected.
~Controller() override
A destructor.
A operation to delete a group.
A operation to deselect a object.
A operation to removes a object from a existing group.
A Operation to remove a object in the scene and the WorkingMemory.
A Stack to save a history of Actions.
The class ShortcutController manages all shortcuts that can be set in the widget.
static ScenePtr create(controller::ControllerPtr controller)
Creates a new instance of the Scene.
Definition Scene.cpp:35
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::vector< std::string > vector_string
Definition Controller.h:47
std::shared_ptr< Controller > ControllerPtr
std::shared_ptr< std::vector< OperationPtr > > OperationPtrListPtr
std::shared_ptr< Operation > OperationPtr
std::shared_ptr< SceneObjectManager > SceneObjectManagerPtr
boost::intrusive_ptr< SceneObject > SceneObjectPtr
Eigen::Quaternionf orientation
Definition Scene.h:44
Eigen::Vector3f position
Definition Scene.h:43