2993 lines
100 KiB
C++
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);
|
|
}
|