Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit 11be79b

Browse files
authored
Merge pull request #30 from annatisch/bug-fixes
Bug fixes
2 parents 6bc12de + 8483ce4 commit 11be79b

File tree

7 files changed

+20165
-81
lines changed

7 files changed

+20165
-81
lines changed

CHANGES.txt

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11

2+
unreleased v0.17.0
3+
------------------
4+
- Restructured dependency installation for wider compatibility:
5+
get_pip.py is now packaged with the plugin.
6+
- Fixed unicode filename errors in thumbnail generation.
7+
- Fixed detection of Bifrost caches as assets.
8+
29
2017.10.16 v0.16.0
310
------------------
411
- Asset path redirection updates

azure_batch_maya/modules/arnold_renderer.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
from default import AzureBatchRenderJob, AzureBatchRenderAssets
1919

2020
try:
21-
str = unicode
21+
str_type = unicode
2222
except NameError:
23-
pass
23+
str_type = str
2424

2525

2626
class ArnoldRenderJob(AzureBatchRenderJob):
@@ -40,7 +40,7 @@ def settings(self):
4040
if self.scene_name == '':
4141
job_name = "Untitled"
4242
else:
43-
job_name = str(os.path.splitext(os.path.basename(self.scene_name))[0])
43+
job_name = str_type(os.path.splitext(os.path.basename(self.scene_name))[0])
4444
file_prefix = cmds.getAttr("defaultRenderGlobals.imageFilePrefix")
4545
if file_prefix:
4646
file_prefix = os.path.split(file_prefix)[1]
@@ -59,7 +59,7 @@ def settings(self):
5959
self.logging = self.display_menu("Logging: ", self.log_levels, log_level+1)
6060

6161
def get_title(self):
62-
return str(cmds.textField(self.job_name, query=True, text=True))
62+
return str_type(cmds.textField(self.job_name, query=True, text=True))
6363

6464
def render_enabled(self):
6565
return True
@@ -147,9 +147,12 @@ def renderer_assets(self):
147147

148148
def setup_script(self, script_handle, pathmap, searchpaths):
149149
search_path = ';'.join(searchpaths).encode('utf-8')
150-
script_handle.write("setAttr -type \"string\" defaultArnoldRenderOptions.procedural_searchpath \"{}\";\n".format(search_path))
151-
script_handle.write("setAttr -type \"string\" defaultArnoldRenderOptions.plugin_searchpath \"{}\";\n".format(search_path))
152-
script_handle.write("setAttr -type \"string\" defaultArnoldRenderOptions.texture_searchpath \"{}\";\n".format(search_path))
150+
procedural_searchpath = str("setAttr -type \"string\" defaultArnoldRenderOptions.procedural_searchpath \"{}\";\n").format(search_path)
151+
plugin_searchpath = str("setAttr -type \"string\" defaultArnoldRenderOptions.plugin_searchpath \"{}\";\n").format(search_path)
152+
texture_searchpath = str("setAttr -type \"string\" defaultArnoldRenderOptions.texture_searchpath \"{}\";\n").format(search_path)
153+
script_handle.write(procedural_searchpath)
154+
script_handle.write(plugin_searchpath)
155+
script_handle.write(texture_searchpath)
153156

154157
# This kind of explicit asset re-direct is kinda ugly - so far
155158
# it only seems to be needed on aiImage nodes, which appear to

azure_batch_maya/plug-in/AzureBatch.py

+34-23
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
INSTALL_DIR = os.path.normpath(
3232
os.path.join(cmds.internalVar(userScriptDir=True), 'azure-batch-libs'))
33-
sys.path.append(INSTALL_DIR)
33+
sys.path.insert(0, INSTALL_DIR)
3434

3535
REQUIREMENTS = {
3636
"pathlib==1.0.1": "pathlib",
@@ -47,7 +47,7 @@
4747
"azure-batch-extensions==1.0.1": "azure.batch_extensions"
4848
}
4949

50-
VERSION = "0.16.0"
50+
VERSION = "0.17.0"
5151
EULA_PREF = "AzureBatch_EULA"
5252
SHELF_FILE = "shelf_AzureBatch.mel"
5353
cmd_name = "AzureBatch"
@@ -269,6 +269,7 @@ def set_environment(plugin_path):
269269
sys.path.append(modpath)
270270
sys.path.append(srcpath)
271271
sys.path.append(os.path.join(srcpath, "ui"))
272+
sys.path.append(tolpath)
272273

273274
script_dirs = os.environ["MAYA_SCRIPT_PATH"] + os.pathsep
274275
os.environ["AZUREBATCH_ICONS"] = AzureBatchSetup.clean(icnpath)
@@ -349,7 +350,7 @@ def dependency_installed(package, namespace):
349350
return True
350351

351352

352-
def install_pkg(package):
353+
def install_pkg(pip, package):
353354
"""Install the specified package by shelling out to pip.
354355
:param str package: A pip-formatted package reference.
355356
@@ -358,9 +359,7 @@ def install_pkg(package):
358359
"""
359360
if not os.path.isdir(INSTALL_DIR):
360361
os.makedirs(INSTALL_DIR)
361-
pip_cmds = ['mayapy', os.path.join(INSTALL_DIR, 'pip'),
362-
'install', package,
363-
'--target', INSTALL_DIR]
362+
pip_cmds = ['mayapy', pip, 'install', package, '--target', INSTALL_DIR]
364363
print(pip_cmds)
365364
installer = subprocess.Popen(pip_cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
366365
installer.wait()
@@ -370,7 +369,7 @@ def install_pkg(package):
370369
raise RuntimeError("Failed to install package: {}".format(package))
371370

372371

373-
def install_namespace_pkg(package, namespace):
372+
def install_namespace_pkg(pip, package, namespace):
374373
"""Azure packages have issues installing one by one as they don't
375374
unpackage correctly into the namespace directory. So we have to install
376375
to a temp directory and move it to the right place.
@@ -381,10 +380,7 @@ def install_namespace_pkg(package, namespace):
381380
temp_target = os.path.join(INSTALL_DIR, 'temp-target')
382381
if not os.path.isdir(temp_target):
383382
os.makedirs(temp_target)
384-
pip_cmds = ['mayapy', os.path.join(INSTALL_DIR, 'pip'),
385-
'install', package,
386-
'--no-deps',
387-
'--target', temp_target]
383+
pip_cmds = ['mayapy', pip, 'install', package, '--no-deps', '--target', temp_target]
388384
print(pip_cmds)
389385
installer = subprocess.Popen(pip_cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
390386
installer.wait()
@@ -447,25 +443,39 @@ def initializePlugin(obj):
447443

448444
print("Attempting to install dependencies via Pip.")
449445
try:
450-
install_script = os.path.normpath(os.path.join( os.environ['AZUREBATCH_TOOLS'], 'install_pip.py'))
451-
installer = subprocess.Popen(["mayapy", install_script, '--target', INSTALL_DIR],
452-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
453-
installer.wait()
454-
if installer.returncode != 0:
446+
import pip
447+
if StrictVersion(pip.__version__) < StrictVersion("9.0.0"):
448+
print("Found out-of-date pip ({}) - attempting to upgrade.".format(pip.__version__))
449+
raise ImportError
450+
print("Found pip installed, version: {}".format(pip.__version__))
451+
pip_location = os.path.dirname(pip.__file__)
452+
except ImportError:
453+
try:
454+
import getpip
455+
print("Running getpip command")
456+
install_script = getpip.__file__
457+
args = ["mayapy", install_script, "--target", INSTALL_DIR]
458+
print(args)
459+
installer = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
460+
installer.wait()
455461
print(installer.stdout.read())
456462
print(installer.stderr.read())
457-
raise RuntimeError("Failed to install pip")
458-
except BaseException as exp:
459-
print("Failed to install Pip. Please install dependencies manually to continue.")
460-
raise
463+
if installer.returncode != 0:
464+
raise RuntimeError("Failed to install pip")
465+
except ImportError as e:
466+
print("Unable to load getpip")
467+
raise
468+
else:
469+
print("Getpip complete")
470+
pip_location = os.path.join(INSTALL_DIR, "pip")
461471
try:
462-
print("Installing dependencies")
472+
print("Installing dependencies using {}".format(pip_location))
463473
for package in missing_libs:
464474
if package in NAMESPACE_PACKAGES:
465475
package_path = NAMESPACE_PACKAGES[package].split('.')
466-
install_namespace_pkg(package, os.path.join(*package_path))
476+
install_namespace_pkg(pip_location, package, os.path.join(*package_path))
467477
else:
468-
install_pkg(package)
478+
install_pkg(pip_location, package)
469479
shutil.copy(os.path.join(INSTALL_DIR, 'azure', '__init__.py'), os.path.join(INSTALL_DIR, 'azure', 'mgmt', '__init__.py'))
470480
except:
471481
error = "Failed to install dependencies - please install manually"
@@ -521,6 +531,7 @@ def uninitializePlugin(obj):
521531
try:
522532
sys.path.extend(os.environ["AZUREBATCH_SCRIPTS"].split(os.pathsep))
523533
sys.path.append(os.environ['AZUREBATCH_MODULES'])
534+
sys.path.append(os.environ['AZUREBATCH_TOOLS'])
524535
except KeyError as e:
525536
print("Couldn't find Azure Batch environment, setting up now...")
526537
setup_module()

azure_batch_maya/scripts/assets.py

+31-15
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,36 @@ def _get_references(self):
500500
self._log.debug("Found {0} references.".format(len(assets)))
501501
return assets
502502

503+
def _get_bifrost_caches(self, assets):
504+
start = maya.start_frame()
505+
end = maya.end_frame()
506+
step = maya.frame_step()
507+
caches = []
508+
cache_paths = []
509+
containers = maya.get_list(type="bifrostContainer")
510+
for container in containers:
511+
for cache_type in ['Foam', 'Guide', 'Liquid', 'LiquidMesh', 'Solid']:
512+
try:
513+
enabled = maya.get_attr(container + ".enable{}Cache".format(cache_type))
514+
except ValueError:
515+
continue
516+
if enabled:
517+
cache_name = maya.get_attr(container + ".{}CacheFileName".format(cache_type.lower()))
518+
cache_path = maya.get_attr(container + ".{}CachePath".format(cache_type.lower()))
519+
cache_paths.append(os.path.join(cache_path, cache_name))
520+
self.pathmaps[cache_path] = utils.get_remote_file_path(cache_path)
521+
self.pathmaps[cache_paths[-1]] = utils.get_remote_file_path(cache_paths[-1])
522+
cache_paths = list(set(cache_paths))
523+
for cache_path in cache_paths:
524+
for frame in range(start, end+step, step):
525+
frame_name = "*.{}.bif".format(str(frame).zfill(4))
526+
caches.extend(glob.glob(os.path.join(cache_path, "**", frame_name)))
527+
caches = list(set(caches))
528+
for cache in caches:
529+
asset = Asset(cache, assets, self.batch, self._log)
530+
if not asset.is_duplicate(assets):
531+
assets.append(asset)
532+
503533
def _get_caches(self):
504534
"""Gather data caches as assets. TODO: This needs to be tested.
505535
We generally only want to gather caches relevant to the current
@@ -518,20 +548,7 @@ def _get_caches(self):
518548
asset = Asset(cache_path, assets, self.batch, self._log)
519549
assets.append(asset)
520550

521-
containers = maya.get_list(type="bifrostContainer")
522-
for container in containers:
523-
if not maya.get_attr(container + ".enableDiskCache"):
524-
continue
525-
bifrost_path = maya.get_attr(container + ".cacheDir")
526-
bifrost_name = maya.get_attr(container + ".cacheName")
527-
start = maya.start_frame()
528-
end = maya.end_frame()
529-
step = maya.frame_step()
530-
for frame in range(start, end+step, step):
531-
cache_file = os.path.join(bifrost_path, bifrost_name + "_p." + str(frame).zfill(4) + ".bif")
532-
if os.path.exists(cache_file):
533-
asset = Asset(cache_file, assets, self.batch, self._log)
534-
assets.append(asset)
551+
self._get_bifrost_caches(assets)
535552
self._log.debug("Found {0} caches.".format(len(assets)))
536553
return assets
537554

@@ -769,4 +786,3 @@ def __call__(self, data, total):
769786
if int(progress) > self.progress:
770787
self.progress = int(progress)
771788
self.queue.put(lambda: self.command(progress))
772-

azure_batch_maya/scripts/tools/generate_thumbnails.py

+22-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
import os
77
import sys
88
import subprocess
9+
import traceback
10+
import shutil
11+
import string
912

13+
14+
printable = set(string.printable)
1015
SUPPORTED_FORMATS = { ".png", ".bmp", ".jpg", ".tga", ".exr", ".jpeg" }
1116

1217
if __name__ == '__main__':
@@ -39,27 +44,39 @@
3944
beauty_pass = [o for o in filtered if 'beauty' in o.lower()]
4045
if beauty_pass:
4146
input_file = beauty_pass[0]
42-
print("Using output '{}' for thumbnail generation.".format(input_file))
47+
try:
48+
filtered_input_file = input_file.encode('utf-8')
49+
except UnicodeDecodeError:
50+
temp_dir = os.path.join(cwd, 'temp_images')
51+
if not os.path.isdir(temp_dir):
52+
print("Creating directory for non-unicode outputs.")
53+
os.makedirs(temp_dir)
54+
filtered_input_file = filter(lambda x: x in printable, input_file)
55+
filtered_input_file = os.path.join(temp_dir, os.path.basename(filtered_input_file))
56+
shutil.copyfile(input_file, filtered_input_file)
57+
print("Using output '{}' for thumbnail generation.".format(filtered_input_file))
4358

4459
task_id = os.environ['AZ_BATCH_TASK_ID']
4560
output_file = os.path.join(thumb_dir, task_id + '_thumb.png')
46-
commands = ['convert', input_file, '-thumbnail', '200x150', output_file]
61+
commands = ['convert', filtered_input_file, '-thumbnail', '200x150', output_file]
4762
if os.name == 'nt':
4863
commands.insert(0, 'magick')
64+
4965
print("Running imagemagick: {}".format(commands))
5066
conversion = subprocess.Popen(commands, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
5167
conversion.wait()
5268
if conversion.returncode != 0:
5369
print("convert exited with code: {}".format(conversion.returncode))
5470
stdout, stderr = conversion.communicate()
55-
print("Stdout: {}".format(stdout))
56-
print("Stderr: {}".format(stderr))
71+
print(stdout)
72+
print(stderr)
5773
raise Exception("Thumbnail conversion failed.")
5874
if not os.path.isfile(output_file):
5975
raise Exception("No output file generated: {}".format(output_file))
6076
print("Successfully created thumbnail: {}".format(output_file))
6177
except Exception as exp:
62-
print(exp)
78+
exc_type, exc_value, exc_traceback = sys.exc_info()
79+
print("".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
6380
finally:
6481
print("Exiting with code: {}".format(render_exit_code))
6582
sys.exit(render_exit_code)

0 commit comments

Comments
 (0)