|
|
|
import contextlib |
|
import threading |
|
from maya import cmds, utils |
|
|
|
|
|
@contextlib.contextmanager |
|
def maintained_selection(): |
|
try: |
|
cmds.ls(selection=True) |
|
yield |
|
finally: |
|
cmds.select(clear=True) |
|
|
|
|
|
@contextlib.contextmanager |
|
def attribute_locks(attrs, lock): |
|
original = [(attr, cmds.getAttr(attr, lock=True)) for attr in attrs] |
|
try: |
|
for attr in attrs: |
|
cmds.setAttr(attr, lock=lock) |
|
yield |
|
finally: |
|
for attr, value in original: |
|
cmds.setAttr(attr, lock=value) |
|
|
|
|
|
@contextlib.contextmanager |
|
def attribute_values(attr_values): |
|
original = [(attr, cmds.getAttr(attr)) for attr in attr_values] |
|
try: |
|
for attr, value in attr_values.items(): |
|
cmds.setAttr(attr, value) |
|
yield |
|
finally: |
|
for attr, value in original: |
|
cmds.setAttr(attr, value) |
|
|
|
|
|
# 1. This was actually an unknown node that was generated via Redshift |
|
# from the artist who has the plugin loaded, but the next artist who |
|
# takes over does not have that plugin so became referencing unknown |
|
# node. |
|
# And the unknow node was required to be deleted for publish. |
|
cmds.delete("sharedUnknownNode") |
|
|
|
# 2. We need at least 12 attributes to cause the crash |
|
node_attrs = {} |
|
for i in range(12): |
|
node = cmds.group(world=True, empty=True) |
|
node_attrs[node + ".tx"] = 0 |
|
|
|
|
|
def run(): |
|
# 3. This step was actually processing file texture nodes, changing |
|
# file path, colorspace.. and other attributes. |
|
# And ensure the attribute not locked before setting them. |
|
with contextlib.nested( |
|
maintained_selection(), |
|
attribute_locks(node_attrs.keys(), lock=False), |
|
attribute_values(node_attrs), |
|
): |
|
cmds.select(clear=True) |
|
|
|
|
|
# Only cause the crash in other thread, the above script will not crash if |
|
# executed in main thread. |
|
thd = threading.Thread(target=lambda: utils.executeInMainThreadWithResult(run)) |
|
thd.start() |
|
|
|
|
|
# Once the above thread completed, save the file will crash Maya. |
|
# cmds.file(rename="/any/path/output.ma") |
|
# cmds.file(save=True, force=True) # <------CRASH |