TextureControl.cc 41.4 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  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.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16
17
18
19
//  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.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================




35

Jan Möbius's avatar
 
Jan Möbius committed
36
37
38
39
40
#include <QtGui>

#include "TextureControl.hh"

#include <iostream>
41
#include <ACG/GL/GLState.hh>
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45

#include "OpenFlipper/BasePlugin/PluginFunctions.hh"
#include "OpenFlipper/common/GlobalOptions.hh"

46
47
#include <math.h>

48
49
50
51
#define TEXTUREDATA "TextureData"



Dirk Wilden's avatar
Dirk Wilden committed
52
53
54
55
56
57
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension , int _id)
{
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) );
58
    return;
Dirk Wilden's avatar
Dirk Wilden committed
59
60
61
62
63
64
65
66
67
  }

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

68
  if ( texData->textureExists(_textureName) ) {
Dirk Wilden's avatar
Dirk Wilden committed
69
70
71
    emit log(LOGERR,"Trying to add already existing texture " + _textureName + " for object " + QString::number(_id) );
    return;
  }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

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

  QImage textureImage;
  getImage(_filename,textureImage);

  // ================================================================================
  // 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 ) )
    glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(textureImage);

  if ( obj->dataType( DATA_POLY_MESH ) )
    glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(textureImage);

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

  if (glName == 0) {
    emit log(LOGERR,"Unable to bind texture!");
    return;
  }

  texData->addTexture(_textureName,_filename,_dimension,glName);
102
  texData->texture(_textureName).disable();
Dirk Wilden's avatar
Dirk Wilden committed
103
104
}

Jan Möbius's avatar
 
Jan Möbius committed
105
106
void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension)
{
107
108
109
  // Add this texture to the list of global textures
  if ( ! globalTextures_.textureExists(_textureName) ) {
    globalTextures_.addTexture(_textureName,_filename,_dimension,0);
110
    globalTextures_.texture(_textureName).disable();
111
112

    QImage textureImage;
113
    getImage(_filename,textureImage);
114
115
    globalTextures_.texture(_textureName).textureImage = textureImage;

116
117
118
119
  } else {
    emit log(LOGERR,"Trying to add already existing global texture " + _textureName );
    return;
  }
120

121
  // Add a new entry to the global Texture menu
Jan Möbius's avatar
 
Jan Möbius committed
122
  QAction* new_texture = new QAction(_textureName, this);
123
  new_texture->setStatusTip(tr("Switch all objects to this Texture ( if available )"));
Jan Möbius's avatar
 
Jan Möbius committed
124
125
126
127
128
  new_texture->setCheckable(true);
  actionGroup_->addAction(new_texture);
  textureMenu_->addAction(new_texture);
  new_texture->setChecked(true);
  textureActions_.push_back(new_texture);
129

130
}
131

132
void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) {
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
   // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) );
  }

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
      emit log(LOGERR,"Trying to add textures to object failed because of unsupported object type");
      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;
160
  _textureId = texData->texture(_name).id();
161

162
163
164
  //hide the texture (its accessible through the multiTexture)
  texData->texture(_name).hidden( true );

165
166
167
168
169
170
171
172
173
174
175
176
177
  QImage textureImage;
  getImage(_filename,textureImage);
  texData->texture(_name).textureImage = textureImage;

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

}

178
void TextureControlPlugin::getImage( QString _fileName, QImage& _image ) {
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  QString loadFilename;

  if ( _fileName.startsWith("/") )
    loadFilename = _fileName;
  else
    loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + _fileName;

  if ( !_image.load( loadFilename ) ){
        emit log(LOGERR, "Cannot load texture " + _fileName + " at : " + loadFilename);
        _image.load(OpenFlipper::Options::textureDirStr() + QDir::separator() + "unknown.png");
  }

}

void TextureControlPlugin::addedEmptyObject( int _id ) {
  fileOpened(_id);
Jan Möbius's avatar
 
Jan Möbius committed
195
196
}

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

200
201
202
203
204
205
206
207
208
209
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) );
  }

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
      emit log(LOGERR,"Trying to add textures to object failed because of unsupported object type");
      return;
210
211
  }

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  // 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) {

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

    QImage textureImage;
