import Blender
from Blender.Geometry import BezierInterp as interpolate
from Blender.Mathutils import Vector as vec
def curve2mesh(c):
vlists=[]
for cn in c:
npoints = len(cn)
points=[]
first=True
for segment in range(npoints-1):
a=cn[segment].vec
b=cn[segment+1].vec
lastpoints = interpolate(vec(a[1]),vec(a[2]),
vec(b[0]), vec(b[1]),6)
if first:
first = False
points.append(lastpoints[0])
points.extend(lastpoints[1:])
if cn.isCyclic():
a=cn[-1].vec
b=cn[0].vec
lastpoints=interpolate(vec(a[1]), vec(a[2]),
vec(b[0]), vec(b[1]),6)
points.extend(lastpoints[:-2])
vlists.append(points)
return vlists
Выделенные строки показывают два важных аспекта. Первая показывает фактическую интерполяцию. Мы переименовали довольно неуклюжее имя функции BezierInterp() в interpolate() , и она принимает пять аргументов. Первые четыре берутся от двух объектов BezTriple , между которыми мы интерполируем. В каждом объекте BezTriple можно получить доступ к списку из трех векторов: входящая рукоять, позиция точки, и исходящая рукоять (смотри следующий рисунок). Мы передаем позицию первой точки и исходящей рукояти и позицию второй точки и входящей рукояти. Пятый аргумент является количеством точек, которые мы хотим получить на выходе функции interpolate() .
Вторая выделенная строка заботится о замкнутых кривых- кривых, в которых их первые и последние точки связаны. Это является случаем всех кривых, которые формируют символы в тексте. Функция возвращает список списков. Каждый список содержит все интерполированные точки (кортежи из x, y, z координат) для каждой кривой. Заметьте, что некоторые символы состоят из более, чем одной кривой. Например, небольшая буква e во многих шрифтах, или буква o состоит из двух кривых, одна задаёт внешнюю границу буквы и одна внутреннюю. Объект Text3d , содержащий текст Foo , например, возвращает список из пяти списков - первый будет содержать вершины, определяющие большую букву F , а второй и третий будут содержать вершины для двух кривых, которые создают маленькую букву o, так же будет с четвертым и пятым.
Выдавливание рёберного цикла
Выдавливание (Extrusion)является процессом, где мы дублируем вершины (и, возможно, соединяющие их рёбра) и перемещаем их в некотором направлении, после чего мы соединяем эти дубликаты вершин с их оригиналами новыми рёбрами, и заканчиваем операцию, создавая новую грань между старыми и новыми вершинами. Нам нужно это для того, чтобы утопить очертание нашего текста, чтобы создать бороздку с вертикальными стенками. Функция extrude_selected_edges() в Tools.py принимает меш и вектор как аргументы, и выдавит вершины на выбранных рёбрах в меше в направлении вектора, добавляя все необходимые новые рёбра и грани. Поскольку эта техника является расширением того, что мы уже видели раньше, код не показан здесь.
Расширение (Expanding) рёберного цикла
Если у нас есть список рёбер, формирующих замкнутую кривую (или более одного), определяющий символ, мы хотели бы окружить эти рёбра дополнительным рёберным циклом, чтобы создать лучшее "выполнение" любого модификатора subsurface, который конечный пользователь может связать с нашим мешем. Это был бы довольно сложный процесс, если мы должны были бы вычислять это в 3D, но, к счастью, наши преобразованные символы имеют все свои вершины на плоскости xy (дело в том, что все символы в новых экземплярах Text3d объекта лежат на плоскости xy)..
Всего лишь два измерения - это вполне податливая проблема. Для каждой точки в нашем рёберном цикле мы определяем направление вершинной нормали. Вершинная нормальявляется линией, разрезающей пополам угол между двумя рёбрами, которые делят рассматриваемую нами точку. Если два ребра коллинеарны (или почти так), мы берем за вершинную нормаль линию, перпендикулярную одному из рёбер. Позиция точки, создаваемой в новом рёберном цикле, будет где-нибудь на этой нормали. Для того, чтобы определиться, должны ли мы перемещать наружу или внутрь вдоль этой нормали, мы просто пробуем одно направление и проверяем новую позицию - находится ли она внутри границ нашего символа. Если это так, мы берём обратное направление.
Читать дальше