Commit 7ab5c068 authored by Johannes Lenzen's avatar Johannes Lenzen

keep tracking image usage for drawing(do not tracking usage

 beyond TextureControl) safe for change image in TextureSetting Share texture
 if open multiple images. Remove while removing object from sceneTree.

Patch by: Shaun Song <sxsong1207@qq.com>
parent c0787ef8
......@@ -102,10 +102,10 @@ QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
connect(zoomInButton, SIGNAL( clicked() ), this,SLOT( zoomIn() ) );
connect(zoomOutButton,SIGNAL( clicked() ), this,SLOT( zoomOut() ) );
connect(clampButton, SIGNAL( clicked() ), this,SLOT( clamp() ) );
QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
panner->setMouseButton( Qt::MidButton );
// delete widget on close
setAttribute(Qt::WA_DeleteOnClose, true);
......@@ -118,6 +118,10 @@ QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
image_ = 0;
}
QwtFunctionPlot::~QwtFunctionPlot()
{
delete histogram_;
}
//------------------------------------------------------------------------------
void QwtFunctionPlot::setFunction( std::vector<double>& _values)
......
......@@ -105,7 +105,7 @@ public:
explicit QwtFunctionPlot( QWidget* _parent = 0 );
/// Destructor
~QwtFunctionPlot() {}
~QwtFunctionPlot();
// set the function to plot
void setFunction( std::vector<double>& _values );
......@@ -131,7 +131,7 @@ public slots:
void zoomIn();
void zoomOut();
void clamp();
void replot();
private:
......
......@@ -426,8 +426,9 @@ void texturePropertiesWidget::slotButtonBoxClicked(QAbstractButton* _button){
texture.filename( currentImage_ );
// Add it to the imagestore and set the index in the texture description
texture.textureImageId( imageStore().addImageFile(currentImage_) );
int newImageId = imageStore().addImageFile(currentImage_);
texture.textureImageId( newImageId );
texData_->addManagedImageId( newImageId );
changed = true;
}
......
......@@ -66,6 +66,11 @@ class ImageStore {
void removeImage(int _id);
inline const QMap<int,QImage>& imageMap() const{return imageMap_;}
inline const QMap< QString,QPair<int,QDateTime> >& filenameMap() const {return filenameMap_;}
inline const QMap<int,QString>& reverseFilenameMap() const {return reverseFilenameMap_;}
inline const QMap<int,unsigned int>& refCount() const {return refCount_;}
private:
QMap<int,QImage> imageMap_;
QMap< QString,QPair<int,QDateTime> > filenameMap_;
......
......@@ -53,7 +53,7 @@
#endif
#define TEXTUREDATA "TextureData"
TextureControlPlugin::TextureControlPlugin() :
......@@ -96,6 +96,7 @@ void TextureControlPlugin::slotTextureAdded(QString _textureName , QString _file
newId = imageStore().addImage(_image);
else
newId = imageStore().addImageFile(_fileName);
texData->addManagedImageId(newId);
if ( newId == -1 ) {
emit log(LOGERR,imageStore().error());
......@@ -163,6 +164,7 @@ void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _fil
newImageId = imageStore().addImage(_image);
else
newImageId = imageStore().addImageFile(_filename);
globalTextures_.addManagedImageId(newImageId);
if ( newImageId == -1 ) {
emit log(LOGERR,imageStore().error());
......@@ -221,21 +223,21 @@ void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QStrin
//hide the texture (its accessible through the multiTexture)
texData->texture(_name).hidden( true );
// 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);
//
// // 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);
// Store the new texture in the list of this textureGroup
if ( _textureId != -1 ) {
......@@ -254,7 +256,7 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
// emit log(LOGERR,"addedEmptyObject: Unable to get Object for id " + QString::number(_id) );
return;
}
// Check if we support this kind of data
if ( !obj->dataType(DATA_TRIANGLE_MESH) && !obj->dataType(DATA_POLY_MESH)
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
......@@ -270,20 +272,20 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
{
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) {
// Add to image store
int newImageId = imageStore().addImageFile(globalTextures_.textures()[i].filename());
texData->addManagedImageId(newImageId);
if ( newImageId == -1 ) {
emit log(LOGERR,imageStore().error());
continue;
......@@ -293,7 +295,7 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
// 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(imageStore().getImage(newImageId,0));
......@@ -314,7 +316,7 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
if (obj->dataType(DATA_BSPLINE_SURFACE))
glName = PluginFunctions::bsplineSurfaceObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId, 0));
#endif
// ================================================================================
// Store texture information in objects metadata
// ================================================================================
......@@ -329,8 +331,8 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
continue;
}
// ================================================================================
// Update texture mapping in meshNode
// ================================================================================
......@@ -341,7 +343,7 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
if ( obj->dataType( DATA_POLY_MESH ) ){
PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( 0 );
}
}
}
......@@ -634,7 +636,7 @@ void TextureControlPlugin::slotTextureIndexPropertyName(int _id, QString& _prope
emit log(LOGERR,"slotTextureIndexPropertyName: Unable to get Object for id " + QString::number(_id) );
return;
}
// Get texture index property name
if( obj->dataType( DATA_TRIANGLE_MESH ) ) {
_propertyName = PluginFunctions::triMeshObject(obj)->meshNode()->indexPropertyName().c_str();
......@@ -704,20 +706,20 @@ void TextureControlPlugin::slotTextureFilename( int _id, QString _textureName, Q
}
}
}
_textureFilename = OpenFlipper::Options::textureDir().path() +
_textureFilename = OpenFlipper::Options::textureDir().path() +
QDir::separator().toLatin1() + (globalTextures_.texture(_textureName)).filename();
QFile f(_textureFilename);
if(!f.exists()) _textureFilename = "NOT_FOUND";
return;
}
void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName ){
_textureName = "NONE";
// Get the object
BaseObjectData* obj;
if (! PluginFunctions::getObject( _id , obj ) ) {
......@@ -730,23 +732,23 @@ void TextureControlPlugin::slotGetCurrentTexture( int _id, QString& _textureName
TextureData* texData = dynamic_cast< TextureData* > ( obj->objectData(TEXTUREDATA) );
if (texData == 0) {
#ifndef NDEBUG
// Iterate over all per Object datas and output them
QMap<QString, PerObjectData*>::const_iterator mapIter = obj->getPerObjectDataMap().begin();
QMap<QString, PerObjectData*>::const_iterator mapIter = obj->getPerObjectDataMap().begin();
while ( mapIter != obj->getPerObjectDataMap().end() ) {
++mapIter;
}
#endif
return;
}
// Iterate over all available textures
for ( uint i = 0 ; i < texData->textures().size() ; ++i) {
if ( (texData->textures()[i]).enabled() ){
_textureName = (texData->textures()[i]).name();
if ( (texData->textures()[i]).type() == MULTITEXTURE ) {
return;
}
......@@ -777,7 +779,7 @@ void TextureControlPlugin::slotGetSubTextures( int _id, QString _multiTextureNam
emit log(LOGERR, "slotGetSubTextures: Texture not available! " + _multiTextureName );
return;
}
if ( texData->texture(_multiTextureName).type() == MULTITEXTURE )
_subTextures = texData->texture(_multiTextureName).multiTextureList;
else
......@@ -1052,7 +1054,7 @@ void TextureControlPlugin::slotDrawModeChanged(int _viewerId ) {
}
emit updateView();
}
......@@ -1061,7 +1063,7 @@ void TextureControlPlugin::slotObjectUpdated(int _identifier, const UpdateType&
{
if( !_type.contains(UPDATE_ALL) && !_type.contains(UPDATE_GEOMETRY) && !_type.contains(UPDATE_TOPOLOGY) )
return;
// ================================================================================
// Get updated object
// ================================================================================
......@@ -1283,7 +1285,7 @@ void TextureControlPlugin::slotSetTextureMode(QString _textureName ,QString _mod
localTex.parameters.repeatMax = texture.parameters.repeatMax;
changed = true;
}
if ( _mode.contains("min_val") && (texture.parameters.repeatMin != localTex.parameters.repeatMin) ){
localTex.parameters.repeatMin = texture.parameters.repeatMin;
changed = true;
......@@ -1390,7 +1392,7 @@ void TextureControlPlugin::pluginsInitialized() {
// ================================================================================
// Create action group and menu for global textures
// ================================================================================
actionGroup_ = new QActionGroup( 0 );
actionGroup_ = new QActionGroup(this);
actionGroup_->setExclusive( true );
connect( actionGroup_, SIGNAL( triggered( QAction * ) ),
this, SLOT( slotTextureMenu( QAction * ) ) );
......@@ -1400,6 +1402,11 @@ void TextureControlPlugin::pluginsInitialized() {
connect(AC_Texture_Settings, SIGNAL(triggered()), this, SLOT(slotSetTextureProperties()));
textureMenu_->addAction(AC_Texture_Settings);
QAction *AC_Print_Pool_Info = new QAction(tr("&Print Image Pool Info"), this);
AC_Print_Pool_Info->setStatusTip(tr("Print stats info of image pool"));
connect(AC_Print_Pool_Info, SIGNAL(triggered()), this, SLOT(slotPrintImagePoolInfo()));
textureMenu_->addAction(AC_Print_Pool_Info);
textureMenu_->addSeparator();
textureMenu_->addActions(actionGroup_->actions());
......@@ -1431,7 +1438,32 @@ void TextureControlPlugin::slotSetTextureProperties() {
settingsDialog_->show( &globalTextures_, -1);
}
void TextureControlPlugin::applyDialogSettings(TextureData* _texData, QString _textureName, int _id) {
void TextureControlPlugin::slotPrintImagePoolInfo() {
size_t sumRefCount=0;
for(auto it=imageStore().refCount().begin(),end=imageStore().refCount().end();it!=end;++it)
{
sumRefCount+=it.value();
}
size_t sumBytes = 0;
for(auto it=imageStore().imageMap().begin(),end=imageStore().imageMap().end();it!=end;++it)
{
sumBytes+=it.value().byteCount();
}
QString poolInfo = tr("PoolInfo:[%1 images][%2 files][%3 refs][%4 KB]").arg(imageStore().imageMap().size())
.arg(imageStore().filenameMap().size()).arg(sumRefCount).arg(sumBytes/1024);
for(auto it=imageStore().refCount().begin(),end=imageStore().refCount().end();it!=end;++it)
{
emit log(LOGSTATUS,tr("%1 %2").arg(imageStore().reverseFilenameMap()[it.key()]).arg(it.value()));
}
emit log(LOGINFO, poolInfo);
}
void TextureControlPlugin::applyDialogSettings(TextureData *_texData, QString _textureName, int _id) {
if (_id != -1)
{
......@@ -1484,8 +1516,8 @@ void TextureControlPlugin::applyDialogSettings(TextureData* _texData, QString _t
emit updateView();
}
else
}
else
{
// global texture
......@@ -1575,7 +1607,7 @@ void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) {
if (! PluginFunctions::getObject( _id , obj ) ) {
emit log(LOGERR,"doSwitchTexture: Unable to get Object for id " + QString::number(_id) );
}
// Ignore light sources: ( TODO: Maybe use better detetion if textures are usefull )
if ( obj->dataType(typeId("Light")) )
return;
......@@ -1680,11 +1712,11 @@ void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) {
PluginFunctions::triMeshObject(obj)->textureNode()->activateTexture(0);
// Set the mapping between texture ids in the index property and their gl Names
PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( texData->textureMap() );
if (PluginFunctions::triMeshObject(obj)->mesh()->has_halfedge_texcoords2D())
PluginFunctions::triMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("h:texcoords2D");
} else if( obj->dataType( DATA_POLY_MESH ) ){
// Set the property map for mapping between faces and textures
PluginFunctions::polyMeshObject(obj)->meshNode()->setIndexPropertyName( texData->texture( _textureName).indexMappingProperty().toStdString() );
......@@ -1692,10 +1724,10 @@ void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) {
PluginFunctions::polyMeshObject(obj)->textureNode()->activateTexture(0);
// Set the mapping between texture ids in the index property and their gl Names
PluginFunctions::polyMeshObject(obj)->meshNode()->setTextureMap( texData->textureMap() );
if (PluginFunctions::polyMeshObject(obj)->mesh()->has_halfedge_texcoords2D())
PluginFunctions::polyMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("h:texcoords2D");
PluginFunctions::polyMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("h:texcoords2D");
} else {
emit log(LOGERR, "doSwitchTexture: MultiTexture Error: Only supported on Tri or Poly Mesh for Texture: " + _textureName );
}
......@@ -1706,14 +1738,14 @@ void TextureControlPlugin::doSwitchTexture( QString _textureName , int _id ) {
// Disable the mapping properties ( only for multi texture mode )
PluginFunctions::triMeshObject(obj)->meshNode()->setIndexPropertyName("No Texture Index");
PluginFunctions::triMeshObject(obj)->meshNode()->setTextureMap( 0 );
if ( texData->texture(_textureName).type() == HALFEDGEBASED ) {
// We set it to the standard name here, as we copy user texture coordinates to the global representation
PluginFunctions::triMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("h:texcoords2D");
PluginFunctions::triMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("h:texcoords2D");
} else {
PluginFunctions::triMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("No Texture");
PluginFunctions::triMeshObject(obj)->meshNode()->setHalfedgeTextcoordPropertyName("No Texture");
}
} else if ( obj->dataType( DATA_POLY_MESH ) ){
// Activate the requested texture in texture node
PluginFunctions::polyMeshObject(obj)->textureNode()->activateTexture( texData->texture( _textureName ).glName() );
......@@ -1843,7 +1875,7 @@ void TextureControlPlugin::slotUpdateContextMenu( int _objectId ) {
// Prepare Texture menu
// ================================================================================
contextMenu_->clear();
QActionGroup* actionGroup = new QActionGroup(0);
QActionGroup* actionGroup = new QActionGroup(this);
actionGroup->setExclusive( true );
connect( actionGroup, SIGNAL( triggered( QAction * ) ),
this, SLOT( slotTextureContextMenu( QAction * ) ) );
......@@ -1947,38 +1979,38 @@ void TextureControlPlugin::getCoordinates1D(QString _textureName, int _id, std::
// collect the 1d texture coords from vertex or halfedge porperty, depending on the texture type
_x.clear();
if( obj->dataType( DATA_TRIANGLE_MESH ) )
if( obj->dataType( DATA_TRIANGLE_MESH ) )
{
TriMesh* mesh = PluginFunctions::triMesh(obj);
if ( texData->texture(_textureName).type() == VERTEXBASED )
{
OpenMesh::VPropHandleT< double > coordProp;
if ( !mesh->get_property_handle(coordProp, _textureName.toStdString() ) )
{
emit log(LOGERR,tr("getCoordinates1D: Texture Property not found: Object %1 , TextureName %2").arg(_id).arg(_textureName) );
return;
}
for ( TriMesh::VertexIter v_it = mesh->vertices_begin() ; v_it != mesh->vertices_end(); ++v_it)
_x.push_back( mesh->property(coordProp,*v_it) );
} // end of if vertex based for tri meshes
else if ( texData->texture(_textureName).type() == HALFEDGEBASED )
else if ( texData->texture(_textureName).type() == HALFEDGEBASED )
{
OpenMesh::HPropHandleT< double > coordProp;
if ( !mesh->get_property_handle(coordProp, _textureName.toStdString() ) )
{
emit log(LOGERR,tr("getCoordinates1D: Texture Property not found: Object %1 , TextureName %2").arg(_id).arg(_textureName) );
return;
}
for ( TriMesh::HalfedgeIter h_it = mesh->halfedges_begin() ; h_it != mesh->halfedges_end(); ++h_it)
_x.push_back( mesh->property(coordProp,*h_it) );
} // end of if halfedge based for tri meshes
} // end of if tri mesh
else if ( obj->dataType( DATA_POLY_MESH ) )
{
......@@ -2060,7 +2092,7 @@ void TextureControlPlugin::getCoordinates1D(QString _textureName, int _id, std::
}
}// end of if polyhedral mesh
#endif
}
void TextureControlPlugin::slotAboutToRestore( int _objectid ) {
......@@ -2100,7 +2132,7 @@ void TextureControlPlugin::slotRestored( int _objectid ) {
// ================================================================================
QString currentTexture;
slotGetCurrentTexture(_objectid,currentTexture);
// ================================================================================
// Enable the last active texture
// ================================================================================
......
......@@ -163,6 +163,9 @@ class TextureControlPlugin : public QObject, BaseInterface, BackupInterface, Tex
/// Slot for showing the TextureProperties Dialog
void slotSetTextureProperties();
/// Print Pool Info
void slotPrintImagePoolInfo();
public :
/// Constructor
TextureControlPlugin();
......
......@@ -42,6 +42,7 @@
#include "TextureData.hh"
#include "ImageStorage.hh"
#include <iostream>
//-----------------------------------------------------------------------------------
......@@ -74,7 +75,10 @@ TextureData::TextureData() :
//-----------------------------------------------------------------------------------
TextureData::~TextureData() {
for(const int& id:managedImageId_)
{
imageStore().removeImage(id);
}
}
//-----------------------------------------------------------------------------------
......@@ -331,3 +335,6 @@ std::map< int, std::string>* TextureData::propertyMap(){
return &propertyMap_;
}
void TextureData::addManagedImageId(int _imageId){
managedImageId_.push_back(_imageId);
}
\ No newline at end of file
......@@ -52,9 +52,9 @@
#include <ACG/GL/gl.hh>
#include <vector>
#include <map>
#include <set>
#include <cfloat>
enum TextureType { UNSET = 1 << 0,
/// Texture Coordinates are stored on a per Vertex basis
VERTEXBASED = 1 << 1,
......@@ -68,7 +68,7 @@ enum TextureType { UNSET = 1 << 0,
class Texture {
public :
Texture();
// copy constructor
Texture( const Texture& _tex)
: parameters(_tex.parameters),
......@@ -195,13 +195,13 @@ class TextureData : public PerObjectData
TextureData();
/// Destructor
~TextureData();
// copy Operator returning an exact copy of this Object
virtual PerObjectData* copyPerObjectData( ) {
// Create an object copy (This will call all copy constructors of the included data objects! )
TextureData* copy = new TextureData(*this);
return copy;
}
......@@ -222,7 +222,7 @@ class TextureData : public PerObjectData
/// Add a Texture without file backing
int addTexture ( QString _textureName , uint _dimension, GLuint _glName ){return addTexture ( _textureName , QString("Invalid") , _dimension, _glName );}
/// Add a Texture
int addTexture ( QString _textureName , QString _filename , uint _dimension, GLuint _glName );
......@@ -265,8 +265,9 @@ class TextureData : public PerObjectData
*/
std::map< int, std::string >* propertyMap();
void addManagedImageId(int _imageId);
private :
std::vector<int> managedImageId_;
std::map< int, GLuint> textureMap_;
std::map< int, std::string> propertyMap_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment