45 #include "MaterialPicker.hh" 49 #include <ACG/QtWidgets/QtMaterialDialog.hh> 52 #include <ACG/Scenegraph/MaterialNode.hh> 54 #include <QMessageBox> 58 MaterialPicker::MaterialPicker()
60 pickModeName_(
"MaterialPicker"),
61 propName_(name()+QString(
"/Materials")),
62 pickMaterialButton_(0),
63 fillMaterialButton_(0),
64 materialListWidget_(0),
76 MaterialPicker::~MaterialPicker() {
82 void MaterialPicker::initializePlugin() {
83 QWidget* toolBox =
new QWidget();
85 pickMaterialButton_ =
new QPushButton(
"&pick Material", toolBox);
86 fillMaterialButton_ =
new QPushButton(
"&fill Material", toolBox);
87 QPushButton* clearListButton =
new QPushButton(
"Clear List", toolBox);
88 QPushButton* removeItemButton =
new QPushButton(
"Remove", toolBox);
90 pickMaterialButton_->setCheckable(
true);
91 fillMaterialButton_->setCheckable(
true);
93 QLabel* materials =
new QLabel(
"Materials:");
95 materialListWidget_ =
new QListWidget(toolBox);
99 for (
int i = 0; i < materialStrings_.size(); ++i)
101 QStringList savedString = materialStrings_[i].split(
";");
102 std::stringstream stream;
103 MaterialInfo materialInfo;
104 stream << savedString[1].toStdString();
105 stream >> materialInfo.color_material;
108 stream << savedString[2].toStdString();
109 stream >> materialInfo.base_color;
112 stream << savedString[3].toStdString();
113 stream >> materialInfo.ambient_color;
116 stream << savedString[4].toStdString();
117 stream >> materialInfo.diffuse_color;
120 stream << savedString[5].toStdString();
121 stream >> materialInfo.specular_color;
124 stream << savedString[6].toStdString();
125 stream >> materialInfo.shininess;
128 stream << savedString[7].toStdString();
129 stream >> materialInfo.reflectance;
132 stream << savedString[8].toStdString();
133 stream >> materialInfo.key;
135 if (materialInfo.key != Qt::Key_unknown) {
136 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
139 materialListWidget_->addItem( itemName(savedString[0],materialInfo.key) );
140 materialList_.push_back(materialInfo);
144 if (materialStrings_.size())
145 materialListWidget_->setCurrentItem(materialListWidget_->item(0));
147 fillMaterialButton_->setEnabled(
false);
149 QGridLayout* removeGrid =
new QGridLayout();
150 removeGrid->addWidget(removeItemButton,0,0);
151 removeGrid->addWidget(clearListButton,0,1);
153 QGridLayout* pickGrid =
new QGridLayout();
154 pickGrid->addWidget(pickMaterialButton_, 0, 0);
155 pickGrid->addWidget(fillMaterialButton_, 0, 1);
157 QBoxLayout* layout =
new QBoxLayout(QBoxLayout::TopToBottom, toolBox);
158 layout->addWidget(materials);
159 layout->addWidget(materialListWidget_);
161 layout->addLayout(removeGrid);
162 layout->addLayout(pickGrid);
164 connect(pickMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotPickMaterialMode()));
165 connect(fillMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotFillMaterialMode()));
166 connect(clearListButton, SIGNAL(clicked()),
this, SLOT(clearList()));
167 connect(materialListWidget_, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(editMode(QListWidgetItem*)));
168 connect(materialListWidget_->itemDelegate(), SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)),
this,SLOT(saveNewName(QWidget*, QAbstractItemDelegate::EndEditHint)));
169 connect(removeItemButton, SIGNAL(clicked()),
this, SLOT(slotRemoveCurrentItem()));
170 connect(materialListWidget_,SIGNAL(customContextMenuRequested(
const QPoint&)),
this,SLOT(createContextMenu(
const QPoint&)));
172 materialListWidget_->setContextMenuPolicy(Qt::CustomContextMenu);
173 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"material_picker.png");
174 emit addToolbox( tr(
"Material Picker"), toolBox, toolIcon);
178 void MaterialPicker::removeItem(QListWidgetItem* _item)
180 unsigned index = materialListWidget_->row(_item);
181 materialListWidget_->takeItem(index);
182 materialList_.erase(materialList_.begin()+index);
183 materialStrings_.erase(materialStrings_.begin()+index);
184 if (materialStrings_.isEmpty())
188 fillMaterialButton_->setEnabled(materialListWidget_->count());
191 std::map<int,size_t>::iterator eraseIter = shortKeyRow_.end();
192 for (std::map<int,size_t>::iterator iter = shortKeyRow_.begin(); iter != shortKeyRow_.end(); ++iter)
194 if (iter->second > index)
196 else if (iter->second == index)
199 if (eraseIter != shortKeyRow_.end())
200 shortKeyRow_.erase(eraseIter);
206 void MaterialPicker::clearList() {
207 materialListWidget_->clear();
208 materialList_.clear();
209 materialStrings_.clear();
210 fillMaterialButton_->setEnabled(
false);
218 void MaterialPicker::slotRemoveCurrentItem()
220 if (!materialListWidget_->count())
224 QListWidgetItem* item = materialListWidget_->currentItem();
225 msgBox.setText(tr(
"Remove ")+plainName(item->text(),materialListWidget_->currentRow())+tr(
"?"));
226 msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
227 msgBox.setDefaultButton(QMessageBox::Ok);
228 int ret = msgBox.exec();
230 if (ret == QMessageBox::Ok)
231 removeItem(materialListWidget_->currentItem());
235 void MaterialPicker::slotPickMaterialMode() {
236 pickMaterialButton_->setChecked(
true);
237 fillMaterialButton_->setChecked(
false);
238 pickMaterial_ =
true;
239 fillMaterial_ =
false;
247 void MaterialPicker::slotFillMaterialMode() {
248 fillMaterialButton_->setChecked(
true);
249 pickMaterialButton_->setChecked(
false);
250 fillMaterial_ =
true;
251 pickMaterial_ =
false;
259 void MaterialPicker::pluginsInitialized() {
260 emit addPickMode(pickModeName_);
261 for (
unsigned i = 0; i < supportedKeys_; ++i)
262 emit registerKey (Qt::Key_1+i, Qt::ControlModifier, QString(tr(
"Material %1")).arg(i+1),
false);
267 void MaterialPicker::slotMouseEvent(QMouseEvent* _event) {
271 if (_event->type() == QEvent::MouseButtonPress) {
272 size_t node_idx, target_idx;
281 if ( pickMaterial_ && !fillMaterial_ ) {
287 MaterialInfo materialInfo;
289 materialInfo.base_color = material->
base_color();
293 materialInfo.shininess = material->
shininess();
294 materialInfo.reflectance = material->
reflectance();
296 materialInfo.key = Qt::Key_unknown;
297 if (shortKeyRow_.size() < supportedKeys_)
299 materialInfo.key = Qt::Key_1+(int)shortKeyRow_.size();
300 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
304 QString
name = QString(
"material id: %1").arg(material->
id());
305 materialListWidget_->addItem( itemName(name,materialInfo.key) );
307 materialListWidget_->setCurrentItem( materialListWidget_->item(materialListWidget_->count() - 1) );
309 materialList_.push_back(materialInfo);
312 QString matStr = materialString(materialInfo,name);
313 materialStrings_.push_back(matStr);
316 fillMaterialButton_->setEnabled(
true);
321 }
else if ( fillMaterial_ && !pickMaterial_ ){
326 if (materialListWidget_->count() > 0)
328 int row = materialListWidget_->currentRow();
347 void MaterialPicker::editModeCurrent()
349 editMode(materialListWidget_->currentItem());
354 _item->setFlags(_item->flags() | Qt::ItemIsEditable);
355 materialListWidget_->editItem(_item);
356 _item->setText( plainName(_item->text(),materialListWidget_->row(_item)));
362 saveNewName(materialListWidget_->currentItem());
367 if (materialList_[index].key == Qt::Key_unknown)
371 return str.remove(0,4);
376 unsigned index = materialListWidget_->row(_item);
377 QString str = materialStrings_[index];
378 QStringList strList = str.split(
";");
381 strList[0] = _item->text();
383 if (materialList_[index].key != Qt::Key_unknown)
384 _item->setText( itemName(strList[0], materialList_[index].key) );
389 for (
int i = 0; i < strList.size()-1; ++i)
390 str += strList[i] +
";";
391 str += strList[strList.size()-1];
392 materialStrings_[index] = str;
399 if (_key == Qt::Key_unknown)
402 return QString(tr(
"(%1) ")).arg(QString::number(_key-Qt::Key_1+1)) +_name;
407 void MaterialPicker::slotPickModeChanged(
const std::string& _mode) {
408 pickMaterialButton_->setChecked( _mode == pickModeName_ && pickMaterial_ );
409 fillMaterialButton_->setChecked( _mode == pickModeName_ && fillMaterial_ );
413 void MaterialPicker::slotKeyEvent(QKeyEvent* _event)
415 for (
unsigned i = 0; i < supportedKeys_; ++i)
417 int key = Qt::Key_1+i;
418 if (_event->key() == key && _event->modifiers() == Qt::ControlModifier)
420 if (shortKeyRow_.find(key) == shortKeyRow_.end())
422 slotFillMaterialMode();
423 materialListWidget_->setCurrentRow((
int)shortKeyRow_[key]);
430 std::map<int,size_t>::iterator iter = shortKeyRow_.find(_key);
432 if (iter != shortKeyRow_.end())
435 int oldIndex = (int)iter->second;
436 QListWidgetItem* oldItem = materialListWidget_->item(oldIndex);
438 oldItem->setText( plainName(oldItem->text(),oldIndex) );
439 materialList_[oldIndex].key = Qt::Key_unknown;
440 materialStrings_[oldIndex] = materialString(materialList_[oldIndex],oldItem->text());
441 saveNewName(oldItem);
445 int newIndex = materialListWidget_->currentRow();
446 QListWidgetItem* newItem = materialListWidget_->item(newIndex);
447 materialList_[newIndex].key = _key;
449 materialStrings_[newIndex] = materialString(materialList_[newIndex],newItem->text());
450 saveNewName(newItem);
452 shortKeyRow_[_key] = newIndex;
457 std::stringstream stream;
458 stream << _name.toStdString();
459 stream <<
";" << _mat.color_material;
460 stream <<
";" << _mat.base_color;
461 stream <<
";" << _mat.ambient_color;
462 stream <<
";" << _mat.diffuse_color;
463 stream <<
";" << _mat.specular_color;
464 stream <<
";" << _mat.shininess;
465 stream <<
";" << _mat.reflectance;
466 stream <<
";" << _mat.key;
468 return QString(stream.str().c_str());
471 void MaterialPicker::slotMaterialProperties()
477 materialListWidget_->setDisabled(
true);
480 int row = materialListWidget_->currentRow();
481 materialNode_->colorMaterial(materialList_[row].color_material);
482 materialNode_->set_base_color(materialList_[row].base_color);
483 materialNode_->set_ambient_color(materialList_[row].ambient_color);
484 materialNode_->set_diffuse_color(materialList_[row].diffuse_color);
485 materialNode_->set_specular_color(materialList_[row].specular_color);
486 materialNode_->set_shininess(materialList_[row].shininess);
487 materialNode_->set_reflectance(materialList_[row].reflectance);
491 dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
493 connect(dialog,SIGNAL(finished(
int)),
this,SLOT(slotEnableListWidget(
int)));
494 connect(dialog,SIGNAL(accepted()),
this,SLOT(slotMaterialChanged()));
496 dialog->setWindowIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png"));
502 void MaterialPicker::slotMaterialChanged()
506 int index = materialListWidget_->currentRow();
509 materialInfo.color_material = materialNode_->colorMaterial();
510 materialInfo.base_color = materialNode_->base_color();
511 materialInfo.ambient_color = materialNode_->ambient_color();
512 materialInfo.diffuse_color = materialNode_->diffuse_color();
513 materialInfo.specular_color = materialNode_->specular_color();
514 materialInfo.shininess = materialNode_->shininess();
515 materialInfo.reflectance = materialNode_->reflectance();
516 materialInfo.key = materialList_[index].key;
517 QString name = plainName(materialListWidget_->currentItem()->text(),materialListWidget_->currentRow());
518 materialStrings_[index] = materialString(materialInfo,name);
519 materialList_[index] = materialInfo;
526 void MaterialPicker::slotEnableListWidget(
int _save){
527 materialListWidget_->setEnabled(
true);
528 if (_save == QDialog::Accepted)
529 slotMaterialChanged();
530 materialNode_.reset();
536 QMenu *menu =
new QMenu(materialListWidget_);
538 QAction* action = menu->addAction(tr(
"Material Properties"));
540 icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png");
541 action->setIcon(icon);
542 action->setEnabled(
true);
543 connect(action,SIGNAL(triggered(
bool)),
this,SLOT(slotMaterialProperties()));
545 action = menu->addAction(tr(
"Rename"));
546 connect(action,SIGNAL(triggered(
bool)),
this,SLOT(editModeCurrent()));
548 action = menu->addAction(tr(
"Remove"));
549 connect(action, SIGNAL(triggered(
bool)),
this,SLOT(slotRemoveCurrentItem()));
551 menu->addSeparator();
554 for (
unsigned i = 0; i < supportedKeys_; ++i)
557 QAction* action = menu->addAction(tr(
"Key %1").arg(i+1));
558 connect(action,&QAction::triggered, [=]() { changeHotKey(Qt::Key_1+i); } );
560 std::map<int,size_t>::iterator iter = shortKeyRow_.find(Qt::Key_1 + i);
563 if (iter != shortKeyRow_.end() && iter->second ==
static_cast<size_t>(materialListWidget_->currentRow()))
564 action->setDisabled(
true);
567 menu->exec(materialListWidget_->mapToGlobal(_point),0);
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void editMode(QListWidgetItem *_item)
items can be renamed by double clicking them
void set_specular_color(const Vec4f &_s)
set the specular color
const Vec4f & ambient_color() const
get the ambient color.
const Vec4f & specular_color() const
get the specular color
void set_ambient_color(const Vec4f &_a)
set the ambient color.
float shininess() const
get shininess
void saveNewName(QWidget *_editor, QAbstractItemDelegate::EndEditHint _hint)
saves the new material name with hotkey hint
void set_shininess(float _s)
set shininess
const Vec4f & diffuse_color() const
get the diffuse color.
QString materialString(const MaterialInfo &_mat, const QString &_name)
returns a formatted string for saving
void set_diffuse_color(const Vec4f &_d)
set the diffuse color.
Viewer::ActionMode actionMode()
Get the current Action mode.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
pick any of the prior targets (should be implemented for all nodes)
QString name()
Return a name for the plugin.
const std::string pickMode()
Get the current Picking mode.
const Vec4f & base_color() const
get the base color ( same as emission() )
void createContextMenu(const QPoint &_point)
creates context menu on current item (current is the item at mouse position)
void set_reflectance(double _m)
set reflectance
void set_base_color(const Vec4f &_c)
set the base color ( Same as set_emission(const Vec4f& _c) )
ACG::SceneGraph::MaterialNode MaterialNode
Materialnode.
QString itemName(const QString &_name, int _key)
returns the item name with hotkey hint
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
QString plainName(const QString &string, int index)
returns the plain name of the material without hotkey hint
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
double reflectance() const
get reflectance
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void changeHotKey(const int _key)
change specified HotKey to current item
void colorMaterial(const bool _cm)
Set colorMaterial.