Michel Anders - Написание скриптов для Blender 2.49
Схема кода: leftright.py
Схематически мы предпримем следующие шаги:
1. Получить активный объект.
2. Проверить, что это - меш и получить меш-данные.
3. Добавить две новых группы вершин к объекту - Left и Right.
4. Для всех вершин в меше:
1. Посчитать вес
2. Если x-координата > 0:
3. Добавить индекс вершины и вес в группу вершин right
4. Если x-координата < 0:
5. Добавить индекс вершины и вес в группу вершин left
Для того, чтобы убедиться, что новая группа вершин пуста, мы проверяем, существует ли уже эта группа, и в этом случае удаляем из неё вершины. Эта проверка выделена в коде:
def leftright(me,maximum=1.0):
center=vec(0,0,0)
left =[]
right=[]
for v in me.verts:
weight = (v.co-center).length/maximum
if v.co.x > 0.0 :
right.append((v.index, weight))
elif v.co.x > 0.0 :
left.append((v.index, weight))
return left,right
if __name__ == "__main__":
try:
ob = Blender.Scene.GetCurrent().objects.active
me = ob.getData(mesh=True)
vgroups = me.getVertGroupNames()
if 'Left' in vgroups:
me.removeVertsFromGroup('Left')
else:
me.addVertGroup('Left')
if 'Right' in vgroups:
me.removeVertsFromGroup('Right')
else:
me.addVertGroup('Right')
left,right = leftright(me,vec(ob.getSize()).length)
for v,w in left:
me.assignVertsToGroup('Left',[v],
w,Blender.Mesh.AssignModes.ADD)
for v,w in right:
me.assignVertsToGroup('Right',[v],w,
Blender.Mesh.AssignModes.ADD)
Blender.Window.Redraw()
except Exception as e:
Blender.Draw.PupMenu('Error%t|'+str(e)[:80])
Полный скрипт доступен в файле leftright.py. Формуле, вычисляющей вес, возможно, нужно некоторое объяснение: для того, чтобы назначить максимальный вес 1.0 в точке, лежащей на наибольшем расстоянии от центра объекта, мы должны масштабировать максимально возможным расстоянием. Мы могли бы пройтись циклом по всем вершинам, чтобы сначала определить максимум, но здесь мы решаем аппроксимировать этот максимум корнем от суммы квадратов размеров. Это заведомо больше максимального расстояния, так что максимальный вес, назначаемый любой из вершин, вероятно, будет меньше чем 1.0. Тем не менее, получение размера - значительно быстрее, чем расчет точного максимума для больших мешей. Также заметьте, что мы вычисляем расстояние до центра (центр объекта в режиме просмотра вершин в меше - всегда в (0, 0, 0)).
Он может отличаться от того, что пользователь может воспринимать как центр меша. (Центр объекта отображается как розовая точка в Блендере и может быть изменён, чтобы лежать в средней позиции всех вершин, с помощью Object | Transform | Center new.)
Результирующий вес для меша может выглядеть похожим на это:
Модификаторы
Модификаторы - это инструменты, которые изменяют меш не-разрушающим способом, и могут корректироваться интерактивно. Другие объекты также могут иметь модификаторы: 3d-текст, Метаболлы и Кривые, например. Эти объекты могут быть представлены как сетки, так что их тоже можно модифицировать. Всё же не все модификаторы могут быть связаны с этими объектами. При желании, эффекты модификаторов можно сделать постоянными, применив их (apply). Блендер обеспечивает целый ряд модификаторов от subsurface до всех видов деформирующих модификаторов. Таблица показывает список доступных модификаторов:
Модификатор Влияние групп вершин
displacement (смещение) да
curve (кривая) да
explode (взрыв) да
lattice (решетка) да
mask (маскирование) да
meshdeform (деформация мешем) да
shrinkwrap (усаживающаяся упаковка) да
simpledeform (простая деформация) да
smooth (смягчение) да
wave (волна) да
array (массив) нет
bevel (скос или фаска) нет
boolean (объединение/пересечение/вычитание объектов) нет
build (построение) нет
cast (бросать) нет
decimate (уменьшение количества вершин) нет
edgesplit (разделение рёбер) нет
mirror (зеркально) нет
subsurface (подразделение поверхности) нет
uvproject (UV-проецирование) нет
Particle system (Система частиц) да
Примечание:
На многие параметры можно воздействовать различными группами вершин
armature (арматура) да
Примечание:
Влияние каждой кости может быть ограничено единственной группой вершин
Много модификаторов возможно настроить так, чтобы ограничить их влияние специфичной группой вершин, и есть несколько специальных модификаторов. Система частиц считается модификатором, хотя обычно системы частиц управляются через свой собственный набор инструментов. Также, связь с группами вершин у неё в некотором смысле обратная: вместо ограничивающего влияния на вершины в пределах группы вершин, веса вершин группы могут влиять на все типы параметров системы частицы, как например, плотность эмиссии и скорости частиц. Мы увидим пример этого в секции Полёт искр.
Модификаторы Арматуры также немного специфичны, так как они не ограничивают свое влияние единственной группой вершин. Тем не менее, их можно сконфигурировать так, чтобы ограничить влияние каждой отдельной кости на специфичную группу вершин, как мы изучим в секции Кости.
С точки зрения программиста на Питоне, список модификаторов является свойством объекта (то есть, НЕ меша, лежащего в его основе). Объекты, ссылающиеся на один и тот же меш, могут иметь различные модификаторы. Этот список содержит объекты Модификаторов, и их можно добавлять к нему и удалять из него, а отдельные модификаторы можно перемещать вверх или вниз по списку. Порядок модификаторов в некоторых случаях важен. Например, при добавлении модификатора subsurface после зеркального модификатора результат может выглядеть отличающимся от того, что получится при добавлении зеркального модификатора перед модификатором subsurface.
Объект модификатора имеет тип и имя (первоначально представленное типом, но оно может быть установлено во что-то более подходящее). Тип - один из типов в списке констант в Modifier.Types. Каждый объект модификатора может иметь множество настроек, которые индексируются ключами, определёнными в Modifier.Settings. Не все настройки подходят для всех типов.
Если у нас было два объекта, меш-объект с именем Target (Цель) и объект-решетка (lattice) с именем Deformer, и мы хотели бы ассоциировать объект Deformer как модификатор решетки на объект Target, следующий кусок кода поможет достичь эту цель:
import Blender
from Blender import Modifier
target = Blender.Object.Get('Target')
deformer= Blender.Object.Get('Deformer')
mod = target.modifiers.append(Modifier.Types.LATTICE)
mod[Modifier.Settings.OBJECT] = deformer
target.makeDisplayList()
Blender.Window.RedrawAll()
Если объект Target имел группу вершин с именем Right, состоящую из вершин в правой половине объекта, мы могли бы ограничить влияние модификатора, изменив атрибут VERTGROUP. Наш кусок кода должен измениться таким образом (дополнительная строка выделена):
import Blender
from Blender import Modifier
target = Blender.Object.Get('Target')
deformer= Blender.Object.Get('Deformer')
mod = target.modifiers.append(Modifier.Types.LATTICE)
mod[Modifier.Settings.OBJECT] = deformer
mod[Modifier.Settings.VERTGROUP] = 'Right'
target.makeDisplayList()
Blender.Window.RedrawAll()
Гравировка
Рассмотрим следующую проблему: дан некоторый текст, мы хотим отрендерить этот текст в виде утопленных бороздок на поверхности, подобно тому, как если бы они были выгравированы. Это не так уж просто, как кажется. Конечно, достаточно просто создать текстовый объект, но для того, чтобы манипулировать этим текстом, мы хотели бы преобразовать этот текстовый объект в меш. Интерфейс Блендера предлагает эту возможность в меню объектов, но как ни странно, API Блендера не предоставляет эквиалентной функции. Так, нашим первым барьером будет преобразование текстового объекта в меш.
Вторая проблема, которую мы должны решить - как выдавить набор вершин или рёбер на нужную глубину от поверхности. Опять же, в API Блендера нет функции для этого, так что мы должны добавить её к нашему пакету инструментов сами.
Последняя проблема более тонкая. Если нам каким-нибудь образом удалось создать несколько утопленных канавок, мы могли бы захотеть сделать краями чуть менее острыми, так как в действительности ничто не имеет абсолютно острых краёв. Существуют различные способы добиться этого, но многие из них включают добавление модификатора в наш меш. Модификатора скоса bevel может быть достаточно, чтобы убрать только острые края, но вполне вероятно, мы хотели бы добавить модификатор subsurface к нашему мешу целиком. Здесь у нас есть проблема: при заполнении промежутков между символами нашего текста, весьма вероятно, что мы столкнёмся со множеством узких треугольников. Эти треугольники испортят внешний вид результата нашего модификатора subsurface, как можно увидеть на следующем рисунке: