Написание скриптов для Blender 2.49
Шрифт:
• Размер строкового свойства ограничен 127 символами, и этого слишком мало, чтобы сохранить даже один кадр с координатами вершин для меша средних размеров
Несмотря на недостатки использования реестра, мы будем использовать его для разработки двух функций - одну для сохранения координат вершин для данного номера кадра, и одну для извлечения этих данных и применения их к вершинам меша. Сначала мы определяем вспомогательную функцию ckey, которая возвращает ключ для использования с функциями реестра, исходя из имени объекта, чьи данные меша мы хотим кешировать:
Не перепутайте реестр Блендера с реестром Windows. Оба предназначены для аналогичных целей - обеспечить устойчивую память для всех типов данных, но это разные объекты. Фактические данные в реестре Блендера, которые записаны на диск, по умолчанию находятся в каталоге .blender/scripts/bpydata/config/, и это местоположение может быть изменено заданием параметра datadir с помощью Blender.Set.
Наша функция storemesh принимает в качестве аргументов объект и номер кадра. Первым действием нужно извлечь координаты вершин из данных меша, связанных с объектом. Затем она извлекает все данные, сохранённые в реестре Блендера для объекта, с которым мы имеем дело, и мы передаем дополнительный параметр True (Истина), указывающий, что если нет данных в памяти, GetKey должна проверить их наличие на диске. Если совсем нет никаких данных, сохранённых для нашего объекта, GetKey возвращает None, и в этом случае мы инициализируем наш кеш пустым словарём.
Впоследствии, мы сохраняем координаты нашего меша в этом словаре, проиндексированном номером кадра (выделено в следующем куске кода). Мы преобразуем этот номер кадра из целого в строку, которую нужно использовать в качестве фактического ключа, поскольку функция Блендера SetKey принимает ключи строкового типа при сохранении данных реестра на диск, и вызовет исключение, если она сталкивается с целым. Последняя строка снова вызывает SetKey с дополнительным аргументом True, чтобы указать, что мы хотим сохранять данные также на диск.
Функция retrievemesh принимает в качестве аргументов объект и номер кадра. Если она находит кешированные данные для данного объекта и кадра, она назначает загруженные координаты вершинам в меше. Сначала мы определим два новых исключения, означающие некоторые специфические ошибочные состояния, с которыми retrievemesh может столкнуться:
retrievemesh вызовет исключение NoSuchProperty, если объект не имеет связанных кешированных данных меша, и исключение NoFrameCached если данные присутствуют, но не для указанного кадра. Выделенная строка в следующем коде заслуживает некоторого внимания. Мы выбираем связанные данные меша у объекта с mesh=True. Это даст завёрнутый (wrapped) меш, а не копию, так что любые данные вершин, к которым мы получаем доступ, или изменяем, ссылаются на фактические данные. Также, мы сталкиваемся со встроенный функцией Питона zip, которая принимает два списка и возвращает список, состоящий из кортежей двух элементов, по одному из каждого списка. Это эффективно позволяет просматривать два списка параллельно. В нашем случае, эти списки - список вершин и список координат и мы просто преобразуем эти координаты в векторы и назначаем их в атрибут co каждой вершины:
Чтобы завершить наш набор функций кеша, мы определяем функцию clearcache, которая пытается удалять данные в реестре, связанные с нашим объектом. Конструкция try … except … обеспечивает, чтобы при отсутствии сохранённых данных, действие было молча проигнорировано:
Наш скрипт будет использоваться не только как скриптсвязь, связанная с объектом, но он также будет использоваться автономно (по нажатию Alt + P в текстовом редакторе, например), чтобы обеспечить пользователя средствами для идентификации цели, которая создаст отпечаток, чтобы очищать кеш, и, чтобы ассоциировать скриптсвязь с активным объектом. При использовании таким образом, он обеспечивает конечного пользователя несколькими управляющими меню, показанными на скриншотах. Первый показывает возможные действия:
Второй скриншот показывает всплывающее меню с предложением выбрать объект из списка Меш– объектов, из которого пользователь может выбрать, чем создавать отпечаток:
Мы сначала определяем вспомогательную функцию, которая будет использована выпадающим меню, обеспечивающим пользователя выбором Меш– объектов, для использования в качестве цели при создании отпечатка. getmeshobjects принимает аргумент scene и возвращает список имен всех Меш– объектов. Как показано на скриншоте, список объектов-целей включает в том числе исходный объект. Хотя это законно, но вряд ли очень полезно:
Само меню осуществляется функцией targetmenu, определенной следующим образом: