TextureControl.cc 73.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
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
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33 34 35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36 37 38 39 40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42 43 44 45




46

Jan Möbius's avatar
 
Jan Möbius committed
47 48 49 50 51
#include <QtGui>

#include "TextureControl.hh"

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

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

59 60
#include <math.h>

61
#define TEXTUREDATA "TextureData"
62
 
63

Dirk Wilden's avatar
Dirk Wilden committed
64 65 66 67 68
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension , int _id)
{
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
69
    emit log(LOGERR,"slotTextureAdded: Unable to get Object for id " + QString::number(_id) );
70
    return;
Dirk Wilden's avatar
Dirk Wilden committed
71 72 73 74 75 76 77 78 79
  }

  // 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);
  }

80
  if ( texData->textureExists(_textureName) ) {
81
    emit log(LOGERR,"slotTextureAdded: Trying to add already existing texture " + _textureName + " for object " + QString::number(_id) );
Dirk Wilden's avatar
Dirk Wilden committed
82 83
    return;
  }
84 85 86 87 88

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

89 90
  // 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
91

92 93 94 95
  if ( newId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
96 97 98 99 100 101 102 103

  // ================================================================================
  // 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 ) )
104
    glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
105 106

  if ( obj->dataType( DATA_POLY_MESH ) )
107
    glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
108 109 110 111 112 113

  // ================================================================================
  // Store texture information in objects metadata
  // ================================================================================

  if (glName == 0) {
114
    emit log(LOGERR,"slotTextureAdded: Unable to bind texture!");
115 116 117 118
    return;
  }

  texData->addTexture(_textureName,_filename,_dimension,glName);
119 120 121 122

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

123
  texData->texture(_textureName).disable();
Dirk Wilden's avatar
Dirk Wilden committed
124 125
}

Jan Möbius's avatar
 
Jan Möbius committed
126 127
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension)
{
128 129 130
  // Add this texture to the list of global textures
  if ( ! globalTextures_.textureExists(_textureName) ) {
    globalTextures_.addTexture(_textureName,_filename,_dimension,0);
131
    globalTextures_.texture(_textureName).disable();
132

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

135 136 137 138
    if ( newImageId == -1 ) {
      emit log(LOGERR,imageStore().error());
      return;
    }
Dirk Wilden's avatar
 
Dirk Wilden committed
139

140
    globalTextures_.texture(_textureName).textureImageId(newImageId);
141

142
  } else {
143
    emit log(LOGERR,"slotTextureAdded: Trying to add already existing global texture " + _textureName );
144 145
    return;
  }
146

147
  // Add a new entry to the global Texture menu
Jan Möbius's avatar
 
Jan Möbius committed
148
  QAction* new_texture = new QAction(_textureName, this);
149
  new_texture->setStatusTip(tr("slotTextureAdded: Switch all objects to this Texture ( if available )"));
Jan Möbius's avatar
 
Jan Möbius committed
150 151 152 153 154
  new_texture->setCheckable(true);
  actionGroup_->addAction(new_texture);
  textureMenu_->addAction(new_texture);
  new_texture->setChecked(true);
  textureActions_.push_back(new_texture);
155

156
}
157

158
void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) {
159 160 161
   // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
162
    emit log(LOGERR,"slotMultiTextureAdded: Unable to get Object for id " + QString::number(_id) );
163 164 165 166
  }

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
167
      emit log(LOGERR,"slotMultiTextureAdded: Trying to add textures to object failed because of unsupported object type");
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
      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
  _textureId = -1;
186
  _textureId = texData->texture(_name).id();
187

188 189 190
  //hide the texture (its accessible through the multiTexture)
  texData->texture(_name).hidden( true );

191 192
  // Add to image store
  int newImageId = imageStore().addImageFile(_name);
Dirk Wilden's avatar
 
Dirk Wilden committed
193

194 195 196 197
  if ( newImageId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
Dirk Wilden's avatar
 
Dirk Wilden committed
198

199 200
  // Add to texture description
  texData->texture(_name).textureImageId(newImageId);
201 202 203 204 205

  // Store the new texture in the list of this textureGroup
  if ( _textureId != -1 ) {
    texData->texture(_textureGroup).multiTextureList << _name ;
  } else {
206
    emit log(LOGERR,"slotMultiTextureAdded: Error when getting internal id of new multitexture!");
207 208 209 210 211
  }

}

void TextureControlPlugin::addedEmptyObject( int _id ) {
212 213 214 215
  
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
216
//     emit log(LOGERR,"addedEmptyObject: Unable to get Object for id " + QString::number(_id) );
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    return;
  }
  
  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
    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) {
234 235 236 237 238 239 240 241 242

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

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

243 244 245 246 247 248 249
    // ================================================================================
    // 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 ) )
250
      glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
251 252
    
    if ( obj->dataType( DATA_POLY_MESH ) )
253
      glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
254 255 256 257 258 259
    
    // ================================================================================
    // Store texture information in objects metadata
    // ================================================================================
    if (glName != 0) {
      texData->addTexture(globalTextures_.textures()[i], glName);
260 261 262

      // Add to texture description
      texData->setImage(globalTextures_.textures()[i].name(),newImageId);
263 264
    }
    else {
265
      imageStore().removeImage(newImageId);
266
      emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
      continue;
    }
    
    
    // ================================================================================
    // Update texture mapping in meshNode
    // ================================================================================
    if( obj->dataType( DATA_TRIANGLE_MESH ) ){
      PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
    
    if ( obj->dataType( DATA_POLY_MESH ) ){
      PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
    
  }
Jan Möbius's avatar
 
Jan Möbius committed
283 284
}

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

288 289 290 291 292 293
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _objectId , obj ) ) {
    return;
  }

294 295 296
  // ================================================================================
  // Create a backup of the original per Vertex texture Coordinates
  // ================================================================================
297
  
298 299 300 301 302 303 304 305 306 307 308 309 310
  if ( _mesh->has_vertex_texcoords2D() ){
  
    OpenMesh::VPropHandleT< typename MeshT::TexCoord2D > oldVertexCoords;
    if ( !_mesh->get_property_handle(oldVertexCoords,"Original Per Vertex Texture Coords") )
      _mesh->add_property(oldVertexCoords,"Original Per Vertex Texture Coords");
    
    for ( TriMesh::VertexIter v_it = _mesh->vertices_begin(); v_it != _mesh->vertices_end(); ++v_it)
      _mesh->property(oldVertexCoords, v_it ) =  _mesh->texcoord2D( v_it );

    slotTextureAdded("Original Per Vertex Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Vertex Texture Coords","type=vertexbased",_objectId);
  }
  
311 312 313
  // ================================================================================
  // Create a backup of the original per Face texture Coordinates
  // ================================================================================
314
  
315 316 317 318 319 320 321 322 323 324 325 326
  if ( _mesh->has_halfedge_texcoords2D() ){
    
    OpenMesh::HPropHandleT< typename MeshT::TexCoord2D > oldHalfedgeCoords;
    if ( !_mesh->get_property_handle(oldHalfedgeCoords,"Original Per Face Texture Coords") )
      _mesh->add_property(oldHalfedgeCoords,"Original Per Face Texture Coords");
    
    for ( TriMesh::HalfedgeIter he_it = _mesh->halfedges_begin(); he_it != _mesh->halfedges_end(); ++he_it)
      _mesh->property(oldHalfedgeCoords, he_it ) =  _mesh->texcoord2D( he_it );

    slotTextureAdded("Original Per Face Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Face Texture Coords","type=halfedgebased",_objectId);
  }
327

328 329
}

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

333 334 335
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
336
    emit log(LOGERR,"fileOpened: Unable to get Object for id " + QString::number(_id) );
337
    return;
338 339 340 341 342
  }

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
      return;
343 344
  }

345 346 347
  // 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){
348 349
    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
350
  }
351 352 353 354 355

  // 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
356
      handleFileOpenTextures(mesh,_id);
357 358 359
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PolyMesh* mesh = PluginFunctions::polyMesh(obj);
    if ( mesh )
Jan Möbius's avatar
Jan Möbius committed
360
      handleFileOpenTextures(mesh,_id);
361 362
  }

363 364
}

365 366 367 368 369 370 371
void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage& _image , int _id ) {

  // ================================================================================
  // Get the new object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
372
    emit log(LOGERR,"slotTextureChangeImage: Unable to get Object for id " + QString::number(_id) );
373 374 375 376 377 378 379 380
  }

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

  if ( texData == 0 || ( !texData->textureExists(_textureName))  ) {
381
    emit log(LOGERR,"slotTextureChangeImage: Texture does not exist: " + _textureName + " (objectid=" + QString::number(_id) + ")");
382 383 384 385 386 387 388
    return;
  }

  // ================================================================================
  // Update the image
  // ================================================================================
  Texture& texture = texData->texture(_textureName);
389 390 391 392 393 394

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

  // Add to texture description
  texture.textureImageId(newImageId);
