TextureControl.cc 82.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40 41 42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43 44 45 46 47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
49 50 51 52 53


#include "TextureControl.hh"

#include <iostream>
54
#include <ACG/GL/GLState.hh>
Jan Möbius's avatar
 
Jan Möbius committed
55

56 57 58
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/BasePlugin/PluginFunctionsViewControls.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
59
#include "ImageStorage.hh"
Jan Möbius's avatar
 
Jan Möbius committed
60

61 62 63 64 65 66
#if QT_VERSION >= 0x050000 
#include <QtWidgets>
#else
#include <QtGui>
#endif

67
#ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
68
#include <ObjectTypes/VolumeMeshObject/VolumeMeshDrawModesContainer.hh>
69 70
#endif

71
#define TEXTUREDATA "TextureData"
72
 
73

Jan Möbius's avatar
Jan Möbius committed
74 75 76 77 78 79 80 81 82 83

TextureControlPlugin::TextureControlPlugin() :
settingsDialog_(0),
textureMenu_(0),
actionGroup_(0),
contextMenu_(0)
{

}

Dirk Wilden's avatar
Dirk Wilden committed
84 85 86 87 88
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension , int _id)
{
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
89
    emit log(LOGERR,"slotTextureAdded: Unable to get Object for id " + QString::number(_id) );
90
    return;
Dirk Wilden's avatar
Dirk Wilden committed
91 92 93 94 95 96 97 98 99
  }

  // Get Texture data for this object or create one if it does not exist
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    texData = new TextureData();
    obj->setObjectData(TEXTUREDATA, texData);
  }

100
  if ( texData->textureExists(_textureName) ) {
101
    emit log(LOGERR,"slotTextureAdded: Trying to add already existing texture " + _textureName + " for object " + QString::number(_id) );
Dirk Wilden's avatar
Dirk Wilden committed
102 103
    return;
  }
104 105 106 107 108

  // ================================================================================
  // Get the image file
  // ================================================================================

109 110
  // Add Image to the image store and set the index in the texture description
  int newId = imageStore().addImageFile(_filename);
Dirk Wilden's avatar
 
Dirk Wilden committed
111

112 113 114 115
  if ( newId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
116 117 118 119 120 121 122 123

  // ================================================================================
  // Add the texture to the texture node and get the corresponding id
  // ================================================================================
  GLuint glName = 0;

  //inform textureNode about the new texture
  if( obj->dataType( DATA_TRIANGLE_MESH ) )
124
    glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
125 126

  if ( obj->dataType( DATA_POLY_MESH ) )
127
    glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
128

129 130 131 132 133 134 135 136 137
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
  if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) )
    glName = PluginFunctions::hexahedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
  if ( obj->dataType( DATA_POLYHEDRAL_MESH ) )
    glName = PluginFunctions::polyhedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
#endif

138 139 140 141 142
  // ================================================================================
  // Store texture information in objects metadata
  // ================================================================================

  if (glName == 0) {
143
    emit log(LOGERR,"slotTextureAdded: Unable to bind texture!");
144 145 146 147
    return;
  }

  texData->addTexture(_textureName,_filename,_dimension,glName);
148 149 150 151

  // Remember id in texture descriptor
  texData->setImage(_textureName,newId);

152
  texData->texture(_textureName).disable();
Dirk Wilden's avatar
Dirk Wilden committed
153 154
}

Jan Möbius's avatar
 
Jan Möbius committed
155 156
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension)
{
157 158 159
  // Add this texture to the list of global textures
  if ( ! globalTextures_.textureExists(_textureName) ) {
    globalTextures_.addTexture(_textureName,_filename,_dimension,0);
160
    globalTextures_.texture(_textureName).disable();
161

162
    int newImageId = imageStore().addImageFile(_filename);
Dirk Wilden's avatar
 
Dirk Wilden committed
163

164 165 166 167
    if ( newImageId == -1 ) {
      emit log(LOGERR,imageStore().error());
      return;
    }
Dirk Wilden's avatar
 
Dirk Wilden committed
168

169
    globalTextures_.texture(_textureName).textureImageId(newImageId);
170

171
  } else {
172
    emit log(LOGERR,"slotTextureAdded: Trying to add already existing global texture " + _textureName );
173 174
    return;
  }
175

176
  // Add a new entry to the global Texture menu
Jan Möbius's avatar
 
Jan Möbius committed
177
  QAction* new_texture = new QAction(_textureName, this);
178
  new_texture->setStatusTip(tr("slotTextureAdded: Switch all objects to this Texture ( if available )"));
Jan Möbius's avatar
 
Jan Möbius committed
179 180 181 182 183
  new_texture->setCheckable(true);
  actionGroup_->addAction(new_texture);
  textureMenu_->addAction(new_texture);
  new_texture->setChecked(true);
  textureActions_.push_back(new_texture);
184

185
}
186

187
void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) {
188 189 190
   // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
191
    emit log(LOGERR,"slotMultiTextureAdded: Unable to get Object for id " + QString::number(_id) );
192 193 194 195
  }

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
196
      emit log(LOGERR,"slotMultiTextureAdded: Trying to add textures to object failed because of unsupported object type");
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
      return;
  }

  // Get Texture data for this object or create one if it does not exist
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    texData = new TextureData();
    obj->setObjectData(TEXTUREDATA, texData);
  }

  if ( !texData->textureExists( _textureGroup ) )
    texData->addMultiTexture( _textureGroup );

  // Add the texture
  slotTextureAdded( _name , _filename , 2 , _id);

  // Get the id of the new texture
214
  _textureId = texData->texture(_name).id();
215

216 217 218
  //hide the texture (its accessible through the multiTexture)
  texData->texture(_name).hidden( true );

219
  // Add to image store
220
  int newImageId = imageStore().addImageFile(_filename);
Dirk Wilden's avatar
 
Dirk Wilden committed
221

222 223 224 225
  if ( newImageId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
Dirk Wilden's avatar
 
Dirk Wilden committed
226

227 228
  // Add to texture description
  texData->texture(_name).textureImageId(newImageId);
229 230 231 232 233

  // Store the new texture in the list of this textureGroup
  if ( _textureId != -1 ) {
    texData->texture(_textureGroup).multiTextureList << _name ;
  } else {
234
    emit log(LOGERR,"slotMultiTextureAdded: Error when getting internal id of new multitexture!");
235 236 237 238 239
  }

}

void TextureControlPlugin::addedEmptyObject( int _id ) {
240

241 242 243
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
244
//     emit log(LOGERR,"addedEmptyObject: Unable to get Object for id " + QString::number(_id) );
245 246 247 248
    return;
  }
  
  // Check if we support this kind of data
249 250 251 252 253 254 255 256 257
  if ( !obj->dataType(DATA_TRIANGLE_MESH)   && !obj->dataType(DATA_POLY_MESH)
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
       && !obj->dataType(DATA_HEXAHEDRAL_MESH)
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
       && !obj->dataType(DATA_POLYHEDRAL_MESH)
#endif
     )
  {
258 259 260 261 262 263 264 265 266 267 268 269
    return;
  }
  
  // Get Texture data for this object or create one if it does not exist
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    texData = new TextureData();
    obj->setObjectData(TEXTUREDATA, texData);
  }
  
  // Iterate over all available global textures and add them to the object
  for ( uint i = 0 ; i < globalTextures_.textures().size() ; ++i) {
270 271 272 273 274 275 276 277 278

    // Add to image store
    int newImageId = imageStore().addImageFile(globalTextures_.textures()[i].filename());

    if ( newImageId == -1 ) {
      emit log(LOGERR,imageStore().error());
      continue;
    }

279 280 281 282 283 284 285
    // ================================================================================
    // Add the texture to the texture node and get the corresponding id
    // ================================================================================
    GLuint glName = 0;
    
    //inform textureNode about the new texture
    if( obj->dataType( DATA_TRIANGLE_MESH ) )
286
      glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
287

288
    if ( obj->dataType( DATA_POLY_MESH ) )
289
      glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
290 291 292 293 294 295 296 297 298

#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
    if( obj->dataType( DATA_HEXAHEDRAL_MESH ) )
      glName = PluginFunctions::hexahedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
    if ( obj->dataType( DATA_POLYHEDRAL_MESH ) )
      glName = PluginFunctions::polyhedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
#endif
299 300 301 302 303 304
    
    // ================================================================================
    // Store texture information in objects metadata
    // ================================================================================
    if (glName != 0) {
      texData->addTexture(globalTextures_.textures()[i], glName);
305 306 307

      // Add to texture description
      texData->setImage(globalTextures_.textures()[i].name(),newImageId);
308 309
    }
    else {
310
      imageStore().removeImage(newImageId);
311
      emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
312 313 314 315 316 317 318 319 320 321
      continue;
    }
    
    
    // ================================================================================
    // Update texture mapping in meshNode
    // ================================================================================
    if( obj->dataType( DATA_TRIANGLE_MESH ) ){
      PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
322

323 324 325 326 327
    if ( obj->dataType( DATA_POLY_MESH ) ){
      PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
    
  }
Jan Möbius's avatar
 
Jan Möbius committed
328 329
}

330
template< typename MeshT >
Jan Möbius's avatar
Jan Möbius committed
331
void TextureControlPlugin::handleFileOpenTextures( MeshT*& _mesh , int _objectId ) {
332

333 334 335 336 337 338
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _objectId , obj ) ) {
    return;
  }

339 340 341 342 343
  if ( _mesh->has_vertex_texcoords2D() ){
    slotTextureAdded("Original Per Vertex Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Vertex Texture Coords","type=vertexbased",_objectId);
  }

344
  if ( _mesh->has_halfedge_texcoords2D() ){
345 346 347
    slotTextureAdded("Original Per Face Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Face Texture Coords","type=halfedgebased",_objectId);
  }
348

349 350
}

351 352 353 354 355 356 357 358 359 360 361 362
#ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
template< typename VolumeMeshObjectT >
void TextureControlPlugin::handleFileOpenTexturesOVM( VolumeMeshObjectT* _obj, int _objectId ) {

  if ( _obj->texcoords().vertex_texcoords_available() ){
    slotTextureAdded("Original Per Vertex Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Vertex Texture Coords","type=vertexbased",_objectId);
  }

}
#endif

363
void TextureControlPlugin::fileOpened( int _id ) {
364
  // TODO:: Store original texture coords in a new property!
Jan Möbius's avatar
Jan Möbius committed
365

366 367 368
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
369
    emit log(LOGERR,"fileOpened: Unable to get Object for id " + QString::number(_id) );
370
    return;
371 372 373
  }

  // Check if we support this kind of data
374 375 376 377 378 379 380 381 382
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH)
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
       && !obj->dataType(DATA_HEXAHEDRAL_MESH)
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
       && !obj->dataType(DATA_POLYHEDRAL_MESH)
#endif
     )
  {
383
      return;
384 385
  }

386 387 388
  // Get Texture data for this object or create one if it does not exist
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
389 390
    emit log(LOGERR,tr("fileOpened: Unable to get texture object data for id %1.").arg(_id) );
    return;
Jan Möbius's avatar
 
Jan Möbius committed
391
  }
392 393 394 395 396

  // Check if the file contains a texture map, store original textures and handle them before adding global textures
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    if ( mesh )
Jan Möbius's avatar
Jan Möbius committed
397
      handleFileOpenTextures(mesh,_id);
398 399 400
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PolyMesh* mesh = PluginFunctions::polyMesh(obj);
    if ( mesh )
Jan Möbius's avatar
Jan Möbius committed
401
      handleFileOpenTextures(mesh,_id);
402
  }
403 404 405 406 407 408 409 410 411 412 413 414
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    HexahedralMeshObject* ovm_obj = PluginFunctions::hexahedralMeshObject(_id);
    handleFileOpenTexturesOVM(ovm_obj, _id);
  }
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PolyhedralMeshObject* ovm_obj = PluginFunctions::polyhedralMeshObject(_id);
    handleFileOpenTexturesOVM(ovm_obj, _id);
  }
#endif
415

416 417
}

418 419 420 421 422 423 424
void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage& _image , int _id ) {

  // ================================================================================
  // Get the new object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
425
    emit log(LOGERR,"slotTextureChangeImage: Unable to get Object for id " + QString::number(_id) );
426 427 428 429 430 431 432 433
  }

  // ================================================================================
  // Get Texture data for this object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );

  if ( texData == 0 || ( !texData->textureExists(_textureName))  ) {
434
    emit log(LOGERR,"slotTextureChangeImage: Texture does not exist: " + _textureName + " (objectid=" + QString::number(_id) + ")");
435 436 437 438 439 440 441
    return;
  }

  // ================================================================================
  // Update the image
  // ================================================================================
  Texture& texture = texData->texture(_textureName);
442 443 444 445 446 447

  // Add to image store
  int newImageId = imageStore().addImage(_image);

  // Add to texture description
  texture.textureImageId(newImageId);
