Interactive/ProMaterialConversionCustom.py

# (C) Copyright 2012 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.

# You will need Autodesk Showcase 2009 or later.
#
 
#
# You will get a number of menu items on the material that is currently selected.
# You can persistently choose what aspects of that material you want
# editable by choosing the "add generic parameters" menu item.

__all__ = ['MaterialTypeCustom', 'instantiate']

from awSupportApi              import ApplicationMode
from GenericPopupMenu          import GenericPopupMenuItem
from MessageInterpreter        import MessageInterpreter
from MaterialList              import MaterialListUiItem
from ParameterConstant         import ParameterConstant as PC
from ParameterGroupUtilities   import ModifyParameter
from RTFapi                    import Parameter, Node, \
                                      MaterialConverter
from UserCustomization         import UserCustomBase, CustomInfo

import MaterialIO, ModelIO

class MaterialType( UserCustomBase ):
    def __init__( self ):
        self.__myInterpreter = LocalInterpreter()
        self.__myMaterialOnNode = None
        self.__myMaterialMenuItem = {}

    def getInterpreter( self, isInteractive ):
        return (self.__myInterpreter if isInteractive else None)

    def appendMenuItems(self,id, menu):
        if "Appearance" == id:
            self.__myMaterialMenuItem[id] = menu.appendItem(_( 'Add generic parameters' ),
                                                            self.__onAddGeneric )
            pass

    def enableMenuStates(self,id,enableStates):
        if "Appearance" == id:
            if self.__myInterpreter:
                enabled = self.__myInterpreter.Enabled()
            else:
                enabled = False
            enableStates[self.__myMaterialMenuItem[id]] = enabled

    def appendMenuItemsNode(self,id,menu,nodeInfo):
        if "Smart" == id:
            (nodeId, nodeLabel, leaf, sel) = nodeInfo
            node = Node.getNodeById(nodeId)
            if node:
                app = node.getAppearance()
                if app:
                    mat = app.getMaterial()
                    self.__myMaterialOnNode = mat.getName()

                    menu.appendItem( _('Add generic parameters'),
                                     self.__onSaveMaterialOnNode )

    def appendPopupMenuItems( self, id, popupMenu, item ):
        if "MaterialSelector" == id:
            if isinstance( item, MaterialListUiItem ):
                menuItem = GenericPopupMenuItem(_( 'Add generic parameters'),
                                                self.__setGeneric,
                                                item )
                popupMenu.append( menuItem )

    def __onAddGeneric( self, event ):
        if self.__myInterpreter:
            self.__myInterpreter.changeActiveToGeneric()

    def __setGeneric( self, item ):
        if self.__myInterpreter is not None:
            self.__myInterpreter.changeToGeneric( item.name() )

    def __onSaveMaterialOnNode( self, event ):
        if self.__myInterpreter is not None:
            self.__myInterpreter.changeToGeneric( self.__myMaterialOnNode )


def instantiate():
    return MaterialType()


def PRO(v):
    return v

class LocalInterpreter( MessageInterpreter ):

    def __init__( self ):
        MessageInterpreter.__init__( self )
        self.__myMaterials = None
        self.__myModels = None


    def SET_DOCUMENT( self, message ):
        document, = message.data
        self.__myMaterials = document.get(MaterialIO.id)
        self.__myModels = document.get( ModelIO.id )


    def APPLICATION_CLOSE_SCENE( self, message ):
        self.__myMaterials = None
        self.__myModels = None


    def Enabled( self ):
        return ApplicationMode.instance().isAuthoringMode() \
           and self.__myModels is not None \
           and not self.__myModels.selected.empty()


    def changeActiveToGeneric( self ):
        for nodeId in self.__myModels.selected:
            node = Node.getNodeById(nodeId)
            if node:
                app = node.getAppearance()
                if app:
                    self.changeToGenericMat( app.getMaterial() )


    def changeToGeneric( self, name ):
        # If how is None, remove the parameter
        # otherwise set the value to it, assuming
        # that it's a string.

        # If reset is False, unless how is None, append
        # how to the current value, rather than replacing it

        # Send the SELECTION_CHANGED message to trick UI
        # into rebuilding
        if self.__myMaterials is not None and name in self.__myMaterials:
            self.changeToGenericMat(self.__myMaterials[name])


    def changeToGenericMat( self, material ):
        if material is None or material.get() is None:
            return False

        result = True
        matType = material.getType()

        if matType.startswith("ProMaterial::"):
            mc = MaterialConverter()
            result = mc.convert( material )
        else:
            print "Did not find the type %s" % (matType)
            result = False

        if result:
            ModifyParameter( 
                material, 
                PC.kParameterEditOverride,
                Parameter.kString,
                "diffuse specular specular2 transparency reflect bump",
                True 
                )
            material.setType( "A3S::" + material.getType() )
            self.sendMessage( "SELECTION_CHANGED", () )
        else:
            print "Failed to convert %s" % (matType)


def info():
    customInfo = CustomInfo()
    customInfo.vendor = 'Autodesk'
    customInfo.version = '3.0'
    customInfo.api = '2013'
    customInfo.shortInfo = "Convert material type to generic material."
    customInfo.longInfo = \
""""Add generic parameters" menu item is added under several corresponding menus for converting \
material type to generic material.
"""
    return customInfo