//============================================================================= // // OpenFlipper // Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen // www.openflipper.org // //----------------------------------------------------------------------------- // // License // // OpenFlipper is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // //----------------------------------------------------------------------------- // // $Revision$ // $Author$ // $Date$ // //============================================================================= #include #include "TextureControl.hh" #include #include #include "OpenFlipper/BasePlugin/PluginFunctions.hh" #include "OpenFlipper/common/GlobalOptions.hh" #define TEXTUREDATA "TextureData" void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension , int _id) { std::cerr << "slotLocalTextureAdded " << _textureName.toStdString() << std::endl; // TODO: Load texture?! ... // Get the new object BaseObjectData* obj; if (! PluginFunctions::getObject( _id , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) ); } // Get Texture data for this object 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); } // Add this texture to the list of global textures if ( ! texData->textureExists(_textureName) ) { texData->addTexture(_textureName,_filename,_dimension,0); texData->texture(_textureName).enabled = false; } else { emit log(LOGERR,"Trying to add already existing texture " + _textureName + " for object " + QString::number(_id) ); return; } } void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _filename , uint _dimension) { // Add this texture to the list of global textures if ( ! globalTextures_.textureExists(_textureName) ) { globalTextures_.addTexture(_textureName,_filename,_dimension,0); globalTextures_.texture(_textureName).enabled = false; QString loadFilename; if ( _filename.startsWith("/") ) loadFilename = _filename; else loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + _filename; QImage textureImage; if ( !textureImage.load( loadFilename ) ){ emit log(LOGERR, "Cannot load texture " + _filename ); textureImage.load(OpenFlipper::Options::textureDirStr() + QDir::separator() + "unknown.png"); } globalTextures_.texture(_textureName).textureImage = textureImage; } else { emit log(LOGERR,"Trying to add already existing global texture " + _textureName ); return; } // Add a new entry to the global Texture menu QAction* new_texture = new QAction(_textureName, this); new_texture->setStatusTip(tr("Switch all objects to this Texture ( if available )")); new_texture->setCheckable(true); actionGroup_->addAction(new_texture); textureMenu_->addAction(new_texture); new_texture->setChecked(true); textureActions_.push_back(new_texture); } void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QString _name , QString _filename , int _id , int& _textureId ) { std::cerr << "slotMultiTextureAdded" << std::endl; } void TextureControlPlugin::fileOpened( int _id ) { // TODO:: Store original texture coords in a new property! // Get the new object BaseObjectData* obj; if (! PluginFunctions::getObject( _id , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) ); } // Check if we support this kind of data if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH) ) { emit log(LOGERR,"Trying to add textures to object failed because of unsupported object type"); return; } // Get Texture data for this object or create one if it does not exist TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0){ texData = new TextureData(); obj->setObjectData(TEXTUREDATA, texData); } // Iterate over all available global textures and add them to the object for ( uint i = 0 ; i < globalTextures_.textures().size() ; ++i) { // ================================================================================ // Get the image file // ================================================================================ // TODO: support arbitrary paths! QString loadFilename; if ( globalTextures_.textures()[i].filename.startsWith("/") ) loadFilename = globalTextures_.textures()[i].filename; else loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + globalTextures_.textures()[i].filename; QImage textureImage; if ( !textureImage.load( loadFilename ) ){ emit log(LOGERR, "Cannot load texture " + globalTextures_.textures()[i].filename ); textureImage.load(OpenFlipper::Options::textureDirStr() + QDir::separator() + "unknown.png"); } // ================================================================================ // Add the texture to the texture node and get the corresponding id // ================================================================================ GLuint glName = 0; //inform textureNode about the new texture if( obj->dataType( DATA_TRIANGLE_MESH ) ) glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(textureImage); if ( obj->dataType( DATA_POLY_MESH ) ) glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(textureImage); // ================================================================================ // Store texture information in objects metadata // ================================================================================ if (glName != 0) { texData->addTexture(globalTextures_.textures()[i], glName); texData->setImage(globalTextures_.textures()[i].name,textureImage); } else { emit log(LOGERR,"Unable to bind Texture"); continue; } // ================================================================================ // Update texture mapping in meshNode // ================================================================================ if( obj->dataType( DATA_TRIANGLE_MESH ) ){ // PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( texData->textureMap() ); // PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( texData->propertyMap() ); PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( 0 ); PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( 0 ); // TODO: Multitexturing has to set the right map here! } if ( obj->dataType( DATA_POLY_MESH ) ){ PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( 0 ); PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( 0 ); // TODO: Multitexturing has to set the right map here! } } } void TextureControlPlugin::slotTextureUpdated( QString _textureName , int _identifier ) { // ================================================================================ // Get updated object // ================================================================================ BaseObjectData* obj; if (! PluginFunctions::getObject( _identifier , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(_identifier) ); return; } // ================================================================================ // Get objects texture data and verify that texture exists // ================================================================================ TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0){ std::cerr << "Texture data not found!" << std::endl; return; } if ( ! texData->textureExists(_textureName) ) { std::cerr << "Texture not found on object" << std::endl; return; } if ( ! texData->texture(_textureName).enabled ) { texData->texture(_textureName).dirty = true; std::cerr << "Texture is not active on object" << std::endl; return; } // ================================================================================ // As the current texture is active, update it // ================================================================================ if( obj->dataType( DATA_TRIANGLE_MESH ) ) { TriMesh* mesh = PluginFunctions::triMesh(obj); doUpdateTexture(texData->texture(_textureName), *mesh); PluginFunctions::triMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat); } else if ( obj->dataType( DATA_POLY_MESH ) ) { PolyMesh* mesh = PluginFunctions::polyMesh(obj); doUpdateTexture(texData->texture(_textureName), *mesh); PluginFunctions::polyMeshObject(obj)->textureNode()->set_repeat(texData->texture(_textureName).parameters.repeat); } // Mark the texture as not dirty texData->texture(_textureName).dirty = false; emit updateView(); } template< typename MeshT > void TextureControlPlugin::doUpdateTexture ( Texture& _texture, MeshT& _mesh ) { if ( _texture.type == HALFEDGEBASED ) { if (_texture.dimension == 1) { OpenMesh::HPropHandleT< double > texture; if ( ! _mesh.get_property_handle(texture, _texture.name.toStdString() ) ) { emit log(LOGERR,"Unable to get property " + _texture.name ); return; } copyTexture(_texture, _mesh, texture); } else if ( _texture.dimension == 2 ) { OpenMesh::HPropHandleT< OpenMesh::Vec2d > texture2D; if ( ! _mesh.get_property_handle( texture2D, _texture.name.toStdString() ) ) { emit log(LOGERR,"Unable to get property " + _texture.name); return; } copyTexture( _texture, _mesh, texture2D); } else emit log(LOGERR, "Unsupported Texture Dimension " + QString::number(_texture.dimension) ); } else if ( _texture.type == VERTEXBASED ) { if ( _texture.dimension == 1 ) { OpenMesh::VPropHandleT< double > texture; if ( ! _mesh.get_property_handle(texture,_texture.name.toStdString() ) ) { emit log(LOGERR,"Unable to get property " + _texture.name ); return; } copyTexture(_texture, _mesh, texture); } else if ( _texture.dimension == 2 ) { OpenMesh::VPropHandleT< OpenMesh::Vec2d > texture2D; if ( ! _mesh.get_property_handle(texture2D,_texture.name.toStdString() ) ) { emit log(LOGERR,"Unable to get property " + _texture.name ); return; } copyTexture( _texture, _mesh, texture2D); } /*else if ( textures_[_textureid].dimension == 3 ) { OpenMesh::VPropHandleT< OpenMesh::Vec3d > scalarField3D; if ( ! _mesh.get_property_handle(scalarField3D,_texture.name) ) { emit log(LOGERR,"Unable to get property " + _texture.name ); return; } copyTexture(_textureid, _mesh, scalarField3D); }*/ else emit log(LOGERR, "Unsupported Texture Dimension " + QString::number(_texture.dimension) ); } else emit log(LOGERR, "Unsupported Texture type"); } void TextureControlPlugin::computeValue(Texture& _texture, double _min, double _max, double& _value) { const bool clamp = _texture.parameters.clamp ; const bool center = _texture.parameters.center; const double max_val = _texture.parameters.max_val; const bool abs = _texture.parameters.abs; const double clamp_max = _texture.parameters.clamp_max; const double clamp_min = _texture.parameters.clamp_min; const bool scale = _texture.parameters.scale; const double scaleFactor = fabs(_max) + fabs(_min); const bool repeat = _texture.parameters.repeat; // Use absolute value as requested by plugin if ( abs ) _value = fabs(_value); // Clamp if requested if ( clamp ) { if ( _value > clamp_max ) _value = clamp_max; if (_value < clamp_min) _value = clamp_min; } // if the texture should not be repeated, scale to 0..1 if ( ! repeat ) { if (! center ) { if ( scale) { _value /= scaleFactor; _value -= _min/scaleFactor; } } else { // the values above zero are mapped to 0.5..1 the negative ones to 0.5..0 if (_value > 0.0) { _value /= ( _max * 2.0); _value += 0.5; } else { _value /= ( _min * 2.0); _value = 0.5 - _value; } } } else { _value -= _min; _value *= max_val / (_max - _min); } } void TextureControlPlugin::slotObjectUpdated(int _identifier) { // ================================================================================ // Get updated object // ================================================================================ if ( _identifier == -1 ) return; BaseObjectData* obj; if (! PluginFunctions::getObject( _identifier , obj ) ) { emit log(LOGERR,"slotObjectUpdated: Unable to get Object for id " + QString::number(_identifier) ); return; } // ================================================================================ // Get objects texture data and verify that texture exists // ================================================================================ TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0){ std::cerr << "slotObjectUpdated: Texture data not found!" << std::endl; return; } // ================================================================================ // Set all textures to dirty // ================================================================================ // TODO : if not in the texture rendering mode, do not emit update // Involves adding a interface part to react on draw mode changes // basic check implemented for ( uint i = 0; i < texData->textures().size(); ++i ) { texData->textures()[i].dirty = true; bool update = false; for ( int j = 0 ; j < PluginFunctions::viewers() ; ++j ) { update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED ); update |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED ); } if ( update && texData->textures()[i].enabled ) emit updateTexture( texData->textures()[i].name , _identifier ); } } void TextureControlPlugin::slotUpdateAllTextures( ) { std::cerr << "slotUpdateAllTextures: not implemented yet ... might be removed" << std::endl; // TODO : Check // // Force an update of all textures which are available for the updated object // for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) // for ( uint i = 0 ; i < textures_.size() ; ++i ) // emit updateTexture( textures_[i].name , o_it->id() ); } void TextureControlPlugin::slotSetTextureMode(QString _textureName ,QString _mode) { // ================================================================================ // Update texture settings for global textures // ================================================================================ if ( ! globalTextures_.textureExists(_textureName) ) { emit log(LOGERR,"Global texture does not exist: " + _textureName); return; } // ================================================================================ // Parse parameters and update them in the texture data // ================================================================================ Texture& texture = globalTextures_.texture(_textureName); int i = 0; QString nextString = _mode.section(',',i,i); while ( nextString != "" ) { QString sectionName = nextString.section('=',0,0); QString value = nextString.section('=',1,1); if ( sectionName == "clamp" ) { texture.parameters.clamp = StringToBool(value); } else if ( sectionName == "clamp_max" ) { texture.parameters.clamp_max = value.toDouble(); } else if ( sectionName == "clamp_min" ) { texture.parameters.clamp_min = value.toDouble(); } else if ( sectionName == "max_val" ) { texture.parameters.max_val = value.toDouble(); } else if ( sectionName == "repeat" ) { texture.parameters.repeat = StringToBool(value); } else if ( sectionName == "center" ) { texture.parameters.center = StringToBool(value); } else if ( sectionName == "scale" ) { texture.parameters.scale = StringToBool(value); } else if ( sectionName == "type" ) { if (value == "halfedgebased") { texture.type = HALFEDGEBASED; } else { texture.type = VERTEXBASED; } } else emit log(LOGERR,"Unknown texture mode : " + sectionName); ++i; nextString = _mode.section(',',i,i); } // ================================================================================ // Mark updated texture as dirty // ================================================================================ texture.dirty = true; // 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); //check if something changed bool changed = false; if ( _mode.contains("clamp") && (texture.parameters.clamp != localTex.parameters.clamp) ){ localTex.parameters.clamp = texture.parameters.clamp; changed = true; } if ( _mode.contains("clamp_max") && (texture.parameters.clamp_max != localTex.parameters.clamp_max) ){ localTex.parameters.clamp_max = texture.parameters.clamp_max; changed = true; } if ( _mode.contains("clamp_min") && (texture.parameters.clamp_min != localTex.parameters.clamp_min) ){ localTex.parameters.clamp_min = texture.parameters.clamp_min; changed = true; } if ( _mode.contains("max_val") && (texture.parameters.max_val != localTex.parameters.max_val) ){ localTex.parameters.max_val = texture.parameters.max_val; changed = true; } if ( _mode.contains("repeat") && (texture.parameters.repeat != localTex.parameters.repeat) ){ localTex.parameters.repeat = texture.parameters.repeat; changed = true; } if ( _mode.contains("center") && (texture.parameters.center != localTex.parameters.center) ){ localTex.parameters.center = texture.parameters.center; changed = true; } if ( _mode.contains("scale") && (texture.parameters.scale != localTex.parameters.scale) ){ localTex.parameters.scale = texture.parameters.scale; changed = true; } if ( _mode.contains("type") && (texture.type != localTex.type) ){ localTex.type = texture.type; changed = true; } //only update if the texture is enabled if (changed){ if ( texData->isEnabled(_textureName) ) emit updateTexture( _textureName, o_it->id() ); else localTex.dirty = true; } } } } } bool TextureControlPlugin::StringToBool(QString _value){ if (_value == "false") return false; else return true; } void TextureControlPlugin::slotSetTextureMode(QString _textureName, QString _mode, int _id) { // Get the new object BaseObjectData* obj; if (! PluginFunctions::getObject( _id , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) ); } // Get Texture data for this object TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if ( texData == 0 || ( !texData->textureExists(_textureName)) ) { emit log(LOGERR,"Texture does not exist: " + _textureName + " (object=" + QString::number(_id) + ")"); return; } // ================================================================================ // Parse parameters and update them in the texture data // ================================================================================ Texture& texture = texData->texture(_textureName); bool changed = false; int i = 0; QString nextString = _mode.section(',',i,i); while ( nextString != "" ) { QString sectionName = nextString.section('=',0,0); QString value = nextString.section('=',1,1); if ( sectionName == "clamp" ) { if ( StringToBool(value) != texture.parameters.clamp ) { texture.parameters.clamp = StringToBool(value); changed = true; } } else if ( sectionName == "clamp_max" ) { if (value.toDouble() != texture.parameters.clamp_max){ texture.parameters.clamp_max = value.toDouble(); changed = true; } } else if ( sectionName == "clamp_min" ) { if (value.toDouble() != texture.parameters.clamp_min){ texture.parameters.clamp_min = value.toDouble(); changed = true; } } else if ( sectionName == "max_val" ) { if (value.toDouble() != texture.parameters.max_val){ texture.parameters.max_val = value.toDouble(); changed = true; } } else if ( sectionName == "repeat" ) { if ( StringToBool(value) != texture.parameters.repeat ) { texture.parameters.repeat = StringToBool(value); changed = true; } } else if ( sectionName == "center" ) { if ( StringToBool(value) != texture.parameters.center ) { texture.parameters.center = StringToBool(value); changed = true; } } else if ( sectionName == "scale" ) { if ( StringToBool(value) != texture.parameters.scale ) { texture.parameters.scale = StringToBool(value); changed = true; } } else if ( sectionName == "type" ) { if (value == "halfedgebased") { texture.type = HALFEDGEBASED; changed = true; } else { texture.type = VERTEXBASED; changed = true; } } else emit log(LOGERR,"Unknown texture mode : " + sectionName); ++i; nextString = _mode.section(',',i,i); } //only update if the texture is enabled if (changed){ if ( texData->isEnabled(_textureName) ) emit updateTexture( _textureName, _id ); else texture.dirty = true; } } void TextureControlPlugin::pluginsInitialized() { // ================================================================================ // Create global texture menu // ================================================================================ textureMenu_ = new QMenu(tr("&Texture Control")); textureMenu_->setTearOffEnabled(true); emit addMenubarAction(textureMenu_->menuAction(), VIEWMENU ); // ================================================================================ // Create Settings dialog // ================================================================================ // TODO : Settings dialog updates required to change global/local textures,... settingsDialog_ = new texturePropertiesWidget(0); connect( settingsDialog_, SIGNAL( applyProperties(TextureData*,QString,int) ), this, SLOT( applyDialogSettings(TextureData*,QString,int) )); // ================================================================================ // Create action group and menu for global textures // ================================================================================ actionGroup_ = new QActionGroup( 0 ); actionGroup_->setExclusive( true ); connect( actionGroup_, SIGNAL( triggered( QAction * ) ), this, SLOT( slotTextureMenu( QAction * ) ) ); QAction* AC_Texture_Settings = new QAction(tr("&Texture Settings"), this); AC_Texture_Settings->setStatusTip(tr("Set the texture visualization properties")); connect(AC_Texture_Settings, SIGNAL(triggered()), this, SLOT(slotSetTextureProperties())); textureMenu_->addAction(AC_Texture_Settings); textureMenu_->addSeparator(); textureMenu_->addActions(actionGroup_->actions()); // ================================================================================ // Create basic per object context menu // ================================================================================ contextMenu_ = new QMenu(0); contextMenu_->setTitle("Textures"); emit addContextMenuItem(contextMenu_->menuAction() ,DATA_TRIANGLE_MESH , CONTEXTOBJECTMENU ); emit addContextMenuItem(contextMenu_->menuAction() ,DATA_POLY_MESH , CONTEXTOBJECTMENU ); } void TextureControlPlugin::slotSetTextureProperties() { settingsDialog_->show( &globalTextures_, -1); } void TextureControlPlugin::applyDialogSettings(TextureData* _texData, QString _textureName, int _id) { if (_id != -1){ //local texture if ( _texData->isEnabled(_textureName) ){ slotTextureUpdated( _textureName , _id ); emit updateView(); }else _texData->texture( _textureName ).dirty = true; } else { // global texture _texData->texture( _textureName ).dirty = true; Texture& globalTexture = _texData->texture(_textureName); // check if the local textures need to be updated for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it){ TextureData* texData = dynamic_cast< TextureData* > ( o_it->objectData(TEXTUREDATA) ); if ( texData != 0 && texData->textureExists(_textureName) ){ //overwrite local parameters Texture& localTexture = texData->texture(_textureName); bool changed = false; if (localTexture.parameters.clamp != globalTexture.parameters.clamp){ localTexture.parameters.clamp = globalTexture.parameters.clamp; changed = true; } if (localTexture.parameters.clamp_max != globalTexture.parameters.clamp_max){ localTexture.parameters.clamp_max = globalTexture.parameters.clamp_max; changed = true; } if (localTexture.parameters.clamp_min != globalTexture.parameters.clamp_min){ localTexture.parameters.clamp_min = globalTexture.parameters.clamp_min; changed = true; } if (localTexture.parameters.max_val != globalTexture.parameters.max_val){ localTexture.parameters.max_val = globalTexture.parameters.max_val; changed = true; } if (localTexture.parameters.repeat != globalTexture.parameters.repeat){ localTexture.parameters.repeat = globalTexture.parameters.repeat; changed = true; } if (localTexture.parameters.center != globalTexture.parameters.center){ localTexture.parameters.center = globalTexture.parameters.center; changed = true; } if (localTexture.parameters.scale != globalTexture.parameters.scale){ localTexture.parameters.scale = globalTexture.parameters.scale; changed = true; } // update if something has changed if ( changed ){ if ( texData->isEnabled(_textureName) ) slotTextureUpdated( _textureName , o_it->id() ); else texData->texture( _textureName ).dirty = true; } } } } } void TextureControlPlugin::slotTextureMenu(QAction* _action) { // call existing function to switch the texture slotSwitchTexture( _action->text() ); } void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) { std::cerr << "TextureControlPlugin::doSwitchTexture : " << _textureName.toStdString(); std::cerr << " object=" << _id << std::endl; // Get the new object BaseObjectData* obj; if (! PluginFunctions::getObject( _id , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(_id) ); } // ================================================================================ // Get Texture data for current object // ================================================================================ TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0) { std::cerr << "Object has no texture data" << std::endl; return; } // ================================================================================ // Enable the given texture exclusively // ================================================================================ if ( texData->enableTexture( _textureName , true ) ) { std::cerr << "Enabled Texture " << _textureName.toStdString() << std::endl; } else { std::cerr << "Failed to enabled Texture" << std::endl; return; } // ================================================================================ // If texture is flagged dirty, update it ( this jumps to texture updated // which will update the visualization ) // ================================================================================ if ( texData->texture( _textureName).dirty ) { // TODO: maybe introduce lock to prevent extra redraws if updating all objects emit updateTexture( texData->texture( _textureName ).name , obj->id() ); return; } // ================================================================================ // Update texture map from meshNode and activate it // ================================================================================ if( obj->dataType( DATA_TRIANGLE_MESH ) ){ doUpdateTexture(texData->texture(_textureName), *PluginFunctions::triMeshObject(obj)->mesh()); PluginFunctions::triMeshObject(obj)->textureNode()->activateTexture( texData->texture( _textureName ).glName ); // PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( texData->textureMap() ); // PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( texData->propertyMap() ); PluginFunctions::triMeshObject(obj)->meshNode()->set_texture_map( 0 ); PluginFunctions::triMeshObject(obj)->meshNode()->set_property_map( 0 ); // TODO: Multitexturing has to set the right map here! } if ( obj->dataType( DATA_POLY_MESH ) ){ doUpdateTexture(texData->texture(_textureName), *PluginFunctions::polyMeshObject(obj)->mesh()); PluginFunctions::polyMeshObject(obj)->textureNode()->activateTexture( texData->texture( _textureName ).glName ); // PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( texData->textureMap() ); // PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( texData->propertyMap() ); PluginFunctions::polyMeshObject(obj)->meshNode()->set_texture_map( 0 ); PluginFunctions::polyMeshObject(obj)->meshNode()->set_property_map( 0 ); // TODO: Multitexturing has to set the right map here! } } void TextureControlPlugin::slotSwitchTexture( QString _textureName , int _id ) { std::cerr << "TextureControlPlugin::slotSwitchTexture : " << _textureName.toStdString(); std::cerr << "object=" << _id << std::endl; doSwitchTexture(_textureName, _id); // ================================================================================ // Switch to a texture drawMode // ================================================================================ bool textureMode = false; for ( int j = 0 ; j < PluginFunctions::viewers() ; ++j ) { textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED ); textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED ); } if ( !textureMode ) PluginFunctions::setDrawMode( ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED ); emit updateView(); // TODO: Update menu // QList menuEntries = actionGroup_->actions(); // // for ( int i = 0 ; i < menuEntries.size(); ++i ) { // if ( menuEntries[i]->text() == _textureName ) // menuEntries[i]->setChecked(true); // } // updateDialog(); } void TextureControlPlugin::slotSwitchTexture( QString _textureName ) { std::cerr << "TextureControlPlugin::slotSwitchTexture : " << _textureName.toStdString() << std::endl; for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ; o_it != PluginFunctions::objectsEnd(); ++o_it) doSwitchTexture(_textureName, o_it->id() ); // ================================================================================ // Switch to a texture drawMode // ================================================================================ bool textureMode = false; for ( int j = 0 ; j < PluginFunctions::viewers() ; ++j ) { textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED ); textureMode |= ( PluginFunctions::drawMode(j) == ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED ); } if ( !textureMode ) PluginFunctions::setDrawMode( ACG::SceneGraph::DrawModes::SOLID_TEXTURED_SHADED ); emit updateView(); // TODO: Update menu // QList menuEntries = actionGroup_->actions(); // // for ( int i = 0 ; i < menuEntries.size(); ++i ) { // if ( menuEntries[i]->text() == _textureName ) // menuEntries[i]->setChecked(true); // } // updateDialog(); } void TextureControlPlugin::slotUpdateContextMenu( int _objectId ) { std::cerr << "TextureControlPlugin::slotUpdateContextMenu " << _objectId << std::endl; // ================================================================================ // Get picking object object // ================================================================================ if ( _objectId == -1 ) return; BaseObjectData* obj; if (! PluginFunctions::getObject( _objectId , obj ) ) { emit log(LOGERR,"slotUpdateContextMenu: Unable to get Object for id " + QString::number(_objectId) ); return; } // ================================================================================ // Get objects texture data and verify that texture exists // ================================================================================ TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0){ std::cerr << "TextureControlPlugin::slotUpdateContextMenu: Texture data not found!" << std::endl; return; } // ================================================================================ // Prepare Texture menu // ================================================================================ contextMenu_->clear(); QActionGroup* actionGroup = new QActionGroup(0); actionGroup->setExclusive( true ); connect( actionGroup, SIGNAL( triggered( QAction * ) ), this, SLOT( slotTextureContextMenu( QAction * ) ) ); QAction* action = actionGroup->addAction( "Texture Settings" ); contextMenu_->addAction( action ); contextMenu_->addSeparator(); for ( uint i = 0 ; i < texData->textures().size() ; ++i ) { action = actionGroup->addAction( texData->textures()[i].name ); action->setCheckable(true); if ( texData->textures()[i].enabled ) action->setChecked(true); contextMenu_->addAction( action ); } } void TextureControlPlugin::slotTextureContextMenu( QAction * _action ) { // id of object for which the context menu is created, is stored in the action QVariant idVariant = _action->data( ); int id = idVariant.toInt(); std::cerr << "TextureControlPlugin::slotTextureContextMenu : " << id << std::endl; if (_action->text() == "Texture Settings"){ BaseObjectData* obj; if (! PluginFunctions::getObject( id , obj ) ) { emit log(LOGERR,"Unable to get Object for id " + QString::number(id) ); return; } TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) ); if (texData == 0){ QMessageBox msgBox; msgBox.setText("Cannot show Properties. No Textures available!"); msgBox.exec(); return; } else { settingsDialog_->show( texData, id, obj->name() ); } } else { slotSwitchTexture( _action->text() , id ); } } Q_EXPORT_PLUGIN2( texturecontrolplugin , TextureControlPlugin );