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

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

Jan Möbius's avatar
 
Jan Möbius committed
43
44
45
46


#include "TextureControl.hh"

47
#include "ImageStorage.hh"
Jan Möbius's avatar
 
Jan Möbius committed
48

Jan Möbius's avatar
Jan Möbius committed
49
50
#include <QMessageBox>

51

52
#if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
53
54
#endif

55
#define TEXTUREDATA "TextureData"
56
 
57

Jan Möbius's avatar
Jan Möbius committed
58
59
60
61
62
63
64
65
66
67

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

}

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

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

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

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

93
  // Add Image to the image store and set the index in the texture description
94
95
96
97
98
  int newId;
  if(_fileName.isEmpty())
    newId = imageStore().addImage(_image);
  else
    newId = imageStore().addImageFile(_fileName);
Dirk Wilden's avatar
 
Dirk Wilden committed
99

100
101
102
103
  if ( newId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
104
105
106
107
108
109
110
111

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

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

117
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
118
119
120
  if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) )
    glName = PluginFunctions::hexahedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
#endif
121
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
122
123
124
125
  if ( obj->dataType( DATA_POLYHEDRAL_MESH ) )
    glName = PluginFunctions::polyhedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
#endif

126
127
128
129
130
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
  if (obj->dataType(DATA_BSPLINE_SURFACE))
    glName = PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->add_texture(imageStore().getImage(newId, 0));
#endif

131
132
133
134
135
  // ================================================================================
  // Store texture information in objects metadata
  // ================================================================================

  if (glName == 0) {
136
    emit log(LOGERR,"slotTextureAdded: Unable to bind texture!");
137
138
139
    return;
  }

140
141
142
143
  if(_fileName.isEmpty())
    texData->addTexture(_textureName,_dimension,glName);
  else
    texData->addTexture(_textureName,_fileName,_dimension,glName);
144
145
146
147

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

148
  texData->texture(_textureName).disable();
Dirk Wilden's avatar
Dirk Wilden committed
149
150
}

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

161
162
163
164
165
    int newImageId;
    if(_filename.isEmpty())
      newImageId = imageStore().addImage(_image);
    else
      newImageId = imageStore().addImageFile(_filename);
Dirk Wilden's avatar
 
Dirk Wilden committed
166

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

172
    globalTextures_.texture(_textureName).textureImageId(newImageId);
173

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

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

188
}
189

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

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

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

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

  // Add the texture
214
215
216
217
  if(_filename.isEmpty())
    slotTextureAdded( _name , _image , 2 , _id);
  else
    slotTextureAdded( _name , _filename , 2 , _id);
218
219

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

222
223
224
  //hide the texture (its accessible through the multiTexture)
  texData->texture(_name).hidden( true );

225
  // Add to image store
226
227
228
229
230
  int newImageId;
  if(_filename.isEmpty())
    newImageId = imageStore().addImage(_image);
  else
    newImageId = imageStore().addImageFile(_filename);
Dirk Wilden's avatar
 
Dirk Wilden committed
231

232
233
234
235
  if ( newImageId == -1 ) {
    emit log(LOGERR,imageStore().error());
    return;
  }
Dirk Wilden's avatar
 
Dirk Wilden committed
236

237
238
  // Add to texture description
  texData->texture(_name).textureImageId(newImageId);
239
240
241
242
243

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

}

void TextureControlPlugin::addedEmptyObject( int _id ) {
250

251
252
253
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
254
//     emit log(LOGERR,"addedEmptyObject: Unable to get Object for id " + QString::number(_id) );
255
256
257
258
    return;
  }
  
  // Check if we support this kind of data
259
  if ( !obj->dataType(DATA_TRIANGLE_MESH)   && !obj->dataType(DATA_POLY_MESH)
260
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
261
262
       && !obj->dataType(DATA_HEXAHEDRAL_MESH)
#endif
263
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
264
       && !obj->dataType(DATA_POLYHEDRAL_MESH)
265
266
267
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
       && !obj->dataType(DATA_BSPLINE_SURFACE)
268
269
270
#endif
     )
  {
271
272
273
274
275
276
277
278
279
280
281
282
    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) {
283
284
285
286
287
288
289
290
291

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

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

292
293
294
295
296
297
298
    // ================================================================================
    // 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 ) )
299
      glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
300

301
    if ( obj->dataType( DATA_POLY_MESH ) )
302
      glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
303

304
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
305
306
307
    if( obj->dataType( DATA_HEXAHEDRAL_MESH ) )
      glName = PluginFunctions::hexahedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
#endif
308
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
309
310
311
    if ( obj->dataType( DATA_POLYHEDRAL_MESH ) )
      glName = PluginFunctions::polyhedralMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
#endif
312
313
314
315
316

#ifdef ENABLE_BSPLINESURFACE_SUPPORT
    if (obj->dataType(DATA_BSPLINE_SURFACE))
      glName = PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId, 0));
#endif
317
318
319
320
321
322
    
    // ================================================================================
    // Store texture information in objects metadata
    // ================================================================================
    if (glName != 0) {
      texData->addTexture(globalTextures_.textures()[i], glName);
323
324
325

      // Add to texture description
      texData->setImage(globalTextures_.textures()[i].name(),newImageId);
326
327
    }
    else {
328
      imageStore().removeImage(newImageId);
329
      emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
330
331
332
333
334
335
336
337
338
339
      continue;
    }
    
    
    // ================================================================================
    // Update texture mapping in meshNode
    // ================================================================================
    if( obj->dataType( DATA_TRIANGLE_MESH ) ){
      PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
340

341
342
343
344
345
    if ( obj->dataType( DATA_POLY_MESH ) ){
      PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
    
  }
Jan Möbius's avatar
 
Jan Möbius committed
346
347
}

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

351
352
353
354
355
356
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _objectId , obj ) ) {
    return;
  }

357
358
359
360
361
  if ( _mesh->has_vertex_texcoords2D() ){
    slotTextureAdded("Original Per Vertex Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Vertex Texture Coords","type=vertexbased",_objectId);
  }

362
  if ( _mesh->has_halfedge_texcoords2D() ){
363
364
365
    slotTextureAdded("Original Per Face Texture Coords","unknown.png",2,_objectId);
    slotSetTextureMode("Original Per Face Texture Coords","type=halfedgebased",_objectId);
  }
366

367
368
}

369
#if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
370
371
372
373
374
375
376
377
378
379
380
template< typename VolumeMeshObjectT >
void TextureControlPlugin::handleFileOpenTexturesOVM( VolumeMeshObjectT* _obj, int _objectId ) {

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

}
#endif

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

384
385
386
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
387
    emit log(LOGERR,"fileOpened: Unable to get Object for id " + QString::number(_id) );
388
    return;
389
390
391
  }

  // Check if we support this kind of data
392
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH)
393
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
394
395
       && !obj->dataType(DATA_HEXAHEDRAL_MESH)
#endif
396
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
397
398
399
400
       && !obj->dataType(DATA_POLYHEDRAL_MESH)
#endif
     )
  {
401
      return;
402
403
  }

404
405
406
  // 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){
407
408
    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
409
  }
410
411
412
413
414

  // 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
415
      handleFileOpenTextures(mesh,_id);
416
417
418
  } else if ( obj->dataType( DATA_POLY_MESH ) ) {
    PolyMesh* mesh = PluginFunctions::polyMesh(obj);
    if ( mesh )
Jan Möbius's avatar
Jan Möbius committed
419
      handleFileOpenTextures(mesh,_id);
420
  }
421
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
422
423
424
425
426
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    HexahedralMeshObject* ovm_obj = PluginFunctions::hexahedralMeshObject(_id);
    handleFileOpenTexturesOVM(ovm_obj, _id);
  }
#endif
427
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
428
429
430
431
432
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PolyhedralMeshObject* ovm_obj = PluginFunctions::polyhedralMeshObject(_id);
    handleFileOpenTexturesOVM(ovm_obj, _id);
  }
#endif
433

434
435
}

436
437
438
439
440
441
442
void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage& _image , int _id ) {

  // ================================================================================
  // Get the new object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
443
    emit log(LOGERR,"slotTextureChangeImage: Unable to get Object for id " + QString::number(_id) );
444
445
446
447
448
449
450
451
  }

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

  if ( texData == 0 || ( !texData->textureExists(_textureName))  ) {
452
    emit log(LOGERR,"slotTextureChangeImage: Texture does not exist: " + _textureName + " (objectid=" + QString::number(_id) + ")");
453
454
455
456
457
458
459
    return;
  }

  // ================================================================================
  // Update the image
  // ================================================================================
  Texture& texture = texData->texture(_textureName);
460
461
462
463
464
465

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

  // Add to texture description
  texture.textureImageId(newImageId);
466
467
468
469
470

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

471
472
473
474
475
  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());
  }
476
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
477
478
479
480
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  }
#endif
481
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
482
483
484
485
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
  }
#endif
486

487
488
489
490
491
492
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
  else if (obj->dataType(DATA_BSPLINE_SURFACE)) {
    PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->set_texture(_image, texData->texture(_textureName).glName());
  }
#endif

493
  emit updateView();
494
495
496
497
498
499
500
501
502

}

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

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

  // ================================================================================
  // Update the image in the global texture
  // ================================================================================
  Texture& texture = globalTextures_.texture(_textureName);
511
512
513
514
515
516

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

  // Add to texture description
  texture.textureImageId(newImageId);
517
518
519
520
521
522
523
524
525
526

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

529
530
531
532
533
          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());
          }
534
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
535
536
537
538
          else if ( o_it->dataType( DATA_HEXAHEDRAL_MESH ) ) {
            PluginFunctions::hexahedralMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          }
#endif
539
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
540
541
542
          else if ( o_it->dataType( DATA_POLYHEDRAL_MESH ) ) {
            PluginFunctions::polyhedralMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
          }
543
544
545
546
547
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
          else if (o_it->dataType(DATA_BSPLINE_SURFACE)) {
            PluginFunctions::bsplineSurfaceObject(o_it)->textureNode()->set_texture(_image, texData->texture(_textureName).glName());
          }
548
#endif
549
550
551
      }
  }

552
553
  emit updateView();

554
555
}

556
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image, int _id ){
557

558
559
560
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
561
    emit log(LOGERR,"slotTextureGetImage: Unable to get Object for id " + QString::number(_id) );
562
563
564
565
566
567
568
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
569
    emit log(LOGERR, tr("slotTextureGetImage: Object has no texture data! Object: %1").arg(_id) );
570
571
572
573
574
575
576
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
577
    emit log(LOGERR, "slotTextureGetImage: Texture not available! " + _textureName );
578
579
580
581
582
583
    return;
  }

  if ( texData->texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
584
    _image = imageStore().getImage(texData->texture(_textureName).textureImageId(),0 );
585
586
}

587

588
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image ){
589

590
  if ( ! globalTextures_.textureExists(_textureName) ) {
591
    emit log(LOGERR,"slotTextureGetImage: Global texture does not exist: " + _textureName);
592
593
594
595
596
597
    return;
  }

  if ( globalTextures_.texture(_textureName).type() == MULTITEXTURE )
    _image = QImage();
  else
598
    _image = imageStore().getImage(globalTextures_.texture(_textureName).textureImageId(),0);
599
600
}

601
void TextureControlPlugin::slotTextureIndex( QString _textureName, int _id, int& _index){
602

603
604
605
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
606
    emit log(LOGERR,"slotTextureIndex: Unable to get Object for id " + QString::number(_id) );
607
608
609
610
611
612
613
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
614
    emit log(LOGERR, tr("slotTextureIndex: Object has no texture data! Object: %1").arg(_id) );
615
616
617
618
619
620
621
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_textureName) ) {
622
    emit log(LOGERR, "slotTextureIndex: Texture not available! " + _textureName );
623
624
625
626
627
628
    return;
  }

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

629
void TextureControlPlugin::slotTextureIndexPropertyName(int _id, QString& _propertyName) {
630

631
632
633
    // Get the object
    BaseObjectData* obj;
    if (! PluginFunctions::getObject(  _id , obj ) ) {
634
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to get Object for id " + QString::number(_id) );
635
636
637
638
639
640
        return;
    }
    
    // Get texture index property name
    if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
        _propertyName = PluginFunctions::triMeshObject(obj)->meshNode()->indexPropertyName().c_str();
641
    } else if( obj->dataType( DATA_POLY_MESH ) ) {
642
643
        _propertyName = PluginFunctions::polyMeshObject(obj)->meshNode()->indexPropertyName().c_str();
    } else {
644
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to access mesh for object with id " + QString::number(_id) );
645
646
647
    }
}

648
void TextureControlPlugin::slotTextureName( int _id, int _textureIndex, QString& _textureName){
649

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

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

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

671
  emit log(LOGERR, "slotTextureName: TextureIndex not available! (" + QString::number(_textureIndex) + ")" );
672
673
674
675
  _textureName = "NOT_FOUND";
  return;
}

676
void TextureControlPlugin::slotTextureFilename( int _id, QString _textureName, QString& _textureFilename){
677

678
679
680
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
681
    emit log(LOGERR,"slotTextureFilename: Unable to get Object for id " + QString::number(_id) );
682
683
684
685
686
687
688
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
689
    emit log(LOGERR, tr("slotTextureFilename: Object has no texture data! Object: %1").arg(_id) );
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
    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() + 
709
      QDir::separator().toLatin1() + (globalTextures_.texture(_textureName)).filename();
710
711
712
713
714
715
716
  
  QFile f(_textureFilename);
  if(!f.exists()) _textureFilename = "NOT_FOUND";
  
  return;
}

