Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 (uint 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  if ( textureList->invisibleRootItem()->childCount() == 0 ) {
138  QMessageBox msgBox(this);
139  msgBox.setText("Cannot show Properties. No Textures available!");
140  msgBox.exec();
141  return;
142  }
143 
144  if (id_ == -1)
145  textureLabel->setText("<B>Global Textures</B>");
146  else
147  textureLabel->setText("<B>Textures for object '" + _name + "'</B>");
148 
149  propChanged_ = false;
150 
151  if (activeItem == 0){
152 
153  textureList->setCurrentItem( textureList->topLevelItem(0) );
154  textureChanged( textureList->topLevelItem(0), 0 );
155 
156  } else {
157  textureList->setCurrentItem( activeItem );
158  textureChanged( activeItem, 0 );
159  }
160 
161  QDialog::show();
162 }
163 
164 void texturePropertiesWidget::textureAboutToChange(QTreeWidgetItem* _item, int _column){
165 
166  if (propChanged_){
167  QMessageBox msgBox(this);
168  msgBox.setText("The properties of the current texture have been changed.");
169  msgBox.setInformativeText("Do you want to apply these changes?");
170  msgBox.setStandardButtons(QMessageBox::Apply | QMessageBox::Discard );
171  msgBox.setDefaultButton(QMessageBox::Apply);
172  int ret = msgBox.exec();
173 
174  if (ret == QMessageBox::Apply){
175  //just hit the applyButton ;)
176  for (int i=0; i < buttonBox->buttons().count(); i++)
177  if ( buttonBox->standardButton( buttonBox->buttons()[i] ) == QDialogButtonBox::Apply )
178  slotButtonBoxClicked( buttonBox->buttons()[i] );
179 
180  textureList->setCurrentItem( _item );
181  textureChanged( _item,_column );
182 
183  } else {
184  propChanged_ = false;
185 
186  textureList->setCurrentItem( _item );
187  textureChanged( _item,_column );
188  }
189  }
190 }
191 
192 void texturePropertiesWidget::textureChanged(QTreeWidgetItem* _item, int _column){
193 
194  // ================================================================================
195  // opened changes for the last texture so switch back
196  // ================================================================================
197  if ( propChanged_ ){
198  textureList->setCurrentItem( curItem_ );
199  return;
200  }
201 
202  // ================================================================================
203  // Unable to find the right texture
204  // ================================================================================
205  if ( !texData_->textureExists( _item->text(_column) ) )
206  return;
207 
208  // ================================================================================
209  // Set name of the texture
210  // ================================================================================
211  textureName_ = _item->text(_column);
212 
213  // ================================================================================
214  // Get Object to parse Properties
215  // ================================================================================
216 // BaseObjectData* obj;
217 // if ( PluginFunctions::getObject( id_ , obj ) ) {
218 // if( obj->dataType( DATA_TRIANGLE_MESH ) ){
219 // TriMesh* mesh = PluginFunctions::triMeshObject(obj)->mesh();
220 // std::string fprops;
221 // mesh->fprop_stats(fprops);
222 // QString facePropertyString(fprops.c_str());
223 // QStringList faceProperties = facePropertyString.split(QRegExp("\n"));
224 //
225 // std::cerr << "Got : \n" ;
226 // for ( int i = 0 ; i < faceProperties.size(); ++i ) {
227 // faceProperties[i] = faceProperties[i].trimmed();
228 // if ( ( ! faceProperties[i].size() == 0 ) && faceProperties[i] != "<fprop>" )
229 // std::cerr << faceProperties[i].toStdString() << std::endl;
230 // else
231 // continue;
232 //
233 // OpenMesh::FPropHandleT< int > indexPropertyTest;
234 // if ( mesh->get_property_handle(indexPropertyTest,faceProperties[i].toStdString()) ) {
235 // std::cerr << "Got handle : " << faceProperties[i].toStdString() << std::endl;
236 // } else {
237 // std::cerr << "Unable to get Handle : " << faceProperties[i].toStdString() << std::endl;
238 // }
239 // }
240 //
241 // } else if( obj->dataType( DATA_POLY_MESH ) ){
242 // PolyMesh* mesh = PluginFunctions::polyMeshObject(obj)->mesh();
243 // }
244 // }
245 
246  // ================================================================================
247  // Update the dialog
248  // ================================================================================
249  Texture& texture = texData_->texture(textureName_);
250 
251  repeatBox->setChecked(texture.parameters.repeat);
252  clampBox->setChecked(texture.parameters.clamp);
253  centerBox->setChecked(texture.parameters.center);
254  absBox->setChecked(texture.parameters.abs);
255 
256  max_val->setValue( texture.parameters.repeatMax );
257  clamp_min->setValue( texture.parameters.clampMin );
258  clamp_max->setValue( texture.parameters.clampMax );
259 
260  switch (texture.type()) {
261  case MULTITEXTURE:
262  typeLabel->setText("Type: MultiTexture");
263  indexLabel->setEnabled(true);
264  indexBox->setEnabled(true);
265  indexBox->clear();
266  indexBox->addItem("TODO");
267  break;
268  case HALFEDGEBASED:
269  typeLabel->setText("Type: HalfedgeBased");
270  indexLabel->setEnabled(false);
271  indexBox->setEnabled(false);
272  indexBox->clear();
273  break;
274  case VERTEXBASED:
275  typeLabel->setText("Type: VertexBased");
276  indexLabel->setEnabled(false);
277  indexBox->setEnabled(false);
278  indexBox->clear();
279  break;
280  case ENVIRONMENT:
281  typeLabel->setText("Type: Environment Map");
282  indexLabel->setEnabled(false);
283  indexBox->setEnabled(false);
284  indexBox->clear();
285  break;
286  case UNSET:
287  typeLabel->setText("Type: Unset");
288  indexLabel->setEnabled(false);
289  indexBox->setEnabled(false);
290  indexBox->clear();
291  break;
292  }
293 
294  // Show the texture Image
295  bool ok = false;
296  imageLabel->setPixmap(QPixmap::fromImage( imageStore().getImage(texture.textureImageId(),&ok) ));
297 
298  if ( !ok ) {
299  std::cerr<< imageStore().error().toStdString();
300  }
301 
302  imageLabel->setScaledContents(true);
303 
304  if ( texture.filename().startsWith("/") )
305  fileLabel->setText( "File: " + texture.filename() );
306  else
307  fileLabel->setText( "File: " + OpenFlipper::Options::textureDirStr() + QDir::separator() + texture.filename() );
308 
309  currentImage_ = texture.filename();
310 
311  // update plot only when dimension is 1
312  if ( texture.dimension() == 1 && id_ != -1) {
313 
314  #ifdef WITH_QWT
315 
316  std::vector< double > coords;
317 
318  emit getCoordinates1D(textureName_, id_, coords);
319 
320  if ( ! coords.empty() ){
321 
322  functionPlot_->setFunction( coords );
323 
324  functionPlot_->setParameters(repeatBox->isChecked(), max_val->value(),
325  clampBox->isChecked(), clamp_min->value(), clamp_max->value(),
326  centerBox->isChecked(),
327  absBox->isChecked(),
328  scaleBox->isChecked());
329 
330  bool ok = false;
331  image_ = imageStore().getImage(texture.textureImageId(),&ok);
332  if ( !ok ) {
333  std::cerr << imageStore().error().toStdString();
334  }
335 
336 
337  functionPlot_->setImage( &image_ );
338 
339  functionPlot_->replot();
340  }
341 
342  #endif
343  }
344 
345  propChanged_ = false;
346  curItem_ = textureList->currentItem();
347 
348 }
349 
350 void texturePropertiesWidget::slotChangeImage()
351 {
352 
353  QString fileName = QFileDialog::getOpenFileName(this,
354  tr("Open Image"),
355  OpenFlipper::Options::currentTextureDirStr(),
356  tr("Images (*.png *.xpm *.jpg *.tga *.tif *.tiff *.bmp);;All Files (*.*)"));
357 
358  if (QFile(fileName).exists()) {
359  QFileInfo fileInfo(fileName);
360  OpenFlipper::Options::currentTextureDir(fileInfo.absolutePath());
361 
362  imageLabel->setPixmap(fileName);
363  imageLabel->setScaledContents(true);
364 
365  fileLabel->setText("File: " + fileName);
366 
367  currentImage_ = fileName;
368  image_ = imageLabel->pixmap()->toImage();
369 
370  #ifdef WITH_QWT
371  functionPlot_->setImage(&image_);
372  functionPlot_->replot();
373  #endif
374 
375  propChanged_ = true;
376  }
377 
378 }
379 
380 void texturePropertiesWidget::slotButtonBoxClicked(QAbstractButton* _button){
381 
382  QDialogButtonBox::StandardButton btn = buttonBox->standardButton(_button);
383 
384  if ( btn == QDialogButtonBox::Apply || btn == QDialogButtonBox::Ok){
385 
386  //applySettings
387  bool changed = false;
388 
389  Texture& texture = texData_->texture(textureName_);
390 
391  if ( texture.parameters.repeat != repeatBox->isChecked() ){
392  texture.parameters.repeat=repeatBox->isChecked();
393  changed = true;
394  }
395  if ( texture.parameters.clamp != clampBox->isChecked() ){
396  texture.parameters.clamp=clampBox->isChecked();
397  changed = true;
398  }
399  if ( texture.parameters.center != centerBox->isChecked() ){
400  texture.parameters.center=centerBox->isChecked();
401  changed = true;
402  }
403  if ( texture.parameters.abs != absBox->isChecked() ){
404  texture.parameters.abs=absBox->isChecked();
405  changed = true;
406  }
407  if ( texture.parameters.scale != scaleBox->isChecked() ){
408  texture.parameters.scale=scaleBox->isChecked();
409  changed = true;
410  }
411 
412  if ( texture.parameters.repeatMax != max_val->value() ){
413  texture.parameters.repeatMax = max_val->value();
414  changed = true;
415  }
416 
417  if ( texture.parameters.clampMin != clamp_min->value() ){
418  texture.parameters.clampMin = clamp_min->value();
419  changed = true;
420  }
421 
422  if ( texture.parameters.clampMax != clamp_max->value() ){
423  texture.parameters.clampMax = clamp_max->value();
424  changed = true;
425  }
426 
427  if ( texture.filename() != currentImage_ ){
428  // Set the new filename of the image
429  texture.filename( currentImage_ );
430 
431  // Add it to the imagestore and set the index in the texture description
432  texture.textureImageId( imageStore().addImageFile(currentImage_) );
433 
434  changed = true;
435  }
436 
437  //inform the plugin about the update
438  if (changed)
439  emit applyProperties(texData_, textureName_, id_ );
440 
441  propChanged_ = false;
442  }
443 
444  if ( btn == QDialogButtonBox::Apply )
445  return;
446  else
447  hide();
448 }
449 
450 void texturePropertiesWidget::slotPropertiesChanged(double /*_value*/){
451  propChanged_ = true;
452 
453  #ifdef WITH_QWT
454  functionPlot_->setParameters(repeatBox->isChecked(), max_val->value(),
455  clampBox->isChecked(), clamp_min->value(), clamp_max->value(),
456  centerBox->isChecked(),
457  absBox->isChecked(),
458  scaleBox->isChecked());
459 
460  functionPlot_->replot();
461  #endif
462 }
std::vector< Texture > & textures()
Get reference to the texture vector.
Definition: TextureData.cc:316
TexParameters parameters
Parameters of the texture.
Definition: TextureData.hh:144
Texture & texture(QString _textureName)
Get the texture object.
Definition: TextureData.cc:277
bool textureExists(QString _textureName)
Check if a texture exists.
Definition: TextureData.cc:93