448 449 450 451 452

  // ================================================================================
  // Flag dirty or update
  // ================================================================================

453 454 455 456 457
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    PluginFunctions::triMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PluginFunctions::triMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  }
458 459 460 461 462 463 464 465 466 467
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  }
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  }
#endif
468 469

  emit updateView();
470 471 472 473 474 475 476 477 478

}

void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage& _image ) {

  // ================================================================================
  // Update texture Image for global textures
  // ================================================================================
  if ( ! globalTextures_.textureExists(_textureName) ) {
479
    emit log(LOGERR,"slotTextureChangeImage: Global texture does not exist: " + _textureName);
480 481 482 483 484 485 486
    return;
  }

  // ================================================================================
  // Update the image in the global texture
  // ================================================================================
  Texture& texture = globalTextures_.texture(_textureName);
487 488 489 490 491 492

  // Add to image store
  int newImageId = imageStore().addImage(_image);

  // Add to texture description
  texture.textureImageId(newImageId);
493 494 495 496 497 498 499 500 501 502

  // ================================================================================
  // check if the local textures need to be updated
  // ================================================================================
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it){

    TextureData* texData = dynamic_cast< TextureData* > ( o_it->objectData(TEXTUREDATA) );
    if (texData != 0)
      if ( texData->textureExists(_textureName) ){
        Texture& localTex = texData->texture(_textureName);
503
        localTex.textureImageId(newImageId);
504

505 506 507 508 509
          if( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
            PluginFunctions::triMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          } else if ( o_it->dataType( DATA_POLY_MESH ) ) {
            PluginFunctions::triMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          }
510 511 512 513 514 515 516 517 518 519
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
          else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) ) {
            PluginFunctions::hexahedralMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          }
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
          else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) ) {
            PluginFunctions::polyhedralMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          }
#endif
520 521 522
      }
  }

523 524
  emit updateView();

525 526
}

527
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image, int _id ){
528

529 530 531
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
532
    emit log(LOGERR,"slotTextureGetImage: Unable to get Object for id " + QString::number(_id) );
533 534 535 536 537 538 539
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
540
    emit log(LOGERR, tr("slotTextureGetImage: Object has no texture data! Object: %1").arg(_id) );
541 542 543 544 545 546 547
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
548
    emit log(LOGERR, "slotTextureGetImage: Texture not available! " + _textureName );
549 550 551 552 553 554
    return;
  }

  if ( texData->texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
555
    _image = imageStore().getImage(texData->texture(_textureName).textureImageId(),0 );
556 557
}

558

559
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image ){
560

561
  if ( ! globalTextures_.textureExists(_textureName) ) {
562
    emit log(LOGERR,"slotTextureGetImage: Global texture does not exist: " + _textureName);
563 564 565 566 567 568
    return;
  }

  if ( globalTextures_.texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
569
    _image = imageStore().getImage(globalTextures_.texture(_textureName).textureImageId(),0);
570 571
}

572
void TextureControlPlugin::slotTextureIndex( QString _textureName, int _id, int& _index){
573

574 575 576
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
577
    emit log(LOGERR,"slotTextureIndex: Unable to get Object for id " + QString::number(_id) );
578 579 580 581 582 583 584
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
585
    emit log(LOGERR, tr("slotTextureIndex: Object has no texture data! Object: %1").arg(_id) );
586 587 588 589 590 591 592
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
593
    emit log(LOGERR, "slotTextureIndex: Texture not available! " + _textureName );
594 595 596 597 598 599
    return;
  }

  _index = texData->texture(_textureName).id();
}

600
void TextureControlPlugin::slotTextureIndexPropertyName(int _id, QString& _propertyName) {
601

602 603 604
    // Get the object
    BaseObjectData* obj;
    if (! PluginFunctions::getObject(  _id , obj ) ) {
605
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to get Object for id " + QString::number(_id) );
606 607 608 609 610 611
        return;
    }
    
    // Get texture index property name
    if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
        _propertyName = PluginFunctions::triMeshObject(obj)->meshNode()->indexPropertyName().c_str();
612
    } else if( obj->dataType( DATA_POLY_MESH ) ) {
613 614
        _propertyName = PluginFunctions::polyMeshObject(obj)->meshNode()->indexPropertyName().c_str();
    } else {
615
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to access mesh for object with id " + QString::number(_id) );
616 617 618
    }
}

619
void TextureControlPlugin::slotTextureName( int _id, int _textureIndex, QString& _textureName){
620

621 622 623
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
624
    emit log(LOGERR,"slotTextureName: Unable to get Object for id " + QString::number(_id) );
625 626 627 628 629 630 631
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
632
    emit log(LOGERR, tr("slotTextureName: Object has no texture data! Object: %1").arg(_id) );
633 634 635 636 637 638 639 640 641
    return;
  }

  for (uint i=0; i < texData->textures().size(); i++ )
    if ( (texData->textures()[i]).id() == _textureIndex ){
      _textureName = (texData->textures()[i]).name();
      return;
    }

642
  emit log(LOGERR, "slotTextureName: TextureIndex not available! (" + QString::number(_textureIndex) + ")" );
643 644 645 646
  _textureName = "NOT_FOUND";
  return;
}

647
void TextureControlPlugin::slotTextureFilename( int _id, QString _textureName, QString& _textureFilename){
648

649 650 651
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
652
    emit log(LOGERR,"slotTextureFilename: Unable to get Object for id " + QString::number(_id) );
653 654 655 656 657 658 659
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
660
    emit log(LOGERR, tr("slotTextureFilename: Object has no texture data! Object: %1").arg(_id) );
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
    return;
  }

  // Search in local textures
  for (uint i=0; i < texData->textures().size(); i++ ) {
      for (int j=0; j < texData->textures()[i].multiTextureList.size(); j++ ) {
          if ( (texData->textures()[i]).name() == _textureName ){
              Texture& tex = texData->texture((texData->textures()[i]).name());
              _textureFilename = tex.filename();
              return;
          } else if ( (texData->textures()[i]).multiTextureList[j] == _textureName ){
              Texture& tex = texData->texture((texData->textures()[i]).multiTextureList[j]);
              _textureFilename = tex.filename();
              return;
          }
      }
  }
  
  _textureFilename = OpenFlipper::Options::textureDir().path() + 
680
      QDir::separator().toLatin1() + (globalTextures_.texture(_textureName)).filename();
681 682 683 684 685 686 687
  
  QFile f(_textureFilename);
  if(!f.exists()) _textureFilename = "NOT_FOUND";
  
  return;
}

688
void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName ){
689

Dirk Wilden's avatar
Dirk Wilden committed
690 691
  _textureName = "NONE";
  
692 693 694
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
695
    emit log(LOGERR,"slotGetCurrentTexture: Unable to get Object for id " + QString::number(_id) );
696 697 698 699 700 701
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
702 703 704 705 706 707
  if (texData == 0) {
    #ifndef NDEBUG
    
      // Iterate over all per Object datas and output them
      QMap<QString, PerObjectData*>::const_iterator mapIter = obj->getPerObjectDataMap().begin();  
      while ( mapIter != obj->getPerObjectDataMap().end() ) {
708
        ++mapIter;
709 710 711
      }
    #endif
    
712
    return;
713
  }
714 715
  
  // Iterate over all available textures
716 717
  for ( uint i = 0 ; i < texData->textures().size() ; ++i) {
  
718 719 720
    if ( (texData->textures()[i]).enabled() ){
      _textureName = (texData->textures()[i]).name();
      
721
      if ( (texData->textures()[i]).type() == MULTITEXTURE ) {
722
        return;
723
      }
724
    }
725
  }
726 727 728 729 730 731
}

void TextureControlPlugin::slotGetSubTextures( int _id, QString _multiTextureName, QStringList& _subTextures ){
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
732
    emit log(LOGERR,"slotGetSubTextures: Unable to get Object for id " + QString::number(_id) );
733 734 735 736 737 738 739
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
740
    emit log(LOGERR, tr("slotGetSubTextures: Object has no texture data! Object: %1").arg(_id) );
741 742 743 744 745 746 747
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_multiTextureName) ) {
748
    emit log(LOGERR, "slotGetSubTextures: Texture not available! " + _multiTextureName );
749 750 751 752 753 754 755 756 757 758
    return;
  }
  
  if ( texData->texture(_multiTextureName).type() == MULTITEXTURE )
    _subTextures = texData->texture(_multiTextureName).multiTextureList;
  else
    _subTextures = QStringList();
}

