TextureControl.cc 84.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);
99
  texData->addManagedImageId(newId);
Dirk Wilden's avatar
 
Dirk Wilden committed
100

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

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

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

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

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

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

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

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

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

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

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

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

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

174
    globalTextures_.texture(_textureName).textureImageId(newImageId);
175

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

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

190
}
191

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

  // Check if we support this kind of data
  if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) {
201
      emit log(LOGERR,"slotMultiTextureAdded: Trying to add textures to object failed because of unsupported object type");
202
203
204
205
206
207
208
209
210
211
212
213
214
215
      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
216
217
218
219
  if(_filename.isEmpty())
    slotTextureAdded( _name , _image , 2 , _id);
  else
    slotTextureAdded( _name , _filename , 2 , _id);
220
221

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

224
225
  //hide the texture (its accessible through the multiTexture)
  texData->texture(_name).hidden( true );
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//
//  // Add to image store
//  int newImageId;
//  if(_filename.isEmpty())
//    newImageId = imageStore().addImage(_image);
//  else
//    newImageId = imageStore().addImageFile(_filename);
//
//  if ( newImageId == -1 ) {
//    emit log(LOGERR,imageStore().error());
//    return;
//  }
//
//  // Add to texture description
//  texData->texture(_name).textureImageId(newImageId);
241
242
243
244
245

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

}

void TextureControlPlugin::addedEmptyObject( int _id ) {
252

253
254
255
  // Get the new object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
256
//     emit log(LOGERR,"addedEmptyObject: Unable to get Object for id " + QString::number(_id) );
257
258
    return;
  }
259

260
  // Check if we support this kind of data
261
  if ( !obj->dataType(DATA_TRIANGLE_MESH)   && !obj->dataType(DATA_POLY_MESH)
262
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
263
264
       && !obj->dataType(DATA_HEXAHEDRAL_MESH)
#endif
265
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
266
       && !obj->dataType(DATA_POLYHEDRAL_MESH)
267
268
269
#endif
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
       && !obj->dataType(DATA_BSPLINE_SURFACE)
270
271
272
#endif
     )
  {
273
274
    return;
  }
275

276
277
278
279
280
281
  // 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);
  }
282

283
284
  // Iterate over all available global textures and add them to the object
  for ( uint i = 0 ; i < globalTextures_.textures().size() ; ++i) {
285
286
287

    // Add to image store
    int newImageId = imageStore().addImageFile(globalTextures_.textures()[i].filename());
288
    texData->addManagedImageId(newImageId);
289
290
291
292
293
    if ( newImageId == -1 ) {
      emit log(LOGERR,imageStore().error());
      continue;
    }

294
295
296
297
    // ================================================================================
    // Add the texture to the texture node and get the corresponding id
    // ================================================================================
    GLuint glName = 0;
298

299
300
    //inform textureNode about the new texture
    if( obj->dataType( DATA_TRIANGLE_MESH ) )
301
      glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
302

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

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

#ifdef ENABLE_BSPLINESURFACE_SUPPORT
    if (obj->dataType(DATA_BSPLINE_SURFACE))
      glName = PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId, 0));
#endif
319

320
321
322
323
324
    // ================================================================================
    // Store texture information in objects metadata
    // ================================================================================
    if (glName != 0) {
      texData->addTexture(globalTextures_.textures()[i], glName);
325
326
327

      // Add to texture description
      texData->setImage(globalTextures_.textures()[i].name(),newImageId);
328
329
    }
    else {
330
      imageStore().removeImage(newImageId);
331
      emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
332
333
      continue;
    }
334
335


336
337
338
339
340
341
    // ================================================================================
    // Update texture mapping in meshNode
    // ================================================================================
    if( obj->dataType( DATA_TRIANGLE_MESH ) ){
      PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
342

343
344
345
    if ( obj->dataType( DATA_POLY_MESH ) ){
      PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( 0 );
    }
346

347
  }
Jan Möbius's avatar
 
Jan Möbius committed
348
349
}

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

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

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

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

369
370
}

371
#if defined(ENABLE_HEXAHEDRALMESH_SUPPORT) || defined(ENABLE_POLYHEDRALMESH_SUPPORT) || defined(ENABLE_TETRAHEDRALMESH_SUPPORT)
372
373
374
375
376
377
378
379
380
381
382
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

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

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

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

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

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

436
437
}

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

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

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

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

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

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

  // Add to texture description
  texture.textureImageId(newImageId);
468
469
470
471
472

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

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

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

495
  emit updateView();
496
497
498
499
500
501
502
503
504

}

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

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

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

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

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

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

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

554
555
  emit updateView();

556
557
}

558
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image, int _id ){
559

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

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

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

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

589

590
void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _image ){
591

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

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

603
void TextureControlPlugin::slotTextureIndex( QString _textureName, int _id, int& _index){
604

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

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

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

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

631
void TextureControlPlugin::slotTextureIndexPropertyName(int _id, QString& _propertyName) {
632

633
634
635
    // Get the object
    BaseObjectData* obj;
    if (! PluginFunctions::getObject(  _id , obj ) ) {
636
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to get Object for id " + QString::number(_id) );
637
638
        return;
    }
639

640
641
642
    // Get texture index property name
    if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
        _propertyName = PluginFunctions::triMeshObject(obj)->meshNode()->indexPropertyName().c_str();
643
    } else if( obj->dataType( DATA_POLY_MESH ) ) {
644
645
        _propertyName = PluginFunctions::polyMeshObject(obj)->meshNode()->indexPropertyName().c_str();
    } else {
646
        emit log(LOGERR,"slotTextureIndexPropertyName: Unable to access mesh for object with id " + QString::number(_id) );
647
648
649
    }
}

650
void TextureControlPlugin::slotTextureName( int _id, int _textureIndex, QString& _textureName){
651

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

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

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

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

678
void TextureControlPlugin::slotTextureFilename( int _id, QString _textureName, QString& _textureFilename){
679

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

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
  if (texData == 0) {
691
    emit log(LOGERR, tr("slotTextureFilename: Object has no texture data! Object: %1").arg(_id) );
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;
          }
      }
  }
709
710

  _textureFilename = OpenFlipper::Options::textureDir().path() +
711
      QDir::separator().toLatin1() + (globalTextures_.texture(_textureName)).filename();
712

713
714
  QFile f(_textureFilename);
  if(!f.exists()) _textureFilename = "NOT_FOUND";
715

716
717
718
  return;
}

719
void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName ){
720

Dirk Wilden's avatar
Dirk Wilden committed
721
  _textureName = "NONE";
722

723
724
725
  // Get the object
  BaseObjectData* obj;
  if (! PluginFunctions::getObject(  _id , obj ) ) {
726
    emit log(LOGERR,"slotGetCurrentTexture: Unable to get Object for id " + QString::number(_id) );
727
728
729
730
731
732
  }

  // ================================================================================
  // Get Texture data for current object
  // ================================================================================
  TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
733
734
  if (texData == 0) {
    #ifndef NDEBUG
735

736
      // Iterate over all per Object datas and output them
737
      QMap<QString, PerObjectData*>::const_iterator mapIter = obj->getPerObjectDataMap().begin();
738
      while ( mapIter != obj->getPerObjectDataMap().end() ) {
739
        ++mapIter;
740
741
      }
    #endif
742

743
    return;
744
  }
745

746
  // Iterate over all available textures
747
  for ( uint i = 0 ; i < texData->textures().size() ; ++i) {
748

749
750
    if ( (texData->textures()[i]).enabled() ){
      _textureName = (texData->textures()[i]).name();
751

752
      if ( (texData->textures()[i]).type() == MULTITEXTURE ) {
753
        return;
754
      }
755
    }
756
  }
757
758
759
760
761
762
}

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

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

  // ================================================================================
  // Check for requested Texture
  // ================================================================================
  if ( !texData->textureExists(_multiTextureName) ) {
779
    emit log(LOGERR, "slotGetSubTextures: Texture not available! " + _multiTextureName );
780
781
    return;
  }
782

783
784
785
786
787
788
789
  if ( texData->texture(_multiTextureName).type() == MULTITEXTURE )
    _subTextures = texData->texture(_multiTextureName).multiTextureList;
  else
    _subTextures = QStringList();
}

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

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

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

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

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

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

839
  // ================================================================================
840
  // Enable the texture in texture node
841
842
843
844
  // ================================================================================
  if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
    TriMesh* mesh = PluginFunctions::triMesh(obj);
    doUpdateTexture(texData->texture(_textureName), *mesh);
845
846
847
    // 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() );
848
849
850
851
    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);
852
853
854
    // 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() );
855
    PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat);
856
  }
857
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
858
859
860
861
862
863
864
865
866
867
  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
868
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
869
870
871
872
873
874
875
876
877
878
  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
879
880
881
882
883
884
885
886
887
#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
888

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

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

Jan Möbius's avatar
 
Jan Möbius committed
899
900
}

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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