Если вам надо передать в дефолтный оператор что-то из дефолтных типов, вы с высокой вероятностью столкнетесь с очень странной ошибкой:
TypeError: Converting py args to operator properties:
WM_OT_obj_import.files expected a each sequence member to be a dict for an RNA collection, not OperatorFileListElement
tl;dr Вместо передачи коллекции объектов нужного нам класса (напр. CollectionProperty(type=OperatorFileListElement)
), делаем словарь, в котором ключи соответствуют полям класса, и прямо так его передаём в оператор, который сам это всё соберёт.
Предыстория: мне понадобилось автоматизировать импорт большой кучи .OBJ
файлов из разных папок. Вызывать bpy.ops.wm.obj_import()
на каждый файл – сомнительная история, да и по скорости это заметно уступало импорту всех файлов в папке одним вызовом оператора.
Неожиданные проблемы начались при попытке передать список файлов files
, который согласно документации должен быть коллекцией OperatorFileListElement
.
Прицепить его можно «как обычно» к сцене:
from bpy.props import CollectionProperty
from bpy.types import OperatorFileListElement
bpy.types.Scene.filelist = CollectionProperty(
name="File Lists",
type=OperatorFileListElement,
)
Вот только при попытке вызвать bpy.ops.wm.obj_import(directory=root, files=context.scene.filelist)
вываливается та самая ошибка:
TypeError: Converting py args to operator properties:
WM_OT_obj_import.files expected a each sequence member to be a dict for an RNA collection, not OperatorFileListElement
Решений есть две штуки:
- Для оператора в UI
- Для оператора без UI
Если у нас вызов дефолтного оператора производится без интерфейса, то нужно сделать словарь, в котором ключи повторяют имена полей нужного нам класса, в данном случае у OperatorFileListElement(PropertyGroup) это просто name
, куда записывается имя нужного файла в directory
.
Затем этот словарь мы напрямую передаём параметром в оператор, который «собирает» нужные объекты сам.
filepath = bpy.data.filepath
search_path = os.path.dirname(filepath)
file_dicts = []
for root, dirs, files in os.walk(search_path):
for file in files:
file_dicts.append({'name': file})
if len(file_dicts) > 0:
bpy.ops.wm.obj_import(directory=root,
files=file_dicts)
file_dicts.clear()
Видимо expected a each sequence member to be a dict for an RNA collection то и значит, но понять это сходу довольно сложно.
Добавить комментарий