pxmlw6n2f/Gazebo_Distributed_MPI/gazebo/gui/ModelListWidget.cc

2993 lines
100 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include <functional>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include <ignition/math/Angle.hh>
#include <sdf/sdf.hh>
#include "gazebo/common/Console.hh"
#include "gazebo/common/Events.hh"
#include "gazebo/common/Image.hh"
#include "gazebo/common/SystemPaths.hh"
#include "gazebo/gui/GuiEvents.hh"
#include "gazebo/gui/GuiIface.hh"
#include "gazebo/gui/ModelListWidget.hh"
#include "gazebo/gui/ModelListWidgetPrivate.hh"
#include "gazebo/gui/ModelRightMenu.hh"
#include "gazebo/gui/qtpropertybrowser/qttreepropertybrowser.h"
#include "gazebo/gui/qtpropertybrowser/qtvariantproperty.h"
#include "gazebo/rendering/Light.hh"
#include "gazebo/rendering/RenderEvents.hh"
#include "gazebo/rendering/RenderingIface.hh"
#include "gazebo/rendering/Scene.hh"
#include "gazebo/rendering/UserCamera.hh"
#include "gazebo/rendering/Visual.hh"
#include "gazebo/transport/Node.hh"
#include "gazebo/transport/Publisher.hh"
// avoid collision from Mac OS X's ConditionalMacros.h
#ifdef __MACH__
#undef TYPE_BOOL
#endif
using namespace gazebo;
using namespace gui;
extern ModelRightMenu *g_modelRightMenu;
/////////////////////////////////////////////////
ModelListWidget::ModelListWidget(QWidget *_parent)
: QWidget(_parent), dataPtr(new ModelListWidgetPrivate)
{
this->setObjectName("modelList");
this->dataPtr->requestMsg = NULL;
this->dataPtr->propMutex = new std::mutex();
this->dataPtr->receiveMutex = new std::mutex();
QVBoxLayout *mainLayout = new QVBoxLayout;
this->dataPtr->modelTreeWidget = new QTreeWidget();
this->dataPtr->modelTreeWidget->setObjectName("modelTreeWidget");
this->dataPtr->modelTreeWidget->setColumnCount(1);
this->dataPtr->modelTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
this->dataPtr->modelTreeWidget->header()->hide();
this->dataPtr->modelTreeWidget->setFocusPolicy(Qt::NoFocus);
this->dataPtr->modelTreeWidget->setSelectionMode(
QAbstractItemView::ExtendedSelection);
this->dataPtr->modelTreeWidget->setSelectionBehavior(
QAbstractItemView::SelectRows);
this->dataPtr->modelTreeWidget->setVerticalScrollMode(
QAbstractItemView::ScrollPerPixel);
connect(this->dataPtr->modelTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *,
int)),
this, SLOT(OnModelSelection(QTreeWidgetItem *, int)));
connect(this->dataPtr->modelTreeWidget,
SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(OnCustomContextMenu(const QPoint &)));
this->dataPtr->variantManager = new QtVariantPropertyManager();
this->dataPtr->propTreeBrowser = new QtTreePropertyBrowser();
this->dataPtr->propTreeBrowser->setObjectName("propTreeBrowser");
this->dataPtr->propTreeBrowser->setStyleSheet(
"QTreeView::branch:selected:active { background-color: transparent; }");
this->dataPtr->variantFactory = new QtVariantEditorFactory();
this->dataPtr->propTreeBrowser->setFactoryForManager(
this->dataPtr->variantManager,
this->dataPtr->variantFactory);
connect(this->dataPtr->variantManager,
SIGNAL(propertyChanged(QtProperty*)),
this, SLOT(OnPropertyChanged(QtProperty *)));
connect(this->dataPtr->propTreeBrowser,
SIGNAL(currentItemChanged(QtBrowserItem*)),
this, SLOT(OnCurrentPropertyChanged(QtBrowserItem *)));
QFrame *frame = new QFrame;
QVBoxLayout *frameLayout = new QVBoxLayout;
QSplitter *splitter = new QSplitter(Qt::Vertical, this);
splitter->addWidget(this->dataPtr->modelTreeWidget);
splitter->addWidget(this->dataPtr->propTreeBrowser);
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 2);
splitter->setCollapsible(0, false);
splitter->setCollapsible(1, false);
frameLayout->addWidget(splitter);
frameLayout->setContentsMargins(0, 0, 0, 0);
frame->setLayout(frameLayout);
mainLayout->addWidget(frame);
this->setLayout(mainLayout);
this->layout()->setContentsMargins(0, 0, 0, 0);
this->ResetTree();
this->dataPtr->connections.push_back(
gui::Events::ConnectModelUpdate(
std::bind(&ModelListWidget::OnModelUpdate, this,
std::placeholders::_1)));
this->dataPtr->connections.push_back(
gui::Events::ConnectLightUpdate(
std::bind(&ModelListWidget::OnLightUpdate, this,
std::placeholders::_1)));
this->dataPtr->connections.push_back(
rendering::Events::ConnectCreateScene(
std::bind(&ModelListWidget::OnCreateScene, this,
std::placeholders::_1)));
this->dataPtr->connections.push_back(
rendering::Events::ConnectRemoveScene(
std::bind(&ModelListWidget::OnRemoveScene, this,
std::placeholders::_1)));
this->dataPtr->connections.push_back(
event::Events::ConnectSetSelectedEntity(
std::bind(&ModelListWidget::OnSetSelectedEntity, this,
std::placeholders::_1, std::placeholders::_2)));
QTimer::singleShot(500, this, SLOT(Update()));
}
/////////////////////////////////////////////////
ModelListWidget::~ModelListWidget()
{
this->dataPtr->connections.clear();
delete this->dataPtr->propMutex;
delete this->dataPtr->receiveMutex;
}
/////////////////////////////////////////////////
void ModelListWidget::OnModelSelection(QTreeWidgetItem *_item, int /*_column*/)
{
if (_item)
{
std::string name = _item->data(0, Qt::UserRole).toString().toStdString();
this->dataPtr->propTreeBrowser->clear();
if (name == "Scene")
{
this->dataPtr->requestMsg = msgs::CreateRequest("scene_info",
this->dataPtr->selectedEntityName);
this->dataPtr->requestPub->Publish(*this->dataPtr->requestMsg);
}
else if (name == "Models")
{
this->dataPtr->modelsItem->setExpanded(
!this->dataPtr->modelsItem->isExpanded());
}
else if (name == "Lights")
{
this->dataPtr->lightsItem->setExpanded(
!this->dataPtr->lightsItem->isExpanded());
}
else if (name == "Physics")
{
this->dataPtr->requestMsg = msgs::CreateRequest("physics_info",
this->dataPtr->selectedEntityName);
this->dataPtr->requestPub->Publish(*this->dataPtr->requestMsg);
}
else if (name == "Spherical Coordinates")
{
this->dataPtr->requestMsg = msgs::CreateRequest(
"spherical_coordinates_info",
this->dataPtr->selectedEntityName);
this->dataPtr->requestPub->Publish(*this->dataPtr->requestMsg);
}
else if (name == "GUI")
{
QtVariantProperty *item = NULL;
rendering::UserCameraPtr cam = gui::get_active_camera();
if (!cam)
return;
// Create a camera item
QtProperty *topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("camera"));
auto cameraBrowser = this->dataPtr->propTreeBrowser->addProperty(topItem);
// Create and set the gui camera name
std::string cameraName = cam->Name();
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(cameraName.c_str());
topItem->addSubProperty(item);
item->setEnabled(false);
// Create and set the gui camera clip distance items
auto clipItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("clip"));
topItem->addSubProperty(clipItem);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("near"));
item->setValue(cam->NearClip());
clipItem->addSubProperty(item);
item->setEnabled(true);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("far"));
item->setValue(cam->FarClip());
clipItem->addSubProperty(item);
item->setEnabled(true);
// Create and set the gui camera pose
item = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
{
topItem->addSubProperty(item);
ignition::math::Pose3d cameraPose = cam->WorldPose();
this->FillPoseProperty(msgs::Convert(cameraPose), item);
// set expanded to true by default for easier viewing
this->dataPtr->propTreeBrowser->setExpanded(cameraBrowser, true);
for (auto browser : cameraBrowser->children())
{
this->dataPtr->propTreeBrowser->setExpanded(browser, true);
}
}
}
else
{
this->dataPtr->propTreeBrowser->clear();
event::Events::setSelectedEntity(name, "normal");
}
}
else
this->dataPtr->selectedEntityName.clear();
}
/////////////////////////////////////////////////
void ModelListWidget::OnSetSelectedEntity(const std::string &_name,
const std::string &/*_mode*/)
{
this->dataPtr->selectedEntityName = _name;
this->dataPtr->propTreeBrowser->clear();
if (!this->dataPtr->selectedEntityName.empty())
{
QTreeWidgetItem *mItem = this->ListItem(
this->dataPtr->selectedEntityName,
this->dataPtr->modelsItem);
QTreeWidgetItem *lItem = this->ListItem(
this->dataPtr->selectedEntityName,
this->dataPtr->lightsItem);
if (mItem)
{
if (this->dataPtr->requestPub)
{
this->dataPtr->requestMsg = msgs::CreateRequest("entity_info",
this->dataPtr->selectedEntityName);
this->dataPtr->requestPub->Publish(*this->dataPtr->requestMsg);
}
this->dataPtr->modelTreeWidget->setCurrentItem(mItem);
mItem->setExpanded(!mItem->isExpanded());
}
else if (lItem)
{
rendering::LightPtr light =
gui::get_active_camera()->GetScene()->GetLight(
this->dataPtr->selectedEntityName);
light->FillMsg(this->dataPtr->lightMsg);
this->dataPtr->propTreeBrowser->clear();
this->dataPtr->fillTypes.push_back("Light");
this->dataPtr->modelTreeWidget->setCurrentItem(lItem);
}
}
else if (this->dataPtr->modelTreeWidget->currentItem())
{
this->dataPtr->modelTreeWidget->currentItem()->setSelected(false);
}
}
/////////////////////////////////////////////////
void ModelListWidget::Update()
{
if (!this->dataPtr->fillTypes.empty())
{
std::lock_guard<std::mutex> lock(*this->dataPtr->propMutex);
this->dataPtr->fillingPropertyTree = true;
this->dataPtr->propTreeBrowser->clear();
if (this->dataPtr->fillTypes[0] == "Model")
this->FillPropertyTree(this->dataPtr->modelMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Link")
this->FillPropertyTree(this->dataPtr->linkMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Joint")
this->FillPropertyTree(this->dataPtr->jointMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Scene")
this->FillPropertyTree(this->dataPtr->sceneMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Physics")
this->FillPropertyTree(this->dataPtr->physicsMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Light")
this->FillPropertyTree(this->dataPtr->lightMsg, NULL);
else if (this->dataPtr->fillTypes[0] == "Spherical Coordinates")
this->FillPropertyTree(this->dataPtr->sphericalCoordMsg, NULL);
this->dataPtr->fillingPropertyTree = false;
this->dataPtr->fillTypes.pop_front();
}
if (!this->dataPtr->modelTreeWidget->currentItem())
{
std::lock_guard<std::mutex> lock(*this->dataPtr->propMutex);
this->dataPtr->propTreeBrowser->clear();
}
this->ProcessRemoveEntity();
this->ProcessModelMsgs();
this->ProcessLightMsgs();
QTimer::singleShot(1000, this, SLOT(Update()));
}
/////////////////////////////////////////////////
void ModelListWidget::OnModelUpdate(const msgs::Model &_msg)
{
std::lock_guard<std::mutex> lock(*this->dataPtr->receiveMutex);
msgs::Model msg;
msg.CopyFrom(_msg);
this->dataPtr->modelMsgs.push_back(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::OnLightUpdate(const msgs::Light &_msg)
{
std::lock_guard<std::mutex> lock(*this->dataPtr->receiveMutex);
msgs::Light msg;
msg.CopyFrom(_msg);
this->dataPtr->lightMsgs.push_back(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::ProcessModelMsgs()
{
std::lock_guard<std::mutex> lock(*this->dataPtr->receiveMutex);
for (auto iter = this->dataPtr->modelMsgs.begin();
iter != this->dataPtr->modelMsgs.end(); ++iter)
{
std::string name = (*iter).name();
QTreeWidgetItem *listItem = this->ListItem((*iter).name(),
this->dataPtr->modelsItem);
if (!listItem)
{
if (!(*iter).has_deleted() || !(*iter).deleted())
{
// Create an item for the model name
QTreeWidgetItem *topItem = new QTreeWidgetItem(
this->dataPtr->modelsItem,
QStringList(QString("%1").arg(QString::fromStdString(name))));
topItem->setData(0, Qt::UserRole, QVariant((*iter).name().c_str()));
this->dataPtr->modelTreeWidget->addTopLevelItem(topItem);
for (int i = 0; i < (*iter).link_size(); i++)
{
std::string linkName = (*iter).link(i).name();
int index = linkName.rfind("::") + 2;
std::string linkNameShort = linkName.substr(index,
linkName.size() - index);
QTreeWidgetItem *linkItem = new QTreeWidgetItem(topItem,
QStringList(QString("%1").arg(
QString::fromStdString(linkNameShort))));
linkItem->setData(0, Qt::UserRole, QVariant(linkName.c_str()));
linkItem->setData(1, Qt::UserRole, QVariant((*iter).name().c_str()));
linkItem->setData(2, Qt::UserRole, QVariant((*iter).id()));
linkItem->setData(3, Qt::UserRole, QVariant("Link"));
this->dataPtr->modelTreeWidget->addTopLevelItem(linkItem);
}
for (int i = 0; i < (*iter).joint_size(); i++)
{
std::string jointName = (*iter).joint(i).name();
int index = jointName.rfind("::") + 2;
std::string jointNameShort = jointName.substr(
index, jointName.size() - index);
QTreeWidgetItem *jointItem = new QTreeWidgetItem(topItem,
QStringList(QString("%1").arg(
QString::fromStdString(jointNameShort))));
jointItem->setData(0, Qt::UserRole, QVariant(jointName.c_str()));
jointItem->setData(3, Qt::UserRole, QVariant("Joint"));
this->dataPtr->modelTreeWidget->addTopLevelItem(jointItem);
}
}
}
else
{
if ((*iter).has_deleted() && (*iter).deleted())
{
int i = this->dataPtr->modelsItem->indexOfChild(listItem);
this->dataPtr->modelsItem->takeChild(i);
}
else
{
listItem->setText(0, (*iter).name().c_str());
listItem->setData(1, Qt::UserRole, QVariant((*iter).name().c_str()));
}
}
}
this->dataPtr->modelMsgs.clear();
}
/////////////////////////////////////////////////
void ModelListWidget::OnResponse(ConstResponsePtr &_msg)
{
if (!this->dataPtr->requestMsg || _msg->id() !=
this->dataPtr->requestMsg->id())
return;
if (_msg->has_type() && _msg->type() == this->dataPtr->modelMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->modelMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Model");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() ==
this->dataPtr->linkMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->linkMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Link");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() ==
this->dataPtr->jointMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->jointMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Joint");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() ==
this->dataPtr->sceneMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->sceneMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Scene");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() ==
this->dataPtr->physicsMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->physicsMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Physics");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() ==
this->dataPtr->lightMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->lightMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Light");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() &&
_msg->type() == this->dataPtr->sphericalCoordMsg.GetTypeName())
{
this->dataPtr->propMutex->lock();
this->dataPtr->sphericalCoordMsg.ParseFromString(_msg->serialized_data());
this->dataPtr->fillTypes.push_back("Spherical Coordinates");
this->dataPtr->propMutex->unlock();
}
else if (_msg->has_type() && _msg->type() == "error")
{
if (_msg->response() == "nonexistent")
{
this->dataPtr->removeEntityList.push_back(
this->dataPtr->selectedEntityName);
}
}
delete this->dataPtr->requestMsg;
this->dataPtr->requestMsg = NULL;
}
/////////////////////////////////////////////////
void ModelListWidget::RemoveEntity(const std::string &_name)
{
QTreeWidgetItem *items[2];
items[0] = this->dataPtr->modelsItem;
items[1] = this->dataPtr->lightsItem;
for (int i = 0; i < 2; ++i)
{
QTreeWidgetItem *listItem = this->ListItem(_name, items[i]);
if (listItem)
{
items[i]->takeChild(items[i]->indexOfChild(listItem));
this->dataPtr->propTreeBrowser->clear();
this->dataPtr->selectedEntityName.clear();
this->dataPtr->sdfElement.reset();
this->dataPtr->fillTypes.clear();
return;
}
}
}
/////////////////////////////////////////////////
QTreeWidgetItem *ModelListWidget::ListItem(const std::string &_name,
QTreeWidgetItem *_parent)
{
QTreeWidgetItem *listItem = NULL;
// Find an existing element with the name from the message
for (int i = 0; i < _parent->childCount() && !listItem; ++i)
{
QTreeWidgetItem *item = _parent->child(i);
std::string listData = item->data(0, Qt::UserRole).toString().toStdString();
if (listData == _name)
{
listItem = item;
break;
}
for (int j = 0; j < item->childCount(); j++)
{
QTreeWidgetItem *childItem = item->child(j);
listData = childItem->data(0, Qt::UserRole).toString().toStdString();
if (listData == _name)
{
listItem = childItem;
break;
}
}
}
return listItem;
}
/////////////////////////////////////////////////
void ModelListWidget::OnCustomContextMenu(const QPoint &_pt)
{
QTreeWidgetItem *item = this->dataPtr->modelTreeWidget->itemAt(_pt);
if (!item)
return;
// Check to see if the selected item is a model
int i = this->dataPtr->modelsItem->indexOfChild(item);
if (i >= 0)
{
g_modelRightMenu->Run(item->text(0).toStdString(),
this->dataPtr->modelTreeWidget->mapToGlobal(_pt),
ModelRightMenu::EntityTypes::MODEL);
return;
}
// Check to see if the selected item is a light
i = this->dataPtr->lightsItem->indexOfChild(item);
if (i >= 0)
{
g_modelRightMenu->Run(item->text(0).toStdString(),
this->dataPtr->modelTreeWidget->mapToGlobal(_pt),
ModelRightMenu::EntityTypes::LIGHT);
}
// Check to see if the selected item is a link
if (item->data(3, Qt::UserRole).toString().toStdString() == "Link")
{
g_modelRightMenu->Run(item->data(0, Qt::UserRole).toString().toStdString(),
this->dataPtr->modelTreeWidget->mapToGlobal(_pt),
ModelRightMenu::EntityTypes::LINK);
}
}
/////////////////////////////////////////////////
void ModelListWidget::OnCurrentPropertyChanged(QtBrowserItem *_item)
{
if (_item)
this->dataPtr->selectedProperty = _item->property();
else
this->dataPtr->selectedProperty = NULL;
}
/////////////////////////////////////////////////
void ModelListWidget::OnPropertyChanged(QtProperty *_item)
{
std::unique_lock<std::mutex> lock(*this->dataPtr->propMutex, std::defer_lock);
if (!lock.try_lock())
return;
if (this->dataPtr->selectedProperty != _item ||
this->dataPtr->fillingPropertyTree)
{
return;
}
QTreeWidgetItem *currentItem =
this->dataPtr->modelTreeWidget->currentItem();
if (!currentItem)
return;
if (this->dataPtr->modelsItem->indexOfChild(currentItem) != -1 ||
this->dataPtr->modelsItem->indexOfChild(currentItem->parent()) != -1)
this->ModelPropertyChanged(_item);
else if (this->dataPtr->lightsItem->indexOfChild(currentItem) != -1)
this->LightPropertyChanged(_item);
else if (currentItem == this->dataPtr->sceneItem)
this->ScenePropertyChanged(_item);
else if (currentItem == this->dataPtr->physicsItem)
this->PhysicsPropertyChanged(_item);
else if (currentItem == this->dataPtr->guiItem)
this->GUIPropertyChanged(_item);
}
/////////////////////////////////////////////////
void ModelListWidget::LightPropertyChanged(QtProperty * /*_item*/)
{
msgs::Light msg;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == "name")
msg.set_name(this->dataPtr->variantManager->value(
(*iter)).toString().toStdString());
else if ((*iter)->propertyName().toStdString() == "pose")
{
ignition::math::Pose3d pose;
pose.Set(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "x")).toDouble(),
this->dataPtr->variantManager->value(
this->ChildItem((*iter), "y")).toDouble(),
this->dataPtr->variantManager->value(
this->ChildItem((*iter), "z")).toDouble(),
this->dataPtr->variantManager->value(
this->ChildItem((*iter), "roll")).toDouble(),
this->dataPtr->variantManager->value(
this->ChildItem((*iter), "pitch")).toDouble(),
this->dataPtr->variantManager->value(
this->ChildItem((*iter), "yaw")).toDouble());
msgs::Set(msg.mutable_pose(), pose);
}
else if ((*iter)->propertyName().toStdString() == "range")
msg.set_range(this->dataPtr->variantManager->value((*iter)).toDouble());
else if ((*iter)->propertyName().toStdString() == "diffuse")
this->FillColorMsg((*iter), msg.mutable_diffuse());
else if ((*iter)->propertyName().toStdString() == "specular")
this->FillColorMsg((*iter), msg.mutable_specular());
else if ((*iter)->propertyName().toStdString() == "attenuation")
{
msg.set_attenuation_constant(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "constant")).toDouble());
msg.set_attenuation_linear(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "linear")).toDouble());
msg.set_attenuation_quadratic(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "quadratic")).toDouble());
}
else if ((*iter)->propertyName().toStdString() == "spot light")
{
msg.set_spot_inner_angle(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "inner angle")).toDouble());
msg.set_spot_outer_angle(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "outer angle")).toDouble());
msg.set_spot_falloff(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "falloff")).toDouble());
}
}
/// \TODO: Allow users to change light type
msg.set_type(this->dataPtr->lightType);
this->dataPtr->lightPub->Publish(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::GUIPropertyChanged(QtProperty *_item)
{
// Only camera pose editable for now
QtProperty *cameraProperty = this->ChildItem("camera");
if (!cameraProperty)
return;
QtProperty *cameraPoseProperty = this->ChildItem(cameraProperty, "pose");
if (cameraPoseProperty)
{
std::string changedProperty = _item->propertyName().toStdString();
if (changedProperty == "x"
|| changedProperty == "y"
|| changedProperty == "z"
|| changedProperty == "roll"
|| changedProperty == "pitch"
|| changedProperty == "yaw")
{
msgs::Pose poseMsg;
this->FillPoseMsg(cameraPoseProperty, &poseMsg, poseMsg.GetDescriptor());
rendering::UserCameraPtr cam = gui::get_active_camera();
if (cam)
cam->SetWorldPose(msgs::ConvertIgn(poseMsg));
}
}
QtProperty *cameraClipProperty = this->ChildItem(cameraProperty, "clip");
if (cameraPoseProperty)
{
std::string changedProperty = _item->propertyName().toStdString();
rendering::UserCameraPtr cam = gui::get_active_camera();
if (cam)
{
if (changedProperty == "near")
{
cam->SetClipDist(this->dataPtr->variantManager->value(
this->ChildItem(cameraClipProperty, "near")).toDouble(),
cam->FarClip());
}
else if (changedProperty == "far")
{
cam->SetClipDist(cam->NearClip(), this->dataPtr->variantManager->value(
this->ChildItem(cameraClipProperty, "far")).toDouble());
}
else
{
gzerr << "Unable to process user camera clip property["
<< changedProperty << "]\n";
}
}
else
{
gzerr << "Unable to get pointer to active user camera when setting clip "
<< "plane values. This should not happen.\n";
}
}
}
/////////////////////////////////////////////////
void ModelListWidget::PhysicsPropertyChanged(QtProperty * /*_item*/)
{
msgs::Physics msg;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == "gravity")
this->FillVector3Msg((*iter), msg.mutable_gravity());
else if ((*iter)->propertyName().toStdString() == "magnetic field")
this->FillVector3Msg((*iter), msg.mutable_magnetic_field());
else if ((*iter)->propertyName().toStdString() == "enable physics")
msg.set_enable_physics(
this->dataPtr->variantManager->value((*iter)).toBool());
else if ((*iter)->propertyName().toStdString() == "solver")
{
msg.set_iters(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "iterations")).toInt());
msg.set_sor(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "SOR")).toDouble());
}
else if ((*iter)->propertyName().toStdString() == "constraints")
{
msg.set_cfm(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "CFM")).toDouble());
msg.set_erp(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "ERP")).toDouble());
msg.set_contact_max_correcting_vel(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "max velocity")).toDouble());
msg.set_contact_surface_layer(this->dataPtr->variantManager->value(
this->ChildItem((*iter), "surface layer")).toDouble());
}
else if ((*iter)->propertyName().toStdString() == "real time update rate")
{
msg.set_real_time_update_rate(
this->dataPtr->variantManager->value((*iter)).toDouble());
}
else if ((*iter)->propertyName().toStdString() == "max step size")
{
msg.set_max_step_size(
this->dataPtr->variantManager->value((*iter)).toDouble());
}
}
msg.set_type(this->dataPtr->physicsType);
this->dataPtr->physicsPub->Publish(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::ScenePropertyChanged(QtProperty */*_item*/)
{
msgs::Scene msg;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == "ambient")
this->FillColorMsg((*iter), msg.mutable_ambient());
else if ((*iter)->propertyName().toStdString() == "background")
this->FillColorMsg((*iter), msg.mutable_background());
else if ((*iter)->propertyName().toStdString() == "shadows")
msg.set_shadows(this->dataPtr->variantManager->value((*iter)).toBool());
}
msg.set_name(gui::get_world());
this->dataPtr->scenePub->Publish(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::ModelPropertyChanged(QtProperty *_item)
{
msgs::Model msg;
google::protobuf::Message *fillMsg = &msg;
QTreeWidgetItem *currentItem = this->dataPtr->modelTreeWidget->currentItem();
// check if it's a link
if (currentItem->data(3, Qt::UserRole).toString().toStdString() == "Link")
{
// this->dataPtr->modelMsg may not have been set
// so get the model name from the current item
msg.set_name(currentItem->data(1, Qt::UserRole).toString().toStdString());
msg.set_id(currentItem->data(2, Qt::UserRole).toInt());
// set link id and strip link name.
msgs::Link *linkMsg = msg.add_link();
linkMsg->set_id(this->dataPtr->linkMsg.id());
std::string linkName = this->dataPtr->linkMsg.name();
size_t index = linkName.find_last_of("::");
if (index != std::string::npos)
linkName = linkName.substr(index+1);
linkMsg->set_name(linkName);
fillMsg = linkMsg;
}
else
{
msg.set_id(this->dataPtr->modelMsg.id());
msg.set_name(this->dataPtr->modelMsg.name());
}
const google::protobuf::Descriptor *descriptor = fillMsg->GetDescriptor();
const google::protobuf::Reflection *reflection = fillMsg->GetReflection();
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if (!this->HasChildItem(*iter, _item))
continue;
const google::protobuf::FieldDescriptor *field =
descriptor->FindFieldByName((*iter)->propertyName().toStdString());
// If the message has the field, and it's another message type, then
// recursively call FillMsg
if (field &&
field->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE)
{
if (field->is_repeated())
{
this->FillMsg((*iter), reflection->AddMessage(fillMsg, field),
field->message_type(), _item);
}
else
{
this->FillMsg((*iter),
reflection->MutableMessage(fillMsg, field),
field->message_type(), _item);
}
}
else if (field)
{
this->FillMsgField((*iter), fillMsg, reflection, field);
}
else
{
gzerr << "Unable to process["
<< (*iter)->propertyName().toStdString() << "]\n";
}
}
this->dataPtr->modelPub->Publish(msg);
}
/////////////////////////////////////////////////
void ModelListWidget::FillMsgField(QtProperty *_item,
google::protobuf::Message *_message,
const google::protobuf::Reflection *_reflection,
const google::protobuf::FieldDescriptor *_field)
{
if (_field->type() == google::protobuf::FieldDescriptor::TYPE_INT32)
_reflection->SetInt32(_message, _field,
this->dataPtr->variantManager->value(_item).toInt());
else if (_field->type() == google::protobuf::FieldDescriptor::TYPE_DOUBLE)
_reflection->SetDouble(_message, _field,
this->dataPtr->variantManager->value(_item).toDouble());
else if (_field->type() == google::protobuf::FieldDescriptor::TYPE_FLOAT)
_reflection->SetFloat(_message, _field,
this->dataPtr->variantManager->value(_item).toDouble());
else if (_field->type() == google::protobuf::FieldDescriptor::TYPE_BOOL)
_reflection->SetBool(_message, _field,
this->dataPtr->variantManager->value(_item).toBool());
else if (_field->type() == google::protobuf::FieldDescriptor::TYPE_STRING)
_reflection->SetString(_message, _field,
this->dataPtr->variantManager->value(_item).toString().toStdString());
else if (_field->type() == google::protobuf::FieldDescriptor::TYPE_UINT32)
_reflection->SetUInt32(_message, _field,
this->dataPtr->variantManager->value(_item).toUInt());
else
gzerr << "Unable to fill message field[" << _field->type() << "]\n";
}
/////////////////////////////////////////////////
void ModelListWidget::FillColorMsg(QtProperty *_item, msgs::Color *_msg)
{
_msg->set_r(this->dataPtr->variantManager->value(
this->ChildItem(_item, "Red")).toDouble() / 255.0);
_msg->set_g(this->dataPtr->variantManager->value(
this->ChildItem(_item, "Green")).toDouble() / 255.0);
_msg->set_b(this->dataPtr->variantManager->value(
this->ChildItem(_item, "Blue")).toDouble() / 255.0);
_msg->set_a(this->dataPtr->variantManager->value(
this->ChildItem(_item, "Alpha")).toDouble() / 255.0);
}
/////////////////////////////////////////////////
void ModelListWidget::FillVector3Msg(QtProperty *_item, msgs::Vector3d *_msg)
{
_msg->set_x(this->dataPtr->variantManager->value(
this->ChildItem(_item, "x")).toDouble());
_msg->set_y(this->dataPtr->variantManager->value(
this->ChildItem(_item, "y")).toDouble());
_msg->set_z(this->dataPtr->variantManager->value(
this->ChildItem(_item, "z")).toDouble());
}
/////////////////////////////////////////////////
void ModelListWidget::FillGeometryMsg(QtProperty *_item,
google::protobuf::Message *_message,
const google::protobuf::Descriptor *_descriptor,
QtProperty * /*_changedItem*/)
{
QtProperty *typeProperty = this->ChildItem(_item, "type");
std::string type = typeProperty->valueText().toStdString();
const google::protobuf::Reflection *reflection = _message->GetReflection();
reflection->SetEnum(_message, _descriptor->FindFieldByName("type"),
_descriptor->FindEnumValueByName(type));
// make sure type content is lowercase
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
const google::protobuf::FieldDescriptor *field =
_descriptor->FindFieldByName(type);
google::protobuf::Message *message =
_message->GetReflection()->MutableMessage(_message, field);
if (type == "box")
{
QtProperty *sizeProperty = this->ChildItem(_item, "size");
msgs::BoxGeom *boxMsg = (msgs::BoxGeom*)(message);
double xValue = this->dataPtr->variantManager->value(
this->ChildItem(sizeProperty, "x")).toDouble();
double yValue = this->dataPtr->variantManager->value(
this->ChildItem(sizeProperty, "y")).toDouble();
double zValue = this->dataPtr->variantManager->value(
this->ChildItem(sizeProperty, "z")).toDouble();
boxMsg->mutable_size()->set_x(xValue);
boxMsg->mutable_size()->set_y(yValue);
boxMsg->mutable_size()->set_z(zValue);
}
else if (type == "sphere")
{
QtProperty *radiusProperty = this->ChildItem(_item, "radius");
msgs::SphereGeom *sphereMsg = (msgs::SphereGeom*)(message);
sphereMsg->set_radius(
this->dataPtr->variantManager->value(radiusProperty).toDouble());
}
else if (type == "cylinder")
{
QtProperty *radiusProperty = this->ChildItem(_item, "radius");
QtProperty *lengthProperty = this->ChildItem(_item, "length");
msgs::CylinderGeom *cylinderMsg = (msgs::CylinderGeom*)(message);
cylinderMsg->set_radius(
this->dataPtr->variantManager->value(radiusProperty).toDouble());
cylinderMsg->set_length(
this->dataPtr->variantManager->value(lengthProperty).toDouble());
}
else if (type == "plane")
{
QtProperty *normalProperty = this->ChildItem(_item, "normal");
msgs::PlaneGeom *planeMessage = (msgs::PlaneGeom*)(message);
double xValue = this->dataPtr->variantManager->value(
this->ChildItem(normalProperty, "x")).toDouble();
double yValue = this->dataPtr->variantManager->value(
this->ChildItem(normalProperty, "y")).toDouble();
double zValue = this->dataPtr->variantManager->value(
this->ChildItem(normalProperty, "z")).toDouble();
planeMessage->mutable_normal()->set_x(xValue);
planeMessage->mutable_normal()->set_y(yValue);
planeMessage->mutable_normal()->set_z(zValue);
}
else if (type == "image")
{
QtProperty *fileProp = this->ChildItem(_item, "filename");
QtProperty *scaleProp = this->ChildItem(_item, "scale");
QtProperty *heightProp = this->ChildItem(_item, "height");
QtProperty *thresholdProp = this->ChildItem(_item, "threshold");
QtProperty *granularityProp = this->ChildItem(_item, "granularity");
msgs::ImageGeom *imageMessage = (msgs::ImageGeom*)(message);
imageMessage->set_uri(
this->dataPtr->variantManager->value(fileProp).toString().toStdString());
imageMessage->set_scale(
this->dataPtr->variantManager->value(scaleProp).toDouble());
imageMessage->set_height(
this->dataPtr->variantManager->value(heightProp).toDouble());
imageMessage->set_threshold(
this->dataPtr->variantManager->value(thresholdProp).toInt());
imageMessage->set_granularity(
this->dataPtr->variantManager->value(granularityProp).toInt());
}
else if (type == "heightmap")
{
QtProperty *sizeProp = this->ChildItem(_item, "size");
QtProperty *offsetProp = this->ChildItem(_item, "offset");
QtProperty *fileProp = this->ChildItem(_item, "filename");
double px, py, pz;
msgs::HeightmapGeom *heightmapMessage = (msgs::HeightmapGeom*)(message);
msgs::Set(heightmapMessage->mutable_image(),
common::Image(this->dataPtr->variantManager->value(
fileProp).toString().toStdString()));
px = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "x")).toDouble();
py = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "y")).toDouble();
pz = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "z")).toDouble();
heightmapMessage->mutable_size()->set_x(px);
heightmapMessage->mutable_size()->set_y(py);
heightmapMessage->mutable_size()->set_z(pz);
px = this->dataPtr->variantManager->value(
this->ChildItem(offsetProp, "x")).toDouble();
py = this->dataPtr->variantManager->value(
this->ChildItem(offsetProp, "y")).toDouble();
pz = this->dataPtr->variantManager->value(
this->ChildItem(offsetProp, "z")).toDouble();
heightmapMessage->mutable_origin()->set_x(px);
heightmapMessage->mutable_origin()->set_y(py);
heightmapMessage->mutable_origin()->set_z(pz);
}
else if (type == "mesh")
{
QtProperty *sizeProp = this->ChildItem(_item, "scale");
QtProperty *fileProp = this->ChildItem(_item, "filename");
double px, py, pz;
msgs::MeshGeom *meshMessage = (msgs::MeshGeom*)(message);
meshMessage->set_filename(this->dataPtr->variantManager->value(
fileProp).toString().toStdString());
px = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "x")).toDouble();
py = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "y")).toDouble();
pz = this->dataPtr->variantManager->value(
this->ChildItem(sizeProp, "z")).toDouble();
meshMessage->mutable_scale()->set_x(px);
meshMessage->mutable_scale()->set_y(py);
meshMessage->mutable_scale()->set_z(pz);
}
else
gzerr << "Unknown geom type[" << type << "]\n";
}
/////////////////////////////////////////////////
void ModelListWidget::FillPoseMsg(QtProperty *_item,
google::protobuf::Message *_message,
const google::protobuf::Descriptor *_descriptor)
{
const google::protobuf::Descriptor *posDescriptor;
const google::protobuf::FieldDescriptor *posField;
google::protobuf::Message *posMessage;
const google::protobuf::Reflection *posReflection;
const google::protobuf::Descriptor *orientDescriptor;
const google::protobuf::FieldDescriptor *orientField;
google::protobuf::Message *orientMessage;
const google::protobuf::Reflection *orientReflection;
posField = _descriptor->FindFieldByName("position");
posDescriptor = posField->message_type();
posMessage = _message->GetReflection()->MutableMessage(_message, posField);
posReflection = posMessage->GetReflection();
orientField = _descriptor->FindFieldByName("orientation");
orientDescriptor = orientField->message_type();
orientMessage = _message->GetReflection()->MutableMessage(
_message, orientField);
orientReflection = orientMessage->GetReflection();
this->FillMsgField(this->ChildItem(_item, "x"), posMessage, posReflection,
posDescriptor->FindFieldByName("x"));
this->FillMsgField(this->ChildItem(_item, "y"), posMessage, posReflection,
posDescriptor->FindFieldByName("y"));
this->FillMsgField(this->ChildItem(_item, "z"), posMessage, posReflection,
posDescriptor->FindFieldByName("z"));
double roll, pitch, yaw;
roll = this->dataPtr->variantManager->value(
this->ChildItem(_item, "roll")).toDouble();
pitch = this->dataPtr->variantManager->value(
this->ChildItem(_item, "pitch")).toDouble();
yaw = this->dataPtr->variantManager->value(
this->ChildItem(_item, "yaw")).toDouble();
ignition::math::Quaterniond q(roll, pitch, yaw);
orientReflection->SetDouble(
orientMessage,
orientDescriptor->FindFieldByName("x"),
q.X());
orientReflection->SetDouble(
orientMessage,
orientDescriptor->FindFieldByName("y"),
q.Y());
orientReflection->SetDouble(
orientMessage,
orientDescriptor->FindFieldByName("z"),
q.Z());
orientReflection->SetDouble(
orientMessage,
orientDescriptor->FindFieldByName("w"),
q.W());
}
/////////////////////////////////////////////////
void ModelListWidget::FillMsg(QtProperty *_item,
google::protobuf::Message *_message,
const google::protobuf::Descriptor *_descriptor,
QtProperty *_changedItem)
{
if (!_item)
return;
if (_item->propertyName().toStdString() == "link")
{
QtProperty *nameItem = this->ChildItem(_item, "name");
QtVariantProperty *idItem =
dynamic_cast<QtVariantProperty *>(this->ChildItem(_item, "id"));
((msgs::Link*)(_message))->set_name(nameItem->valueText().toStdString());
((msgs::Link*)(_message))->set_id(idItem->value().toInt());
}
else if (_item->propertyName().toStdString() == "collision")
{
QtProperty *nameItem = this->ChildItem(_item, "name");
QtVariantProperty *idItem =
dynamic_cast<QtVariantProperty *>(this->ChildItem(_item, "id"));
((msgs::Collision*)_message)->set_name(nameItem->valueText().toStdString());
((msgs::Collision*)(_message))->set_id(idItem->value().toInt());
}
if (_item->propertyName().toStdString() == "geometry" &&
this->HasChildItem(_item, _changedItem))
{
this->FillGeometryMsg(_item, _message, _descriptor, _changedItem);
}
else if (_item->propertyName().toStdString() == "pose")
{
if (this->HasChildItem(_item, _changedItem))
{
this->FillPoseMsg(_item, _message, _descriptor);
}
}
else
{
const google::protobuf::Reflection *reflection = _message->GetReflection();
QList<QtProperty*> properties = _item->subProperties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if (!this->HasChildItem(*iter, _changedItem))
continue;
const google::protobuf::FieldDescriptor *field =
_descriptor->FindFieldByName((*iter)->propertyName().toStdString());
// If the message has the field, and it's another message type, then
// recursively call FillMsg
if (field &&
field->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE)
{
if (field->is_repeated())
{
this->FillMsg((*iter), reflection->AddMessage(_message, field),
field->message_type(), _changedItem);
}
else
{
this->FillMsg((*iter),
reflection->MutableMessage(_message, field),
field->message_type(), _changedItem);
}
}
else if (field)
{
this->FillMsgField((*iter), _message, reflection, field);
}
else
{
gzerr << "Unable to process["
<< (*iter)->propertyName().toStdString() << "]\n";
}
}
}
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::PopChildItem(QList<QtProperty*> &_list,
const std::string &_name)
{
for (QList<QtProperty*>::iterator iter = _list.begin();
iter != _list.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == _name)
{
iter = _list.erase(iter);
return (*iter);
}
}
return NULL;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ParentItemValue(const std::string &_name)
{
QtProperty *result = NULL;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((*iter)->valueText().toStdString() == _name)
return NULL;
else if ((result = this->ParentItemValue(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ParentItemValue(QtProperty *_item,
const std::string &_name)
{
if (!_item)
return NULL;
QtProperty *result = NULL;
QList<QtProperty*> subProperties = _item->subProperties();
for (QList<QtProperty*>::iterator iter = subProperties.begin();
iter != subProperties.end(); ++iter)
{
if ((*iter)->valueText().toStdString() == _name)
{
result = _item;
break;
}
else if ((result = this->ParentItemValue(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ParentItem(const std::string &_name)
{
QtProperty *result = NULL;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == _name)
return NULL;
else if ((result = this->ParentItem(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ParentItem(QtProperty *_item,
const std::string &_name)
{
if (!_item)
return NULL;
QtProperty *result = NULL;
QList<QtProperty*> subProperties = _item->subProperties();
for (QList<QtProperty*>::iterator iter = subProperties.begin();
iter != subProperties.end(); ++iter)
{
if ((*iter)->propertyName().toStdString() == _name)
{
result = _item;
break;
}
else if ((result = this->ParentItem(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
bool ModelListWidget::HasChildItem(QtProperty *_parent, QtProperty *_child)
{
if (!_parent)
return false;
if (_parent == _child)
return true;
bool result = false;
QList<QtProperty*> subProperties = _parent->subProperties();
for (QList<QtProperty*>::iterator iter = subProperties.begin();
iter != subProperties.end(); ++iter)
{
if ((result = this->HasChildItem(*iter, _child)))
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ChildItemValue(const std::string &_name)
{
QtProperty *result = NULL;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((result = this->ChildItemValue(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ChildItemValue(QtProperty *_item,
const std::string &_name)
{
if (!_item)
return NULL;
if (_item->valueText().toStdString() == _name)
return _item;
QtProperty *result = NULL;
QList<QtProperty*> subProperties = _item->subProperties();
for (QList<QtProperty*>::iterator iter = subProperties.begin();
iter != subProperties.end(); ++iter)
{
if ((result = this->ChildItem(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ChildItem(const std::string &_name)
{
QtProperty *result = NULL;
QList<QtProperty*> properties = this->dataPtr->propTreeBrowser->properties();
for (QList<QtProperty*>::iterator iter = properties.begin();
iter != properties.end(); ++iter)
{
if ((result = this->ChildItem(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
QtProperty *ModelListWidget::ChildItem(QtProperty *_item,
const std::string &_name)
{
if (!_item)
return NULL;
if (_item->propertyName().toStdString() == _name)
return _item;
QtProperty *result = NULL;
QList<QtProperty*> subProperties = _item->subProperties();
for (QList<QtProperty*>::iterator iter = subProperties.begin();
iter != subProperties.end(); ++iter)
{
if ((result = this->ChildItem(*iter, _name)) != NULL)
break;
}
return result;
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::SphericalCoordinates &_msg,
QtProperty * /*_parent*/)
{
QtVariantProperty *item = NULL;
item = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::enumTypeId(), tr("Surface Model"));
QStringList types;
const google::protobuf::EnumDescriptor *surfaceModelEnum =
_msg.GetDescriptor()->FindEnumTypeByName("SurfaceModel");
if (!surfaceModelEnum)
{
gzerr << "Unable to get SurfaceModel enum descriptor from "
<< "SphericalCoordinates message. msgs::SphericalCoordinates "
<< "has probably changed\n";
types << "invalid";
}
else
{
for (int i = 0; i < surfaceModelEnum->value_count(); ++i)
types << surfaceModelEnum->value(i)->name().c_str();
}
item->setAttribute("enumNames", types);
item->setValue(0);
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("Latitude"));
item->setValue(_msg.latitude_deg());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("Longitude"));
item->setValue(_msg.longitude_deg());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("Elevation"));
item->setValue(_msg.elevation());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("Heading"));
item->setValue(_msg.heading_deg());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Joint &_msg,
QtProperty * /*_parent*/)
{
QtProperty *topItem = NULL;
QtVariantProperty *item = NULL;
// joint name
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.name().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
// joint type
if (_msg.has_type())
{
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("type"));
std::string jointType = msgs::ConvertJointType(_msg.type());
item->setValue(jointType.c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
// parent link
if (_msg.has_parent())
{
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("parent link"));
item->setValue(_msg.parent().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
// child link
if (_msg.has_child())
{
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("child link"));
item->setValue(_msg.child().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
// Pose value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
this->dataPtr->propTreeBrowser->addProperty(topItem);
topItem->setEnabled(false);
this->FillPoseProperty(_msg.pose(), topItem);
// Angle
for (int i = 0; i < _msg.angle_size(); ++i)
{
std::string angleName = "angle_" + std::to_string(i);
item = this->dataPtr->variantManager->addProperty(QVariant::String,
QString::fromStdString(angleName));
item->setValue(_msg.angle(i));
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
// Add joint axes if present
for (int i = 0; i < 2; ++i)
{
const msgs::Axis *axis = NULL;
std::string axisName;
if (i == 0 && _msg.has_axis1())
{
axis = &(_msg.axis1());
axisName = "axis1";
}
else if (i == 1 && _msg.has_axis2())
{
axis = &(_msg.axis2());
axisName = "axis2";
}
if (axis)
{
// Axis shape value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr(axisName.c_str()));
this->dataPtr->propTreeBrowser->addProperty(topItem);
topItem->setEnabled(false);
/// XYZ of the axis
QtProperty *xyzItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("xyz"));
topItem->addSubProperty(xyzItem);
xyzItem->setEnabled(false);
this->FillVector3dProperty(axis->xyz(), xyzItem);
// lower limit
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("lower"));
item->setValue(axis->limit_lower());
topItem->addSubProperty(item);
item->setEnabled(false);
// upper limit
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("upper"));
item->setValue(axis->limit_upper());
topItem->addSubProperty(item);
item->setEnabled(false);
// limit effort
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("effort"));
item->setValue(axis->limit_effort());
topItem->addSubProperty(item);
item->setEnabled(false);
// limit velocity
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("velocity"));
item->setValue(axis->limit_velocity());
topItem->addSubProperty(item);
item->setEnabled(false);
// damping
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("damping"));
item->setValue(axis->damping());
topItem->addSubProperty(item);
item->setEnabled(false);
// friction
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("friction"));
item->setValue(axis->friction());
topItem->addSubProperty(item);
item->setEnabled(false);
}
}
// gearbox
if (_msg.has_gearbox())
{
msgs::Joint::Gearbox gearboxMsg = _msg.gearbox();
if (gearboxMsg.has_gearbox_reference_body())
{
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("gearbox_reference_body"));
item->setValue(gearboxMsg.gearbox_reference_body().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
if (gearboxMsg.has_gearbox_ratio())
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("gearbox_ratio"));
item->setValue(gearboxMsg.gearbox_ratio());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
}
// screw
if (_msg.has_screw())
{
msgs::Joint::Screw screwMsg = _msg.screw();
if (screwMsg.has_thread_pitch())
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("thread_pitch"));
item->setValue(screwMsg.thread_pitch());
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
}
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Link &_msg,
QtProperty *_parent)
{
QtProperty *topItem = NULL;
QtProperty *inertialItem = NULL;
QtVariantProperty *item = NULL;
// id, store it but but make it hidden
QtBrowserItem *browserItem = NULL;
item = this->dataPtr->variantManager->addProperty(QVariant::String, tr("id"));
item->setValue(_msg.id());
this->AddProperty(item, _parent);
browserItem = this->dataPtr->propTreeBrowser->items(item)[0];
this->dataPtr->propTreeBrowser->setItemVisible(browserItem, false);
// name
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.name().c_str());
this->AddProperty(item, _parent);
// TODO: setting link name currently causes problems
item->setEnabled(false);
// Self-collide
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("self_collide"));
if (_msg.has_self_collide())
item->setValue(_msg.self_collide());
else
item->setValue(true);
this->AddProperty(item, _parent);
item->setEnabled(false);
// gravity
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("gravity"));
if (_msg.has_gravity())
item->setValue(_msg.gravity());
else
item->setValue(true);
this->AddProperty(item, _parent);
// kinematic
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("kinematic"));
if (_msg.has_kinematic())
item->setValue(_msg.kinematic());
else
item->setValue(false);
this->AddProperty(item, _parent);
// canonical
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("canonical"));
if (_msg.has_canonical())
item->setValue(_msg.canonical());
else
item->setValue(false);
this->AddProperty(item, _parent);
item->setEnabled(false);
// pose
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
this->AddProperty(topItem, _parent);
this->FillPoseProperty(_msg.pose(), topItem);
if (_msg.has_canonical() && _msg.canonical())
topItem->setEnabled(false);
// Inertial
inertialItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("inertial"));
this->AddProperty(inertialItem, _parent);
// TODO: disable setting inertial properties until there are tests
// in place to verify the functionality
inertialItem->setEnabled(false);
// Inertial::Mass
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("mass"));
if (_msg.inertial().has_mass())
item->setValue(_msg.inertial().mass());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::ixx
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("ixx"));
if (_msg.inertial().has_ixx())
item->setValue(_msg.inertial().ixx());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::ixy
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("ixy"));
if (_msg.inertial().has_ixy())
item->setValue(_msg.inertial().ixy());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::ixz
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("ixz"));
if (_msg.inertial().has_ixz())
item->setValue(_msg.inertial().ixz());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::iyy
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("iyy"));
if (_msg.inertial().has_iyy())
item->setValue(_msg.inertial().iyy());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::iyz
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("iyz"));
if (_msg.inertial().has_iyz())
item->setValue(_msg.inertial().iyz());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
// Inertial::izz
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("izz"));
if (_msg.inertial().has_izz())
item->setValue(_msg.inertial().izz());
else
item->setValue(0.0);
inertialItem->addSubProperty(item);
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
inertialItem->addSubProperty(topItem);
this->FillPoseProperty(_msg.inertial().pose(), topItem);
for (int i = 0; i < _msg.collision_size(); i++)
{
QtVariantProperty *prop;
prop = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("collision"));
prop->setToolTip(tr(_msg.collision(i).name().c_str()));
this->AddProperty(prop, _parent);
this->FillPropertyTree(_msg.collision(i), prop);
// TODO: disable setting collision properties until there are tests
// in place to verify the functionality
prop->setEnabled(false);
}
for (int i = 0; i < _msg.visual_size(); i++)
{
QtVariantProperty *prop;
prop = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("visual"));
prop->setToolTip(tr(_msg.visual(i).name().c_str()));
this->AddProperty(prop, _parent);
this->FillPropertyTree(_msg.visual(i), prop);
// TODO: disable setting visual properties until there are tests
// in place to verify the functionality
prop->setEnabled(false);
}
for (int i = 0; i < _msg.sensor_size(); i++)
{
QtVariantProperty *prop;
prop = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), "sensor");
prop->setToolTip(tr(_msg.sensor(i).name().c_str()));
this->AddProperty(prop, _parent);
// this->FillPropertyTree(_msg.sensor(i), prop);
}
// battery
for (int i = 0; i < _msg.battery_size(); ++i)
{
QtVariantProperty *batteryItem;
batteryItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("battery"));
batteryItem->setToolTip(tr(_msg.battery(i).name().c_str()));
this->AddProperty(batteryItem, _parent);
batteryItem->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.battery(i).name().c_str());
batteryItem->addSubProperty(item);
// Battery::Voltage
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("voltage"));
item->setValue(_msg.battery(i).voltage());
batteryItem->addSubProperty(item);
}
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Collision &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding collision elements."
<< " This should never happen." << std::endl;
return;
}
QtProperty *topItem = NULL;
QtVariantProperty *item = NULL;
// id, store it but but make it hidden
QtBrowserItem *browserItem = NULL;
item = this->dataPtr->variantManager->addProperty(QVariant::String, tr("id"));
item->setValue(_msg.id());
_parent->addSubProperty(item);
browserItem = this->dataPtr->propTreeBrowser->items(item)[0];
this->dataPtr->propTreeBrowser->setItemVisible(browserItem, false);
// name
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.name().c_str());
_parent->addSubProperty(item);
// Laser Retro value
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("laser_retro"));
if (_msg.has_laser_retro())
item->setValue(_msg.laser_retro());
else
item->setValue(0.0);
_parent->addSubProperty(item);
// Pose value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("pose"));
_parent->addSubProperty(topItem);
this->FillPoseProperty(_msg.pose(), topItem);
// Geometry shape value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("geometry"));
_parent->addSubProperty(topItem);
this->FillPropertyTree(_msg.geometry(), topItem);
// Surface value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("surface"));
_parent->addSubProperty(topItem);
this->FillPropertyTree(_msg.surface(), topItem);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Surface &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding surface elements."
<< " This should never happen." << std::endl;
return;
}
QtProperty *frictionItem = NULL;
QtProperty *torsionalItem = NULL;
QtProperty *odeItem = NULL;
QtVariantProperty *item = NULL;
// Restituion Coefficient
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("restitution_coefficient"));
item->setValue(_msg.restitution_coefficient());
_parent->addSubProperty(item);
// Bounce Threshold
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("bounce_threshold"));
item->setValue(_msg.bounce_threshold());
_parent->addSubProperty(item);
// Soft CFM
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("soft_cfm"));
item->setValue(_msg.soft_cfm());
_parent->addSubProperty(item);
// Soft ERP
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("soft_erp"));
item->setValue(_msg.soft_erp());
_parent->addSubProperty(item);
// KP
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("kp"));
item->setValue(_msg.kp());
_parent->addSubProperty(item);
// KD
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("kd"));
item->setValue(_msg.kd());
_parent->addSubProperty(item);
// max vel
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("max_vel"));
item->setValue(_msg.max_vel());
_parent->addSubProperty(item);
// min depth
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("min_depth"));
item->setValue(_msg.min_depth());
_parent->addSubProperty(item);
// Friction
frictionItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("friction"));
_parent->addSubProperty(frictionItem);
// Mu
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("mu"));
item->setValue(_msg.friction().mu());
frictionItem->addSubProperty(item);
// Mu2
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("mu2"));
item->setValue(_msg.friction().mu2());
frictionItem->addSubProperty(item);
// slip1
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("slip1"));
item->setValue(_msg.friction().slip1());
frictionItem->addSubProperty(item);
// slip2
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("slip2"));
item->setValue(_msg.friction().slip2());
frictionItem->addSubProperty(item);
// Fdir1
QtProperty *fdirItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("fdir1"));
frictionItem->addSubProperty(fdirItem);
this->FillVector3dProperty(_msg.friction().fdir1(), fdirItem);
// Torsional
torsionalItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("torsional"));
frictionItem->addSubProperty(torsionalItem);
// Coefficient
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("coefficient"));
item->setValue(_msg.friction().torsional().coefficient());
torsionalItem->addSubProperty(item);
// Use patch radius
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("use_patch_radius"));
item->setValue(_msg.friction().torsional().use_patch_radius());
torsionalItem->addSubProperty(item);
// Patch radius
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("patch_radius"));
item->setValue(_msg.friction().torsional().patch_radius());
torsionalItem->addSubProperty(item);
// Surface radius
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("surface_radius"));
item->setValue(_msg.friction().torsional().surface_radius());
torsionalItem->addSubProperty(item);
// ODE
odeItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("ode"));
torsionalItem->addSubProperty(odeItem);
// slip torsional
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("slip"));
item->setValue(_msg.friction().torsional().ode().slip());
odeItem->addSubProperty(item);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Geometry &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding geometry elements."
<< " This should never happen." << std::endl;
return;
}
QtVariantProperty *item = NULL;
item = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::enumTypeId(), tr("type"));
QStringList types;
types << "BOX" << "SPHERE" << "CYLINDER" << "PLANE" << "MESH" << "IMAGE"
<< "HEIGHTMAP";
item->setAttribute("enumNames", types);
_parent->addSubProperty(item);
if (_msg.type() == msgs::Geometry::BOX)
{
item->setValue(0);
QtProperty *sizeItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("size"));
_parent->addSubProperty(sizeItem);
this->FillVector3dProperty(_msg.box().size(), sizeItem);
}
else if (_msg.type() == msgs::Geometry::SPHERE)
{
item->setValue(1);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("radius"));
item->setValue(_msg.sphere().radius());
_parent->addSubProperty(item);
}
else if (_msg.type() == msgs::Geometry::CYLINDER)
{
item->setValue(2);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("radius"));
item->setValue(_msg.cylinder().radius());
_parent->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("length"));
item->setValue(_msg.cylinder().length());
_parent->addSubProperty(item);
}
else if (_msg.type() == msgs::Geometry::PLANE)
{
item->setValue(3);
QtProperty *normalItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("normal"));
_parent->addSubProperty(normalItem);
this->FillVector3dProperty(_msg.plane().normal(), normalItem);
}
else if (_msg.type() == msgs::Geometry::MESH)
{
item->setValue(4);
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("filename"));
item->setValue(_msg.mesh().filename().c_str());
_parent->addSubProperty(item);
QtProperty *sizeItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("scale"));
_parent->addSubProperty(sizeItem);
this->FillVector3dProperty(_msg.mesh().scale(), sizeItem);
}
else if (_msg.type() == msgs::Geometry::IMAGE)
{
item->setValue(5);
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("uri"));
item->setValue(_msg.image().uri().c_str());
_parent->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("scale"));
item->setValue(_msg.image().scale());
_parent->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("height"));
item->setValue(_msg.image().height());
_parent->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Int,
tr("threshold"));
item->setValue(_msg.image().threshold());
_parent->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Int,
tr("granularity"));
item->setValue(_msg.image().granularity());
_parent->addSubProperty(item);
}
else if (_msg.type() == msgs::Geometry::HEIGHTMAP)
{
item->setValue(6);
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("uri"));
item->setValue(_msg.image().uri().c_str());
_parent->addSubProperty(item);
QtProperty *sizeItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("size"));
_parent->addSubProperty(sizeItem);
this->FillVector3dProperty(_msg.heightmap().size(), sizeItem);
sizeItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("offset"));
_parent->addSubProperty(sizeItem);
this->FillVector3dProperty(_msg.heightmap().origin(), sizeItem);
}
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Visual &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding visual elements."
<< " This should never happen." << std::endl;
return;
}
QtProperty *topItem = NULL;
QtVariantProperty *item = NULL;
// Name value
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.name().c_str());
_parent->addSubProperty(item);
// Laser Retro value
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("laser_retro"));
if (_msg.has_laser_retro())
item->setValue(_msg.laser_retro());
else
item->setValue(0.0);
_parent->addSubProperty(item);
// cast shadows value
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("cast_shadows"));
if (_msg.has_cast_shadows())
item->setValue(_msg.cast_shadows());
else
item->setValue(true);
_parent->addSubProperty(item);
// transparency
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("transparency"));
if (_msg.has_transparency())
item->setValue(_msg.transparency());
else
item->setValue(0.0);
_parent->addSubProperty(item);
// Pose value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("pose"));
_parent->addSubProperty(topItem);
this->FillPoseProperty(_msg.pose(), topItem);
// Geometry shape value
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(),
tr("geometry"));
_parent->addSubProperty(topItem);
this->FillPropertyTree(_msg.geometry(), topItem);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Model &_msg,
QtProperty * /*_parent*/)
{
QtProperty *topItem = NULL;
QtVariantProperty *item = NULL;
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
item->setValue(_msg.name().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
// TODO: setting model name currently causes problems
item->setEnabled(false);
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("is_static"));
if (_msg.has_is_static())
item->setValue(_msg.is_static());
else
item->setValue(false);
/// \todo Dynamically setting a model static doesn't currently work.
item->setEnabled(false);
this->dataPtr->propTreeBrowser->addProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("self_collide"));
if (_msg.has_self_collide())
item->setValue(_msg.self_collide());
else
item->setValue(false);
item->setEnabled(false);
this->dataPtr->propTreeBrowser->addProperty(item);
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
QtBrowserItem *bItem = this->dataPtr->propTreeBrowser->addProperty(topItem);
this->dataPtr->propTreeBrowser->setExpanded(bItem, false);
this->FillPoseProperty(_msg.pose(), topItem);
for (int i = 0; i < _msg.link_size(); i++)
{
QtVariantProperty *prop;
prop = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("link"));
prop->setToolTip(tr(_msg.link(i).name().c_str()));
bItem = this->dataPtr->propTreeBrowser->addProperty(prop);
this->dataPtr->propTreeBrowser->setExpanded(bItem, false);
this->FillPropertyTree(_msg.link(i), prop);
}
}
/////////////////////////////////////////////////
void ModelListWidget::FillVector3dProperty(const msgs::Vector3d &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding Vector3d elements."
<< " This should never happen." << std::endl;
return;
}
QtVariantProperty *item;
ignition::math::Vector3d value;
value = msgs::ConvertIgn(_msg);
value.Round(6);
// Add X value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "x"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double, "x");
_parent->addSubProperty(item);
}
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
item->setValue(value.X());
// Add Y value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "y"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double, "y");
_parent->addSubProperty(item);
}
static_cast<QtVariantPropertyManager*>(
this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
item->setValue(value.Y());
// Add Z value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "z"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double, "z");
_parent->addSubProperty(item);
}
static_cast<QtVariantPropertyManager*>(
this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
item->setValue(value.Z());
}
/////////////////////////////////////////////////
void ModelListWidget::FillPoseProperty(const msgs::Pose &_msg,
QtProperty *_parent)
{
if (!_parent)
{
gzwarn << "Null QtProperty parent, not adding pose elements."
<< " This should never happen." << std::endl;
return;
}
QtVariantProperty *item;
ignition::math::Pose3d value;
value = msgs::ConvertIgn(_msg);
value.Round(6);
ignition::math::Vector3d rpy = value.Rot().Euler();
rpy.Round(6);
this->FillVector3dProperty(_msg.position(), _parent);
// Add Roll value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "roll"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double, "roll");
_parent->addSubProperty(item);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "decimals", 6);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "singleStep", 0.05);
}
item->setValue(rpy.X());
// Add Pitch value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "pitch"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
"pitch");
_parent->addSubProperty(item);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "decimals", 6);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "singleStep", 0.05);
}
item->setValue(rpy.Y());
// Add Yaw value
item = static_cast<QtVariantProperty*>(this->ChildItem(_parent, "yaw"));
if (!item)
{
item = this->dataPtr->variantManager->addProperty(QVariant::Double, "yaw");
_parent->addSubProperty(item);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "decimals", 6);
static_cast<QtVariantPropertyManager *>(
this->dataPtr->variantFactory->propertyManager(
item))->setAttribute(item, "singleStep", 0.05);
}
item->setValue(rpy.Z());
}
/////////////////////////////////////////////////
void ModelListWidget::OnRequest(ConstRequestPtr &_msg)
{
if (_msg->request() == "entity_delete")
{
this->dataPtr->removeEntityList.push_back(_msg->data());
}
}
/////////////////////////////////////////////////
void ModelListWidget::ProcessRemoveEntity()
{
for (auto iter = this->dataPtr->removeEntityList.begin();
iter != this->dataPtr->removeEntityList.end(); ++iter)
{
this->RemoveEntity(*iter);
}
this->dataPtr->removeEntityList.clear();
}
/////////////////////////////////////////////////
void ModelListWidget::OnRemoveScene(const std::string &/*_name*/)
{
this->ResetTree();
this->dataPtr->propTreeBrowser->clear();
if (this->dataPtr->node)
this->dataPtr->node->Fini();
this->dataPtr->node.reset();
this->dataPtr->requestPub.reset();
this->dataPtr->modelPub.reset();
this->dataPtr->scenePub.reset();
this->dataPtr->physicsPub.reset();
this->dataPtr->lightPub.reset();
this->dataPtr->responseSub.reset();
this->dataPtr->requestSub.reset();
}
/////////////////////////////////////////////////
void ModelListWidget::OnCreateScene(const std::string &_name)
{
this->ResetTree();
this->dataPtr->propTreeBrowser->clear();
this->InitTransport(_name);
// this->requestMsg = msgs::CreateRequest("scene_info");
// this->requestPub->Publish(*this->requestMsg);
}
/////////////////////////////////////////////////
void ModelListWidget::InitTransport(const std::string &_name)
{
if (this->dataPtr->node)
{
this->dataPtr->node->Fini();
this->dataPtr->node.reset();
this->dataPtr->requestPub.reset();
this->dataPtr->modelPub.reset();
this->dataPtr->scenePub.reset();
this->dataPtr->physicsPub.reset();
this->dataPtr->lightPub.reset();
this->dataPtr->responseSub.reset();
this->dataPtr->requestSub.reset();
}
this->dataPtr->node = transport::NodePtr(new transport::Node());
if (_name.empty())
this->dataPtr->node->TryInit(common::Time::Maximum());
else
this->dataPtr->node->Init(_name);
this->dataPtr->modelPub = this->dataPtr->node->Advertise<msgs::Model>(
"~/model/modify");
this->dataPtr->scenePub = this->dataPtr->node->Advertise<msgs::Scene>(
"~/scene");
this->dataPtr->physicsPub = this->dataPtr->node->Advertise<msgs::Physics>(
"~/physics");
this->dataPtr->lightPub = this->dataPtr->node->Advertise<msgs::Light>(
"~/light/modify");
this->dataPtr->requestPub = this->dataPtr->node->Advertise<msgs::Request>(
"~/request");
this->dataPtr->responseSub = this->dataPtr->node->Subscribe("~/response",
&ModelListWidget::OnResponse, this);
this->dataPtr->requestSub = this->dataPtr->node->Subscribe("~/request",
&ModelListWidget::OnRequest, this, false);
}
/////////////////////////////////////////////////
void ModelListWidget::ResetTree()
{
this->dataPtr->modelTreeWidget->clear();
// Create the top level of items in the tree widget
{
// GUI item
this->dataPtr->guiItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("GUI"))));
this->dataPtr->guiItem->setData(0, Qt::UserRole, QVariant(tr("GUI")));
this->dataPtr->modelTreeWidget->addTopLevelItem(this->dataPtr->guiItem);
// Scene item
this->ResetScene();
// Spherical coordinates item
this->dataPtr->sphericalCoordItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("Spherical Coordinates"))));
this->dataPtr->sphericalCoordItem->setData(0,
Qt::UserRole, QVariant(tr("Spherical Coordinates")));
this->dataPtr->modelTreeWidget->addTopLevelItem(
this->dataPtr->sphericalCoordItem);
// Physics item
this->dataPtr->physicsItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("Physics"))));
this->dataPtr->physicsItem->setData(0, Qt::UserRole,
QVariant(tr("Physics")));
this->dataPtr->modelTreeWidget->addTopLevelItem(this->dataPtr->physicsItem);
// Models item
this->dataPtr->modelsItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("Models"))));
this->dataPtr->modelsItem->setData(0, Qt::UserRole, QVariant(tr("Models")));
this->dataPtr->modelTreeWidget->addTopLevelItem(this->dataPtr->modelsItem);
// Lights item
this->dataPtr->lightsItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("Lights"))));
this->dataPtr->lightsItem->setData(0, Qt::UserRole, QVariant(tr("Lights")));
this->dataPtr->modelTreeWidget->addTopLevelItem(this->dataPtr->lightsItem);
}
this->dataPtr->fillingPropertyTree = false;
this->dataPtr->selectedProperty = NULL;
}
/////////////////////////////////////////////////
void ModelListWidget::ResetScene()
{
this->dataPtr->sceneItem = new QTreeWidgetItem(
static_cast<QTreeWidgetItem*>(0),
QStringList(QString("%1").arg(tr("Scene"))));
this->dataPtr->sceneItem->setData(0, Qt::UserRole, QVariant(tr("Scene")));
this->dataPtr->modelTreeWidget->addTopLevelItem(this->dataPtr->sceneItem);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Scene &_msg,
QtProperty * /*_parent*/)
{
// QtProperty *topItem = NULL;
QtVariantProperty *item = NULL;
// Create and set the ambient color property
item = this->dataPtr->variantManager->addProperty(QVariant::Color,
tr("ambient"));
if (_msg.has_ambient())
{
QColor clr(_msg.ambient().r()*255, _msg.ambient().g()*255,
_msg.ambient().b()*255, _msg.ambient().a()*255);
item->setValue(clr);
}
this->dataPtr->propTreeBrowser->addProperty(item);
// Create and set the background color property
item = this->dataPtr->variantManager->addProperty(QVariant::Color,
tr("background"));
if (_msg.has_background())
{
QColor clr(_msg.background().r()*255, _msg.background().g()*255,
_msg.background().b()*255, _msg.background().a()*255);
item->setValue(clr);
}
this->dataPtr->propTreeBrowser->addProperty(item);
// Create and set the shadows property
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("shadows"));
if (_msg.has_shadows())
item->setValue(_msg.shadows());
this->dataPtr->propTreeBrowser->addProperty(item);
/// \TODO: Put fog back in
/*topItem = this->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("fog"));
QtBrowserItem *bItem = this->propTreeBrowser->addProperty(topItem);
this->propTreeBrowser->setExpanded(bItem, false);
item = this->variantManager->addProperty(QVariant::Color, tr("color"));
topItem->addSubProperty(item);
item = this->variantManager->addProperty(QVariant::Double, tr("start"));
topItem->addSubProperty(item);
item = this->variantManager->addProperty(QVariant::Double, tr("end"));
topItem->addSubProperty(item);
item = this->variantManager->addProperty(QVariant::Double, tr("density"));
topItem->addSubProperty(item);
*/
/// \TODO: Put sky modification back in GUI
/*
topItem = this->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("sky"));
bItem = this->propTreeBrowser->addProperty(topItem);
this->propTreeBrowser->setExpanded(bItem, false);
*/
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Physics &_msg,
QtProperty * /*_parent*/)
{
QtVariantProperty *item = NULL;
if (_msg.has_type())
{
this->dataPtr->physicsType = _msg.type();
item = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::enumTypeId(), tr("physics engine"));
QStringList types;
const google::protobuf::EnumDescriptor *engineTypeEnum =
_msg.GetDescriptor()->FindEnumTypeByName("Type");
if (!engineTypeEnum)
{
gzerr << "Unable to get Type enum descriptor from "
<< "Physics message. msgs::Physics "
<< "has probably changed\n";
types << "invalid";
}
else
{
types << engineTypeEnum->value(_msg.type()-1)->name().c_str();
}
item->setAttribute("enumNames", types);
item->setValue(0);
this->dataPtr->propTreeBrowser->addProperty(item);
item->setEnabled(false);
}
item = this->dataPtr->variantManager->addProperty(QVariant::Bool,
tr("enable physics"));
if (_msg.has_enable_physics())
item->setValue(_msg.enable_physics());
this->dataPtr->propTreeBrowser->addProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("real time update rate"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_real_time_update_rate())
item->setValue(_msg.real_time_update_rate());
this->dataPtr->propTreeBrowser->addProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("max step size"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_max_step_size())
item->setValue(_msg.max_step_size());
this->dataPtr->propTreeBrowser->addProperty(item);
QtProperty *gravityItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("gravity"));
this->dataPtr->propTreeBrowser->addProperty(gravityItem);
if (_msg.has_gravity())
this->FillVector3dProperty(_msg.gravity(), gravityItem);
else
{
msgs::Vector3d xyz;
xyz.set_x(0);
xyz.set_y(0);
xyz.set_z(-9.8);
this->FillVector3dProperty(xyz, gravityItem);
}
QtProperty *magneticFieldItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("magnetic field"));
this->dataPtr->propTreeBrowser->addProperty(magneticFieldItem);
if (_msg.has_magnetic_field())
this->FillVector3dProperty(_msg.magnetic_field(), magneticFieldItem);
else
{
msgs::Vector3d xyz;
xyz.set_x(0.0);
xyz.set_y(0.0);
xyz.set_z(0.0);
this->FillVector3dProperty(xyz, magneticFieldItem);
}
QtProperty *solverItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("solver"));
this->dataPtr->propTreeBrowser->addProperty(solverItem);
item = this->dataPtr->variantManager->addProperty(QVariant::Int,
tr("iterations"));
if (_msg.has_iters())
item->setValue(_msg.iters());
solverItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("SOR"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_sor())
item->setValue(_msg.sor());
solverItem->addSubProperty(item);
QtProperty *constraintsItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("constraints"));
this->dataPtr->propTreeBrowser->addProperty(constraintsItem);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("CFM"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_cfm())
item->setValue(_msg.cfm());
constraintsItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("ERP"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_erp())
item->setValue(_msg.erp());
constraintsItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("max velocity"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_contact_max_correcting_vel())
item->setValue(_msg.contact_max_correcting_vel());
constraintsItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("surface layer"));
static_cast<QtVariantPropertyManager*>
(this->dataPtr->variantFactory->propertyManager(item))->setAttribute(
item, "decimals", 6);
if (_msg.has_contact_surface_layer())
item->setValue(_msg.contact_surface_layer());
constraintsItem->addSubProperty(item);
}
/////////////////////////////////////////////////
void ModelListWidget::FillPropertyTree(const msgs::Light &_msg,
QtProperty * /*_parent*/)
{
QtVariantProperty *item = NULL;
QtProperty *topItem = NULL;
this->dataPtr->lightType = _msg.type();
item = this->dataPtr->variantManager->addProperty(QVariant::String,
tr("name"));
if (_msg.has_name())
item->setValue(_msg.name().c_str());
this->dataPtr->propTreeBrowser->addProperty(item);
topItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("pose"));
this->dataPtr->propTreeBrowser->addProperty(topItem);
if (_msg.has_pose())
this->FillPoseProperty(_msg.pose(), topItem);
else
this->FillPoseProperty(msgs::Convert(ignition::math::Pose3d()), topItem);
// Create and set the diffuse color property
item = this->dataPtr->variantManager->addProperty(QVariant::Color,
tr("diffuse"));
if (_msg.has_diffuse())
{
QColor clr(_msg.diffuse().r()*255, _msg.diffuse().g()*255,
_msg.diffuse().b()*255, _msg.diffuse().a()*255);
item->setValue(clr);
}
this->dataPtr->propTreeBrowser->addProperty(item);
// Create and set the specular color property
item = this->dataPtr->variantManager->addProperty(QVariant::Color,
tr("specular"));
if (_msg.has_specular())
{
QColor clr(_msg.specular().r()*255, _msg.specular().g()*255,
_msg.specular().b()*255, _msg.specular().a()*255);
item->setValue(clr);
}
this->dataPtr->propTreeBrowser->addProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("range"));
if (_msg.has_range())
item->setValue(_msg.range());
this->dataPtr->propTreeBrowser->addProperty(item);
QtProperty *attenuationItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("attenuation"));
this->dataPtr->propTreeBrowser->addProperty(attenuationItem);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("constant"));
if (_msg.has_attenuation_constant())
item->setValue(_msg.attenuation_constant());
attenuationItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("linear"));
if (_msg.has_attenuation_linear())
item->setValue(_msg.attenuation_linear());
attenuationItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("quadratic"));
if (_msg.has_attenuation_quadratic())
item->setValue(_msg.attenuation_quadratic());
attenuationItem->addSubProperty(item);
if (_msg.has_spot_inner_angle() || _msg.has_spot_outer_angle() ||
_msg.has_spot_falloff())
{
QtProperty *spotItem = this->dataPtr->variantManager->addProperty(
QtVariantPropertyManager::groupTypeId(), tr("spot light"));
this->dataPtr->propTreeBrowser->addProperty(spotItem);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("inner angle"));
if (_msg.has_spot_inner_angle())
item->setValue(_msg.spot_inner_angle());
spotItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("outer angle"));
if (_msg.has_spot_outer_angle())
item->setValue(_msg.spot_outer_angle());
spotItem->addSubProperty(item);
item = this->dataPtr->variantManager->addProperty(QVariant::Double,
tr("falloff"));
if (_msg.has_spot_falloff())
item->setValue(_msg.spot_falloff());
spotItem->addSubProperty(item);
}
}
/////////////////////////////////////////////////
void ModelListWidget::ProcessLightMsgs()
{
std::lock_guard<std::mutex> lock(*this->dataPtr->receiveMutex);
for (auto iter = this->dataPtr->lightMsgs.begin();
iter != this->dataPtr->lightMsgs.end(); ++iter)
{
std::string name = (*iter).name();
QTreeWidgetItem *listItem = this->ListItem((*iter).name(),
this->dataPtr->lightsItem);
if (!listItem)
{
// Create a top-level tree item for the path
QTreeWidgetItem *item = new QTreeWidgetItem(this->dataPtr->lightsItem,
QStringList(QString("%1").arg(QString::fromStdString(name))));
item->setData(0, Qt::UserRole, QVariant((*iter).name().c_str()));
this->dataPtr->modelTreeWidget->addTopLevelItem(item);
}
else
{
listItem->setData(0, Qt::UserRole, QVariant((*iter).name().c_str()));
}
}
this->dataPtr->lightMsgs.clear();
}
/////////////////////////////////////////////////
void ModelListWidget::AddProperty(QtProperty *_item, QtProperty *_parent)
{
if (!_item)
{
gzwarn << "Null QtProperty item, not adding."
<< " This should never happen." << std::endl;
return;
}
if (_parent)
_parent->addSubProperty(_item);
else
this->dataPtr->propTreeBrowser->addProperty(_item);
}