void TextureControlPlugin::slotTextureUpdated( QString _textureName , int _identifier ){
759

760 761 762 763 764
  // ================================================================================
  // Get updated object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _identifier , obj ) ) {
765
    emit log(LOGERR,"slotTextureUpdated: Unable to get Object for id " + QString::number(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
766 767
    return;
  }
768

769
  //skip object if its not a mesh
770 771 772 773 774 775 776 777
  if(   !obj->dataType( DATA_TRIANGLE_MESH )   && !obj->dataType( DATA_POLY_MESH )
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
     && !obj->dataType( DATA_HEXAHEDRAL_MESH )
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
     && !obj->dataType( DATA_POLYHEDRAL_MESH )
#endif
    )
778 779
    return;

780 781 782 783 784
  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
785
    emit log(LOGERR,tr("slotTextureUpdated: Texture data not found: Object %1" ).arg(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
786
    return;
787
  }
Jan Möbius's avatar
 
Jan Möbius committed
788

789 790 791
  // ================================================================================
  // Check if texture exists
  // ================================================================================
792
  if ( ! texData->textureExists(_textureName) ) {
793
    emit log(LOGERR,"slotTextureUpdated: Texture " + _textureName + " not found on object " + QString::number(_identifier) );
794
    return;
795
  }
Jan Möbius's avatar
 
Jan Möbius committed
796

797 798 799
  // ================================================================================
  // If texture is not enabled, mark it as dirty and defer update to visualization update
  // ================================================================================
800
  if ( ! texData->texture(_textureName).enabled() ) {
801
    texData->texture(_textureName).setDirty();
802 803
    return;
  }
Jan Möbius's avatar
 
Jan Möbius committed
804

805
  // ================================================================================
806
  // Enable the texture in texture node
807 808 809 810
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
811 812 813
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::triMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
814 815 816 817
    PluginFunctions::triMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PolyMesh* mesh = PluginFunctions::polyMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
818 819 820
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::polyMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
821
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
822
  }
823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
#ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    HexahedralMesh* mesh = PluginFunctions::hexahedralMesh(obj);
    HexahedralMeshObject* meshObj = PluginFunctions::hexahedralMeshObject(obj);
    doUpdateTextureOVM(texData->texture(_textureName), *mesh, *meshObj);
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  }
#endif
#ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PolyhedralMesh* mesh = PluginFunctions::polyhedralMesh(obj);
    PolyhedralMeshObject* meshObj = PluginFunctions::polyhedralMeshObject(obj);
    doUpdateTextureOVM(texData->texture(_textureName), *mesh, *meshObj);
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  }
#endif
Jan Möbius's avatar
 
Jan Möbius committed
845

846 847 848
  // ================================================================================
  // Mark texture as not dirty
  // ================================================================================
849
  texData->texture(_textureName).clean();
Jan Möbius's avatar
 
Jan Möbius committed
850

851 852 853 854 855
  // ================================================================================
  // Tell plugins to update texture
  // ================================================================================
  emit updatedObject(obj->id(),UPDATE_TEXTURE);

Jan Möbius's avatar
 
Jan Möbius committed
856 857
}

858 859 860 861 862 863
void TextureControlPlugin::slotUpdateTexture( QString _textureName , int _identifier) {
  if ( _textureName == "Reflection Lines" )
    slotTextureUpdated( _textureName , _identifier );

}

Jan Möbius's avatar
 
Jan Möbius committed
864
template< typename MeshT >
865
void TextureControlPlugin::doUpdateTexture ( Texture& _texture, MeshT& _mesh )
Jan Möbius's avatar
 
