Книга: Написание скриптов для Blender 2.49

От нодов к Pynodes

От нодов к Pynodes

Сила системы Нодов Блендера проистекает не только из её многочисленных встроенных типов нодов, и множества способов, которыми эти ноды могут быть связаны, но также из того, что мы можем написать новые ноды на Питоне, которые можно связывать так же, как обычные ноды.

Для Pynodes нужен способ получать доступ к информации, передаваемой входными сокетами и способ посылать рассчитанные результаты в выходные сокеты. Понятие нода и сокетов структурировано в соответствии с объектно-ориентированной моделью. Давайте бросим первый взгляд на небольшой пример кода, чтобы доказать, что это не страшно  (ветераны объектно-ориентированного программирования: поглядите в другую сторону или  смотрите сквозь пальцы, чтобы просто разобраться с определением класса из следующего примера):

from Blender import Node
class MyNode(Node.Scripted):
   def __init__(self, sockets):
      sockets.input  = [Node.Socket('Coords',
                           val= 3*[1.0])]
      sockets.output = [Node.Socket('Color',
                           val = 4*[1.0])]
   def __call__(self):
      x,y,z = self.input.Coords
      self.output.Color = [abs(x),abs(y),abs(z),1.0]

Прежде чем мы посмотрим на этот код подробно, попробуем его в Блендере, чтобы посмотреть, как он работает на практике:

1. Откройте новый файл в текстовом редакторе и дайте ему значимое имя.

2. Скопируйте код примера.

3. Создайте простую сцену, например, простую UV-сферу в начале координат с парой ламп и камерой.

4. Назначьте Нодовый материал сфере как обычно.

5. Наконец, добавьте динамический (Dinamic) нод в Нодовом редакторе (Add | Dynamic) и выберите имя файла, который Вы отредактировали, щелчком на кнопке выбора динамического нода и выбрав файл из списка.

Результирующая сеть нодов (часто называемая макаронами (noodle)), может выглядеть похоже на это:


Если Вы рендерите сферу, результатом будет красочный шар, похожий на виджет выбора цвета.

Теперь вернёмся к коду.

На первой строке мы импортируем модуль Node из Блендера, поскольку мы создаём новый тип нода, но основное его поведение уже определено в модуле Node.

Затем мы определяем класс MyNode, подкласс Node.Scripted, который будет вести себя просто подобно ноду Scripted, за исключением тех частей, которые мы переопределим.

Затем, мы определяем функцию __init__(), которая будет вызваться первый раз при создании этого типа Pynode в редакторе нодов, или всякий раз, когда мы щелкаем на кнопку Update. Когда это случается, Блендер передаёт два аргумента в эту функцию: self, ссылку на нод, который мы используем, и sockets, ссылку на объект, которая будет указывать на наши списки входных и выходных сокетов. С их помощью ноды в редакторе нодов получают данные на вход или посылают их дальше.

На выделенной строке мы определяем список определений входных сокетов; в нашем случае только один с названием Coords. Это   -  векторный   вход,   поскольку инициализируется списком трех чисел с плавающей точкой, который определяет значение по умолчанию, если этот входной сокет не подключен к другому ноду. Векторные сокеты представлены как синие круги в нодовом редакторе.

Другие типы входного сокета также возможны и этот тип определяется величиной аргумента val. Выходные сокеты определяются так же. Список трех чисел с плавающей точкой определяет векторный сокет, список четырех чисел - цветовой сокет (с красным, зеленым, синим, и альфа компонентом), а сокет, представляющий простое значение, как, например, интенсивность, инициализируется единственным числом. Заметьте, что мы не можем отличать входы, которые должны заполняться пользователем от тех, что должны быть подключены к другому ноду. Мы используем входные сокеты для них обоих и должны подтверждать их предполагаемое использование. К настоящему времени, нет средства добавлять кнопки или другие управляющие элементы на Pynode.

Нашему примеру Pynode нужен также выход, так что мы определяем список, состоящий из единственного выходного сокета называемого Color. У него есть четыре величины с плавающей точкой по-умолчанию, определяющих красную, зеленую, синюю, и альфа величины соответственно.

Затем мы определяем функцию __call__(), которая вызывается всякий раз при затенении пикселя. Она не принимает никаких аргументов, но self - это ссылка на текущий нод, которая используется в следующих строках для получения доступа к входному и выходному сокетам.

В теле функции __call__() мы извлекаем три компонента из входного сокета с названием Coords и назначаем их переменным, которые легко запомнить. Наконец, мы создаем новый четырехкомпонентный список, который представляет наш рассчитанный цвет и назначаем его выходному сокету с названием Color.

Это - основа для определения простых текстур, но существует больше информации, пригодной для нода (как мы увидим в следующих разделах), так что мы сможем разработать несколько красивых продвинутых эффектов. В следующем разделе мы создадим чуть более сложный нод, который формируется на тех же принципах, что мы видели раньше, но создаёт более полезные узоры.

Оглавление книги

Оглавление статьи/книги

Генерация: 1.611. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз