45#include "MaterialPicker.hh"
49#include <ACG/QtWidgets/QtMaterialDialog.hh>
52#include <ACG/Scenegraph/MaterialNode.hh>
58MaterialPicker::MaterialPicker()
60 pickModeName_(
"MaterialPicker"),
61 propName_(name()+QString(
"/Materials")),
62 pickMaterialButton_(nullptr),
63 fillMaterialButton_(nullptr),
64 materialListWidget_(nullptr),
77MaterialPicker::~MaterialPicker() {
84void MaterialPicker::initializePlugin() {
85 QWidget* toolBox =
new QWidget();
87 pickMaterialButton_ =
new QPushButton(
"&pick Material", toolBox);
88 fillMaterialButton_ =
new QPushButton(
"&fill Material", toolBox);
89 QPushButton* clearListButton =
new QPushButton(
"Clear List", toolBox);
90 QPushButton* removeItemButton =
new QPushButton(
"Remove", toolBox);
92 pickMaterialButton_->setCheckable(
true);
93 fillMaterialButton_->setCheckable(
true);
95 QLabel* materials =
new QLabel(
"Materials:");
97 materialListWidget_ =
new QListWidget(toolBox);
101 for (
int i = 0; i < materialStrings_.size(); ++i)
103 QStringList savedString = materialStrings_[i].split(
";");
104 std::stringstream stream;
105 MaterialInfo materialInfo;
106 stream << savedString[1].toStdString();
107 stream >> materialInfo.color_material;
110 stream << savedString[2].toStdString();
111 stream >> materialInfo.base_color;
114 stream << savedString[3].toStdString();
115 stream >> materialInfo.ambient_color;
118 stream << savedString[4].toStdString();
119 stream >> materialInfo.diffuse_color;
122 stream << savedString[5].toStdString();
123 stream >> materialInfo.specular_color;
126 stream << savedString[6].toStdString();
127 stream >> materialInfo.shininess;
130 stream << savedString[7].toStdString();
131 stream >> materialInfo.reflectance;
134 stream << savedString[8].toStdString();
135 stream >> materialInfo.key;
137 if (materialInfo.key != Qt::Key_unknown) {
138 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
141 materialListWidget_->addItem(
itemName(savedString[0],materialInfo.key) );
142 materialList_.push_back(materialInfo);
146 if (materialStrings_.size())
147 materialListWidget_->setCurrentItem(materialListWidget_->item(0));
149 fillMaterialButton_->setEnabled(
false);
151 QGridLayout* removeGrid =
new QGridLayout();
152 removeGrid->addWidget(removeItemButton,0,0);
153 removeGrid->addWidget(clearListButton,0,1);
155 QGridLayout* pickGrid =
new QGridLayout();
156 pickGrid->addWidget(pickMaterialButton_, 0, 0);
157 pickGrid->addWidget(fillMaterialButton_, 0, 1);
159 QBoxLayout* layout =
new QBoxLayout(QBoxLayout::TopToBottom, toolBox);
160 layout->addWidget(materials);
161 layout->addWidget(materialListWidget_);
163 layout->addLayout(removeGrid);
164 layout->addLayout(pickGrid);
166 connect(pickMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotPickMaterialMode()));
167 connect(fillMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotFillMaterialMode()));
168 connect(clearListButton, SIGNAL(clicked()),
this, SLOT(clearList()));
169 connect(materialListWidget_, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(
editMode(QListWidgetItem*)));
170 connect(materialListWidget_->itemDelegate(), SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)),
this,SLOT(
saveNewName(QWidget*, QAbstractItemDelegate::EndEditHint)));
171 connect(removeItemButton, SIGNAL(clicked()),
this, SLOT(slotRemoveCurrentItem()));
172 connect(materialListWidget_,SIGNAL(customContextMenuRequested(
const QPoint&)),
this,SLOT(
createContextMenu(
const QPoint&)));
174 materialListWidget_->setContextMenuPolicy(Qt::CustomContextMenu);
175 toolIcon_ =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"material_picker.png");
176 emit addToolbox( tr(
"Material Picker"), toolBox, toolIcon_);
180void MaterialPicker::removeItem(QListWidgetItem* _item)
182 unsigned index = materialListWidget_->row(_item);
183 materialListWidget_->takeItem(index);
184 materialList_.erase(materialList_.begin()+index);
185 materialStrings_.erase(materialStrings_.begin()+index);
186 if (materialStrings_.isEmpty())
190 fillMaterialButton_->setEnabled(materialListWidget_->count());
193 std::map<int,size_t>::iterator eraseIter = shortKeyRow_.end();
194 for (std::map<int,size_t>::iterator iter = shortKeyRow_.begin(); iter != shortKeyRow_.end(); ++iter)
196 if (iter->second > index)
198 else if (iter->second == index)
201 if (eraseIter != shortKeyRow_.end())
202 shortKeyRow_.erase(eraseIter);
208void MaterialPicker::clearList() {
209 materialListWidget_->clear();
210 materialList_.clear();
211 materialStrings_.clear();
212 fillMaterialButton_->setEnabled(
false);
220void MaterialPicker::slotRemoveCurrentItem()
222 if (!materialListWidget_->count())
226 QListWidgetItem* item = materialListWidget_->currentItem();
227 msgBox.setText(tr(
"Remove ")+
plainName(item->text(),materialListWidget_->currentRow())+tr(
"?"));
228 msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
229 msgBox.setDefaultButton(QMessageBox::Ok);
230 int ret = msgBox.exec();
232 if (ret == QMessageBox::Ok)
233 removeItem(materialListWidget_->currentItem());
237void MaterialPicker::slotPickMaterialMode() {
238 pickMaterialButton_->setChecked(
true);
239 fillMaterialButton_->setChecked(
false);
249void MaterialPicker::slotFillMaterialMode() {
250 fillMaterialButton_->setChecked(
true);
251 pickMaterialButton_->setChecked(
false);
261void MaterialPicker::pluginsInitialized() {
262 emit addPickMode(pickModeName_);
263 for (
unsigned i = 0; i < supportedKeys_; ++i)
264 emit registerKey (Qt::Key_1+i, Qt::ControlModifier, QString(tr(
"Material %1")).arg(i+1),
false);
269void MaterialPicker::slotMouseEvent(QMouseEvent* _event) {
273 if (_event->type() == QEvent::MouseButtonPress) {
274 size_t node_idx, target_idx;
289 MaterialInfo materialInfo;
291 materialInfo.base_color = material->
base_color();
295 materialInfo.shininess = material->
shininess();
296 materialInfo.reflectance = material->
reflectance();
298 materialInfo.key = Qt::Key_unknown;
299 if (shortKeyRow_.size() < supportedKeys_)
301 materialInfo.key = Qt::Key_1+(int)shortKeyRow_.size();
302 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
306 QString
name = QString(
"material id: %1").arg(material->
id());
307 materialListWidget_->addItem(
itemName(
name,materialInfo.key) );
309 materialListWidget_->setCurrentItem( materialListWidget_->item(materialListWidget_->count() - 1) );
311 materialList_.push_back(materialInfo);
315 materialStrings_.push_back(matStr);
318 fillMaterialButton_->setEnabled(
true);
328 if (materialListWidget_->count() > 0)
330 int row = materialListWidget_->currentRow();
349void MaterialPicker::editModeCurrent()
351 editMode(materialListWidget_->currentItem());
356 _item->setFlags(_item->flags() | Qt::ItemIsEditable);
357 materialListWidget_->editItem(_item);
358 _item->setText(
plainName(_item->text(),materialListWidget_->row(_item)));
369 if (materialList_[index].key == Qt::Key_unknown)
373 return str.remove(0,4);
378 unsigned index = materialListWidget_->row(_item);
379 QString str = materialStrings_[index];
380 QStringList strList = str.split(
";");
383 strList[0] = _item->text();
385 if (materialList_[index].key != Qt::Key_unknown)
386 _item->setText(
itemName(strList[0], materialList_[index].key) );
391 for (
int i = 0; i < strList.size()-1; ++i)
392 str += strList[i] +
";";
393 str += strList[strList.size()-1];
394 materialStrings_[index] = str;
401 if (_key == Qt::Key_unknown)
404 return QString(tr(
"(%1) ")).arg(QString::number(_key-Qt::Key_1+1)) +_name;
409void MaterialPicker::slotPickModeChanged(
const std::string& _mode) {
410 pickMaterialButton_->setChecked( _mode == pickModeName_ &&
pickMaterial_ );
411 fillMaterialButton_->setChecked( _mode == pickModeName_ &&
fillMaterial_ );
415void MaterialPicker::slotKeyEvent(QKeyEvent* _event)
417 for (
unsigned i = 0; i < supportedKeys_; ++i)
419 int key = Qt::Key_1+i;
420 if (_event->key() == key && _event->modifiers() == Qt::ControlModifier)
422 if (shortKeyRow_.find(key) == shortKeyRow_.end())
424 slotFillMaterialMode();
425 materialListWidget_->setCurrentRow((
int)shortKeyRow_[key]);
432 std::map<int,size_t>::iterator iter = shortKeyRow_.find(_key);
434 if (iter != shortKeyRow_.end())
437 int oldIndex = (int)iter->second;
438 QListWidgetItem* oldItem = materialListWidget_->item(oldIndex);
440 oldItem->setText(
plainName(oldItem->text(),oldIndex) );
441 materialList_[oldIndex].key = Qt::Key_unknown;
442 materialStrings_[oldIndex] =
materialString(materialList_[oldIndex],oldItem->text());
447 int newIndex = materialListWidget_->currentRow();
448 QListWidgetItem* newItem = materialListWidget_->item(newIndex);
449 materialList_[newIndex].key = _key;
451 materialStrings_[newIndex] =
materialString(materialList_[newIndex],newItem->text());
454 shortKeyRow_[_key] = newIndex;
459 std::stringstream stream;
460 stream << _name.toStdString();
461 stream <<
";" << _mat.color_material;
462 stream <<
";" << _mat.base_color;
463 stream <<
";" << _mat.ambient_color;
464 stream <<
";" << _mat.diffuse_color;
465 stream <<
";" << _mat.specular_color;
466 stream <<
";" << _mat.shininess;
467 stream <<
";" << _mat.reflectance;
468 stream <<
";" << _mat.key;
470 return QString(stream.str().c_str());
473void MaterialPicker::slotMaterialProperties()
479 materialListWidget_->setDisabled(
true);
482 int row = materialListWidget_->currentRow();
483 materialNode_->colorMaterial(materialList_[row].color_material);
484 materialNode_->set_base_color(materialList_[row].base_color);
485 materialNode_->set_ambient_color(materialList_[row].ambient_color);
486 materialNode_->set_diffuse_color(materialList_[row].diffuse_color);
487 materialNode_->set_specular_color(materialList_[row].specular_color);
488 materialNode_->set_shininess(materialList_[row].shininess);
489 materialNode_->set_reflectance(materialList_[row].reflectance);
493 dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
495 connect(dialog,SIGNAL(finished(
int)),
this,SLOT(slotEnableListWidget(
int)));
496 connect(dialog,SIGNAL(accepted()),
this,SLOT(slotMaterialChanged()));
498 dialog->setWindowIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png"));
504void MaterialPicker::slotMaterialChanged()
508 int index = materialListWidget_->currentRow();
510 MaterialInfo materialInfo;
511 materialInfo.color_material = materialNode_->colorMaterial();
512 materialInfo.base_color = materialNode_->base_color();
513 materialInfo.ambient_color = materialNode_->ambient_color();
514 materialInfo.diffuse_color = materialNode_->diffuse_color();
515 materialInfo.specular_color = materialNode_->specular_color();
516 materialInfo.shininess = materialNode_->shininess();
517 materialInfo.reflectance = materialNode_->reflectance();
518 materialInfo.key = materialList_[index].key;
519 QString
name =
plainName(materialListWidget_->currentItem()->text(),materialListWidget_->currentRow());
521 materialList_[index] = materialInfo;
528void MaterialPicker::slotEnableListWidget(
int _save){
529 materialListWidget_->setEnabled(
true);
530 if (_save == QDialog::Accepted)
531 slotMaterialChanged();
532 materialNode_.reset();
538 QMenu *menu =
new QMenu(materialListWidget_);
540 QAction* actionMaterialProperties = menu->addAction(tr(
"Material Properties"));
542 icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png");
543 actionMaterialProperties->setIcon(icon);
544 actionMaterialProperties->setEnabled(
true);
545 connect(actionMaterialProperties,SIGNAL(triggered(
bool)),
this,SLOT(slotMaterialProperties()));
547 actionMaterialProperties = menu->addAction(tr(
"Rename"));
548 connect(actionMaterialProperties,SIGNAL(triggered(
bool)),
this,SLOT(editModeCurrent()));
550 actionMaterialProperties = menu->addAction(tr(
"Remove"));
551 connect(actionMaterialProperties, SIGNAL(triggered(
bool)),
this,SLOT(slotRemoveCurrentItem()));
553 menu->addSeparator();
556 for (
unsigned i = 0; i < supportedKeys_; ++i)
559 QAction* action = menu->addAction(tr(
"Key %1").arg(i+1));
560 connect(action,&QAction::triggered, [=]() {
changeHotKey(Qt::Key_1+i); } );
562 std::map<int,size_t>::iterator iter = shortKeyRow_.find(Qt::Key_1 + i);
565 if (iter != shortKeyRow_.end() && iter->second ==
static_cast<size_t>(materialListWidget_->currentRow()))
566 action->setDisabled(
true);
569 menu->exec(materialListWidget_->mapToGlobal(_point),0);
ACG::SceneGraph::MaterialNode MaterialNode
Materialnode.
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void set_diffuse_color(const Vec4f &_d)
set the diffuse color.
void set_specular_color(const Vec4f &_s)
set the specular color
const Vec4f & base_color() const
get the base color ( same as emission() )
void set_base_color(const Vec4f &_c)
set the base color ( Same as set_emission(const Vec4f& _c) )
float shininess() const
get shininess
void set_reflectance(double _m)
set reflectance
double reflectance() const
get reflectance
const Vec4f & diffuse_color() const
get the diffuse color.
void set_ambient_color(const Vec4f &_a)
set the ambient color.
const Vec4f & ambient_color() const
get the ambient color.
const Vec4f & specular_color() const
get the specular color
void colorMaterial(const bool _cm)
Set colorMaterial.
void set_shininess(float _s)
set shininess
bool fillMaterial_
stores the state of the fill material button
bool pickMaterial_
stores the state of the pick material button
QString materialString(const MaterialInfo &_mat, const QString &_name)
returns a formatted string for saving
void saveNewName(QWidget *_editor, QAbstractItemDelegate::EndEditHint _hint)
saves the new material name with hotkey hint
void changeHotKey(const int _key)
change specified HotKey to current item
QString name()
Return a name for the plugin.
void editMode(QListWidgetItem *_item)
items can be renamed by double clicking them
QString itemName(const QString &_name, int _key)
returns the item name with hotkey hint
QString plainName(const QString &string, int index)
returns the plain name of the material without hotkey hint
void createContextMenu(const QPoint &_point)
creates context menu on current item (current is the item at mouse position)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
const std::string pickMode()
Get the current Picking mode.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
Viewer::ActionMode actionMode()
Get the current Action mode.