Jan Möbius committed
866
{
867

868
  if ( _texture.type() == HALFEDGEBASED ) {
869
    if (_texture.dimension() == 1) {
Jan Möbius's avatar
 
Jan Möbius committed
870 871

      OpenMesh::HPropHandleT< double > texture;
872
      if ( ! _mesh.get_property_handle(texture, _texture.name().toStdString() ) ) {
873
        emit log(LOGERR,tr("doUpdateTexture: HALFEDGEBASED dimension 1: Unable to get property %1").arg(_texture.name()) );
Jan Möbius's avatar
 
Jan Möbius committed
874 875 876
        return;
      }

877
      copyTexture(_texture, _mesh, texture);
Jan Möbius's avatar
 
Jan Möbius committed
878

879
    } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
880 881

      OpenMesh::HPropHandleT< OpenMesh::Vec2d > texture2D;
882
      if ( ! _mesh.get_property_handle( texture2D, _texture.name().toStdString() ) ) {
883
        emit log(LOGERR,tr("doUpdateTexture: HALFEDGEBASED dimension 2: Unable to get property %1").arg(_texture.name()) );
Jan Möbius's avatar
 
Jan Möbius committed
884 885 886
        return;
      }

887
      copyTexture( _texture, _mesh, texture2D);
Jan Möbius's avatar
 
Jan Möbius committed
888

889
    } else
890
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );
891
  } else if ( _texture.type() == VERTEXBASED ) {
892
    if ( _texture.dimension() == 1 ) {
Jan Möbius's avatar
 
Jan Möbius committed
893 894

      OpenMesh::VPropHandleT< double > texture;
895
      if ( ! _mesh.get_property_handle(texture,_texture.name().toStdString() ) ) {
896
        emit log(LOGERR,tr("doUpdateTexture: VERTEXBASED dimension 1: Unable to get property %1").arg(_texture.name()) );
897
        return;
Jan Möbius's avatar
 
Jan Möbius committed
898 899
      }

900
        copyTexture(_texture, _mesh, texture);
Jan Möbius's avatar
 
Jan Möbius committed
901

902
      } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
903 904

        OpenMesh::VPropHandleT< OpenMesh::Vec2d >  texture2D;
905
        if ( ! _mesh.get_property_handle(texture2D,_texture.name().toStdString() ) ) {
906
          emit log(LOGERR,tr("doUpdateTexture: VERTEXBASED dimension 2: Unable to get property %1").arg(_texture.name()) );
907
          return;
Jan Möbius's avatar
 
Jan Möbius committed
908 909
        }

910
        copyTexture( _texture, _mesh, texture2D);
Jan Möbius's avatar
 
Jan Möbius committed
911 912

      } /*else if ( textures_[_textureid].dimension == 3 ) {
913

Jan Möbius's avatar
 
Jan Möbius committed
914
        OpenMesh::VPropHandleT< OpenMesh::Vec3d >  scalarField3D;
915 916
        if ( ! _mesh.get_property_handle(scalarField3D,_texture.name) ) {
          emit log(LOGERR,"Unable to get property " + _texture.name );
917
          return;
Jan Möbius's avatar
 
Jan Möbius committed
918
        }
919

Jan Möbius's avatar
 
Jan Möbius committed
920
        copyTexture(_textureid, _mesh, scalarField3D);
921

Jan Möbius's avatar
 
Jan Möbius committed
922
      }*/ else
923
        emit log(LOGERR, "doUpdateTexture: Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );
924

Jan Möbius's avatar
 
Jan Möbius committed
925
    } else
926
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture type");
927

Jan Möbius's avatar
 
Jan Möbius committed
928 929
}

930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945

#ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
template< typename VolumeMeshT, typename VolumeMeshObjectT >
void TextureControlPlugin::doUpdateTextureOVM ( Texture& _texture, VolumeMeshT& _mesh, VolumeMeshObjectT& _obj )
{
  if ( _texture.type() == VERTEXBASED ) {
    if ( _texture.dimension() == 1 ) {

      if (!_mesh.template vertex_property_exists<double>(_texture.name().toStdString())){
        emit log(LOGERR,tr("doUpdateTexture: VERTEXBASED dimension 1: Unable to get property %1").arg(_texture.name()) );
        return;
      }

      OpenVolumeMesh::VertexPropertyT< double > texture = _mesh.template request_vertex_property<double>(_texture.name().toStdString());
      copyTexture(_texture, _mesh, _obj, texture);

946 947
      VolumeMeshDrawModesContainer drawModesVolumeMesh;
      _obj.setObjectDrawMode(drawModesVolumeMesh.facesTextured);
948 949 950 951 952 953 954 955 956 957 958 959

    }
    else if ( _texture.dimension() == 2 )
    {

        if (!_mesh.template vertex_property_exists<ACG::Vec2d>(_texture.name().toStdString())){
          emit log(LOGERR,tr("doUpdateTexture: VERTEXBASED dimension 2: Unable to get property %1").arg(_texture.name()) );
          return;
        }
        OpenVolumeMesh::VertexPropertyT< ACG::Vec2d > texture = _mesh.template request_vertex_property<ACG::Vec2d>(_texture.name().toStdString());
        copyTexture(_texture, _mesh, _obj, texture);

960 961
        VolumeMeshDrawModesContainer drawModesVolumeMesh;
        _obj.setObjectDrawMode(drawModesVolumeMesh.facesTextured);