395 396 397 398 399

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

400 401 402 403 404 405 406
  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());
  }

  emit updateView();
407 408 409 410 411 412 413 414 415

}

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

  // ================================================================================
  // Update texture Image for global textures
  // ================================================================================
  if ( ! globalTextures_.textureExists(_textureName) ) {
416
    emit log(LOGERR,"slotTextureChangeImage: Global texture does not exist: " + _textureName);
417 418 419 420 421 422 423
    return;
  }

  // ================================================================================
  // Update the image in the global texture
  // ================================================================================
  Texture& texture = globalTextures_.texture(_textureName);
424 425 426 427 428 429

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

  // Add to texture description
  texture.textureImageId(newImageId);
430 431 432 433 434 435 436 437 438 439

  // ================================================================================
  // 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);
440
        localTex.textureImageId(newImageId);
441

442 443 444 445 446
          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());
          }
447 448 449
      }
  }

450 451
  emit updateView();

452 453
}

454 455 456 457 458
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image, int _id ){
  
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
459
    emit log(LOGERR,"slotTextureGetImage: Unable to get Object for id " + QString::number(_id) );
460 461 462 463 464 465 466
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
467
    emit log(LOGERR, tr("slotTextureGetImage: Object has no texture data! Object: %1").arg(_id) );
468 469 470 471 472 473 474
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
475
    emit log(LOGERR, "slotTextureGetImage: Texture not available! " + _textureName );
476 477 478 479 480 481
    return;
  }

  if ( texData->texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
482
    _image = imageStore().getImage(texData->texture(_textureName).textureImageId(),0 );
483 484
}

485

486 487 488
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image ){
  
  if ( ! globalTextures_.textureExists(_textureName) ) {
489
    emit log(LOGERR,"slotTextureGetImage: Global texture does not exist: " + _textureName);
490 491 492 493 494 495
    return;
  }

  if ( globalTextures_.texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
496
    _image = imageStore().getImage(globalTextures_.texture(_textureName).textureImageId(),0);
497 498
}

499 500 501 502 503
void TextureControlPlugin::slotTextureIndex( QString _textureName, int _id, int& _index){
  
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
504
    emit log(LOGERR,"slotTextureIndex: Unable to get Object for id " + QString::number(_id) );
505 506 507 508 509 510 511
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
512
    emit log(LOGERR, tr("slotTextureIndex: Object has no texture data! Object: %1").arg(_id) );
513 514 515 516 517 518 519
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
520
    emit log(LOGERR, "slotTextureIndex: Texture not available! " + _textureName );
521 522 523 524 525 526
    return;
  }

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

527 528 529 530 531
void TextureControlPlugin::slotTextureIndexPropertyName(int _id, QString& _propertyName) {
    
    // Get the object
    BaseObjectData* obj;
    if (! PluginFunctions::getObject(  _id , obj ) ) {
532
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to get Object for id " + QString::number(_id) );
533 534 535 536 537 538 539 540 541
        return;
    }
    
    // Get texture index property name
    if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
        _propertyName = PluginFunctions::triMeshObject(obj)->meshNode()->indexPropertyName().c_str();
    } else if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
        _propertyName = PluginFunctions::polyMeshObject(obj)->meshNode()->indexPropertyName().c_str();
    } else {
542
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to access mesh for object with id " + QString::number(_id) );
543 544 545
    }
}

546 547 548 549 550
void TextureControlPlugin::slotTextureName( int _id, int _textureIndex, QString& _textureName){
  
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
551
    emit log(LOGERR,"slotTextureName: Unable to get Object for id " + QString::number(_id) );
552 553 554 555 556 557 558
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
559
    emit log(LOGERR, tr("slotTextureName: Object has no texture data! Object: %1").arg(_id) );
560 561 562 563 564 565 566 567 568
    return;
  }

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

569
  emit log(LOGERR, "slotTextureName: TextureIndex not available! (" + QString::number(_textureIndex) + ")" );
570 571 572 573
  _textureName = "NOT_FOUND";
  return;
}

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

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
587
    emit log(LOGERR, tr("slotTextureFilename: Object has no texture data! Object: %1").arg(_id) );
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
    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() + 
      QDir::separator().toAscii() + (globalTextures_.texture(_textureName)).filename();
  
  QFile f(_textureFilename);
  if(!f.exists()) _textureFilename = "NOT_FOUND";
  
  return;
}

615 616
void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName ){
  
Dirk Wilden's avatar
Dirk Wilden committed
617 618
  _textureName = "NONE";
  
619 620 621
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
622
    emit log(LOGERR,"slotGetCurrentTexture: Unable to get Object for id " + QString::number(_id) );
623 624 625 626 627 628
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
629 630 631 632 633 634
  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() ) {
635
        ++mapIter;
636 637 638
      }
    #endif
    
639
    return;
640
  }
641 642
  
  // Iterate over all available textures
643 644
  for ( uint i = 0 ; i < texData->textures().size() ; ++i) {
  
645 646 647
    if ( (texData->textures()[i]).enabled() ){
      _textureName = (texData->textures()[i]).name();
      
648
      if ( (texData->textures()[i]).type() == MULTITEXTURE ) {
649
        return;
650
      }
651
    }
652
  }
653 654 655 656 657 658
}

void TextureControlPlugin::slotGetSubTextures( int _id, QString _multiTextureName, QStringList& _subTextures ){
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
659
    emit log(LOGERR,"slotGetSubTextures: Unable to get Object for id " + QString::number(_id) );
660 661 662 663 664 665 666
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
667
    emit log(LOGERR, tr("slotGetSubTextures: Object has no texture data! Object: %1").arg(_id) );
668 669 670 671 672 673 674
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_multiTextureName) ) {
675
    emit log(LOGERR, "slotGetSubTextures: Texture not available! " + _multiTextureName );
676 677 678 679 680 681 682 683 684 685
    return;
  }
  
  if ( texData->texture(_multiTextureName).type() == MULTITEXTURE )
    _subTextures = texData->texture(_multiTextureName).multiTextureList;
  else
    _subTextures = QStringList();
}

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

687 688 689 690 691
  // ================================================================================
  // Get updated object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _identifier , obj ) ) {
692
    emit log(LOGERR,"slotTextureUpdated: Unable to get Object for id " + QString::number(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
693 694
    return;
  }
695

696 697 698 699
  //skip object if its not a mesh
  if( !obj->dataType( DATA_TRIANGLE_MESH ) && !obj->dataType( DATA_POLY_MESH ) )
    return;

700 701 702 703 704
  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
705
    emit log(LOGERR,tr("slotTextureUpdated: Texture data not found: Object %1" ).arg(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
706
    return;
707
  }
Jan Möbius's avatar
 
Jan Möbius committed
708

709 710 711
  // ================================================================================
  // Check if texture exists
  // ================================================================================
712
  if ( ! texData->textureExists(_textureName) ) {
713
    emit log(LOGERR,"slotTextureUpdated: Texture " + _textureName + " not found on object " + QString::number(_identifier) );
714
    return;
715
  }
Jan Möbius's avatar
 
Jan Möbius committed
716

717 718 719
  // ================================================================================
  // If texture is not enabled, mark it as dirty and defer update to visualization update
  // ================================================================================
720
  if ( ! texData->texture(_textureName).enabled() ) {
721
    texData->texture(_textureName).setDirty();
722 723
    return;
  }
Jan Möbius's avatar
 
Jan Möbius committed
724

725
  // ================================================================================
726
  // Enable the texture in texture node
727 728 729 730
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
731 732 733
    // 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() );
734 735 736 737
    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);
738 739 740
    // 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() );
741
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
742
  }
Jan Möbius's avatar
 
Jan Möbius committed
743

744 745 746
  // ================================================================================
  // Mark texture as not dirty
  // ================================================================================
747
  texData->texture(_textureName).clean();
Jan Möbius's avatar
 
Jan Möbius committed
748

749 750 751 752 753
  // ================================================================================
  // Tell plugins to update texture
  // ================================================================================
  emit updatedObject(obj->id(),UPDATE_TEXTURE);

Jan Möbius's avatar
 
Jan Möbius committed
754 755
}

756 757 758 759 760 761
void TextureControlPlugin::slotUpdateTexture( QString _textureName , int _identifier) {
  if ( _textureName == "Reflection Lines" )
    slotTextureUpdated( _textureName , _identifier );

}

Jan Möbius's avatar
 
Jan Möbius committed
762
template< typename MeshT >
763
void TextureControlPlugin::doUpdateTexture ( Texture& _texture, MeshT& _mesh )
Jan Möbius's avatar
 
