Developer Documentation
textureProperties.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 #include "textureProperties.hh"
54 
58 #include "ImageStorage.hh"
59 
60 texturePropertiesWidget::texturePropertiesWidget(QWidget *parent)
61  : QDialog(parent)
62 {
63  setupUi(this);
64 
65  connect(buttonBox, SIGNAL( clicked(QAbstractButton*) ), this , SLOT ( slotButtonBoxClicked(QAbstractButton*) ) );
66  connect(textureList, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(textureChanged(QTreeWidgetItem*,int)) );
67  connect(textureList, SIGNAL(itemPressed(QTreeWidgetItem*,int)), this, SLOT(textureAboutToChange(QTreeWidgetItem*,int)) );
68 
69  //remember changes
70  connect(repeatBox, SIGNAL( clicked() ), this , SLOT ( slotPropertiesChanged() ) );
71  connect(clampBox, SIGNAL( clicked() ), this , SLOT ( slotPropertiesChanged() ) );
72  connect(centerBox, SIGNAL( clicked() ), this , SLOT ( slotPropertiesChanged() ) );
73  connect(absBox, SIGNAL( clicked() ), this , SLOT ( slotPropertiesChanged() ) );
74  connect(scaleBox, SIGNAL( clicked() ), this , SLOT ( slotPropertiesChanged() ) );
75 
76  connect(max_val, SIGNAL( valueChanged(double) ), this , SLOT ( slotPropertiesChanged(double) ) );
77  connect(clamp_min, SIGNAL( valueChanged(double) ), this , SLOT ( slotPropertiesChanged(double) ) );
78  connect(clamp_max, SIGNAL( valueChanged(double) ), this , SLOT ( slotPropertiesChanged(double) ) );
79 
80  connect(changeImageButton, SIGNAL( clicked() ), this, SLOT( slotChangeImage() ) );
81 
82 
83  texData_ = 0;
84 
85  #ifdef WITH_QWT
86  QGridLayout* layout = new QGridLayout( originalData);
87 
88  functionPlot_ = new ACG::QwtFunctionPlot(0);
89 
90  layout->addWidget( functionPlot_ , 0,0 );
91 
92  #endif
93 
94 }
95 
96 void texturePropertiesWidget::show(TextureData* _texData, int _id, QString _name){
97 
98  texData_ = _texData;
99  id_ = _id;
100 
101  textureList->clear();
102 
103  QTreeWidgetItem* activeItem = 0;
104 
105  for (unsigned int i=0; i < texData_->textures().size(); i++) {
106  if ( ! texData_->textures()[i].hidden() ) {
107  if ( texData_->textures()[i].type() != MULTITEXTURE ) {
108 
109  QTreeWidgetItem* item = 0;
110 
111  if ( !texData_->textures()[i].visibleName().isEmpty() )
112  item = new QTreeWidgetItem((QTreeWidget*)0, QStringList( texData_->textures()[i].visibleName() ) );
113  else
114  item = new QTreeWidgetItem((QTreeWidget*)0, QStringList( texData_->textures()[i].name() ) );
115 
116  textureList->addTopLevelItem( item );
117 
118  if (texData_->textures()[i].enabled())
119  activeItem = item;
120 
121  } else {
122  QTreeWidgetItem* parent = 0;
123  if ( !texData_->textures()[i].visibleName().isEmpty() )
124  parent = new QTreeWidgetItem((QTreeWidget*)0, QStringList( texData_->textures()[i].visibleName() ) );
125  else
126  parent = new QTreeWidgetItem((QTreeWidget*)0, QStringList( texData_->textures()[i].name() ) );
127 
128  textureList->addTopLevelItem( parent ) ;
129  for ( int j = 0 ; j < texData_->textures()[i].multiTextureList.size() ; ++j )
130  textureList->addTopLevelItem( new QTreeWidgetItem(parent, QStringList(texData_->textures()[i].multiTextureList[j] )) );
131 
132  if (texData_->textures()[i].enabled())
133  activeItem = parent;
134  }
135  }
136  }
137 
138  if ( textureList->invisibleRootItem()->childCount() == 0 ) {
139  QMessageBox msgBox(this);
140  msgBox.setText("Cannot show Properties. No Textures available!");
141  msgBox.exec();
142  return;
143  }
144 
145  if (id_ == -1)
146  textureLabel->setText("<B>Global Textures</B>");
147  else
148  textureLabel->setText("<B>Textures for object '" + _name + "'</B>");
149 
150  propChanged_ = false;
151 
152  if (activeItem == 0){
153 
154  textureList->setCurrentItem( textureList->topLevelItem(0) );
155  textureChanged( textureList->topLevelItem(0), 0 );
156 
157  } else {
158  textureList->setCurrentItem( activeItem );
159  textureChanged( activeItem, 0 );
160  }
161 
162  QDialog::show();
163 }
164 
165 void texturePropertiesWidget::textureAboutToChange(QTreeWidgetItem* _item, int _column){
166 
167  if (propChanged_){
168  QMessageBox msgBox(this);
169  msgBox.setText("The properties of the current texture have been changed.");
170  msgBox.setInformativeText("Do you want to apply these changes?");
171  msgBox.setStandardButtons(QMessageBox::Apply | QMessageBox::Discard );
172  msgBox.setDefaultButton(QMessageBox::Apply);
173  int ret = msgBox.exec();
174 
175  if (ret == QMessageBox::Apply){
176  //just hit the applyButton ;)
177  for (int i=0; i < buttonBox->buttons().count(); i++)
178  if ( buttonBox->standardButton( buttonBox->buttons()[i] ) == QDialogButtonBox::Apply )
179  slotButtonBoxClicked( buttonBox->buttons()[i] );
180 
181  textureList->setCurrentItem( _item );
182  textureChanged( _item,_column );
183 
184  } else {
185  propChanged_ = false;
186 
187  textureList->setCurrentItem( _item );
188  textureChanged( _item,_column );
189  }
190  }
191 }
192 
193 void texturePropertiesWidget::textureChanged(QTreeWidgetItem* _item, int _column){
194 
195  // ================================================================================
196  // opened changes for the last texture so switch back
197  // ================================================================================
198  if ( propChanged_ ){
199  textureList->setCurrentItem( curItem_ );
200  return;
201  }
202 
203  // ================================================================================
204  // Unable to find the right texture
205  // ================================================================================
206  if ( !texData_->textureExists( _item->text(_column) ) )
207  return;
208 
209  // ================================================================================
210  // Set name of the texture
211  // ================================================================================
212  textureName_ = _item->text(_column);
213 
214  // ================================================================================
215  // Get Object to parse Properties
216  // ================================================================================
217 // BaseObjectData* obj;
218 // if ( PluginFunctions::getObject( id_ , obj ) ) {
219 // if( obj->dataType( DATA_TRIANGLE_MESH ) ){
220 // TriMesh* mesh = PluginFunctions::triMeshObject(obj)->mesh();
221 // std::string fprops;
222 // mesh->fprop_stats(fprops);
223 // QString facePropertyString(fprops.c_str());
224 // QStringList faceProperties = facePropertyString.split(QRegExp("\n"));
225 //
226 // std::cerr << "Got : \n" ;
227 // for ( int i = 0 ; i < faceProperties.size(); ++i ) {
228 // faceProperties[i] = faceProperties[i].trimmed();
229 // if ( ( ! faceProperties[i].size() == 0 ) && faceProperties[i] != "<fprop>" )
230 // std::cerr << faceProperties[i].toStdString() << std::endl;
231 // else
232 // continue;
233 //
234 // OpenMesh::FPropHandleT< int > indexPropertyTest;
235 // if ( mesh->get_property_handle(indexPropertyTest,faceProperties[i].toStdString()) ) {
236 // std::cerr << "Got handle : " << faceProperties[i].toStdString() << std::endl;
237 // } else {
238 // std::cerr << "Unable to get Handle : " << faceProperties[i].toStdString() << std::endl;
239 // }
240 // }
241 //
242 // } else if( obj->dataType( DATA_POLY_MESH ) ){
243 // PolyMesh* mesh = PluginFunctions::polyMeshObject(obj)->mesh();
244 // }
245 // }
246 
247  // ================================================================================
248  // Update the dialog
249  // ================================================================================
250  Texture& texture = texData_->texture(textureName_);
251 
252  repeatBox->setChecked(texture.parameters.repeat);
253  clampBox->setChecked(texture.parameters.clamp);
254  centerBox->setChecked(texture.parameters.center);
255  absBox->setChecked(texture.parameters.abs);
256 
257  max_val->setValue( texture.parameters.repeatMax );
258  clamp_min->setValue( texture.parameters.clampMin );
259  clamp_max->setValue( texture.parameters.clampMax );
260 
261  switch (texture.type()) {
262  case MULTITEXTURE:
263  typeLabel->setText("Type: MultiTexture");
264  indexLabel->setEnabled(true);
265  indexBox->setEnabled(true);
266  indexBox->clear();
267  indexBox->addItem("TODO");
268  break;
269  case HALFEDGEBASED:
270  typeLabel->setText("Type: HalfedgeBased");
271  indexLabel->setEnabled(false);
272  indexBox->setEnabled(false);
273  indexBox->clear();
274  break;
275  case VERTEXBASED:
276  typeLabel->setText("Type: VertexBased");
277  indexLabel->setEnabled(false);
278  indexBox->setEnabled(false);
279  indexBox->clear();
280  break;
281  case ENVIRONMENT:
282  typeLabel->setText("Type: Environment Map");
283  indexLabel->setEnabled(false);
284  indexBox->setEnabled(false);
285  indexBox->clear();
286  break;
287  case UNSET:
288  typeLabel->setText("Type: Unset");
289  indexLabel->setEnabled(false);
290  indexBox->setEnabled(false);
291  indexBox->clear();
292  break;
293  }
294 
295  // Show the texture Image
296  bool ok = false;
297  imageLabel->setPixmap(QPixmap::fromImage( imageStore().getImage(texture.textureImageId(),&ok) ));
298 
299  if ( !ok ) {
300  std::cerr<< imageStore().error().toStdString();
301  }
302 
303  imageLabel->setScaledContents(true);
304 
305  if ( texture.filename().startsWith("/") )
306  fileLabel->setText( "File: " + texture.filename() );
307  else
308  fileLabel->setText( "File: " + OpenFlipper::Options::textureDirStr() + QDir::separator() + texture.filename() );
309 
310  currentImage_ = texture.filename();
311 
312  // update plot only when dimension is 1
313  if ( texture.dimension() == 1 && id_ != -1) {
314 
315  #ifdef WITH_QWT
316 
317  std::vector< double > coords;
318 
319  emit getCoordinates1D(textureName_, id_, coords);
320 
321  if ( ! coords.empty() ){
322 
323  functionPlot_->setFunction( coords );
324 
325  functionPlot_->setParameters(repeatBox->isChecked(), max_val->value(),
326  clampBox->isChecked(), clamp_min->value(), clamp_max->value(),
327  centerBox->isChecked(),
328  absBox->isChecked(),
329  scaleBox->isChecked());
330 
331  bool ok = false;
332  image_ = imageStore().getImage(texture.textureImageId(),&ok);
333  if ( !ok ) {
334  std::cerr << imageStore().error().toStdString();
335  }
336 
337 
338  functionPlot_->setImage( &image_ );
339 
340  functionPlot_->replot();
341  }
342 
343  #endif
344  }
345 
346  propChanged_ = false;
347  curItem_ = textureList->currentItem();
348 
349 }
350 
351 void texturePropertiesWidget::slotChangeImage()
352 {
353 
354  QString fileName = QFileDialog::getOpenFileName(this,
355  tr("Open Image"),
356  OpenFlipper::Options::currentTextureDirStr(),
357  tr("Images (*.png *.xpm *.jpg *.tga *.tif *.tiff *.bmp);;All Files (*.*)"));
358 
359  if (QFile(fileName).exists()) {
360  QFileInfo fileInfo(fileName);
361  OpenFlipper::Options::currentTextureDir(fileInfo.absolutePath());
362 
363  imageLabel->setPixmap(fileName);
364  imageLabel->setScaledContents(true);
365 
366  fileLabel->setText("File: " + fileName);
367 
368  currentImage_ = fileName;
369  image_ = imageLabel->pixmap()->toImage();
370 
371  #ifdef WITH_QWT
372  functionPlot_->setImage(&image_);
373  functionPlot_->replot();
374  #endif
375 
376  propChanged_ = true;
377  }
378 
379 }
380 
381 void texturePropertiesWidget::slotButtonBoxClicked(QAbstractButton* _button){
382 
383  QDialogButtonBox::StandardButton btn = buttonBox->standardButton(_button);
384 
385  if ( btn == QDialogButtonBox::Apply || btn == QDialogButtonBox::Ok){
386 
387  //applySettings
388  bool changed = false;
389 
390  Texture& texture = texData_->texture(textureName_);
391 
392  if ( texture.parameters.repeat != repeatBox->isChecked() ){
393  texture.parameters.repeat=repeatBox->isChecked();
394  changed = true;
395  }
396  if ( texture.parameters.clamp != clampBox->isChecked() ){
397  texture.parameters.clamp=clampBox->isChecked();
398  changed = true;
399  }
400  if ( texture.parameters.center != centerBox->isChecked() ){
401  texture.parameters.center=centerBox->isChecked();
402  changed = true;
403  }
404  if ( texture.parameters.abs != absBox->isChecked() ){
405  texture.parameters.abs=absBox->isChecked();
406  changed = true;
407  }
408  if ( texture.parameters.scale != scaleBox->isChecked() ){
409  texture.parameters.scale=scaleBox->isChecked();
410  changed = true;
411  }
412 
413  if ( texture.parameters.repeatMax != max_val->value() ){
414  texture.parameters.repeatMax = max_val->value();
415  changed = true;
416  }
417 
418  if ( texture.parameters.clampMin != clamp_min->value() ){
419  texture.parameters.clampMin = clamp_min->value();
420  changed = true;
421  }
422 
423  if ( texture.parameters.clampMax != clamp_max->value() ){
424  texture.parameters.clampMax = clamp_max->value();
425  changed = true;
426  }
427 
428  if ( texture.filename() != currentImage_ ){
429  // Set the new filename of the image
430  texture.filename( currentImage_ );
431 
432  // Add it to the imagestore and set the index in the texture description
433  texture.textureImageId( imageStore().addImageFile(currentImage_) );
434 
435  changed = true;
436  }
437 
438  //inform the plugin about the update
439  if (changed)
440  emit applyProperties(texData_, textureName_, id_ );
441 
442  propChanged_ = false;
443  }
444 
445  if ( btn == QDialogButtonBox::Apply )
446  return;
447  else
448  hide();
449 }
450 
451 void texturePropertiesWidget::slotPropertiesChanged(double /*_value*/){
452  propChanged_ = true;
453 
454  #ifdef WITH_QWT
455  functionPlot_->setParameters(repeatBox->isChecked(), max_val->value(),
456  clampBox->isChecked(), clamp_min->value(), clamp_max->value(),
457  centerBox->isChecked(),
458  absBox->isChecked(),
459  scaleBox->isChecked());
460 
461  functionPlot_->replot();
462  #endif
463 }
TexParameters parameters
Parameters of the texture.
Definition: TextureData.hh:144
DLLEXPORT void currentTextureDir(QDir _dir)
Sets the Path to the current texture-directory.