717
void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName ){
718

Dirk Wilden's avatar
Dirk Wilden committed
719
720
  _textureName = "NONE";
  
721
722
723
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
724
    emit log(LOGERR,"slotGetCurrentTexture: Unable to get Object for id " + QString::number(_id) );
725
726
727
728
729
730
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
731
732
733
734
735
736
  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() ) {
737
        ++mapIter;
738
739
740
      }
    #endif
    
741
    return;
742
  }
743
744
  
  // Iterate over all available textures
745
746
  for ( uint i = 0 ; i < texData->textures().size() ; ++i) {
  
747
748
749
    if ( (texData->textures()[i]).enabled() ){
      _textureName = (texData->textures()[i]).name();
      
750
      if ( (texData->textures()[i]).type() == MULTITEXTURE ) {
751
        return;
752
      }
753
    }
754
  }
755
756
757
758
759
760
}

void TextureControlPlugin::slotGetSubTextures( int _id, QString _multiTextureName, QStringList& _subTextures ){
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
761
    emit log(LOGERR,"slotGetSubTextures: Unable to get Object for id " + QString::number(_id) );
762
763
764
765
766
767
768
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
769
    emit log(LOGERR, tr("slotGetSubTextures: Object has no texture data! Object: %1").arg(_id) );
770
771
772
773
774
775
776
    return;
  }

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_multiTextureName) ) {
777
    emit log(LOGERR, "slotGetSubTextures: Texture not available! " + _multiTextureName );
778
779
780
781
782
783
784
785
786
787
    return;
  }
  
  if ( texData->texture(_multiTextureName).type() == MULTITEXTURE )
    _subTextures = texData->texture(_multiTextureName).multiTextureList;
  else
    _subTextures = QStringList();
}

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

789
790
791
792
793
  // ================================================================================
  // Get updated object
  // ================================================================================
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _identifier , obj ) ) {
794
    emit log(LOGERR,"slotTextureUpdated: Unable to get Object for id " + QString::number(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
795
796
    return;
  }
797

798
  //skip object if its not a mesh
799
  if(   !obj->dataType( DATA_TRIANGLE_MESH )   && !obj->dataType( DATA_POLY_MESH )
800
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
801
802
     && !obj->dataType( DATA_HEXAHEDRAL_MESH )
#endif
803
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
804
     && !obj->dataType( DATA_POLYHEDRAL_MESH )
805
806
807
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
     && !obj->dataType(DATA_BSPLINE_SURFACE)
808
809
#endif
    )
810
811
    return;

812
813
814
815
816
  // ================================================================================
  // Get objects texture data and verify that texture exists
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0){
817
    emit log(LOGERR,tr("slotTextureUpdated: Texture data not found: Object %1" ).arg(_identifier) );
Jan Möbius's avatar
 
Jan Möbius committed
818
    return;
819
  }
Jan Möbius's avatar
 
Jan Möbius committed
820

821
822
823
  // ================================================================================
  // Check if texture exists
  // ================================================================================
824
  if ( ! texData->textureExists(_textureName) ) {
825
    emit log(LOGERR,"slotTextureUpdated: Texture " + _textureName + " not found on object " + QString::number(_identifier) );
826
    return;
827
  }
Jan Möbius's avatar
 
Jan Möbius committed
828

829
830
831
  // ================================================================================
  // If texture is not enabled, mark it as dirty and defer update to visualization update
  // ================================================================================
832
  if ( ! texData->texture(_textureName).enabled() ) {
833
    texData->texture(_textureName).setDirty();
834
835
    return;
  }
Jan Möbius's avatar
 
Jan Möbius committed
836

837
  // ================================================================================
838
  // Enable the texture in texture node
839
840
841
842
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
843
844
845
    // 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() );
846
847
848
849
    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);
850
851
852
    // 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() );
853
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
854
  }
855
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
856
857
858
859
860
861
862
863
864
865
  else if ( obj->dataType( DATA_HEXAHEDRAL_MESH ) ) {
    HexahedralMesh* mesh = PluginFunctions::hexahedralMesh(obj);
    HexahedralMeshObject* meshObj = PluginFunctions::hexahedralMeshObject(obj);
    doUpdateTextureOVM(texData->texture(_textureName), *mesh, *meshObj);
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
    PluginFunctions::hexahedralMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  }
