У меня есть код, который выполняет пакетную операцию над файлами в Maya. Фактическая реализация не важна, просто знайте, что она получает список путей к файлам, Maya открывает файлы, а затем операция выполняется с каждым файлом по очереди.
В случаях, когда ссылка по какой-либо причине недействительна (например, неверный путь), я хочу прервать загрузку всей этой сцены и перейти к следующей в списке пакетов.
Глядя на другие вопросы на этом сайте и в других местах, я мог видеть только пользователей, спрашивающих, как запрашивать ссылки. У меня уже есть разумная функция для этого, это то, что делать после того, как эта функция вернет недопустимый ссылочный путь, который ставит меня в тупик.
Разрешение недопустимых путей ссылок исторически выполнялось вручную через всплывающее окно, однако в больших пакетах постоянное присмотр за экземпляром Maya невозможно. Также не подавляется само всплывающее окно, так как я полагаю, что это все равно откроет файл и запустит пакетную операцию на сцене, пока она находится в недопустимом состоянии.
Я просмотрел модуль maya cmds
python, чтобы попробовать и не загружать ссылки, однако при использовании флага loadReferenceDepth
вместе с cmds.file
я все еще получаю всплывающее окно:
cmds.file(r'c:\path\to\file.ma', o=1, f=1, lrd='none') #invalid ref popup during file cmd
Второй подход заключался в том, чтобы изучить maya open API. и зарегистрируйте обратный вызов в событии до открытия. Приведенный ниже код функционально аналогичен настройке пакета:
import maya.OpenMaya as OpenM
batchFileList = [r"c:\path\to\file.ma", r"c:\path\to\file2.ma"]
def _test_raise_exception(arg0, arg1, arg2):
#pretending that a file ref failed below. Ref path validation code would go here.
print '\n'*5+'Test Logging'+'\n'*5
return False
cId = OpenM.MSceneMessage.addCheckFileCallback(OpenM.MSceneMessage.kBeforeOpenCheck, _test_raise_exception)
for file_ in batchFileList:
try:
rv = cmds.file(file_, o=1)
#do stuff to the maya scene here
except:
#something didn't validate on load, except and skip, logging the occurrence.
print 'load cancelled'
OpenM.MSceneMessage.removeCallback(cId)
Однако несмотря на то, что addCheckFileCallback
указывает, что если функция обратного вызова возвращает False
операция прерывается, файл все равно загружается.
Точно так же замена return False
на raise RuntimeError
не позволяет мне поймать исключение. Вместо этого cmds.file
завершается и выводит в журнал только небольшое сообщение о том, что «обратный вызов python не выполнен». В документах по открытому API Python говорится, что привязки предпочитают исключения кодам возврата MStatus хотя, поэтому я ожидал, что это сработает.
Мы удалили класс MStatus. Исключения Python должны использоваться вместо MStatus.
Я что-то упустил здесь? Должен быть способ сделать это. Создание очень грубого синтаксического анализатора .ma — еще один вариант, но это означало бы отказ от поддержки файлов .mb, чего я не хочу делать.
Спасибо за ваше время!