Читаем Написание скриптов для Blender 2.49 полностью

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

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

Схема кода сшивания рёберных циклов

В функции, которая создает новые грани, мы должны выполнить следующие шаги:

1. Удостовериться, что оба рёберных цикла цикла имеют одинаковую и ненулевую длину.

2. Для каждого ребра в цикле 1:

1. Найти ребро в цикле 2, которое ближе всего.

2. Создать грань, соединяющую эти два ребра.

Функция, которая осуществляет эту довольно сложную на вид схему:

def bridge_edgeloops(e1,e2,verts):

    e1 = e1[:]

    e2 = e2[:]

    faces=[]

    if len(e1) == len(e2) and len(e1) > 0 :

Функция принимает аргументы: два списка рёбер и список вершин. Рёбра представлены в виде кортежей двух целых (индексы в списке вершин verts), а вершины - в виде кортежей координат x, y, и z.

Первая вещь, которую мы сделаем - создадим копии двух рёберных списков, поскольку мы не хотим испортить списки в их оригинальном контексте. Список граней, который мы будем строить, инициализируется в пустой список, и мы проверяем разумность и равенство длин обоих рёберных списков. Если это подтверждается, мы приступаем к следующему куску:

for a in e1:

    distance = None  # расстояние

    best = None      # лучший

    enot = []        # отвергнутые рёбра

Мы повторяем по каждому ребру в первом списке, ссылаясь на это ребро через 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

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

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных