Michel Anders - Написание скриптов для Blender 2.49
Дополнительным преимуществом является то, что при этом можно легко упаковать дополнительные ресурсы в тот же .blend файл. Например, скрипт может использовать определенные материалы или текстуры, или Вы можете захотеть включить образец результата вашего скрипта. Единственная вещь, которая очень трудна - распространять таким образом модули Питона. Вы можете использовать оператор import, чтобы получить доступ к другим текстовым файлам, но это может вызвать проблемы (смотри Приложение B). Если у вас есть много кода и он организован в модулях, Вам и вашим пользователям, вероятно, будет лучше, если Вы станете распространять всё в виде ZIP-файла с ясными инструкциями, куда нужно распаковывать этот ZIP-файл.
Для Pynodes (или динамических нодов, смотри Главу 7) у вас нет выбора. Pynodes могут ссылаться только на код Питона, содержащийся в текстах внутри .blend файла. На самом деле это не является ограничением, так как эти Pynodes - неотъемлемая часть материала, а материалы Блендера могут распространяться только внутри .blend файла. Когда эти материалы привязаны или добавлены к связанным с ними нодами, то любые тексты, ассоциированные с Pynodes, привязываются или добавляются также, полностью скрываясь от конечного пользователя через материал, который на самом деле создаётся.
API БлендераПри разработке программ на Питоне в Блендере важно понимать, какие функции обеспечивается API, а тем более, какие нет. API, в основном, даёт доступ ко всем данным и предоставляет функции для манипуляции этими данными. К тому же, API обеспечивает разработчика функциями для рисования на экране и для взаимодействия с интерфейсом пользователя и оконной системой. Что API Блендера не предоставляет - это объектно-специфическую функциональность, кроме присваивания простых свойств, особенно недостаёт всех функций, манипулирующих мешами на уровне вершин, рёбер и граней, кроме как добавления или удаления их.
Это означает, что очень высокоуровневые или сложные задачи, как например, добавление модификатора subsurface на объект Меша или отображение диалога выбора файлов, так же просто, как написание одной строки кода, тогда как важнейшие и, видимо, простые функции, такие как подразбиение (subdividing) ребра или выбор рёберного цикла не доступны. Это не означает, что эти задачи нельзя выполнить, но мы должны программировать их самостоятельно. Так много примеров в этой книге ссылается на модуль, называемый Tools, который мы разработаем в следующих главах, и который будет содержать полезные инструменты от выдавливания граней до замыкания циклов. Где это необходимо и интересно, мы осветим код этого модуля, но, главным образом, он предназначен иметь запас всего того кода, который мог бы увести нас от наших целей.
Следующие разделы дают короткий и очень поверхностный обзор того, что доступно в API Блендера. Множество модулей и утилит будут занимать важное место в следующих главах, когда мы будем разрабатывать практические примеры. Этот обзор предназначен в качестве средства, которое поможет вам начать работу, если вы хотите узнать о некоторых функциональных возможностях и не знаете, где искать в первую очередь. Это далеко не полный список документации по API Блендера. Для этого, проверьте наиболее последнюю версию документации онлайн-API. Вы можете найти ссылку в Приложении A Ссылки и Ресурсы.
Модуль BlenderМодуль Blender служит в качестве контейнера для большинства других модулей и обеспечивает функциональность доступа к системной информации и выполнению общих задач.
Например, такая информация, как версия Блендер, которую вы используете, может быть извлечена с помощью функции Get():
import Blender
version = Blender.Get('version')
Включение всех внешних связанных файлов в .blend файл (в Блендере называемое упаковкой) или сохранение вашего текущего сеанса Блендера в .blend файл - другие примеры функциональности, выполняемой в модуле Блендера верхнего уровня:
import Blender
Blender.PackAll()
Blender.Save('myfile.blend')
Объекты БлендераКаждый тип объекта Блендера (Object, Mesh, Armature, Lamp, Scene и так далее), имеют связанный с ним модуль, который является подмодулем модуля Blender верхнего уровня. Каждый модуль поставляет функции для создания новых объектов и поиска объектов данного типа по имени. Каждый модуль имеет также определённый класс с тем же именем, который осуществляет функциональность, связанную с объектом Блендера.
Заметьте, что в Блендере есть сущности, не только непосредственно видимые на вашей сцене, как например, меши, лампы, или камеры - объекты, но также материалы, текстуры, системы частиц, и даже IPO, действия (Actions), миры, и сцены.
Множество других видов данных в Блендере - не являются Объектами в понимании Блендера (Вы не можете добавить их из другого .blend файла или перемещать их по вашей сцене), но это объекты в понимании Питона. Например, вершины, рёбра, и грани внутри меша выполнены в виде классов: Blender.Mesh.MVert, Blender.Mesh.MEdge, и Blender.Mesh.MFace соответственно.
Множество модулей также имеют свои собственные подмодули; например Модуль Blender.Scene предоставляет доступ к контексту рендера посредством модуля Blender.Scene.Render. Между прочим, этот модуль определяет класс RenderData, который позволяет Вам рендерить неподвижное изображение или анимацию.
Таким образом, с тем, что мы теперь знаем, можно нарисовать два немного различных родословных дерева объектов Блендера.
Первая иллюстрация показывает, какой тип объектов Блендера может содержаться внутри или ссылался на другой объект Блендера, в ней мы ограничимся менее абстрактными объектами:
Конечно, диаграмма выше сильно упрощена, так как мы пропустили некоторые менее важные объекты, и так как она иллюстрирует только единственный тип отношений. Конечно, существует намного больше типов отношений в сцене, такие как, например, отношения родитель-ребенок или ограничения (constraints).
Мы можем сопоставить предшествующую диаграмму со следующей, которая показывает в каком модуле какой тип объекта (класс) определён:
Различия весьма заметны, и их важно иметь в виду, особенно при поиске конкретной информации, содержащейся в документации Blender API. Не ожидайте, что найдёте информацию об объекте Curve (Кривая) в документации о модуле Blender.Object, поскольку кривая в Блендере является специфическим объектом Блендера; класс Curve определён и документирован в Модуле Blender.Curve. В целом можно ожидать, что документация класса находится в модуле тем же названием.
Модуль bpyКроме модуля Blender, есть другой модуль верхнего уровня, с именем bpy, который обеспечивает унифицированный путь доступа к данным. Он считается экспериментальным, но он стабилен и может быть использован как более интуитивный путь доступа к объектам. Например, если мы хотим иметь доступ к объекту с именем MyObject, обычным образом мы должны действовать приблизительно так:
import Blender
ob = Blender.Object.Get(name='MyObject')
С модулем bpy мы можем перефразировать это так:
import bpy
ob = bpy.data.objects['MyObject']
Так же, чтобы получить доступ к активному объекту сцены, мы могли бы написать это:
import Blender
scene = Blender.Scene.GetCurrent()
Что можно записать альтернативным способом:
import bpy
scene = bpy.data.scenes.active
Что из них предпочитать - дело вкуса. Модуль bpy будет единственным способом доступа к данным в ожидаемом Блендере 2.5, но изменения в Блендере 2.5 проникают глубже, чем просто такой способ доступа к данным, так не обманитесь поверхностным сходством имени модулей!
Рисование на экранеДоступ к системе окон Блендера предоставлен модулем Blender.Draw. Здесь Вы найдёте классы и функции для определения кнопок и управляющих меню, и пути взаимодействия с пользователем. Типы графических элементов, которые Вы можете отобразить, используя модуль Draw, ограничены обычно используемыми, и модификации невозможны.
Более передовые функции предоставлены в модуле Blender.BGL, который дает Вам доступ фактически ко всем функциям и константам OpenGL, позволяющим Вам рисовать на экране почти всё, что угодно, и позволить взаимодействовать с пользователем множеством различных способов.
УтилитыНаконец, есть множество модулей, включающих различную функциональность, которые не подходят для любой из предыдущих категорий: