TextureConveyor/TextureConveyor.cpp

//**************************************************************************/
// Copyright (c) 2010 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION: Texture Conveyor
// CREATED: April 2010
//**************************************************************************/

#pragma warning( disable : 4311 4312 )

#include "TextureConveyor.h"
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtCore/QDir>

// Register this plugin, use the TextureConveyor::Initializer function as the initialized, this will be called when the plugin got loaded.
MB_PLUGIN( "TextureConveyor", "Exports Texture Layers", "Autodesk", "http://www.mudbox3d.com", TextureConveyor::Initializer );

TextureConveyor::TextureConveyor( void )
{
}

void TextureConveyor::ExportTextureChannels( void )
{
    // Create the Qt dialog for selection directories.
    // Set file mode to Directory & only show directories.
    QFileDialog dialog(Kernel()->MainWindow(), "Texture Export...");
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setOption(QFileDialog::ShowDirsOnly, true);
    dialog.exec();

    // Verify directory
    QDir directory = dialog.directory();
    if (!directory.exists())
    {
        if (QMessageBox::question(Kernel()->MainWindow(), tr("Question..."), tr("Directory does not exist.  Do you want to create it?")) == QMessageBox::Yes)
        {
            if (!directory.mkpath(directory.absolutePath()))
            {
                QMessageBox::information(Kernel()->MainWindow(), tr("Information..."), tr("Failed to create directory %1.").arg(directory.absolutePath()));
                return;
            }
        }
        else
        {
            QMessageBox::information(Kernel()->MainWindow(), tr("Information..."), tr("No files have been written."));
            return;
        }
    }

    // Enable wait cursor
    Kernel()->WaitCursorStart();

    // Iterate through all the materials in the scene
    for(Node *pNode = Node::First(); pNode; pNode = pNode->Next())
    {
        // Check if this node is a material
        if(pNode->IsKindOf( Material::StaticClass()))
        {
            Material *pMaterial = dynamic_cast<Material *>(pNode);

            if (!pMaterial)
                continue;

            // Iterate through the textures used by this Material.  Textures
            // are stored as "channels", i.e. Diffuse, Specular, Bump, etc...
            // 
            for( int jj = 0; jj < pMaterial->TextureCount(); jj++ )
            {
                // Get the texture 'pool' which contains all the textures
                // for this channel
                TexturePool *pTexturePool = pMaterial->Texture(jj);

                if (pTexturePool)
                {
                    // Each texture pool can have a certain number of tiles - based on the geometry's UVs
                    int iNumTiles = pTexturePool->TileCount();

                    for (int ii = 0; ii < iNumTiles; ii++)
                    {
                        // Create filename
                        QString filename = QString("%1/%2.%3.tile%4.png").arg(directory.absolutePath()).arg(pMaterial->Name()).arg(pTexturePool->Name()).arg(ii+1);

                        Texture *pTexture = pTexturePool->Tile(ii);

                        if (pTexture && pTexture->Width() && pTexture->Height())
                        {
                            Image *pImage = CreateInstance<Image>();
                            pTexture->CopyTo(pImage);
                        
                            pImage->Save(filename);

                            delete pImage;
                        }
                    }
                }
            }       
        }
    }

    // End wait cursor
    Kernel()->WaitCursorEnd();
}

// This function will be called then the plugin is loaded.
void TextureConveyor::Initializer( void )
{
    // Add a menu entry for the TextureConveyor class/
    Kernel()->AddCallbackMenuItem( Kernel::menuFile, QString::null, tr("Export Textures..."), ExportTextureChannels);
}