PropertyBrowserWidget.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/* Qt headers */
25#include <QGridLayout>
26#include <QIcon>
27#include <QLabel>
28#include <QMap>
29
30#include <VirtualRobot/MathTools.h>
31
32/* boost headers */
33#include <boost/format.hpp>
34
35/* QtPropertyBrower headers */
36#include <ArmarXGui/libraries/qtpropertybrowser/src/QtProperty>
37
40
42 QWidget* parent) :
45 spinBoxFactory(new QtDoubleSpinBoxFactory(this)),
46 doubleManager(new QtDoublePropertyManager(this)),
47 groupManager(new QtGroupPropertyManager(this)),
48 stringManager(new QtStringPropertyManager(this))
49{
50 setHeaderVisible(false);
51
52 connect(doubleManager,
53 SIGNAL(valueChanged(QtProperty*, double)),
54 this,
55 SLOT(valueChanged(QtProperty*, double)));
56}
57
58void
60 std::string collection)
61{
62 this->clearAll();
63
64 if (objectClass && collection.length() != 0)
65 {
66 this->setClassAttributes(objectClass, collection, true);
67 this->setFactoryForManager(qobject_cast<QtDoublePropertyManager*>(doubleManager),
68 qobject_cast<QtDoubleSpinBoxFactory*>(spinBoxFactory));
69 }
70}
71
72void
74{
75 this->clearAll();
76
77 if (sceneObject)
78 {
79 currentSceneObject = sceneObject;
80 this->setInstanceAttributes();
81 this->setFactoryForManager(qobject_cast<QtDoublePropertyManager*>(doubleManager),
82 qobject_cast<QtDoubleSpinBoxFactory*>(spinBoxFactory));
83 }
84}
85
86void
87gui::PropertyBrowserWidget::valueChanged(QtProperty* property, double newValue)
88{
89 //only react to changes done in propertyBrowser
90 if (!propertyToId.contains(property) || !currentSceneObject ||
91 propertyToValue[property] == newValue)
92 {
93 return;
94 }
95
97 {
98 propertyToValue[property] = newValue;
99 std::shared_ptr<std::vector<controller::OperationPtr>> operations(
100 new std::vector<controller::OperationPtr>());
101 // Create RotateTranslateOperation for each object
103 controller->getMemoryXController(),
104 controller->getScene(),
105 currentSceneObject->getObjectId(),
106 currentSceneObject->getRotation(),
107 this->createNewRotation(property, newValue),
108 currentSceneObject->getTranslation(),
109 this->createNewTranslation(property, newValue)));
110 operations->push_back(operation);
114 operations);
115 }
116}
117
118void
119gui::PropertyBrowserWidget::setInstanceAttributes()
120{
121 QtProperty* instanceAttributes = groupManager->addProperty(tr("Instance Attributes"));
122
123 QtProperty* objectID = stringManager->addProperty(tr("Object ID"));
124 stringManager->setValue(objectID, QString::fromStdString(currentSceneObject->getObjectId()));
125 instanceAttributes->addSubProperty(objectID);
126
127 // rotation as quaternion properties
128 QtProperty* quaternion = groupManager->addProperty(tr("Rotation as Quaternion"));
129
130 float xQuat, yQuat, zQuat, wQuat;
131 currentSceneObject->getRotation().getValue(xQuat, yQuat, zQuat, wQuat);
132
133 QtProperty* quaternionX = doubleManager->addProperty(tr("x"));
134 QtProperty* quaternionY = doubleManager->addProperty(tr("y"));
135 QtProperty* quaternionZ = doubleManager->addProperty(tr("z"));
136 QtProperty* quaternionW = doubleManager->addProperty(tr("w"));
137
138 // update values in propertyToValue to not react to the comming changes
139 propertyToValue[quaternionX] = (double)xQuat;
140 propertyToValue[quaternionY] = (double)yQuat;
141 propertyToValue[quaternionZ] = (double)zQuat;
142 propertyToValue[quaternionW] = (double)wQuat;
143
144 doubleManager->setValue(quaternionX, (double)xQuat);
145 doubleManager->setValue(quaternionY, (double)yQuat);
146 doubleManager->setValue(quaternionZ, (double)zQuat);
147 doubleManager->setValue(quaternionW, (double)wQuat);
148
149 doubleManager->setSingleStep(quaternionW, 0.01);
150 doubleManager->setSingleStep(quaternionX, 0.01);
151 doubleManager->setSingleStep(quaternionY, 0.01);
152 doubleManager->setSingleStep(quaternionZ, 0.01);
153
154 quaternion->addSubProperty(quaternionX);
155 quaternion->addSubProperty(quaternionY);
156 quaternion->addSubProperty(quaternionZ);
157 quaternion->addSubProperty(quaternionW);
158
159 // rotation as roll-pitch-yaw properties
160 QtProperty* rpy = groupManager->addProperty(tr("Roll-Pitch-Yaw"));
161
162 QtProperty* roll = doubleManager->addProperty(tr("Roll in deg"));
163 QtProperty* pitch = doubleManager->addProperty(tr("Pitch in deg"));
164 QtProperty* yaw = doubleManager->addProperty(tr("Yaw in deg"));
165
166 Eigen::Vector3f rpyVector;
167 VirtualRobot::MathTools::eigen4f2rpy(
168 VirtualRobot::MathTools::quat2eigen4f(xQuat, yQuat, zQuat, wQuat), rpyVector);
169
170 float rollDeg, pitchDeg, yawDeg;
171
172 rollDeg = VirtualRobot::MathTools::rad2deg(rpyVector(0));
173 pitchDeg = VirtualRobot::MathTools::rad2deg(rpyVector(1));
174 yawDeg = VirtualRobot::MathTools::rad2deg(rpyVector(2));
175
176 propertyToValue[roll] = rollDeg;
177 propertyToValue[pitch] = pitchDeg;
178 propertyToValue[yaw] = yawDeg;
179
180 doubleManager->setValue(roll, rollDeg);
181 doubleManager->setValue(pitch, pitchDeg);
182 doubleManager->setValue(yaw, yawDeg);
183
184 doubleManager->setSingleStep(roll, 1);
185 doubleManager->setSingleStep(pitch, 1);
186 doubleManager->setSingleStep(yaw, 1);
187
188 rpy->addSubProperty(roll);
189 rpy->addSubProperty(pitch);
190 rpy->addSubProperty(yaw);
191
192 // translation properties
193 QtProperty* translation = groupManager->addProperty(tr("Translation"));
194
195 float xPos, yPos, zPos;
196 currentSceneObject->getTranslation().getValue(xPos, yPos, zPos);
197
198 QtProperty* translationX = doubleManager->addProperty(tr("X Position"));
199 QtProperty* translationY = doubleManager->addProperty(tr("Y Position"));
200 QtProperty* translationZ = doubleManager->addProperty(tr("Z Position"));
201
202 // update values in propertyToValue to not react to the comming changes
203 propertyToValue[translationX] = (double)xPos;
204 propertyToValue[translationY] = (double)yPos;
205 propertyToValue[translationZ] = (double)zPos;
206
207 doubleManager->setValue(translationX, (double)xPos);
208 doubleManager->setValue(translationY, (double)yPos);
209 doubleManager->setValue(translationZ, (double)zPos);
210
211 doubleManager->setSingleStep(translationX, 0.01);
212 doubleManager->setSingleStep(translationY, 0.01);
213 doubleManager->setSingleStep(translationZ, 0.01);
214
215 translation->addSubProperty(translationX);
216 translation->addSubProperty(translationY);
217 translation->addSubProperty(translationZ);
218
219 QtProperty* matrix = stringManager->addProperty(tr("Matrix"));
220
221 stringManager->setValue(matrix, QString::fromStdString(this->getMatrix()));
222
223 instanceAttributes->addSubProperty(quaternion);
224 instanceAttributes->addSubProperty(rpy);
225 instanceAttributes->addSubProperty(translation);
226 instanceAttributes->addSubProperty(matrix);
227
228 // store ids of changable properties
229 this->insertInMap(quaternionX, "x");
230 this->insertInMap(quaternionY, "y");
231 this->insertInMap(quaternionZ, "z");
232 this->insertInMap(quaternionW, "w");
233 this->insertInMap(roll, "Roll in deg");
234 this->insertInMap(pitch, "Pitch in deg");
235 this->insertInMap(yaw, "Yaw in deg");
236 this->insertInMap(translationX, "X Position");
237 this->insertInMap(translationY, "Y Position");
238 this->insertInMap(translationZ, "Z Position");
239 this->insertInMap(matrix, "Matrix");
240
241 QtBrowserItem* instancesSection = this->addProperty(instanceAttributes);
242 setExpanded(instancesSection, true);
243
244 std::string collection = currentSceneObject->getCollection();
245 std::string objectClass = currentSceneObject->getClassId();
246
247 if (controller::ControllerPtr controller = control.lock())
248 {
249 this->setClassAttributes(
250 controller->getMemoryXController()->getPriorKnowlegdeController()->getObjectClassPtr(
251 objectClass, collection),
252 collection,
253 false);
254 }
255}
256
257void
258gui::PropertyBrowserWidget::setClassAttributes(const memoryx::ObjectClassPtr& objectClass,
259 const std::string& collection,
260 bool expanded)
261{
262 QtProperty* classAttributes = groupManager->addProperty(tr("Class Attributes"));
263
264 QtProperty* className = stringManager->addProperty(tr("Class Name"));
265 stringManager->setValue(className, QString::fromStdString(objectClass->getName()));
266 classAttributes->addSubProperty(className);
267
268 QtProperty* collectionName = stringManager->addProperty(tr("Collection"));
269 stringManager->setValue(collectionName, QString::fromStdString(collection));
270 classAttributes->addSubProperty(collectionName);
271
272 QtProperty* objectClassID = stringManager->addProperty(tr("Object Class ID"));
273 stringManager->setValue(objectClassID, QString::fromStdString(objectClass->getId()));
274 classAttributes->addSubProperty(objectClassID);
275
276 std::map<std::string, std::string>::iterator iterator;
277
278
279 if (controller::ControllerPtr controller = control.lock())
280 {
281 std::map<std::string, std::string> attributes =
282 controller->getMemoryXController()->getPriorKnowlegdeController()->getAllAttributes(
283 objectClass);
284
285 for (iterator = attributes.begin(); iterator != attributes.end(); ++iterator)
286 {
287 QtProperty* property =
288 stringManager->addProperty(QString::fromStdString(iterator->first));
289 stringManager->setValue(property, QString::fromStdString(iterator->second));
290 classAttributes->addSubProperty(property);
291 }
292 }
293
294 QtBrowserItem* classesSection = this->addProperty(classAttributes);
295
296 setExpanded(classesSection, expanded);
297}
298
299void
300gui::PropertyBrowserWidget::clearAll()
301{
302 this->clear();
303 groupManager->clear();
304 doubleManager->clear();
305 stringManager->clear();
306 propertyToId.clear();
307 idToProperty.clear();
308 propertyToValue.clear();
309 currentSceneObject = NULL;
310}
311
312void
314{
315 if (!currentSceneObject || objectID != currentSceneObject->getObjectId())
316 {
317 return;
318 }
319
320 // Set new rotation values
321 float xQuat, yQuat, zQuat, wQuat;
322 currentSceneObject->getRotation().getValue(xQuat, yQuat, zQuat, wQuat);
323
324 // update values in propertyToValue to not react to the comming changes
325 propertyToValue[idToProperty[QString("x")]] = (double)xQuat;
326 propertyToValue[idToProperty[QString("y")]] = (double)yQuat;
327 propertyToValue[idToProperty[QString("z")]] = (double)zQuat;
328 propertyToValue[idToProperty[QString("w")]] = (double)wQuat;
329
330 doubleManager->setValue(idToProperty[QString("x")], (double)xQuat);
331 doubleManager->setValue(idToProperty[QString("y")], (double)yQuat);
332 doubleManager->setValue(idToProperty[QString("z")], (double)zQuat);
333 doubleManager->setValue(idToProperty[QString("w")], (double)wQuat);
334
335 Eigen::Vector3f rpyVector;
336 VirtualRobot::MathTools::eigen4f2rpy(
337 VirtualRobot::MathTools::quat2eigen4f(xQuat, yQuat, zQuat, wQuat), rpyVector);
338
339 float rollDeg, pitchDeg, yawDeg;
340
341 rollDeg = VirtualRobot::MathTools::rad2deg(rpyVector(0));
342 pitchDeg = VirtualRobot::MathTools::rad2deg(rpyVector(1));
343 yawDeg = VirtualRobot::MathTools::rad2deg(rpyVector(2));
344
345
346 propertyToValue[idToProperty[QString("Roll in deg")]] = rollDeg;
347 propertyToValue[idToProperty[QString("Pitch in deg")]] = pitchDeg;
348 propertyToValue[idToProperty[QString("Yaw in deg")]] = yawDeg;
349
350 doubleManager->setValue(idToProperty[QString("Roll in deg")], rollDeg);
351 doubleManager->setValue(idToProperty[QString("Pitch in deg")], pitchDeg);
352 doubleManager->setValue(idToProperty[QString("Yaw in deg")], yawDeg);
353
354 // Set new translation values
355 float xPos, yPos, zPos;
356 currentSceneObject->getTranslation().getValue(xPos, yPos, zPos);
357
358 // update values in propertyToValue to not react to the comming changes
359 propertyToValue[idToProperty[QString("X Position")]] = (double)xPos;
360 propertyToValue[idToProperty[QString("Y Position")]] = (double)yPos;
361 propertyToValue[idToProperty[QString("Z Position")]] = (double)zPos;
362
363 doubleManager->setValue(idToProperty[QString("X Position")], (double)xPos);
364 doubleManager->setValue(idToProperty[QString("Y Position")], (double)yPos);
365 doubleManager->setValue(idToProperty[QString("Z Position")], (double)zPos);
366
367
368 // Set new matrix
369 stringManager->setValue(idToProperty[QString("Matrix")],
370 QString::fromStdString(this->getMatrix()));
371}
372
373void
374gui::PropertyBrowserWidget::insertInMap(QtProperty* property, QString id)
375{
376 propertyToId[property] = id;
377 idToProperty[id] = property;
378}
379
380SbRotation
381gui::PropertyBrowserWidget::createNewRotation(QtProperty* property, double val)
382{
383 SbRotation newRotation = currentSceneObject->getRotation();
384 float xQuat, yQuat, zQuat, wQuat;
385 newRotation.getValue(xQuat, yQuat, zQuat, wQuat);
386
387 Eigen::Vector3f rpy;
388 VirtualRobot::MathTools::eigen4f2rpy(
389 VirtualRobot::MathTools::quat2eigen4f(xQuat, yQuat, zQuat, wQuat), rpy);
390 Eigen::Matrix4f rotationMatrix = Eigen::Matrix4f::Identity();
391 VirtualRobot::MathTools::Quaternion quaternion;
392
393 QString id = propertyToId[property];
394 if (id == QString("x") &&
395 !((float)val == yQuat && yQuat == zQuat && zQuat == wQuat && wQuat == 0.0f))
396 {
397 newRotation = SbRotation((float)val, yQuat, zQuat, wQuat);
398 }
399 else if (id == QString("y") &&
400 !((float)val == xQuat && xQuat == zQuat && zQuat == wQuat && wQuat == 0.0f))
401 {
402 newRotation = SbRotation(xQuat, (float)val, zQuat, wQuat);
403 }
404 else if (id == QString("z") &&
405 !((float)val == xQuat && xQuat == yQuat && yQuat == wQuat && wQuat == 0.0f))
406 {
407 newRotation = SbRotation(xQuat, yQuat, (float)val, wQuat);
408 }
409 else if (id == QString("w") &&
410 !((float)val == xQuat && xQuat == yQuat && yQuat == zQuat && zQuat == 0.0f))
411 {
412 newRotation = SbRotation(xQuat, yQuat, zQuat, (float)val);
413 }
414 else if (id == QString("Roll in deg"))
415 {
416 VirtualRobot::MathTools::rpy2eigen4f(
417 VirtualRobot::MathTools::deg2rad((float)val), rpy(1), rpy(2), rotationMatrix);
418 quaternion = VirtualRobot::MathTools::eigen4f2quat(rotationMatrix);
419 newRotation = SbRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
420 }
421 else if (id == QString("Pitch in deg"))
422 {
423 VirtualRobot::MathTools::rpy2eigen4f(
424 rpy(0), VirtualRobot::MathTools::deg2rad((float)val), rpy(2), rotationMatrix);
425 quaternion = VirtualRobot::MathTools::eigen4f2quat(rotationMatrix);
426 newRotation = SbRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
427 }
428 else if (id == QString("Yaw in deg"))
429 {
430 VirtualRobot::MathTools::rpy2eigen4f(
431 rpy(0), rpy(1), VirtualRobot::MathTools::deg2rad((float)val), rotationMatrix);
432 quaternion = VirtualRobot::MathTools::eigen4f2quat(rotationMatrix);
433 newRotation = SbRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
434 }
435 else
436 {
437 newRotation = currentSceneObject->getRotation();
438 }
439
440 // for debug purpose
441 float x, y, z, w;
442 newRotation.getValue(x, y, z, w);
443 Eigen::Vector3f rot;
444 VirtualRobot::MathTools::eigen4f2rpy(VirtualRobot::MathTools::quat2eigen4f(x, y, z, w), rot);
445
446 ARMARX_INFO_S << "Quat: \n" << x << ", \n" << y << ", \n" << z << ", \n" << w;
447 ARMARX_INFO_S << "RPY: \n" << rot;
448
449 return newRotation;
450}
451
452SbVec3f
453gui::PropertyBrowserWidget::createNewTranslation(QtProperty* property, double val)
454{
455 SbVec3f newPosition;
456 float xPos, yPos, zPos;
457 currentSceneObject->getTranslation().getValue(xPos, yPos, zPos);
458
459 QString id = propertyToId[property];
460
461 if (id == QString("X Position"))
462 {
463 newPosition = SbVec3f((float)val, yPos, zPos);
464 }
465 else if (id == QString("Y Position"))
466 {
467 newPosition = SbVec3f(xPos, (float)val, zPos);
468 }
469 else if (id == QString("Z Position"))
470 {
471 newPosition = SbVec3f(xPos, yPos, (float)val);
472 }
473 else
474 {
475 newPosition = currentSceneObject->getTranslation();
476 }
477
478 return newPosition;
479}
480
481std::string
482gui::PropertyBrowserWidget::getMatrix()
483{
484 SbMatrix sbMatrix;
485 sbMatrix.setRotate(currentSceneObject->getRotation());
486 sbMatrix.setTranslate(currentSceneObject->getTranslation());
487 std::string matrixToString;
488
489 for (int i = 0; i < 4; ++i)
490 {
491 matrixToString.append(boost::str(boost::format("%3.2g %3.2g %3.2g %3.2g") % sbMatrix[i][0] %
492 sbMatrix[i][1] % sbMatrix[i][2] % sbMatrix[i][3]));
493
494 if (i < 3)
495 {
496 matrixToString.append("\n");
497 }
498 }
499
500 return matrixToString;
501}
void setFactoryForManager(PropertyManager *manager, QtAbstractEditorFactory< PropertyManager > *factory)
The QtDoublePropertyManager provides and manages double properties.
The QtDoubleSpinBoxFactory class provides QDoubleSpinBox widgets for properties created by QtDoublePr...
The QtGroupPropertyManager provides and manages group properties.
The QtProperty class encapsulates an instance of a property.
void addSubProperty(QtProperty *property)
The QtStringPropertyManager provides and manages QString properties.
QtTreePropertyBrowser(QWidget *parent=0)
void setHeaderVisible(bool visible)
static const int UNDOABLE
A flag to save the executed operations to the history.
Definition Controller.h:80
static const int EXECUTE_ON_WM
A Flag to execute operations on the WorkingMemory.
Definition Controller.h:66
static const int EXECUTE_ON_SCENE
A flag to execute operations on the Scene.
Definition Controller.h:73
A operation to rotate and translate a object.
void setProperties(const memoryx::ObjectClassPtr &objectClass, std::string collection)
Fill property browser with class attributes of the given objectclass.
PropertyBrowserWidget(const controller::ControllerPtr &control, QWidget *parent=0)
Constructor.
void updateSceneObject(std::string objectID)
Updates the instance properties of the selected object in the scene given by its ID.
#define ARMARX_INFO_S
Definition Logging.h:202
This file is part of ArmarX.
std::shared_ptr< Controller > ControllerPtr
std::shared_ptr< Operation > OperationPtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35
boost::intrusive_ptr< SceneObject > SceneObjectPtr