Jan Möbius committed
764
{
765

766
  if ( _texture.type() == HALFEDGEBASED ) {
767
    if (_texture.dimension() == 1) {
Jan Möbius's avatar
 
Jan Möbius committed
768 769

      OpenMesh::HPropHandleT< double > texture;
770
      if ( ! _mesh.get_property_handle(texture, _texture.name().toStdString() ) ) {
771
        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
772 773 774
        return;
      }

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

777
    } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
778 779

      OpenMesh::HPropHandleT< OpenMesh::Vec2d > texture2D;
780
      if ( ! _mesh.get_property_handle( texture2D, _texture.name().toStdString() ) ) {
781
        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
782 783 784
        return;
      }

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

787
    } else
788
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );
789
  } else if ( _texture.type() == VERTEXBASED ) {
790
    if ( _texture.dimension() == 1 ) {
Jan Möbius's avatar
 
Jan Möbius committed
791 792

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

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

800
      } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
801 802

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

808
        copyTexture( _texture, _mesh, texture2D);
Jan Möbius's avatar
 
Jan Möbius committed
809 810

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

Jan Möbius's avatar
 
Jan Möbius committed
812
        OpenMesh::VPropHandleT< OpenMesh::Vec3d >  scalarField3D;
813 814
        if ( ! _mesh.get_property_handle(scalarField3D,_texture.name) ) {
          emit log(LOGERR,"Unable to get property " + _texture.name );
815
          return;
Jan Möbius's avatar
 
Jan Möbius committed
816
        }
817

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

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

Jan Möbius's avatar
 
Jan Möbius committed
823
    } else
824
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture type");
825

Jan Möbius's avatar
 
Jan Möbius committed
826 827
}

828 829 830 831
void TextureControlPlugin::computeValue(Texture& _texture, double _min, double _max, double& _value) {
   const bool clamp         = _texture.parameters.clamp ;
   const bool center        = _texture.parameters.center;
   const double max_val     = _texture.parameters.max_val;
832
   const double min_val     = _texture.parameters.min_val;
833 834 835 836 837 838
   const bool abs           = _texture.parameters.abs;
   const double clamp_max   = _texture.parameters.clamp_max;
   const double clamp_min   = _texture.parameters.clamp_min;
   const bool scale         = _texture.parameters.scale;
   const double scaleFactor = fabs(_max) + fabs(_min);
   const bool repeat        = _texture.parameters.repeat;
839

Jan Möbius's avatar
 
Jan Möbius committed
840 841 842
   // Use absolute value as requested by plugin
   if ( abs )
      _value = fabs(_value);
843

Jan Möbius's avatar
 
Jan Möbius committed
844 845 846 847 848 849 850
   // Clamp if requested
   if ( clamp ) {
      if ( _value > clamp_max )
         _value = clamp_max;
      if (_value < clamp_min)
         _value = clamp_min;
   }
851

Dirk Wilden's avatar
Dirk Wilden committed
852 853 854 855 856 857 858 859 860 861 862
   // if all texCoords have the same value
   if ( _min == _max ){

      if ( ! repeat )
        _value = 0.0;
      else
        _value = max_val;

     return;
   }

Jan Möbius's avatar
 
Jan Möbius committed
863 864 865
   // if the texture should not be repeated, scale to 0..1
   if ( ! repeat ) {
      if (! center ) {
866
        if ( scale) {
Dirk Wilden's avatar
Dirk Wilden committed
867
          _value /= scaleFactor; //scaleFactor is != 0.0 (otherwise _min==_max)
868
          _value -= _min/scaleFactor;
Jan Möbius's avatar
 
Jan Möbius committed
869 870 871 872
        }
      } else {
         // the values above zero are mapped to 0.5..1 the negative ones to 0.5..0
         if (_value > 0.0) {
Dirk Wilden's avatar
Dirk Wilden committed
873
            _value /= ( _max * 2.0); //_max >= _value > 0.0
Jan Möbius's avatar
 
Jan Möbius committed
874 875
            _value += 0.5;
         } else {
Dirk Wilden's avatar
Dirk Wilden committed
876 877 878 879 880 881
            if ( _min == 0.0 ){
              _value = 0.0;
            } else {
              _value /= ( _min * 2.0);
              _value = 0.5 - _value;
            }
Jan Möbius's avatar
 
Jan Möbius committed
882 883 884 885
         }
      }
   } else {
      _value -= _min;
886 887
      _value *= (max_val - min_val) / (_max - _min);
      _value += min_val;
Jan Möbius's avatar
 
Jan Möbius committed
888
   }
889 890 891 892 893 894 895 896 897
   
   
}

void TextureControlPlugin::slotDrawModeChanged(int _viewerId ) {

  // Only update if we have a relevant draw mode
  if (! ( ( PluginFunctions::drawMode(_viewerId) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED ) ||
          ( PluginFunctions::drawMode(_viewerId) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED) || 
Jan Möbius's avatar
Jan Möbius committed
898 899
          ( PluginFunctions::drawMode(_viewerId) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE) ||
          ( PluginFunctions::drawMode(_viewerId) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE_SHADED) )) {
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
    return;
  }

  // Iterate over all Objects
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ;
                                         o_it != PluginFunctions::objectsEnd();
                                         ++o_it) {

    // Get the corresponding texture data
    TextureData* texData = dynamic_cast< TextureData* > ( o_it->objectData(TEXTUREDATA) );
    if (texData == 0){
      continue;
    }

    // Go over all textures and if one of them is enabled and dirty, update it here
    for ( uint i = 0; i < texData->textures().size(); ++i ) {
      if ( texData->textures()[i].enabled() && texData->textures()[i].dirty() ) {
        emit updateTexture( texData->textures()[i].name() , o_it->id() );
      }
    }


  }
  
  emit updateView();

Jan Möbius's avatar
 
Jan Möbius committed
926 927
}

928
void TextureControlPlugin::slotObjectUpdated(int _identifier, const UpdateType _type)
929 930 931 932
{  
    if( !_type.contains(UPDATE_ALL) && !_type.contains(UPDATE_GEOMETRY) && !_type.contains(UPDATE_TOPOLOGY) )
        return;
    
933 934 935 936 937
  // ================================================================================
  // Get updated object
  // ================================================================================
  if ( _identifier == -1 )
    return;
938

939
  BaseObjectData* obj;
940
  if (! PluginFunctions::getObject(  _identifier , obj ) )
941 942
    return;

943 944 945 946
  //skip object if its not a mesh
  if( !obj->dataType( DATA_TRIANGLE_MESH ) && !obj->dataType( DATA_POLY_MESH ) )
    return;

947 948 949 950 951 952 953 954 955 956 957 958 959
  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    return;
  }

  // ================================================================================
  // Set all textures to dirty
  // ================================================================================
  // TODO : if not in the texture rendering mode, do not emit update
  // Involves adding a interface part to react on draw mode changes
960
  // basic check implemented
961
  for ( uint i = 0; i < texData->textures().size(); ++i ) {
962
    texData->textures()[i].setDirty();
963 964 965 966 967

    bool update = false;
    for ( int j = 0 ; j < PluginFunctions::viewers() ; ++j ) {
       update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED );
       update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED );
Jan Möbius's avatar
Jan Möbius committed
968 969
       update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE );
       update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE_SHADED );
970 971
    }

972
    if ( update && texData->textures()[i].enabled() )
973
      emit updateTexture( texData->textures()[i].name() , _identifier );
974
  }
975

Jan Möbius's avatar
 
Jan Möbius committed
976 977 978
}

void TextureControlPlugin::slotUpdateAllTextures( ) {
979 980 981 982 983 984
  std::cerr << "slotUpdateAllTextures: not implemented yet ... might be removed" << std::endl;
  // TODO : Check
//    // Force an update of all textures which are available for the updated object
//    for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
//       for ( uint i = 0 ; i < textures_.size() ; ++i )
//          emit updateTexture( textures_[i].name , o_it->id() );
Jan Möbius's avatar
 
Jan Möbius committed
985 986
}

987
bool TextureControlPlugin::parseMode( QString _mode, Texture& _texture ) {
988

989
  bool changed = false;
990

991 992 993 994 995 996
  int i = 0;
  QString nextString = _mode.section(',',i,i);
  while ( nextString != "" ) {
    QString sectionName = nextString.section('=',0,0);
    QString value = nextString.section('=',1,1);

997 998 999
    // Cleanup representation
    value       = value.trimmed();
    sectionName = sectionName.trimmed();
Jan Möbius's avatar
Jan Möbius committed
1000
    sectionName = sectionName.toLower();
1001

1002
    if ( sectionName == "clamp" ) {
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
      if ( StringToBool(value) != _texture.parameters.clamp ) {
        _texture.parameters.clamp = StringToBool(value);
        changed = true;
      }
    } else if ( sectionName == "clamp_max" ) {
      if (value.toDouble() != _texture.parameters.clamp_max){
        _texture.parameters.clamp_max = value.toDouble();
        changed = true;
      }
    } else if ( sectionName == "clamp_min" ) {
      if (value.toDouble() != _texture.parameters.clamp_min){
        _texture.parameters.clamp_min = value.toDouble();
        changed = true;
      }
    } else if ( sectionName == "max_val" ) {
      if (value.toDouble() != _texture.parameters.max_val){
        _texture.parameters.max_val = value.toDouble();
        changed = true;
      }
1022 1023 1024 1025 1026
    } else if ( sectionName == "min_val" ) {
      if (value.toDouble() != _texture.parameters.min_val){
        _texture.parameters.min_val = value.toDouble();
        changed = true;
      }
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
    } else if ( sectionName == "repeat" ) {
      if ( StringToBool(value) != _texture.parameters.repeat ) {
        _texture.parameters.repeat = StringToBool(value);
        changed = true;
      }
    } else if ( sectionName == "center" ) {
      if ( StringToBool(value) != _texture.parameters.center ) {
        _texture.parameters.center = StringToBool(value);
        changed = true;
      }
    } else if ( sectionName == "scale" ) {
      if ( StringToBool(value) != _texture.parameters.scale ) {
        _texture.parameters.scale = StringToBool(value);
        changed = true;
      }
1042 1043 1044 1045 1046 1047
    } else if ( sectionName == "abs" ) {
      if ( StringToBool(value) != _texture.parameters.abs ) {
        _texture.parameters.abs = StringToBool(value);
        changed = true;
      }
    } else if ( sectionName == "indexproperty" ) {
1048 1049 1050 1051
      if ( value != _texture.indexMappingProperty() ) {
        _texture.indexMappingProperty( value );
        changed = true;
      }
1052
    } else if ( sectionName == "visiblename" ) {
1053 1054 1055 1056
      if ( value != _texture.visibleName() ) {
        _texture.visibleName( value );
        changed = true;
      }
1057 1058 1059 1060 1061 1062 1063
    } else if ( sectionName == "type" ) {
        if ( ( value == "halfedgebased" ) && ( _texture.type() != HALFEDGEBASED ) ) {
          _texture.type( HALFEDGEBASED );
          changed = true;
        } else if ( (value == "vertexbased") && (_texture.type() != HALFEDGEBASED)  ) {
          _texture.type( VERTEXBASED );
          changed = true;
Jan Möbius's avatar
Jan Möbius committed
1064 1065 1066
        }  else if ( (value == "environmentmap") && (_texture.type() != ENVIRONMENT)  ) {
          _texture.type( ENVIRONMENT );
          changed = true;
1067
        } else {
1068
          emit log(LOGERR,"parseMode: Unknown texture type : " + value + " for texture: " + _texture.name() );
1069 1070
        }
    } else
1071
      emit log(LOGERR,"parseMode: Unknown texture mode : " + sectionName);
1072

1073 1074 1075
    ++i;
    nextString = _mode.section(',',i,i);
  }
1076

1077 1078 1079 1080 1081 1082 1083 1084 1085
  return changed;
}

