Написание скриптов для Blender 2.49 - страница 20

стр.

>

Мы повторяем по каждому ребру в первом списке, ссылаясь на это ребро через a. параметр distance содержит расстояние до ближайшего ребра во втором рёберном списке, а best будет ссылкой на это ребро. enot - список, который копит все рёбра из второго списка, которые находятся на большем расстоянии, чем наилучшее.

В конце каждой итерации, enot будет содержать все рёбра из второго списка минус одно - которое мы считаем ближайшим. Затем мы переназначаем enot на второй список, таким образом второй список уменьшается на одно ребро с каждой итерацией. Мы заканчиваем, как только второй список рёбер будет исчерпан:

>while len(e2):

>    b = e2.pop(0)

Текущее ребро из второго списка, которое мы рассматриваем, называется b. Для наших целей, мы определяем расстояние между a и b как сумму расстояний между соответствующими вершинами в a и b. Также мы проверяем, не окажется ли короче сумма расстояний до перевёрнутых вершин b. Если получилась такая ситуация, мы меняем вершины в ребре b. Это может казаться сложным способом действий, но суммированием двух расстояний мы гарантируем, что рёбра, которые сравнительно коллинеарны (параллельны) - привилегированы, тем самым уменьшая число неплоских граней, которые будут созданы. Проверяя, не приведёт ли перевёрнутый второй край к более короткому расстоянию, мы предотвращаем образование   искорёженного   в   виде   галстука-бабочки четырёхугольника, как проиллюстрировано на следующем рисунке:



Реализация будет выглядеть похоже на предшествующий рисунок, где выделенные вектора - псевдонимы на объект Mathutil.Vector, преобразующий наши кортежи с координатами x, y, и z в соответствующие векторы, которые мы можем вычитать, складывать, и получать их длину.

Сначала мы вычисляем расстояние:

>    d1 = (vec(verts[a[0]]) - vec(verts[b[0]])).length + \

>    (vec(verts[a[1]]) – vec(verts[b[1]])).length

Затем мы проверяем с перевёрнутым ребром b, будет ли в результате расстояние короче:

>    d2 = (vec(verts[a[0]]) - vec(verts[b[1]])).length + \

>    (vec(verts[a[1]]) - vec(verts[b[0]])).length

>    if d2

>        b =(b[1],b[0])

>        d1 = d2

Если рассчитанное расстояние не самое короткое, мы откладываем ребро для следующей итерации, если оно не первое, с которым мы столкнулись:

>    if distance == None or d1

>        if best != None:

>            enot.append(best)

>        best = b

>        distance = d1

>    else:

>        enot.append(b)

Список отклонённых рёбер становится новым e2, затем мы заполняем список граней новой парой рёбер, и переходим к новой итерации по первому списку рёбер (a) – доп. пер.

>e2 = enot

>faces.append((a,best))

Наконец, мы преобразуем наш список граней, состоящий из кортежей двух рёбер, в список кортежей из четырех индексов:

>return [(a[0],b[0],b[1],a[1]) for a,b in faces]

Есть много больше в этом скрипте, и мы вновь будем рассматривать creepycrawlies.py в следующей главе, где мы добавим модификаторы, группы вершин и арматуру к нашей модели. Иллюстрация показывает образцы бестиария, которые могут быть созданы скриптом.




Ослепите вашего босса - гистограммы в стиле Блендер

Чтобы доказать, что Блендер адаптируется ко многим задачам помимо интерактивного создания 3D-графики, мы покажем Вам, как импортировать внешние данные (электронная таблица в формате CSV) и автоматизировать задачу создания и рендеринга представленной в 3D гистограммы.



Идея в том, чтобы запустить Блендер с аргументами, указывающими ему запустить скрипт, который читает .csv файл, рендерит изображение и сохраняет это изображение по окончании. Чтобы это было возможным, нам нужен способ вызывать Блендер с правильными параметрами. Мы дойдём скоро до этого скрипта, но сначала давайте увидим, как передавать параметры в Блендер, чтобы он запускал скрипт на Питоне:

>blender -P /full/path/to/barchart.py

Также возможно вместо этого запустить скрипт из текстового буфера внутри .blend файла по имени этого текстового буфера. Обратите внимание на порядок параметров в этому случае - сначала ставится имя .blend файла:

>blender barchart.blend -P barchart.py

В противоположность тому, что описано в документации API, в Питоне мы можем просто получить доступ к аргументам командной строки следующим образом: