Atom/16852 (#6316)

* discover build folder, don't assume or require

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* update config_utils, no cyclical imports

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* improved docstrings and some code formatting

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* updates to config.py

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* updates to config_utils.py

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* dccsi bootstrap changes

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* fixed testing for bootstrap externally

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* added note for installing substance automation toolkit for tool dev

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* based on user feedback suppress global debug by default in IDE

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>

* small adjustments

Signed-off-by: Jonny Gallowy <gallowj@amazon.com>
This commit is contained in:
Jonny Galloway
2021-12-15 10:25:23 -06:00
committed by GitHub
parent e2679aad57
commit cbba00d473
51 changed files with 1263 additions and 773 deletions
@@ -118,7 +118,7 @@ def clicked_launch_sub_builder():
print(debug_msg)
_LOGGER.debug(debug_msg)
_SUB_BUILDER_PATH = Path(settings.DCCSIG_PATH,
_SUB_BUILDER_PATH = Path(settings.PATH_DCCSIG,
'SDK',
'Substance',
'builder')
@@ -34,7 +34,7 @@ print(_config)
# this is an alternative to "from dynaconf import settings" with Qt
settings = _config.get_config_settings(setup_ly_pyside=True)
# app_path = Path.joinpath(settings.DCCSIG_PATH, < relative path to current script dir >).resolve()
# app_path = Path.joinpath(settings.PATH_DCCSIG, < relative path to current script dir >).resolve()
# 3rd Party (we may or do provide)
from box import Box
@@ -507,7 +507,7 @@ class FBXConverter(QtWidgets.QDialog):
_LOGGER.debug('get_material_definition, os.getcwd() is: {}'.format(os.getcwd()))
# build a resolved absolute path because cwd may be unknown and change running externally
material_file = Path(settings.DCCSIG_PATH,
material_file = Path(settings.PATH_DCCSIG,
'SDK', 'Maya', 'Scripts', 'Python', 'kitbash_converter',
material_file).resolve()
@@ -18,14 +18,14 @@ import site
_MODULE_PATH = os.path.abspath(__file__)
_DCCSIG_REL_PATH = "../../../.."
_DCCSIG_PATH = os.path.join(_MODULE_PATH, _DCCSIG_REL_PATH)
_DCCSIG_PATH = os.path.normpath(_DCCSIG_PATH)
_PATH_DCCSIG = os.path.join(_MODULE_PATH, _DCCSIG_REL_PATH)
_PATH_DCCSIG = os.path.normpath(_PATH_DCCSIG)
_DCCSIG_PATH = os.getenv('DCCSIG_PATH',
os.path.abspath(_DCCSIG_PATH))
_PATH_DCCSIG = os.getenv('PATH_DCCSIG',
os.path.abspath(_PATH_DCCSIG))
# we don't have access yet to the DCCsi Lib\site-packages
site.addsitedir(_DCCSIG_PATH) # PYTHONPATH
site.addsitedir(_PATH_DCCSIG) # PYTHONPATH
# azpy bootstrapping and extensions
import azpy.config_utils
@@ -135,14 +135,14 @@ if _DCCSI_DEV_MODE:
# -------------------------------------------------------------------------
# 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
from azpy.constants import PATH_DCCSI_PYTHON_LIB
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))
os.path.exists(PATH_DCCSI_PYTHON_LIB)
site.addsitedir(PATH_DCCSI_PYTHON_LIB)
_LOGGER.info('azpy 3rdPary site-packages: is: {0}'.format(PATH_DCCSI_PYTHON_LIB))
except Exception as e:
_LOGGER.error('ERROR: {0}, {1}'.format(e, PATH_DCCSI_PYTHON_LIB_PATH))
_LOGGER.error('ERROR: {0}, {1}'.format(e, PATH_DCCSI_PYTHON_LIB))
raise e
# 3rdparty
@@ -175,15 +175,15 @@ try:
except Exception as e:
_LOGGER.critical(_STR_ERROR_ENVAR.format(_BASE_ENVVAR_DICT[ENVAR_DCCSI_SDK_PATH]))
_O3DE_PROJECT_PATH = None
_PATH_O3DE_PROJECT = None
try:
_O3DE_PROJECT_PATH = _BASE_ENVVAR_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_O3DE_PROJECT = _BASE_ENVVAR_DICT[ENVAR_PATH_O3DE_PROJECT]
except Exception as e:
_LOGGER.critical(_STR_ERROR_ENVAR.format(_BASE_ENVVAR_DICT[ENVAR_O3DE_PROJECT_PATH]))
_LOGGER.critical(_STR_ERROR_ENVAR.format(_BASE_ENVVAR_DICT[ENVAR_PATH_O3DE_PROJECT]))
# 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_PATH_DCCSIG = _BASE_ENVVAR_DICT[ENVAR_PATH_DCCSIG]
_O3DE_DCCSI_LOG_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSI_LOG_PATH]
_O3DE_AZPY_PATH = _BASE_ENVVAR_DICT[ENVAR_DCCSI_AZPY_PATH]
# -------------------------------------------------------------------------
@@ -270,18 +270,18 @@ def post_startup():
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)
#_PATH_O3DE_PROJECT = _BASE_ENVVAR_DICT[ENVAR_PATH_O3DE_PROJECT]
_project_workspace = os.path.join(_PATH_O3DE_PROJECT, TAG_MAYA_WORKSPACE)
if os.path.isfile(_project_workspace):
try:
# load workspace
maya.cmds.workspace(_O3DE_PROJECT_PATH, openWorkspace=True)
maya.cmds.workspace(_PATH_O3DE_PROJECT, openWorkspace=True)
_LOGGER.info('Loaded workspace file: {0}'.format(_project_workspace))
maya.cmds.workspace(_O3DE_PROJECT_PATH, update=True)
maya.cmds.workspace(_PATH_O3DE_PROJECT, update=True)
except Exception as e:
_LOGGER.error(e)
else:
_LOGGER.warning('Workspace file not found: {1}'.format(_O3DE_PROJECT_PATH))
_LOGGER.warning('Workspace file not found: {1}'.format(_PATH_O3DE_PROJECT))
# Set up Lumberyard, maya default setting
from set_defaults import set_defaults
@@ -19,10 +19,10 @@ import importlib.util
# if running in py2.7 we won't have access to pathlib yet until we boostrap
# the DCCsi
_MODULE_PATH = os.path.realpath(__file__) # To Do: what if frozen?
_DCCSIG_PATH = os.path.normpath(os.path.join(_MODULE_PATH, '../../../..'))
_DCCSIG_PATH = os.getenv('DCCSIG_PATH', _DCCSIG_PATH)
site.addsitedir(_DCCSIG_PATH)
# print(_DCCSIG_PATH)
_PATH_DCCSIG = os.path.normpath(os.path.join(_MODULE_PATH, '../../../..'))
_PATH_DCCSIG = os.getenv('PATH_DCCSIG', _PATH_DCCSIG)
site.addsitedir(_PATH_DCCSIG)
# print(_PATH_DCCSIG)
# Lumberyard DCCsi site extensions
from pathlib import Path
@@ -46,7 +46,7 @@ _LOGGER = azpy.initialize_logger(_PACKAGENAME,
log_to_file=True,
default_log_level=_log_level)
_LOGGER.debug('Starting up: {0}.'.format({_PACKAGENAME}))
_LOGGER.debug('_DCCSIG_PATH: {}'.format(_DCCSIG_PATH))
_LOGGER.debug('_PATH_DCCSIG: {}'.format(_PATH_DCCSIG))
_LOGGER.debug('_G_DEBUG: {}'.format(_DCCSI_GDEBUG))
_LOGGER.debug('_DCCSI_DEV_MODE: {}'.format(_DCCSI_DEV_MODE))
@@ -59,7 +59,7 @@ if _DCCSI_DEV_MODE:
# we can go ahead and just make sure the the DCCsi env is set
# config is SO generic this ensures we are importing a specific one
_spec_dccsi_config = importlib.util.spec_from_file_location("dccsi.config",
Path(_DCCSIG_PATH,
Path(_PATH_DCCSIG,
"config.py"))
_dccsi_config = importlib.util.module_from_spec(_spec_dccsi_config)
_spec_dccsi_config.loader.exec_module(_dccsi_config)
@@ -96,16 +96,16 @@ from azpy.constants import ENVAR_O3DE_DEV
_O3DE_DEV = Path(os.getenv(ENVAR_O3DE_DEV,
settings.O3DE_DEV)).resolve()
from azpy.constants import ENVAR_O3DE_PROJECT_PATH
_O3DE_PROJECT_PATH = Path(os.getenv(ENVAR_O3DE_PROJECT_PATH,
settings.O3DE_PROJECT_PATH)).resolve()
from azpy.constants import ENVAR_PATH_O3DE_PROJECT
_PATH_O3DE_PROJECT = Path(os.getenv(ENVAR_PATH_O3DE_PROJECT,
settings.PATH_O3DE_PROJECT)).resolve()
from azpy.constants import ENVAR_DCCSI_SDK_PATH
_DCCSI_SDK_PATH = Path(os.getenv(ENVAR_DCCSI_SDK_PATH,
settings.DCCSIG_SDK_PATH)).resolve()
# build some reuseable path parts for the substance builder
_PROJECT_ASSETS_PATH = Path(_O3DE_PROJECT_PATH, 'Assets').resolve()
_PROJECT_ASSETS_PATH = Path(_PATH_O3DE_PROJECT, 'Assets').resolve()
_PROJECT_MATERIALS_PATH = Path(_PROJECT_ASSETS_PATH, 'Materials').resolve()
# -------------------------------------------------------------------------
@@ -117,7 +117,7 @@ if __name__ == "__main__":
"""Run this file as main"""
_LOGGER.info('_O3DE_DEV: {}'.format(_O3DE_DEV))
_LOGGER.info('_O3DE_PROJECT_PATH: {}'.format(_O3DE_PROJECT_PATH))
_LOGGER.info('_PATH_O3DE_PROJECT: {}'.format(_PATH_O3DE_PROJECT))
_LOGGER.info('_DCCSI_SDK_PATH: {}'.format(_DCCSI_SDK_PATH))
_LOGGER.info('_PYSBS_DIR_PATH: {}'.format(_PYSBS_DIR_PATH))
@@ -76,7 +76,7 @@ settings.setenv() # for standalone
# log debug info about Qt/PySide2
_LOGGER.debug('QTFORPYTHON_PATH: {}'.format(settings.QTFORPYTHON_PATH))
_LOGGER.debug('O3DE_BIN_PATH: {}'.format(settings.O3DE_BIN_PATH))
_LOGGER.debug('PATH_O3DE_BIN: {}'.format(settings.PATH_O3DE_BIN))
_LOGGER.debug('QT_PLUGIN_PATH: {}'.format(settings.QT_PLUGIN_PATH))
_LOGGER.debug('QT_QPA_PLATFORM_PLUGIN_PATH: {}'.format(settings.QT_QPA_PLATFORM_PLUGIN_PATH))
# -------------------------------------------------------------------------
@@ -129,15 +129,15 @@ _O3DE_DEV = Path(os.getenv(ENVAR_O3DE_DEV, None)).resolve()
from azpy.constants import ENVAR_O3DE_PROJECT
_O3DE_PROJECT = os.getenv(ENVAR_O3DE_PROJECT, None)
from azpy.constants import ENVAR_O3DE_PROJECT_PATH
_O3DE_PROJECT_PATH = Path(os.getenv(ENVAR_O3DE_PROJECT_PATH, None)).resolve()
from azpy.constants import ENVAR_PATH_O3DE_PROJECT
_PATH_O3DE_PROJECT = Path(os.getenv(ENVAR_PATH_O3DE_PROJECT, None)).resolve()
from azpy.constants import ENVAR_DCCSI_SDK_PATH
_DCCSI_SDK_PATH = Path(os.getenv(ENVAR_DCCSI_SDK_PATH, None)).resolve()
# build some reuseable path parts
_PROJECT_ASSET_PATH = Path(_O3DE_PROJECT_PATH).resolve()
_PROJECT_ASSETS_PATH = Path(_O3DE_PROJECT_PATH, 'Materials').resolve()
_PROJECT_ASSET_PATH = Path(_PATH_O3DE_PROJECT).resolve()
_PROJECT_ASSETS_PATH = Path(_PATH_O3DE_PROJECT, 'Materials').resolve()
# To Do: figure out a proper way to deal with Lumberyard game projects
_GEM_MATPLAY_PATH = Path(_O3DE_DEV, 'Gems', 'AtomContent', 'AtomMaterialPlayground').resolve()
@@ -150,9 +150,9 @@ _SUB_LIBRARY_PATH = Path(_GEM_SUBSOURCELIBRARY, 'Assets', 'SubstanceSource', 'Li
# path to watcher script
_WATCHER_SCRIPT_PATH = Path(_DCCSI_SDK_PATH, 'substance', 'builder', 'watchdog', '__init__.py').resolve()
_TEX_RNDR_PATH = Path(_O3DE_PROJECT_PATH, 'Materials', 'Substance').resolve()
_MAT_OUTPUT_PATH = Path(_O3DE_PROJECT_PATH, 'Materials', 'Substance').resolve()
_SBSAR_COOK_PATH = Path(_O3DE_PROJECT_PATH, 'Materials', 'Substance').resolve()
_TEX_RNDR_PATH = Path(_PATH_O3DE_PROJECT, 'Materials', 'Substance').resolve()
_MAT_OUTPUT_PATH = Path(_PATH_O3DE_PROJECT, 'Materials', 'Substance').resolve()
_SBSAR_COOK_PATH = Path(_PATH_O3DE_PROJECT, 'Materials', 'Substance').resolve()
# -------------------------------------------------------------------------
@@ -171,12 +171,12 @@ class Window(QtWidgets.QDialog):
# we should really init non-Qt stuff and set things up as properties
if project_path is None:
self.project_path = str(_O3DE_PROJECT_PATH)
self.project_path = str(_PATH_O3DE_PROJECT)
else:
self.project_path = Path(project_path)
if default_material_path is None:
self._default_material_path = Path(_DCCSIG_PATH,
self._default_material_path = Path(_PATH_DCCSIG,
'sdk',
'substance',
'resources',
@@ -672,7 +672,7 @@ class Window(QtWidgets.QDialog):
# if you want relative paths here is a better way
# first of all, assume we know the project we are in
#_O3DE_PROJECT_PATH
#_PATH_O3DE_PROJECT
texture_output_path = Path(self.texRenderPathComboBox.currentText()).resolve()
rel_tex_path = None
@@ -928,7 +928,7 @@ def substance_builder_launcher():
_LOGGER.info('file: {}'.format(__file__)) # *might* come back relative
# we should ensure we know the abs path
qss_filepath = Path(_DCCSIG_PATH).resolve().absolute()
qss_filepath = Path(_PATH_DCCSIG).resolve().absolute()
qss_filepath = Path(qss_filepath, 'SDK', 'substance', 'builder',
'ui', 'stylesheets', 'LYstyle.qss').resolve().absolute()
window.setStyleSheet(qss_filepath.read_text())
@@ -67,11 +67,11 @@ from collections import OrderedDict
_SYNTH_ENV_DICT = OrderedDict()
_SYNTH_ENV_DICT = azpy.synthetic_env.stash_env(_SYNTH_ENV_DICT)
# grab a specific path from the base_env
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_DCCSIG_PATH]
_O3DE_PROJECT_PATH = _SYNTH_ENV_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_PATH_DCCSIG]
_PATH_O3DE_PROJECT = _SYNTH_ENV_DICT[ENVAR_PATH_O3DE_PROJECT]
# build some reuseable path parts
_PATH_MOCK_ASSETS = Path(_O3DE_PROJECT_PATH, 'Assets').norm()
_PATH_MOCK_ASSETS = Path(_PATH_O3DE_PROJECT, 'Assets').norm()
_PATH_MOCK_SUBLIB = Path(_PATH_MOCK_ASSETS, 'SubstanceSource').norm()
_PATH_MOCK_SBS = Path(_PATH_MOCK_SUBLIB, 'sbs').norm()
@@ -87,11 +87,11 @@ from collections import OrderedDict
_SYNTH_ENV_DICT = OrderedDict()
_SYNTH_ENV_DICT = azpy.synthetic_env.stash_env(_SYNTH_ENV_DICT)
# grab a specific path from the base_env
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_DCCSIG_PATH]
_O3DE_PROJECT_PATH = _SYNTH_ENV_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_PATH_DCCSIG]
_PATH_O3DE_PROJECT = _SYNTH_ENV_DICT[ENVAR_PATH_O3DE_PROJECT]
# build some reuseable path parts
_PATH_MOCK_ASSETS = Path(_O3DE_PROJECT_PATH, 'Assets').norm()
_PATH_MOCK_ASSETS = Path(_PATH_O3DE_PROJECT, 'Assets').norm()
_PATH_MOCK_SUBLIB = Path(_PATH_MOCK_ASSETS, 'SubstanceSource').norm()
_PATH_MOCK_SBS = Path(_PATH_MOCK_SUBLIB, 'sbs').norm()
@@ -65,11 +65,11 @@ from collections import OrderedDict
_SYNTH_ENV_DICT = OrderedDict()
_SYNTH_ENV_DICT = azpy.synthetic_env.stash_env(_SYNTH_ENV_DICT)
# grab a specific path from the base_env
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_DCCSIG_PATH]
_O3DE_PROJECT_PATH = _SYNTH_ENV_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_PATH_DCCSIG]
_PATH_O3DE_PROJECT = _SYNTH_ENV_DICT[ENVAR_PATH_O3DE_PROJECT]
# build some reuseable path parts
_PATH_MOCK_ASSETS = Path(_O3DE_PROJECT_PATH, 'Assets').norm()
_PATH_MOCK_ASSETS = Path(_PATH_O3DE_PROJECT, 'Assets').norm()
_PATH_MOCK_SUBLIB = Path(_PATH_MOCK_ASSETS, 'SubstanceSource').norm()
_PATH_MOCK_SBS = Path(_PATH_MOCK_SUBLIB, 'sbs').norm()
@@ -189,16 +189,16 @@ if __name__ == "__main__":
from azpy import synthetic_env
_SYNTH_ENV_DICT = synthetic_env.stash_env()
from azpy.constants import ENVAR_DCCSIG_PATH
from azpy.constants import ENVAR_O3DE_PROJECT_PATH
from azpy.constants import ENVAR_PATH_DCCSIG
from azpy.constants import ENVAR_PATH_O3DE_PROJECT
# grab a specific path from the base_env
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_DCCSIG_PATH]
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_PATH_DCCSIG]
# use DCCsi as the project path for this test
_O3DE_PROJECT_PATH = _PATH_DCCSI
_PATH_O3DE_PROJECT = _PATH_DCCSI
_PROJECT_ASSETS_PATH = Path(_O3DE_PROJECT_PATH, 'Assets').resolve()
_PROJECT_ASSETS_PATH = Path(_PATH_O3DE_PROJECT, 'Assets').resolve()
_PROJECT_MATERIALS_PATH = Path(_PROJECT_ASSETS_PATH, 'Materials').resolve()
# this will combine two parts into a single path (object)
@@ -66,11 +66,11 @@ from collections import OrderedDict
_SYNTH_ENV_DICT = OrderedDict()
_SYNTH_ENV_DICT = azpy.synthetic_env.stash_env(_SYNTH_ENV_DICT)
# grab a specific path from the base_env
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_DCCSIG_PATH]
_O3DE_PROJECT_PATH = _SYNTH_ENV_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_DCCSI = _SYNTH_ENV_DICT[ENVAR_PATH_DCCSIG]
_PATH_O3DE_PROJECT = _SYNTH_ENV_DICT[ENVAR_PATH_O3DE_PROJECT]
# build some reuseable path parts
_PATH_MOCK_ASSETS = Path(_O3DE_PROJECT_PATH, 'Assets').norm()
_PATH_MOCK_ASSETS = Path(_PATH_O3DE_PROJECT, 'Assets').norm()
_PATH_MOCK_SUBLIB = Path(_PATH_MOCK_ASSETS, 'SubstanceSource').norm()
_PATH_MOCK_SBS = Path(_PATH_MOCK_SUBLIB, 'sbs').norm()
@@ -17,9 +17,9 @@ import time
# -------------------------------------------------------------------------
# we don't have access yet to the DCCsi Lib\site-packages
# (1) this will give us import access to dccsi and azpy import
_DCCSIG_PATH = os.getenv('DCCSIG_PATH', os.getcwd()) # always?, doubtful
_PATH_DCCSIG = os.getenv('PATH_DCCSIG', os.getcwd()) # always?, doubtful
# ^^ this assume that the \DccScriptingInterface is the cwd!!! (launch there)
site.addsitedir(_DCCSIG_PATH)
site.addsitedir(_PATH_DCCSIG)
# Lumberyard extensions
from azpy.env_bool import env_bool
@@ -72,7 +72,7 @@ from collections import OrderedDict
_SYNTH_ENV_DICT = OrderedDict()
_SYNTH_ENV_DICT = azpy.synthetic_env.stash_env(_SYNTH_ENV_DICT)
_O3DE_DEV = _SYNTH_ENV_DICT[ENVAR_O3DE_DEV]
_O3DE_PROJECT_PATH = _SYNTH_ENV_DICT[ENVAR_O3DE_PROJECT_PATH]
_PATH_O3DE_PROJECT = _SYNTH_ENV_DICT[ENVAR_PATH_O3DE_PROJECT]
# -------------------------------------------------------------------------
@@ -90,7 +90,7 @@ class MyHandler(PatternMatchingEventHandler):
"""
self.outputName = event.src_path.split(".sbsar")[0].split("/")[-1]
self.outputCookPath = event.src_path.split(self.outputName)
self.outputRenderPath = Path(_O3DE_PROJECT_PATH, 'Assets', 'Textures', 'Substance').norm()
self.outputRenderPath = Path(_PATH_O3DE_PROJECT, 'Assets', 'Textures', 'Substance').norm()
_LOGGER.debug(self.outputCookPath, self.outputName, self.outputRenderPath)
pysbs_batch.sbsrender_info(input=event.src_path)