void TextureControlPlugin::slotSetTextureMode(QString _textureName ,QString _mode) {

  // ================================================================================
  // Update texture settings for global textures
  // ================================================================================
  if ( ! globalTextures_.textureExists(_textureName) ) {
1086
    emit log(LOGERR,"slotSetTextureMode: Global texture does not exist: " + _textureName);
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
    return;
  }

  // ================================================================================
  // Parse parameters and update them in the texture data
  // ================================================================================
  Texture& texture = globalTextures_.texture(_textureName);

  // Parse the mode settings
  parseMode(_mode,texture);
Jan Möbius's avatar
Jan Möbius committed
1097
  _mode = _mode.toLower();
1098

1099 1100 1101
  // ================================================================================
  // Mark updated texture as dirty
  // ================================================================================
1102
  texture.setDirty();
1103

1104

Dirk Wilden's avatar
Dirk Wilden committed
1105 1106 1107 1108
  // 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) );
1109

Dirk Wilden's avatar
Dirk Wilden committed
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
    if (texData != 0){

      if ( texData->textureExists(_textureName) ){

        Texture& localTex = texData->texture(_textureName);

        //check if something changed
        bool changed = false;

        if ( _mode.contains("clamp") && (texture.parameters.clamp != localTex.parameters.clamp) ){
          localTex.parameters.clamp = texture.parameters.clamp;
          changed = true;
        }

        if ( _mode.contains("clamp_max") && (texture.parameters.clamp_max != localTex.parameters.clamp_max) ){
          localTex.parameters.clamp_max = texture.parameters.clamp_max;
          changed = true;
        }

        if ( _mode.contains("clamp_min") && (texture.parameters.clamp_min != localTex.parameters.clamp_min) ){
          localTex.parameters.clamp_min = texture.parameters.clamp_min;
          changed = true;
        }

        if ( _mode.contains("max_val") && (texture.parameters.max_val != localTex.parameters.max_val) ){
          localTex.parameters.max_val = texture.parameters.max_val;
          changed = true;
        }
1138 1139 1140 1141 1142
        
        if ( _mode.contains("min_val") && (texture.parameters.min_val != localTex.parameters.min_val) ){
          localTex.parameters.min_val = texture.parameters.min_val;
          changed = true;
        }
Dirk Wilden's avatar
Dirk Wilden committed
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158

        if ( _mode.contains("repeat") && (texture.parameters.repeat != localTex.parameters.repeat) ){
          localTex.parameters.repeat = texture.parameters.repeat;
          changed = true;
        }

        if ( _mode.contains("center") && (texture.parameters.center != localTex.parameters.center) ){
          localTex.parameters.center = texture.parameters.center;
          changed = true;
        }

        if ( _mode.contains("scale") && (texture.parameters.scale != localTex.parameters.scale) ){
          localTex.parameters.scale = texture.parameters.scale;
          changed = true;
        }

1159 1160
        if ( _mode.contains("type") && (texture.type() != localTex.type() ) ){
          localTex.type( texture.type() );
Dirk Wilden's avatar
Dirk Wilden committed
1161 1162 1163
          changed = true;
        }

1164 1165 1166 1167 1168
        if ( _mode.contains("visiblename") && (texture.visibleName() != localTex.visibleName() ) ){
          localTex.visibleName( texture.visibleName() );
          changed = true;
        }

Dirk Wilden's avatar
Dirk Wilden committed
1169 1170 1171 1172 1173
        //only update if the texture is enabled
        if (changed){
          if ( texData->isEnabled(_textureName) )
            emit updateTexture( _textureName, o_it->id() );
          else
1174
            localTex.setDirty();
Dirk Wilden's avatar
Dirk Wilden committed
1175 1176 1177 1178
        }
      }
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
1179 1180
}

Dirk Wilden's avatar
Dirk Wilden committed
1181 1182 1183 1184 1185 1186 1187
bool TextureControlPlugin::StringToBool(QString _value){
  if (_value == "false")
    return false;
  else
    return true;
}

Dirk Wilden's avatar
Dirk Wilden committed
1188
void TextureControlPlugin::slotSetTextureMode(QString _textureName, QString _mode, int _id) {
Dirk Wilden's avatar
Dirk Wilden committed
1189

Dirk Wilden's avatar
Dirk Wilden committed
1190 1191 1192
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
1193
    emit log(LOGERR,"slotSetTextureMode: Unable to get Object for id " + QString::number(_id) );
Dirk Wilden's avatar
Dirk Wilden committed
1194 1195 1196 1197 1198 1199
  }

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

  if ( texData == 0 || ( !texData->textureExists(_textureName))  ) {
1200
    emit log(LOGERR,"slotSetTextureMode: Texture does not exist: " + _textureName + " (object=" + QString::number(_id) + ")");
Dirk Wilden's avatar
Dirk Wilden committed
1201 1202 1203 1204 1205 1206 1207 1208
    return;
  }

  // ================================================================================
  // Parse parameters and update them in the texture data
  // ================================================================================
  Texture& texture = texData->texture(_textureName);

Jan Möbius's avatar
Jan Möbius committed
1209

1210
  bool changed = parseMode(_mode,texture);
Dirk Wilden's avatar
Dirk Wilden committed
1211

Dirk Wilden's avatar
Dirk Wilden committed
1212 1213 1214 1215 1216
  //only update if the texture is enabled
  if (changed){
    if ( texData->isEnabled(_textureName) )
      emit updateTexture( _textureName, _id );
    else
1217
      texture.setDirty();
Dirk Wilden's avatar
Dirk Wilden committed
1218
  }
Dirk Wilden's avatar
Dirk Wilden committed
1219 1220
}

Jan Möbius's avatar
 
Jan Möbius committed
1221
void TextureControlPlugin::pluginsInitialized() {
1222 1223 1224
  // ================================================================================
  // Create global texture menu
  // ================================================================================
Jan Möbius's avatar
 
Jan Möbius committed
1225
  textureMenu_ = new QMenu(tr("&Texture Control"));
1226
  textureMenu_->setTearOffEnabled(true);
Jan Möbius's avatar
 
Jan Möbius committed
1227
  emit addMenubarAction(textureMenu_->menuAction(), VIEWMENU );