#endif
866
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
867
868
869
870
871
872
873
874
875
876
  else if ( obj->dataType( DATA_POLYHEDRAL_MESH ) ) {
    PolyhedralMesh* mesh = PluginFunctions::polyhedralMesh(obj);
    PolyhedralMeshObject* meshObj = PluginFunctions::polyhedralMeshObject(obj);
    doUpdateTextureOVM(texData->texture(_textureName), *mesh, *meshObj);
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName() );
    PluginFunctions::polyhedralMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  }
#endif
877
878
879
880
881
882
883
884
885
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
  else if (obj->dataType(DATA_BSPLINE_SURFACE)) {
    // texcoords are parametric so nothing to update in the bspline surface mesh
    // Texture has been bound to that object by slotAddTexture.. directly or by fileOpened from global texture
    // Just activate it
    PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->activateTexture(texData->texture(_textureName).glName());
    PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
  }
#endif
Jan Möbius's avatar
 
Jan Möbius committed
886

887
888
889
  // ================================================================================
  // Mark texture as not dirty
  // ================================================================================
890
  texData->texture(_textureName).clean();
Jan Möbius's avatar
 
Jan Möbius committed
891

892
893
894
895
896
  // ================================================================================
  // Tell plugins to update texture
  // ================================================================================
  emit updatedObject(obj->id(),UPDATE_TEXTURE);

Jan Möbius's avatar
 
Jan Möbius committed
897
898
}

899
900
901
902
903
904
void TextureControlPlugin::slotUpdateTexture( QString _textureName , int _identifier) {
  if ( _textureName == "Reflection Lines" )
    slotTextureUpdated( _textureName , _identifier );

}

Jan Möbius's avatar
 
Jan Möbius committed
905
template< typename MeshT >
906
void TextureControlPlugin::doUpdateTexture ( Texture& _texture, MeshT& _mesh )
Jan Möbius's avatar
 
Jan Möbius committed
907
{
908

909
  if ( _texture.type() == HALFEDGEBASED ) {
910
    if (_texture.dimension() == 1) {
Jan Möbius's avatar
 
Jan Möbius committed
911
912

      OpenMesh::HPropHandleT< double > texture;
913
      if ( ! _mesh.get_property_handle(texture, _texture.name().toStdString() ) ) {
914
        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
915
916
917
        return;
      }

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

920
    } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
921
922

      OpenMesh::HPropHandleT< OpenMesh::Vec2d > texture2D;
923
      if ( ! _mesh.get_property_handle( texture2D, _texture.name().toStdString() ) ) {
924
        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
925
926
927
        return;
      }

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

930
    } else
931
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );
932
  } else if ( _texture.type() == VERTEXBASED ) {
933
    if ( _texture.dimension() == 1 ) {
Jan Möbius's avatar
 
Jan Möbius committed
934
935

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

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

943
      } else if ( _texture.dimension() == 2 ) {
Jan Möbius's avatar
 
Jan Möbius committed
944
945

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

951
        copyTexture( _texture, _mesh, texture2D);
Jan Möbius's avatar
 
Jan Möbius committed
952
953

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

Jan Möbius's avatar
 
Jan Möbius committed
955
        OpenMesh::VPropHandleT< OpenMesh::Vec3d >  scalarField3D;
956
957
        if ( ! _mesh.get_property_handle(scalarField3D,_texture.name) ) {
          emit log(LOGERR,"Unable to get property " + _texture.name );
958
          return;
Jan Möbius's avatar
 
Jan Möbius committed
959
        }
960

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

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

Jan Möbius's avatar
 
Jan Möbius committed
966
    } else
967
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture type");
968

Jan Möbius's avatar
 
Jan Möbius committed
969
970
}

971

972
#if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
973
974
975
976
977
978
979
980
981
982
983
984
985
986
template< typename VolumeMeshT, typename VolumeMeshObjectT >
void TextureControlPlugin::doUpdateTextureOVM ( Texture& _texture, VolumeMeshT& _mesh, VolumeMeshObjectT& _obj )
{
  if ( _texture.type() == VERTEXBASED ) {
    if ( _texture.dimension() == 1 ) {

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

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

987
988
      VolumeMeshDrawModesContainer drawModesVolumeMesh;
      _obj.setObjectDrawMode(drawModesVolumeMesh.facesTextured);
989
990
991
992
993
994
995
996
997
998
999
1000

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

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

1001
1002
        VolumeMeshDrawModesContainer drawModesVolumeMesh;
        _obj.setObjectDrawMode(drawModesVolumeMesh.facesTextured);
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013

    }
    else
      emit log(LOGERR, "doUpdateTexture: Unsupported Texture Dimension " + QString::number(_texture.dimension() ) );

  } else
    emit log(LOGERR, "doUpdateTexture: Unsupported Texture type");