Refactor DCCsi to work better with O3DE changes (#4226)
* moving files in refactor/re-org Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * dev env refactor/re-org Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * moving/re-org so we can deprate the SDK nomiclature Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * moving/re-org so we can deprate the SDK nomiclature Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Refactoring env so I can replace SDK with Tools folder Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * re-org and prune, from SKD to Tools Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Removing old .bat files from SDK Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * updated how to retreive PYTHONHOME Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Can't use/set PYTHONHOME with DCC Tools Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * small refactor Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * repaired a missed typo (causes error) Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Added missing EntityId.h include to FocusModeInterface.h Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * refactor additional LY to O3DE tags Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Some design scaffold file stubs Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * stubbing in scaffold file pattern Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Removal of corrupted prefabs Signed-off-by: Benjamin Black <benblac@amazon.com> * refactored config_utils to maintain py2.7 support for maya 2020 Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * refactored config_utils to maintain py2.7 support for maya 2020 Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * pruning and cleanup Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * .env is for local dev overrides Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * .env is for local dev overrides Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * clean up init and logging patterns Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * Core refactoring, config.py functional standalone Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * cleaned up some bad logging, fixed up boostrap Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * fixed validation errors Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * fix logging issue, tiddy up Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * tiddy up maya for .bat bootstraping and launch Signed-off-by: Jonny Gallowy <gallowj@amazon.com> * name stub, fix validation Signed-off-by: Jonny Gallowy <gallowj@amazon.com> Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Co-authored-by: Benjamin Black <benblac@amazon.com>
This commit is contained in:
+9
@@ -0,0 +1,9 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
print('Not Implemented')
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
|
||||
"""
|
||||
Module Documentation:
|
||||
DccScriptingInterface:: Tools//maya//scripts//constants.py
|
||||
|
||||
This module is mainly a bunch of commony used constants, and default strings
|
||||
So we can make an update here once that is used elsewhere
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
# built-ins
|
||||
# none
|
||||
|
||||
# -- External Python modules
|
||||
|
||||
# -- DCCsi Extension Modules
|
||||
#import azpy
|
||||
|
||||
# -- maya imports
|
||||
# none
|
||||
# -------------------------------------------------------------------------
|
||||
OBJ_DCCSI_MAINMENU = 'O3deDCCsiMainMenu'
|
||||
TAG_DCCSI_MAINMENU = 'DCCsi (O3DE:Atom)'
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
"""
|
||||
Module Documentation:
|
||||
DccScriptingInterface:: SDK//maya//scripts//set_callbacks.py
|
||||
|
||||
This module manages a set of predefined callbacks for maya
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
# -- Standard Python modules
|
||||
import os
|
||||
import sys
|
||||
import logging as _logging
|
||||
# -- External Python modules
|
||||
from box import Box
|
||||
# maya imports
|
||||
import maya.cmds as mc
|
||||
import maya.api.OpenMaya as om
|
||||
# -- DCCsi Extension Modules
|
||||
from azpy.constants import *
|
||||
import azpy.dcc.maya
|
||||
azpy.dcc.maya.init() # <-- should have already run?
|
||||
import azpy.dcc.maya.callbacks.event_callback_handler as azEvCbH
|
||||
import azpy.dcc.maya.callbacks.node_message_callback_handler as azNdMsH
|
||||
# Node Message Callback Setup
|
||||
import azpy.dcc.maya.callbacks.on_shader_rename as oSR
|
||||
from set_defaults import set_defaults
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
|
||||
# global space
|
||||
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, True)
|
||||
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, True)
|
||||
|
||||
_MODULENAME = r'DCCsi.SDK.Maya.Scripts.set_callbacks'
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_MODULENAME, default_log_level=int(20))
|
||||
_LOGGER.debug('Invoking:: {0}.'.format({_MODULENAME}))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global scope callbacks, set up set and initialize all to None
|
||||
# To Do: should callback initialization use data-driven settings?
|
||||
# To Do: should we move callback initialization to a sub-module?
|
||||
# To Do: move the callback key like 'NewSceneOpened' here (instead of None)
|
||||
# ^ this would provide ability to loop through and replace key with CB object
|
||||
|
||||
_G_CALLBACKS = Box(box_dots=True) # global scope container
|
||||
_G_PRIMEKEY = 'DCCsi_callbacks'
|
||||
_G_CALLBACKS[_G_PRIMEKEY] = True # required prime key
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def init_callbacks(_callbacks=_G_CALLBACKS):
|
||||
# store as a dict (Box is a fancy dict)
|
||||
_callbacks[_G_PRIMEKEY] = True # required prime key
|
||||
|
||||
# signature dict['callback key'] = ('CallBack'(type), func, callbackObj)
|
||||
_callbacks['on_new_file'] = ['NewSceneOpened', set_defaults, None]
|
||||
_callbacks['new_scene_fix_paths'] = ['NewSceneOpened', install_fix_paths, None]
|
||||
_callbacks['post_scene_fix_paths'] = ['PostSceneRead', install_fix_paths, None]
|
||||
_callbacks['workspace_changed'] = ['workspaceChanged', update_workspace, None]
|
||||
_callbacks['quit_app'] = ['quitApplication', uninstall_callbacks, None]
|
||||
|
||||
# nodeMessage style callbacks
|
||||
# fire a function
|
||||
_func_00 = oSR.on_shader_rename_rename_shading_group
|
||||
# using a nodeMessage callback trigger
|
||||
_cb_00 = om.MNodeMessage.addNameChangedCallback
|
||||
# all nodeMessage type callbacks can use 'nodeMessageType' key
|
||||
_callbacks['shader_rename'] = ['nodeMessageType', (_func_00, _cb_00), None]
|
||||
|
||||
return _callbacks
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def uninstall_callbacks():
|
||||
"""Bulk uninstalls hte globally defined set of callbacks:
|
||||
_G_callbacks"""
|
||||
|
||||
global _G_CALLBACKS
|
||||
|
||||
_LOGGER.debug('uninstall_callbacks() fired')
|
||||
|
||||
for key, value in _G_CALLBACKS:
|
||||
if value[2] is not None: # have a cb
|
||||
value[2].uninstall() # so uninstall it
|
||||
else:
|
||||
_LOGGER.warning('No callback in: key {0}, value:{1}'
|
||||
''.format(key, value))
|
||||
_G_CALLBACKS = None
|
||||
_LOGGER.info('DCCSI CALLBACKS UNINSTALLED ... EXITING')
|
||||
return _G_CALLBACKS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def install_callbacks(_callbacks=_G_CALLBACKS):
|
||||
"""Bulk installs the globally defined set of callbacks:
|
||||
_G_callbacks"""
|
||||
|
||||
_LOGGER.debug('install_callback_set() fired')
|
||||
|
||||
_callbacks = init_callbacks(_callbacks)
|
||||
|
||||
# we initialized the box with this so pop it
|
||||
if 'box_dots' in _callbacks:
|
||||
_callbacks.pop('box_dots')
|
||||
|
||||
# don't pass anything but carefully considered dict
|
||||
if _G_PRIMEKEY in _callbacks:
|
||||
_primekey = _callbacks.pop(_G_PRIMEKEY)
|
||||
else:
|
||||
_LOGGER.error('No prime key, use a correct dictionary')
|
||||
#To Do: implement error handling and return codes
|
||||
return _callbacks[None]
|
||||
|
||||
for key, value in _G_CALLBACKS.items():
|
||||
# we popped the prime key should the rest should be safe
|
||||
if value[0] != 'nodeMessageType':
|
||||
# set callback up
|
||||
_cb = azEvCbH.EventCallbackHandler(value[0],
|
||||
value[1])
|
||||
# ^ installs by default
|
||||
# stash it back into managed dict
|
||||
value[2] = _cb
|
||||
# value[2].install()
|
||||
else:
|
||||
# set up callback, value[1] should be tupple(func, trigger)
|
||||
_cb = azNdMsH.NodeMessageCallbackHandler(value[1][0],
|
||||
value[1][1])
|
||||
# ^ installs by default
|
||||
# stash it back into managed dict
|
||||
value[2] = _cb
|
||||
# value[2].install()
|
||||
|
||||
return _callbacks
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def install_fix_paths(foo=None):
|
||||
"""Installs and triggers a fix paths module.
|
||||
This can repair broken reference paths in shaders"""
|
||||
global _fix_paths
|
||||
_fix_paths = None
|
||||
|
||||
_LOGGER.debug('install_fix_paths() fired')
|
||||
|
||||
# if we don't have it already, this function is potentially triggered
|
||||
# by a callback, so we don't need to keep importing it.
|
||||
try:
|
||||
_fix_paths
|
||||
reload(_fix_paths)
|
||||
except Exception as e:
|
||||
try:
|
||||
import fixPaths as _fix_paths
|
||||
except Exception as e:
|
||||
# To Do: not implemented yet
|
||||
_LOGGER.warning('NOT IMPLEMENTED: {0}'.format(e))
|
||||
|
||||
# if we have it, use it
|
||||
if _fix_paths:
|
||||
return _fix_paths.main()
|
||||
else:
|
||||
# To Do: implement error handling and return codes
|
||||
return 1
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def update_workspace(foo=None):
|
||||
"""Forces and update of the workspace (workspace.mel)"""
|
||||
_LOGGER.debug('update_workspace() fired')
|
||||
result = mc.workspace(update=True)
|
||||
return result
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# install and init callbacks on an import obj
|
||||
_G_CALLBACKS = install_callbacks(_G_CALLBACKS)
|
||||
|
||||
# ==========================================================================
|
||||
# Module Tests
|
||||
#==========================================================================
|
||||
if __name__ == '__main__':
|
||||
_G_CALLBACKS = install_callbacks(_G_CALLBACKS)
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
"""
|
||||
Module Documentation:
|
||||
DccScriptingInterface:: SDK//maya//scripts//set_pref_defaults.py
|
||||
|
||||
This module manages a predefined set of prefs for maya
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
# -- Standard Python modules
|
||||
import os
|
||||
import sys
|
||||
# -- External Python modules
|
||||
|
||||
# -- DCCsi Extension Modules
|
||||
import azpy
|
||||
from azpy.constants import *
|
||||
|
||||
# -- maya imports
|
||||
import maya.cmds as mc
|
||||
import maya.mel as mm
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
|
||||
# global space
|
||||
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
|
||||
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
|
||||
|
||||
_MODULENAME = r'DCCsi.SDK.Maya.Scripts.set_defaults'
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_MODULENAME, default_log_level=int(20))
|
||||
_LOGGER.debug('Invoking:: {0}.'.format({_MODULENAME}))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def set_defaults(units='meter'):
|
||||
"""This method will make defined settings changes to Maya prefs,
|
||||
to better configure maya to work with Lumberyard"""
|
||||
# To Do: make this data-driven env/settings, game teams should be able
|
||||
# to opt out and/or set their prefered configuration.
|
||||
|
||||
_LOGGER.debug('set_defaults_lumberyard() fired')
|
||||
|
||||
# set up default units ... this should be moved to bootstrap config
|
||||
_LOGGER.info('Default, 1 Linear Game Unit in Lumberyard == 1 Meter'
|
||||
' in Maya content. Setting default linear units to Meters'
|
||||
' (user can change to other units in the preferences)')
|
||||
|
||||
result = mc.currentUnit(linear=units)
|
||||
|
||||
# set up grid defaults
|
||||
_LOGGER.info('Setting Grid defaults, to match default unit scale.'
|
||||
'(user can change grid config manually')
|
||||
try:
|
||||
mc.grid(size=32, spacing=1, divisions=10)
|
||||
except Exception as e:
|
||||
_LOGGER.warning('{0}'.format(e))
|
||||
|
||||
# viewFit
|
||||
_LOGGER.info('Changing default mc.viewFit')
|
||||
try:
|
||||
mc.viewFit()
|
||||
except Exception as e:
|
||||
_LOGGER.warning('{0}'.format(e))
|
||||
|
||||
# some mel commands
|
||||
_LOGGER.info('Changing sersp camera clipping planes')
|
||||
try:
|
||||
mm.eval(str(r'setAttr "perspShape.nearClipPlane" 0.01;'))
|
||||
mm.eval(str(r'setAttr "perspShape.farClipPlane" 1000;'))
|
||||
except Exception as e:
|
||||
_LOGGER.warning('{0}'.format(e))
|
||||
|
||||
# set up fixPaths
|
||||
_LOGGER.info('~ Setting up fixPaths in default scene')
|
||||
|
||||
return 0
|
||||
# -------------------------------------------------------------------------
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
"""
|
||||
Module Documentation:
|
||||
DccScriptingInterface:: SDK//maya//scripts//set_menu.py
|
||||
|
||||
This module creates and manages a DCCsi mainmenu
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
# -- Standard Python modules
|
||||
# none
|
||||
|
||||
# -- External Python modules
|
||||
# none
|
||||
|
||||
# -- DCCsi Extension Modules
|
||||
import azpy
|
||||
from constants import OBJ_DCCSI_MAINMENU
|
||||
from constants import TAG_DCCSI_MAINMENU
|
||||
|
||||
# -- maya imports
|
||||
import pymel.core as pm
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
|
||||
# global space
|
||||
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
|
||||
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
|
||||
|
||||
_MODULENAME = r'DCCsi.SDK.Maya.Scripts.set_menu'
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_MODULENAME, default_log_level=int(20))
|
||||
_LOGGER.debug('Invoking:: {0}.'.format({_MODULENAME}))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def menu_cmd_test():
|
||||
_LOGGER.info('test_func(), is TESTING main menu')
|
||||
return
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
def set_main_menu(obj_name=OBJ_DCCSI_MAINMENU, label=TAG_DCCSI_MAINMENU):
|
||||
_main_window = pm.language.melGlobals['gMainWindow']
|
||||
|
||||
_menu_obj = obj_name
|
||||
_menu_label = label
|
||||
|
||||
# check if it already exists and remove (so we don't duplicate)
|
||||
if pm.menu(_menu_obj, label=_menu_label, exists=True, parent=_main_window):
|
||||
pm.deleteUI(pm.menu(_menu_obj, e=True, deleteAllItems=True))
|
||||
|
||||
# create the main menu object
|
||||
_custom_tools_menu = pm.menu(_menu_obj,
|
||||
label=_menu_label,
|
||||
parent=_main_window,
|
||||
tearOff=True)
|
||||
|
||||
# make a dummpy sub-menu
|
||||
pm.menuItem(label='Menu Item Stub',
|
||||
subMenu=True,
|
||||
parent=_custom_tools_menu,
|
||||
tearOff=True)
|
||||
|
||||
# make a dummy menu item to test
|
||||
pm.menuItem(label='Test', command=pm.Callback(menu_cmd_test))
|
||||
return _custom_tools_menu
|
||||
|
||||
# ==========================================================================
|
||||
# Run as LICENSE
|
||||
#==========================================================================
|
||||
if __name__ == '__main__':
|
||||
|
||||
_custom_menu = set_main_menu()
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
"""
|
||||
Module Documentation:
|
||||
DccScriptingInterface:: SDK//maya//scripts//set_shelf.py
|
||||
|
||||
This module manages a custom shelf in maya for the DCCsi
|
||||
Reference: https://gist.github.com/vshotarov/1c3176fe9e38dcaadd1e56c2f15c95d9
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
# -- Standard Python modules
|
||||
# none
|
||||
|
||||
# -- External Python modules
|
||||
# none
|
||||
|
||||
# -- DCCsi Extension Modules
|
||||
# none
|
||||
|
||||
# -- Maya Extension Modules
|
||||
import maya.cmds as mc
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _null(*args):
|
||||
pass
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
class customShelf(_Custom_Shelf):
|
||||
'''This is an example shelf.'''
|
||||
|
||||
def build(self):
|
||||
self.add_button(label="button1")
|
||||
self.add_button("button2")
|
||||
self.add_button("popup")
|
||||
p = mc.popupMenu(b=1)
|
||||
self.add_menu_item(p, "popupMenuItem1")
|
||||
self.add_menu_item(p, "popupMenuItem2")
|
||||
sub = self.add_submenu(p, "subMenuLevel1")
|
||||
self.add_menu_item(sub, "subMenuLevel1Item1")
|
||||
sub2 = self.add_submenu(sub, "subMenuLevel2")
|
||||
self.add_menu_item(sub2, "subMenuLevel2Item1")
|
||||
self.add_menu_item(sub2, "subMenuLevel2Item2")
|
||||
self.add_menu_item(sub, "subMenuLevel1Item2")
|
||||
self.add_menu_item(p, "popupMenuItem3")
|
||||
self.add_button("button3")
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
class _Custom_Shelf():
|
||||
'''A simple class to build custom shelves in maya.
|
||||
The build method is empty and an inheriting class should override'''
|
||||
|
||||
def __init__(self, name="DCCsi", icon_path=""):
|
||||
self._name = name
|
||||
|
||||
self._icon_path = icon_path
|
||||
|
||||
self._label_background_color = (0, 0, 0, 0)
|
||||
self._label_colour = (.9, .9, .9)
|
||||
|
||||
self._clean_old_shlef()
|
||||
|
||||
mc.setParent(self._name)
|
||||
|
||||
self.build()
|
||||
|
||||
def build(self):
|
||||
'''Override this method in custom class.
|
||||
Otherwise, nothing is added to the shelf.'''
|
||||
pass
|
||||
|
||||
def add_button(self,
|
||||
label='<NotSet>',
|
||||
icon="commandButton.png",
|
||||
command=_null,
|
||||
doubleCommand=_null):
|
||||
'''Adds a shelf button with the specified label,
|
||||
command, double click command and image.'''
|
||||
mc.setParent(self._name)
|
||||
if icon:
|
||||
icon = self._icon_path + icon
|
||||
mc.shelfButton(width=37, height=37,
|
||||
image=icon,
|
||||
label=label,
|
||||
command=command,
|
||||
doubleClickCommand=doubleCommand,
|
||||
imageOverlayLabel=label,
|
||||
overlayLabelBackColor=self._label_background_color,
|
||||
overlayLabelColor=self._label_colour)
|
||||
|
||||
def add_menu_item(self, parent, label, command=_null, icon=""):
|
||||
'''Adds a shelf button with the specified label,
|
||||
command, double click command and image.'''
|
||||
if icon:
|
||||
icon = self._icon_path + icon
|
||||
return mc.menuItem(p=parent, l=label, c=command, i="")
|
||||
|
||||
def add_submenu(self, parent, label, icon=None):
|
||||
'''Adds a sub menu item with the specified label and icon
|
||||
to the specified parent popup menu.'''
|
||||
if icon:
|
||||
icon = self._icon_path + icon
|
||||
return mc.menuItem(p=parent, l=label, i=icon, subMenu=1)
|
||||
|
||||
def _clean_old_shlef(self):
|
||||
'''Checks if the shelf exists and empties it if it does or
|
||||
creates it if it does not.'''
|
||||
if mc.shelfLayout(self._name, ex=1):
|
||||
if mc.shelfLayout(self._name, q=1, ca=1):
|
||||
for each in mc.shelfLayout(self._name, q=1, ca=1):
|
||||
mc.deleteUI(each)
|
||||
else:
|
||||
mc.shelfLayout(self._name, p="ShelfLayout")
|
||||
|
||||
|
||||
# ==========================================================================
|
||||
# Module Tests
|
||||
# ==========================================================================
|
||||
if __name__ == '__main__':
|
||||
customShelf()
|
||||
pass
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
# coding:utf-8
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""
|
||||
This module fullfils the maya bootstrap pattern as described in their docs
|
||||
https://tinyurl.com/y2aoz8es
|
||||
|
||||
Pattern is similar to Lumberyard Editor\\Scripts\\bootstrap.py
|
||||
|
||||
For now the proper way to initiate Maya boostrapping the DCCsi, is to use
|
||||
the provided env and launcher bat files.
|
||||
|
||||
If you are developing for the DCCsi you can use this launcher to start Maya:
|
||||
DccScriptingInterface\\Launchers\\Windows\\Launch_Maya_2020.bat"
|
||||
|
||||
To Do: ATOM-5861
|
||||
"""
|
||||
__project__ = 'DccScriptingInterface'
|
||||
|
||||
# it is really hard to debug userSetup bootstrapping
|
||||
# this enables some rudimentary logging for debugging
|
||||
_BOOT_INFO = True
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# built in's
|
||||
import os
|
||||
import sys
|
||||
import site
|
||||
import inspect
|
||||
import traceback
|
||||
import logging as _logging
|
||||
|
||||
# -- DCCsi Extension Modules
|
||||
import azpy
|
||||
from azpy.constants import *
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
|
||||
# To Do: needs to be updated to use dynaconf and config.py
|
||||
from azpy.env_base import _BASE_ENVVAR_DICT
|
||||
|
||||
# -- maya imports
|
||||
import maya.cmds as cmds
|
||||
import maya.mel as mel
|
||||
#from pymel.all import *
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# global space
|
||||
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
|
||||
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
|
||||
_DCCSI_DEV_MODE = True # force true for debugger testing
|
||||
|
||||
_ORG_TAG = r'Amazon::Lumberyard'
|
||||
_APP_TAG = r'DCCsi'
|
||||
_TOOL_TAG = r'SDK.Maya.Scripts.userSetup'
|
||||
_TYPE_TAG = r'entrypoint' # bootstrap
|
||||
|
||||
_MODULENAME = str('{0}.{1}'.format(_APP_TAG, _TOOL_TAG))
|
||||
|
||||
_LOGGER = azpy.initialize_logger(_MODULENAME, default_log_level=int(20))
|
||||
_LOGGER.info('Initializing: {0}.'.format({_MODULENAME}))
|
||||
_LOGGER.info('DCCSI_GDEBUG: {0}.'.format({_DCCSI_GDEBUG}))
|
||||
_LOGGER.info('DCCSI_DEV_MODE: {0}.'.format({_DCCSI_DEV_MODE}))
|
||||
|
||||
# flag to turn off setting up callbacks, until they are fully implemented
|
||||
# To Do: consider making it a settings option to define and enable/disable
|
||||
_G_LOAD_CALLBACKS = True # couple bugs, couple NOT IMPLEMENTED
|
||||
_LOGGER.info('DCCSI_MAYA_SET_CALLBACKS: {0}.'.format({_G_LOAD_CALLBACKS}))
|
||||
|
||||
# early attach WingIDE debugger (can refactor to include other IDEs later)
|
||||
if _DCCSI_DEV_MODE:
|
||||
from azpy.test.entry_test import connect_wing
|
||||
foo = connect_wing()
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# To Do REMOVE this block and replace with dev module
|
||||
# debug prints, To Do: this should be moved to bootstrap config
|
||||
#_G_DEBUGGER = os.getenv(ENVAR_DCCSI_GDEBUGGER, "WING")
|
||||
|
||||
#if _DCCSI_DEV_MODE:
|
||||
#if _G_DEBUGGER == "WING":
|
||||
#_LOGGER.info('{0}'.format('-' * 74))
|
||||
#_LOGGER.info('Developer Debug Mode: {0}, Basic debugger: {1}'.format(_G_DEBUG, _G_DEBUGGER))
|
||||
#try:
|
||||
#_LOGGER.info('Attempting to start basic WING debugger')
|
||||
#import azpy.lmbr.test
|
||||
|
||||
#_LOGGER.info('Package Imported: azpy.test')
|
||||
#ouput = azpy.entry_test.main(verbose=False,
|
||||
#connectDebugger=True,
|
||||
#returnOuput=_G_DEBUG)
|
||||
#_LOGGER.info(ouput)
|
||||
#pass
|
||||
#except Exception as e:
|
||||
#_LOGGER.info("Error: azpy.test, entry_test (didn't perform)")
|
||||
#_LOGGER.info("Exception: {0}".format(e))
|
||||
#pass
|
||||
#elif _G_DEBUGGER == "PYCHARM":
|
||||
## https://github.com/juggernate/PyCharm-Maya-Debugging
|
||||
#_LOGGER.info('{0}'.format('-' * 74))
|
||||
#_LOGGER.info('Developer Debug Mode: {0}, Basic debugger: {1}'.format(_G_DEBUG, _G_DEBUGGER))
|
||||
#sys.path.append('C:\Program Files\JetBrains\PyCharm 2019.1.3\debug-eggs\pydevd-pycharm.egg')
|
||||
#try:
|
||||
#_LOGGER.info('Attempting to start basic PYCHARM debugger')
|
||||
## Inside Maya Python Console (Tip: add to a shelf button for quick access)
|
||||
#import pydevd
|
||||
|
||||
#_LOGGER.info('Package Imported: pydevd')
|
||||
#pydevd.settrace('localhost', port=7720, suspend=False)
|
||||
#_LOGGER.info('PYCHARM Debugger Attach Success!!!')
|
||||
## To disconnect run:
|
||||
## pydevd.stoptrace()
|
||||
#pass
|
||||
#except Exception as e:
|
||||
#_LOGGER.info("Error: pydevd.settrace (didn't perform)")
|
||||
#_LOGGER.info("Exception: {0}".format(e))
|
||||
#pass
|
||||
#else:
|
||||
#pass
|
||||
## -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# validate access to the DCCsi and it's Lib site-packages
|
||||
# bootstrap site-packages by version
|
||||
from azpy.constants import PATH_DCCSI_PYTHON_LIB_PATH
|
||||
|
||||
try:
|
||||
os.path.exists(PATH_DCCSI_PYTHON_LIB_PATH)
|
||||
site.addsitedir(PATH_DCCSI_PYTHON_LIB_PATH)
|
||||
_LOGGER.info('azpy 3rdPary site-packages: is: {0}'.format(PATH_DCCSI_PYTHON_LIB_PATH))
|
||||
except Exception as e:
|
||||
_LOGGER.error('ERROR: {0}, {1}'.format(e, PATH_DCCSI_PYTHON_LIB_PATH))
|
||||
raise e
|
||||
|
||||
# 3rdparty
|
||||
from unipath import Path
|
||||
from box import Box
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Maya is frozen
|
||||
#_MODULE_PATH = Path(__file__)
|
||||
# https://tinyurl.com/y49t3zzn
|
||||
# module path when frozen
|
||||
_MODULE_FILEPATH = os.path.abspath(inspect.getfile(inspect.currentframe()))
|
||||
_MODULE_PATH = os.path.dirname(_MODULE_FILEPATH)
|
||||
if _BOOT_INFO:
|
||||
_LOGGER.debug('Boot: CWD: {}'.format(os.getcwd()))
|
||||
_LOGGER.debug('Frozen: _MODULE_FILEPATH: {}'.format(_MODULE_FILEPATH))
|
||||
_LOGGER.debug('Frozen: _MODULE_PATH: {}'.format(_MODULE_PATH))
|
||||
_LOGGER.debug('Module __name__: {}'.format(__name__))
|
||||
# root: INFO: Module __name__: __main__
|
||||
|
||||
_LOGGER.info('_MODULENAME: {}'.format(_MODULENAME))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# check some env var tags (fail if no, likely means no proper code access)
|
||||
_STR_ERROR_ENVAR = "Envar 'key' does not exist in base_env: {0}"
|
||||
_DCCSI_TOOLS_PATH = None
|
||||
# To Do: needs to be updated to use dynaconf and config.py
|
||||
try:
|
||||
_DCCSI_TOOLS_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSI_TOOLS_PATH]
|
||||
except Exception as e:
|
||||
_LOGGER.critical(_STR_ERROR_ENVAR.format(_BASE_ENVVAR_DICT[ENVAR_DCCSI_TOOLS_PATH]))
|
||||
|
||||
_O3DE_PROJECT_PATH = None
|
||||
try:
|
||||
_O3DE_PROJECT_PATH = _BASE_ENVVAR_DICT[ENVAR_O3DE_PROJECT_PATH]
|
||||
except Exception as e:
|
||||
_LOGGER.critical(_STR_ERROR_ENVAR.format(_BASE_ENVVAR_DICT[ENVAR_O3DE_PROJECT_PATH]))
|
||||
|
||||
# check some env var tags (fail if no, likely means no proper code access)
|
||||
_O3DE_DEV = _BASE_ENVVAR_DICT[ENVAR_O3DE_DEV]
|
||||
_O3DE_DCCSIG_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSIG_PATH]
|
||||
_O3DE_DCCSI_LOG_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSI_LOG_PATH]
|
||||
_O3DE_AZPY_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSI_AZPY_PATH]
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# To Do: implement data driven config
|
||||
# Currently not used, but will be where we store the ordered dict
|
||||
# which is parsed from the project bootstrapping config files.
|
||||
_G_app_config = {}
|
||||
|
||||
# global scope maya callbacks container
|
||||
_G_callbacks = Box(box_dots=True) # global scope container
|
||||
|
||||
# used to store fixPaths in the global scope
|
||||
_fix_paths = None
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# add appropriate common tools paths to the maya environment variables
|
||||
def startup():
|
||||
"""Early starup execution before mayautils.executeDeferred().
|
||||
Some things like UI and plugins should be defered to avoid failure"""
|
||||
_LOGGER.info('startup() fired')
|
||||
|
||||
# get known paths
|
||||
_KNOWN_PATHS = site._init_pathinfo()
|
||||
|
||||
if os.path.isdir(_DCCSI_TOOLS_PATH):
|
||||
site.addsitedir(_DCCSI_TOOLS_PATH, _KNOWN_PATHS)
|
||||
try:
|
||||
import azpy.test
|
||||
_LOGGER.info('SUCCESS, import azpy.test')
|
||||
except Exception as e:
|
||||
_LOGGER.warning('startup(), could not import azpy.test')
|
||||
|
||||
_LOGGER.info('startup(), COMPLETE')
|
||||
return 0
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# verify Shared\Python exists and add it as a site dir. Begin imports and config.
|
||||
def post_startup():
|
||||
"""Allows for a defered execution startup sequence"""
|
||||
|
||||
_LOGGER.info('post_startup() fired')
|
||||
|
||||
# plugins, To Do: these should be moved to bootstrapping config
|
||||
try:
|
||||
maya.cmds.loadPlugin("dx11Shader")
|
||||
except Exception as e:
|
||||
_LOGGER.error(e) # not a hard failure
|
||||
|
||||
# Lumberyard DCCsi environment ready or error out.
|
||||
try:
|
||||
import azpy.dcc.maya
|
||||
_LOGGER.info('Python module imported: azpy.dcc.maya')
|
||||
except Exception as e:
|
||||
_LOGGER.error(e)
|
||||
_LOGGER.error(traceback.print_exc())
|
||||
return 1
|
||||
|
||||
# Dccsi azpy maya ready or error out.
|
||||
try:
|
||||
azpy.dcc.maya.init()
|
||||
_LOGGER.info('SUCCESS, azpy.dcc.maya.init(), code accessible.')
|
||||
except Exception as e:
|
||||
_LOGGER.error(e)
|
||||
_LOGGER.error(traceback.print_exc())
|
||||
return 1
|
||||
|
||||
# callbacks, To Do: these should also be moved to the bootstrapping config
|
||||
# Defered startup after the Ui is running.
|
||||
_G_CALLBACKS = Box(box_dots=True) # this just ensures a global scope container
|
||||
if _G_LOAD_CALLBACKS:
|
||||
from set_callbacks import _G_CALLBACKS
|
||||
# ^ need to hold on to this as the install repopulate set
|
||||
|
||||
# this ensures the fixPaths callback is loaded
|
||||
# even when the other global callbacks are disabled
|
||||
from set_callbacks import install_fix_paths
|
||||
install_fix_paths()
|
||||
|
||||
# set the project workspace
|
||||
#_O3DE_PROJECT_PATH = _BASE_ENVVAR_DICT[ENVAR_O3DE_PROJECT_PATH]
|
||||
_project_workspace = os.path.join(_O3DE_PROJECT_PATH, TAG_MAYA_WORKSPACE)
|
||||
if os.path.isfile(_project_workspace):
|
||||
try:
|
||||
# load workspace
|
||||
maya.cmds.workspace(_O3DE_PROJECT_PATH, openWorkspace=True)
|
||||
_LOGGER.info('Loaded workspace file: {0}'.format(_project_workspace))
|
||||
maya.cmds.workspace(_O3DE_PROJECT_PATH, update=True)
|
||||
except Exception as e:
|
||||
_LOGGER.error(e)
|
||||
else:
|
||||
_LOGGER.warning('Workspace file not found: {1}'.format(_O3DE_PROJECT_PATH))
|
||||
|
||||
# Set up Lumberyard, maya default setting
|
||||
from set_defaults import set_defaults
|
||||
set_defaults()
|
||||
|
||||
# Setup UI tools
|
||||
if not maya.cmds.about(batch=True):
|
||||
_LOGGER.info('Add UI dependent tools')
|
||||
# wrap in a try, because we haven't implmented it yet
|
||||
try:
|
||||
mel.eval(str(r'source "{}"'.format(TAG_O3DE_DCC_MAYA_MEL)))
|
||||
except Exception as e:
|
||||
_LOGGER.error(e)
|
||||
|
||||
# manage custom menu in a sub-module
|
||||
from set_menu import set_main_menu
|
||||
set_main_menu()
|
||||
|
||||
# To Do: manage custom shelf in a sub-module
|
||||
|
||||
_LOGGER.info('post_startup(), COMPLETE')
|
||||
_LOGGER.info('DCCsi Bootstrap, COMPLETE')
|
||||
return 0
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
# Early startup config.
|
||||
startup()
|
||||
|
||||
# This allows defered action post boot (atfer UI is active)
|
||||
from maya.utils import executeDeferred
|
||||
post = executeDeferred(post_startup)
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
Reference in New Issue
Block a user