227
    getImage(globalTextures_.textures()[i].filename(),textureImage);
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

    // ================================================================================
    // 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 ) )
      glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(textureImage);

    if ( obj->dataType( DATA_POLY_MESH ) )
      glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(textureImage);

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

245
    if (glName != 0) {
246
      texData->addTexture(globalTextures_.textures()[i], glName);
247
      texData->setImage(globalTextures_.textures()[i].name(),textureImage);
248
249
250
251
252
253
    }
    else {
      emit log(LOGERR,"Unable to bind Texture");
      continue;
    }

254
255
256
257
258

    // ================================================================================
    // Update texture mapping in meshNode
    // ================================================================================
    if( obj->dataType( DATA_TRIANGLE_MESH ) ){
259
260
      PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( 0 );
      PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( 0 );
261
262
263
    }

    if ( obj->dataType( DATA_POLY_MESH ) ){
264
265
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( 0 );
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( 0 );
266
267
    }

Jan Möbius's avatar
 
Jan Möbius committed
268
  }
269
270
271
}

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

273
274
275
276
277
278
  // ================================================================================
  // Get updated object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _identifier , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
279
280
    return;
  }
281

282
283
284
285
286
287
  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    std::cerr << "Texture data not found!" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
288
    return;
289
  }
Jan Möbius's avatar
 
Jan Möbius committed
290

291
292
293
  // ================================================================================
  // Check if texture exists
  // ================================================================================
294
  if ( ! texData->textureExists(_textureName) ) {
295
    emit log(LOGERR,"Texture " + _textureName + " not found on object " + QString::number(_identifier) );
296
    return;
297
  }
Jan Möbius's avatar
 
Jan Möbius committed
298

299
300
301
  // ================================================================================
  // If texture is not enabled, mark it as dirty and defer update to visualization update
  // ================================================================================
302
  if ( ! texData->texture(_textureName).enabled() ) {
303
304
305
    texData->texture(_textureName).dirty = true;
    return;
  }
Jan Möbius's avatar
 
Jan Möbius committed
306

307
308
309
  QImage textureImage;
  getImage( texData->texture(_textureName).filename(), textureImage);

310
311
312
313
314
315
316
  // ================================================================================
  // As the current texture is active, update it
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
    PluginFunctions::triMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
317
    PluginFunctions::triMeshObject(obj)->textureNode()->set_texture( textureImage );
318
319
320
321
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PolyMesh* mesh = PluginFunctions::polyMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
322
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_texture( textureImage );
323
  }
Jan Möbius's avatar
 
Jan Möbius committed
324

325
326
327
  // ================================================================================
  // Mark texture as not dirty
  // ================================================================================
328
  texData->texture(_textureName).dirty = false;
Jan Möbius's avatar
 
Jan Möbius committed
329

330
331
332
333
  // ================================================================================
  // Enable the right draw mode and update
  // ================================================================================
  switchDrawMode(false);
Jan Möbius's avatar
 
Jan Möbius committed
334
335
336
}

template< typename MeshT >
337
void TextureControlPlugin::doUpdateTexture ( Texture& _texture, MeshT& _mesh )
Jan Möbius's avatar
 
Jan Möbius committed
338
{
339

340
  if ( _texture.type == HALFEDGEBASED ) {
341
    if (_texture.dimension() == 1) {
Jan Möbius's avatar
 
Jan Möbius committed
342
343

      OpenMesh::HPropHandleT< double > texture;
344
345
	  if ( ! _mesh.get_property_handle(texture, _texture.name().toStdString() ) ) {
        emit log(LOGERR,"Unable to get property " + _texture.name() );
Jan Möbius's avatar
 
Jan Möbius committed
346
347
348
        return;
      }

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

351
    } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
352
353

      OpenMesh::HPropHandleT< OpenMesh::Vec2d > texture2D;
354
355
	  if ( ! _mesh.get_property_handle( texture2D, _texture.name().toStdString() ) ) {
        emit log(LOGERR,"Unable to get property " + _texture.name() );
Jan Möbius's avatar
 
Jan Möbius committed
356
357
358
        return;
      }

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

361
    } else
362
      emit log(LOGERR, "Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );
363
  } else if ( _texture.type == VERTEXBASED ) {
364
    if ( _texture.dimension() == 1 ) {
Jan Möbius's avatar
 
Jan Möbius committed
365
366

      OpenMesh::VPropHandleT< double > texture;
367
368
	  if ( ! _mesh.get_property_handle(texture,_texture.name().toStdString() ) ) {
        emit log(LOGERR,"Unable to get property " + _texture.name() );
369
        return;
Jan Möbius's avatar
 
Jan Möbius committed
370
371
      }

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

374
      } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
375
376

        OpenMesh::VPropHandleT< OpenMesh::Vec2d >  texture2D;
377
378
		  if ( ! _mesh.get_property_handle(texture2D,_texture.name().toStdString() ) ) {
          emit log(LOGERR,"Unable to get property " + _texture.name() );
379
          return;
Jan Möbius's avatar
 
Jan Möbius committed
380
381
        }

382
        copyTexture( _texture, _mesh, texture2D);
Jan Möbius's avatar
 
Jan Möbius committed
383
384

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

Jan Möbius's avatar
 
Jan Möbius committed
386
        OpenMesh::VPropHandleT< OpenMesh::Vec3d >  scalarField3D;
387
388
        if ( ! _mesh.get_property_handle(scalarField3D,_texture.name) ) {
          emit log(LOGERR,"Unable to get property " + _texture.name );
389
          return;
Jan Möbius's avatar
 
Jan Möbius committed
390
        }
391

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

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

Jan Möbius's avatar
 
Jan Möbius committed
397
398
    } else
      emit log(LOGERR, "Unsupported Texture type");
399

Jan Möbius's avatar
 
Jan Möbius committed
400
401
}

402
403
404
405
406
407
408
409
410
411
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;
   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;
412

Jan Möbius's avatar
 
Jan Möbius committed
413
414
415
   // Use absolute value as requested by plugin
   if ( abs )
      _value = fabs(_value);
416

Jan Möbius's avatar
 
Jan Möbius committed
417
418
419
420
421
422
423
   // Clamp if requested
   if ( clamp ) {
      if ( _value > clamp_max )
         _value = clamp_max;
      if (_value < clamp_min)
         _value = clamp_min;
   }
424

Jan Möbius's avatar
 
Jan Möbius committed
425
426
427
   // if the texture should not be repeated, scale to 0..1
   if ( ! repeat ) {
      if (! center ) {
428
429
430
        if ( scale) {
          _value /= scaleFactor;
          _value -= _min/scaleFactor;
Jan Möbius's avatar
 
Jan Möbius committed
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
        }
      } else {
         // the values above zero are mapped to 0.5..1 the negative ones to 0.5..0
         if (_value > 0.0) {
            _value /= ( _max * 2.0);
            _value += 0.5;
         } else {
            _value /= ( _min * 2.0);
            _value = 0.5 - _value;
         }
      }
   } else {
      _value -= _min;
      _value *= max_val / (_max - _min);
   }
}

void TextureControlPlugin::slotObjectUpdated(int _identifier)
449
{
450
451
452
453
454
  // ================================================================================
  // Get updated object
  // ================================================================================
  if ( _identifier == -1 )
    return;
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _identifier , obj ) ) {
    emit log(LOGERR,"slotObjectUpdated: Unable to get Object for id " + QString::number(_identifier) );
    return;
  }

  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
    std::cerr << "slotObjectUpdated: Texture data not found!" << std::endl;
    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
476
  // basic check implemented
477
478
  for ( uint i = 0; i < texData->textures().size(); ++i ) {
    texData->textures()[i].dirty = true;
479
480
481
482
483
484
485

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

486
    if ( update && texData->textures()[i].enabled() )
487
      emit updateTexture( texData->textures()[i].name() , _identifier );
488
  }
489

Jan Möbius's avatar
 
Jan Möbius committed
490
491
492
}

void TextureControlPlugin::slotUpdateAllTextures( ) {
493
494
495
496
497
498
  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
499
500
501
}

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

503
504
505
506
507
508
509
  // ================================================================================
  // Update texture settings for global textures
  // ================================================================================
  if ( ! globalTextures_.textureExists(_textureName) ) {
    emit log(LOGERR,"Global texture does not exist: " + _textureName);
    return;
  }
510

511
512
513
514
515
516
517
518
519
520
521
522
  // ================================================================================
  // Parse parameters and update them in the texture data
  // ================================================================================
  Texture& texture = globalTextures_.texture(_textureName);

  int i = 0;
  QString nextString = _mode.section(',',i,i);
  while ( nextString != "" ) {
    QString sectionName = nextString.section('=',0,0);
    QString value = nextString.section('=',1,1);

    if ( sectionName == "clamp" ) {
Dirk Wilden's avatar
Dirk Wilden committed
523
      texture.parameters.clamp = StringToBool(value);
524
525
    } else
    if ( sectionName == "clamp_max" ) {
Dirk Wilden's avatar
Dirk Wilden committed
526
      texture.parameters.clamp_max = value.toDouble();
527
528
    } else
    if ( sectionName == "clamp_min" ) {
Dirk Wilden's avatar
Dirk Wilden committed
529
      texture.parameters.clamp_min = value.toDouble();
530
531
    } else
    if ( sectionName == "max_val" ) {
Dirk Wilden's avatar
Dirk Wilden committed
532
      texture.parameters.max_val = value.toDouble();
533
534
    } else
    if ( sectionName == "repeat" ) {
Dirk Wilden's avatar
Dirk Wilden committed
535
      texture.parameters.repeat = StringToBool(value);
536
537
    } else
    if ( sectionName == "center" ) {
Dirk Wilden's avatar
Dirk Wilden committed
538
      texture.parameters.center = StringToBool(value);
539
540
    } else
    if ( sectionName == "scale" ) {
Dirk Wilden's avatar
Dirk Wilden committed
541
      texture.parameters.scale = StringToBool(value);
542
543
544
545
546
547
548
549
550
    } else
    if ( sectionName == "type" ) {
        if (value == "halfedgebased") {
            texture.type = HALFEDGEBASED;
        } else {
            texture.type = VERTEXBASED;
        }
    } else
      emit log(LOGERR,"Unknown texture mode : " + sectionName);
551

552
553
554
    ++i;
    nextString = _mode.section(',',i,i);
  }
555

556
557
558
559
  // ================================================================================
  // Mark updated texture as dirty
  // ================================================================================
  texture.dirty = true;
560

561

Dirk Wilden's avatar
Dirk Wilden committed
562
563
564
565
  // 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) );
566

Dirk Wilden's avatar
Dirk Wilden committed
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
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
615
616
617
618
619
620
621
622
623
624
625
    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;
        }

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

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

        //only update if the texture is enabled
        if (changed){
          if ( texData->isEnabled(_textureName) )
            emit updateTexture( _textureName, o_it->id() );
          else
            localTex.dirty = true;
        }
      }
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
626
627
}

Dirk Wilden's avatar
Dirk Wilden committed
628
629
630
631
632
633
634
bool TextureControlPlugin::StringToBool(QString _value){
  if (_value == "false")
    return false;
  else
    return true;
}

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

Dirk Wilden's avatar
Dirk Wilden committed
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) );
  }

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

  if ( texData == 0 || ( !texData->textureExists(_textureName))  ) {
    emit log(LOGERR,"Texture does not exist: " + _textureName + " (object=" + QString::number(_id) + ")");
    return;
  }

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

Dirk Wilden's avatar
Dirk Wilden committed
656
657
  bool changed = false;

Dirk Wilden's avatar
Dirk Wilden committed
658
659
660
661
662
663
664
  int i = 0;
  QString nextString = _mode.section(',',i,i);
  while ( nextString != "" ) {
    QString sectionName = nextString.section('=',0,0);
    QString value = nextString.section('=',1,1);

    if ( sectionName == "clamp" ) {
Dirk Wilden's avatar
Dirk Wilden committed
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
      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;
      }
    } 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;
      }
    } else if ( sectionName == "type" ) {
Dirk Wilden's avatar
Dirk Wilden committed
700
        if (value == "halfedgebased") {
Dirk Wilden's avatar
Dirk Wilden committed
701
702
          texture.type = HALFEDGEBASED;
          changed = true;
Dirk Wilden's avatar
Dirk Wilden committed
703
        } else {
Dirk Wilden's avatar
Dirk Wilden committed
704
705
          texture.type = VERTEXBASED;
          changed = true;
Dirk Wilden's avatar
Dirk Wilden committed
706
707
708
709
710
711
712
713
        }
    } else
      emit log(LOGERR,"Unknown texture mode : " + sectionName);

    ++i;
    nextString = _mode.section(',',i,i);
  }

Dirk Wilden's avatar
Dirk Wilden committed
714
715
716
717
718
719
720
  //only update if the texture is enabled
  if (changed){
    if ( texData->isEnabled(_textureName) )
      emit updateTexture( _textureName, _id );
    else
      texture.dirty = true;
  }
Dirk Wilden's avatar
Dirk Wilden committed
721
722
}

Jan Möbius's avatar
 
Jan Möbius committed
723
void TextureControlPlugin::pluginsInitialized() {
724
725
726
  // ================================================================================
  // Create global texture menu
  // ================================================================================
Jan Möbius's avatar
 
Jan Möbius committed
727
  textureMenu_ = new QMenu(tr("&Texture Control"));
728
  textureMenu_->setTearOffEnabled(true);
Jan Möbius's avatar
   
Jan Möbius committed
729
  emit addMenubarAction(textureMenu_->menuAction(), VIEWMENU );
730

731
732
733
734
  // ================================================================================
  // Create Settings dialog
  // ================================================================================
  // TODO : Settings dialog updates required to change global/local textures,...
Jan Möbius's avatar
 
Jan Möbius committed
735
  settingsDialog_ = new texturePropertiesWidget(0);
736
737
  connect( settingsDialog_, SIGNAL( applyProperties(TextureData*,QString,int) ),
           this,              SLOT( applyDialogSettings(TextureData*,QString,int) ));
738

739
740
741
742
743
  connect( settingsDialog_, SIGNAL( getCoordinates1D(QString,int,std::vector< double >&)),
           this,              SLOT( getCoordinates1D(QString,int,std::vector< double >&)));

  settingsDialog_->installEventFilter( this );

744
745
746
  // ================================================================================
  // Create action group and menu for global textures
  // ================================================================================
Jan Möbius's avatar
 
Jan Möbius committed
747
748
749
750
  actionGroup_ = new QActionGroup( 0 );
  actionGroup_->setExclusive( true );
  connect( actionGroup_, SIGNAL( triggered( QAction * ) ),
          this, SLOT( slotTextureMenu( QAction * ) ) );
751

Jan Möbius's avatar
 
Jan Möbius committed
752
753
754
755
  QAction* AC_Texture_Settings = new QAction(tr("&Texture Settings"), this);
  AC_Texture_Settings->setStatusTip(tr("Set the texture visualization properties"));
  connect(AC_Texture_Settings, SIGNAL(triggered()), this, SLOT(slotSetTextureProperties()));
  textureMenu_->addAction(AC_Texture_Settings);
756

Jan Möbius's avatar
 
Jan Möbius committed
757
758
  textureMenu_->addSeparator();
  textureMenu_->addActions(actionGroup_->actions());
759
760
761
762
763
764
765
766
767

  // ================================================================================
  // Create basic per object context menu
  // ================================================================================
  contextMenu_ = new QMenu(0);
  contextMenu_->setTitle("Textures");
  emit addContextMenuItem(contextMenu_->menuAction() ,DATA_TRIANGLE_MESH , CONTEXTOBJECTMENU );
  emit addContextMenuItem(contextMenu_->menuAction() ,DATA_POLY_MESH     , CONTEXTOBJECTMENU );

Jan Möbius's avatar
 
Jan Möbius committed
768
}
769

Jan Möbius's avatar
Jan Möbius committed
770
void TextureControlPlugin::slotSetTextureProperties() {
771

772
  settingsDialog_->show( &globalTextures_, -1);
Jan Möbius's avatar
 
Jan Möbius committed
773
}
774

775
void TextureControlPlugin::applyDialogSettings(TextureData* _texData, QString _textureName, int _id) {
776

777
778
779
780
781
782
783
  if (_id != -1){
    //local texture
    if ( _texData->isEnabled(_textureName) ){
      slotTextureUpdated( _textureName  , _id );
      emit updateView();
    }else
      _texData->texture( _textureName ).dirty = true;
784

785
786
787
788
789
790
791
792
793
794
795
  } else {
    // global texture

    _texData->texture( _textureName ).dirty = true;

    Texture& globalTexture = _texData->texture(_textureName);

    // 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) );
Jan Möbius's avatar
 
Jan Möbius committed
796

797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
      if ( texData != 0 && texData->textureExists(_textureName) ){

        //overwrite local parameters
        Texture& localTexture = texData->texture(_textureName);

        bool changed = false;

        if (localTexture.parameters.clamp != globalTexture.parameters.clamp){
          localTexture.parameters.clamp = globalTexture.parameters.clamp;
          changed = true;
        }
        if (localTexture.parameters.clamp_max != globalTexture.parameters.clamp_max){
          localTexture.parameters.clamp_max = globalTexture.parameters.clamp_max;
          changed = true;
        }
        if (localTexture.parameters.clamp_min != globalTexture.parameters.clamp_min){
          localTexture.parameters.clamp_min = globalTexture.parameters.clamp_min;
          changed = true;
        }
        if (localTexture.parameters.max_val != globalTexture.parameters.max_val){
          localTexture.parameters.max_val = globalTexture.parameters.max_val;
          changed = true;
        }
        if (localTexture.parameters.repeat != globalTexture.parameters.repeat){
          localTexture.parameters.repeat = globalTexture.parameters.repeat;
          changed = true;
        }
        if (localTexture.parameters.center != globalTexture.parameters.center){
          localTexture.parameters.center = globalTexture.parameters.center;
          changed = true;
        }
        if (localTexture.parameters.scale != globalTexture.parameters.scale){
          localTexture.parameters.scale = globalTexture.parameters.scale;
          changed = true;
        }

        // update if something has changed
        if ( changed ){
          if ( texData->isEnabled(_textureName) )
            slotTextureUpdated( _textureName  , o_it->id() );
          else
            texData->texture( _textureName ).dirty = true;
        }
      }
    }
  }
}
844

Jan Möbius's avatar
 
Jan Möbius committed
845
void TextureControlPlugin::slotTextureMenu(QAction* _action) {
846
847
  // call existing function to switch the texture
  slotSwitchTexture( _action->text() );
Jan Möbius's avatar
 
Jan Möbius committed
848
849
}

Dirk Wilden's avatar
Dirk Wilden committed
850
void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) {
851

Dirk Wilden's avatar
Dirk Wilden committed
852
853
854
855
856
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
    emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) );
  }
857

Dirk Wilden's avatar
Dirk Wilden committed
858
859
860
861
862
863
864
865
  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
    std::cerr << "Object has no texture data" << std::endl;
    return;
  }
866

Dirk Wilden's avatar
Dirk Wilden committed
867
  // ================================================================================
868
  // Check for requested Texture
Dirk Wilden's avatar
Dirk Wilden committed
869
  // ================================================================================
870
871
  if ( !texData->textureExists(_textureName) ) {
    emit log(LOGERR, "Texture not available! " + _textureName );
Dirk Wilden's avatar
Dirk Wilden committed
872
873
    return;
  }
874

875
876
877
878
879
880
881
882
883
884
885
886
887
888
  // ================================================================================
  // Enable the given texture exclusively or use multitexture setting
  // ================================================================================
  bool multiTextureMode = ( texData->texture(_textureName).type == MULTITEXTURE );
  if ( !multiTextureMode ) {
    if ( ! texData->enableTexture( _textureName , true ) ) {
      emit log(LOGERR, "Failed to enabled Texture " + _textureName );
      return;
    }
  } else {
    // get the list of textures for this mode
    QStringList textureList = texData->texture(_textureName).multiTextureList;

    for ( uint i = 0 ; i < texData->textures().size() ; ++i ) {
889
890
      if ( textureList.contains( texData->textures()[i].name() ) )
        texData->enableTexture( texData->textures()[i].name() , false );
891
       else
892
        texData->disableTexture( texData->textures()[i].name() );
893
894
895
896
897
898

    }

    std::cerr << "Trying to enable multitexture" << std::endl;
  }

Dirk Wilden's avatar
Dirk Wilden committed
899
900
901
902
  // ================================================================================
  // If texture is flagged dirty, update it ( this jumps to texture updated
  // which will update the visualization )
  // ================================================================================
903

904
  if ( !multiTextureMode && texData->texture( _textureName).dirty ) {
905

Dirk Wilden's avatar
Dirk Wilden committed
906
    // TODO: maybe introduce lock to prevent extra redraws if updating all objects
907
    emit updateTexture( texData->texture( _textureName ).name() , obj->id() );
Dirk Wilden's avatar
Dirk Wilden committed
908
909
    return;
  }
910

Dirk Wilden's avatar
Dirk Wilden committed
911
912
913
914
  // ================================================================================
  // Update texture map from meshNode and activate it
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ){
915
916
    if (!multiTextureMode) {
      doUpdateTexture(texData->texture(_textureName), *PluginFunctions::triMeshObject(obj)->mesh());
917
      PluginFunctions::triMeshObject(obj)->textureNode()->activateTexture( texData->texture( _textureName ).glName() );
918
919
920
921
922
923
924
      PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( 0 );
      PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( 0 );
    } else {
      PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( texData->textureMap() );
      PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( 0 );
    }

Dirk Wilden's avatar
Dirk Wilden committed
925
  }
926

Dirk Wilden's avatar
Dirk Wilden committed
927
  if ( obj->dataType( DATA_POLY_MESH ) ){
928
929
    if (!multiTextureMode) {
      doUpdateTexture(texData->texture(_textureName), *PluginFunctions::polyMeshObject(obj)->mesh());
930
      PluginFunctions::polyMeshObject(obj)->textureNode()->activateTexture( texData->texture( _textureName ).glName() );
931
932
933
934
935
936
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( 0 );
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( 0 );
    } else {
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( texData->textureMap() );
      PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( 0 );
    }
Dirk Wilden's avatar
Dirk Wilden committed
937
938
939
940
941
  }

  // ================================================================================
  // Switch to a texture drawMode
  // ================================================================================
942
943
944
945
946
947
  switchDrawMode(multiTextureMode);

}

void TextureControlPlugin::switchDrawMode( bool _multiTexture ) {

Dirk Wilden's avatar
Dirk Wilden committed
948
949
  bool textureMode = false;
  for ( int j = 0 ; j < PluginFunctions::viewers() ; ++j ) {
950
951
952
953
954
955
956
      if ( _multiTexture ) {
        textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE );
        textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE_SHADED );
      } else {
        textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED );
        textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED );
      }
Jan Möbius's avatar
 
Jan Möbius committed
957
  }
958

959
960
961
962
963
964
  if ( !textureMode ) {
    if ( _multiTexture )
      PluginFunctions::setDrawMode( ACG::SceneGraph::DrawModes::SOLID_2DTEXTURED_FACE_SHADED );
    else
      PluginFunctions::setDrawMode( ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED );
  }
Dirk Wilden's avatar
Dirk Wilden committed
965
966

  emit updateView();
967
}
Dirk Wilden's avatar
Dirk Wilden committed
968

969
void TextureControlPlugin::slotSwitchTexture( QString _textureName , int _id ) {
Dirk Wilden's avatar
Dirk Wilden committed
970

971
  doSwitchTexture(_textureName, _id);
Dirk Wilden's avatar
Dirk Wilden committed
972
973
974
975
976
977
978
979
980
981
}

void TextureControlPlugin::slotSwitchTexture( QString _textureName ) {

  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ;
                                        o_it != PluginFunctions::objectsEnd();
                                        ++o_it)

    doSwitchTexture(_textureName, o_it->id() );

Jan Möbius's avatar
 
Jan Möbius committed
982
983
984
}


985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
void TextureControlPlugin::slotUpdateContextMenu( int _objectId ) {

  // ================================================================================
  // Get picking object object
  // ================================================================================
  if ( _objectId == -1 )
    return;

  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _objectId , obj ) ) {
    emit log(LOGERR,"slotUpdateContextMenu: Unable to get Object for id " + QString::number(_objectId) );
    return;
  }

  // ================================================================================
  // Get objects texture data and verify that texture exists
For faster browsing, not all history is shown. View entire blame