Advertisement
ylSiew

3ds max sample UI python methods

Jan 27th, 2015
385
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.73 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from collections import namedtuple
  4. from functools import partial
  5.  
  6. import logging
  7.  
  8. import MaxPlus
  9.  
  10. class MaxUi(object):
  11.     """
  12.    This class is for the generic UI class
  13.    """
  14.  
  15.     def __init__(self):
  16.         """
  17.        Constructor for the Ui class
  18.        :return:
  19.        """
  20.  
  21.         # init logger
  22.         logger = logging.getLogger(__name__)
  23.  
  24.         # define keywords used for core 3ds max main menu items
  25.         self.keywords = ['Edit', 'Tools', 'Group', 'Views', 'Create', 'Modifiers', 'Animation',
  26.                     'Graph Editors', 'Rendering', 'Customize', 'MAXScript', 'Help']
  27.  
  28.         # add identifier char
  29.         self.keywords = ['&'+word for word in self.keywords]
  30.  
  31.         # set up menu hooks in 3ds max
  32.         self.menuSetup()
  33.         logger.info('3ds max UI hook setup successfully!')
  34.  
  35.  
  36.  
  37.     def createMenu(self, menuItemName, parentMenu=MaxPlus.MenuManager.GetMainMenu(),
  38.                    delayCreate=True, position=-1):
  39.         """
  40.        This method creates a new 3ds max Menu item. The parent Menu is the top-level menu by default.
  41.  
  42.        :rtype : Menu/NoneType, MenuBuilder
  43.        :param menuItemName: string for menu menuItemName
  44.        :param parentMenu: Menu that this new menu will be parented to.
  45.        :param delayCreate: boolean determining if the MenuBuilder Create() method is called.
  46.        :param position: int determining the position of the new Menu.
  47.  
  48.        The creation of the Menu can be delayed if this Menu is to have items added to it.
  49.        """
  50.  
  51.         logger = logging.getLogger(__name__)
  52.  
  53.         Menus = namedtuple('Menus', 'menu mb')
  54.  
  55.         # check that menu item does not already exist
  56.         if MaxPlus.MenuManager.MenuExists(menuItemName):
  57.  
  58.             # remove menu
  59.             logger.debug('The menu: {0} already exists...'.format(menuItemName))
  60.  
  61.             self.deleteMenu(menuItemName)
  62.  
  63.         # create new instance of MenuBuilder
  64.         mb = MaxPlus.MenuBuilder(menuItemName)
  65.         logger.debug('MenuBuilder instance of: {0} has been created!'.format(menuItemName))
  66.  
  67.         menu = MaxPlus.MenuManager.FindMenu(menuItemName)
  68.  
  69.         # check if MenuBuilder creation is to be delayed for adding items
  70.         if not delayCreate:
  71.  
  72.             # create the menu and add it to the 3ds max main menu bar
  73.             # this returns the Menu created
  74.             try:
  75.                 menu = mb.Create(parentMenu, position)
  76.  
  77.             except RuntimeError, e:
  78.                 logger.error('\n ### Could not run createMenu for Menu: '
  79.                              '{0}! \n {1} \n'.format(menuItemName, e))
  80.                 raise RuntimeError
  81.  
  82.             except ValueError, e:
  83.                 logger.error('\n ### Incorrect value passed to createMenu for Menu: '
  84.                              '{0}! \n {1} \n'.format(menuItemName, e))
  85.                 raise ValueError
  86.  
  87.             logger.debug('Menu: {0} created with: {1} as parent!'
  88.                          .format(menuItemName, parentMenu.GetTitle()))
  89.  
  90.         # create namedtuple to be returned, return both the Menu and MenuBuilder items so
  91.         # that creation of menus can be left to the addMenuItem instead
  92.         menus = Menus(menu, mb)
  93.  
  94.         return menus
  95.  
  96.  
  97.     def addMenuItem(self, name, category, command, parentMenuBuilder, createMenu=None):
  98.         """
  99.        This method adds a new MenuItem to the specified MenuBuilder in 3ds max.
  100.  
  101.        :rtype : MenuBuilder object
  102.        :param name: string
  103.        :param category: string
  104.        :param command: function
  105.        :param parentMenuBuilder: MenuBuilder object
  106.        :param createMenu: Menu object
  107.        :return: MenuBuilder object
  108.  
  109.        Also optionally can create the final menu if this is the last item added to the MenuBuilder.
  110.        createMenu param should only used in the last item to be added before creating the Menu
  111.        """
  112.  
  113.         logger = logging.getLogger(__name__)
  114.  
  115.         # check that MenuBuilder object is valid
  116.         assert isinstance(parentMenuBuilder, MaxPlus.MenuBuilder), \
  117.             '### {0} is not a valid MenuBuilder object!'.format(parentMenuBuilder)
  118.  
  119.         # create 3ds max action item and validate it
  120.         action = MaxPlus.ActionFactory.Create(category, name, command)
  121.  
  122.         if not action._IsValidWrapper():
  123.             logger.debug('### Action {0} invalid!\n'.format(action.GetId()))
  124.             return
  125.  
  126.         # check for existing menu item and remove it
  127.         if MaxPlus.MenuManager.MenuExists(name):
  128.             self.deleteMenu(name)
  129.  
  130.         # add the action as a menu item
  131.         menuBuilder = parentMenuBuilder.AddItem(action)
  132.  
  133.         logger.debug('Successfully added the item: "{0}" with id: {1} !'.format(name, action.GetId()))
  134.  
  135.         # create menu
  136.         if createMenu is not None:
  137.             try:
  138.                 if type(createMenu) is not MaxPlus.Menu:
  139.                     logger.error('### Error occurred when trying to createMenu! '
  140.                                  '{0} is not a valid Menu object! \n'.format(createMenu))
  141.  
  142.                 parentMenuBuilder.Create(createMenu)
  143.  
  144.                 logger.debug('Successfully created the Menu: {0} and '
  145.                              'parented it to {1} !'.format(name, createMenu))
  146.  
  147.             except RuntimeError, e:
  148.                 logger.warning('\n### Unable to create the Menu: {0} to '
  149.                                'be parented to: {1}!\n'.format(parentMenuBuilder, createMenu))
  150.                 logger.debug('\n{0}!\n'.format(e))
  151.  
  152.         return menuBuilder
  153.  
  154.  
  155.     def deleteMenu(self, menuName):
  156.         """
  157.        This method unregisters the specified menuName item.
  158.  
  159.        :param menuName: string or Menu
  160.        :return:
  161.  
  162.        WARNING: this method should be used with caution to prevent corrupting an existing 3ds max installation.
  163.        Backup your MaxStartUI.mnu file before playing around with the behaviour of this method.
  164.  
  165.        """
  166.  
  167.         logger = logging.getLogger(__name__)
  168.  
  169.         # guard against removing core 3ds max menus
  170.         if menuName in self.keywords:
  171.             logger.warning('\n### Cannot unregister {0} ! This is a core 3ds max menu! \n'.format(menuName))
  172.  
  173.         else:
  174.             # unregister the Menu
  175.             MaxPlus.MenuManager.UnregisterMenu(unicode(menuName))
  176.  
  177.             logger.debug('Unregistered menu: {0} !'.format(menuName))
  178.  
  179.  
  180.     def menuSetup( self ):
  181.         """
  182.        This method registers the generic menu items to the 3ds max menubar.
  183.  
  184.        :rtype : object
  185.        :return:
  186.        """
  187.  
  188.         logger = logging.getLogger(__name__)
  189.  
  190.         genericMainMenu = self.createMenu('generic', delayCreate=False)
  191.  
  192.         # build menus and action items
  193.         # File Menu
  194.         generic_fileMenu = self.createMenu('File', genericMainMenu.menu)
  195.  
  196.         generic_file_publish_axn = self.addMenuItem('Publish file to generic', 'File', partial(self.foo,'publish'),
  197.                                                    generic_fileMenu.mb)
  198.  
  199.         generic_file_getLatest_axn = self.addMenuItem('Get latest revision', 'File', partial(self.foo, 'get latest rev'),
  200.                                                      generic_fileMenu.mb)
  201.  
  202.         generic_file_viewAll_axn = self.addMenuItem('View all revisions', 'File', partial(self.foo, 'view all rev'),
  203.                                                    generic_fileMenu.mb, createMenu=genericMainMenu.menu)
  204.  
  205.         logger.debug('# Finished building File Menu! \n')
  206.  
  207.         # Server Menu
  208.         generic_serverMenu = self.createMenu('Server', genericMainMenu.menu)
  209.  
  210.         generic_server_feedbackMenu = self.createMenu('Feedback', generic_serverMenu.menu)
  211.  
  212.         generic_server_getFeedback_axn = self.addMenuItem('Get latest feedback', 'Feedback', partial(self.foo, 'feedback'),
  213.                                                          generic_server_feedbackMenu.mb)
  214.  
  215.         generic_server_viewAllFeedback_axn = self.addMenuItem('View all feedback', 'Feedback', partial(self.foo, 'all feedback'),
  216.                                                              generic_server_feedbackMenu.mb, createMenu=generic_serverMenu.menu)
  217.  
  218.         generic_server_newTask_axn = self.addMenuItem('Create new Task', 'Server', partial(self.foo, 'create task'),
  219.                                                      generic_serverMenu.mb)
  220.  
  221.         generic_server_taskStatus_axn = self.addMenuItem('Check Task status', 'Server', partial(self.foo, 'check status'),
  222.                                                         generic_serverMenu.mb)
  223.  
  224.         generic_serverMenu.mb.AddSeparator()
  225.  
  226.  
  227.         logger.debug('Menu items setup and added to 3ds max main menubar!')
  228.  
  229.  
  230.  
  231.  
  232.  
  233.     @staticmethod
  234.     def foo( *args ):
  235.         for arg in args:
  236.             print arg
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement