txt = ob.getData()
curve = Blender.Curve.Get(txt.getName())
Теперь мы можем использовать txt, чтобы иметь доступ к Text3d-специфичной информации (например, txt.setText('foo')) и curve, чтобы иметь доступ к Curve-специфичной информации (например, curve.getNumCurves()).
Объект Curve Блендера состоят из множества объектов CurNurb, которые представляют сегменты кривой. Единственный текстовый символ обычно состоит из одного или двух сегментов кривой. Маленькая буква e, например, состоит из внешнего сегмента и небольшого внутреннего сегмента кривой. Объекты CurNurb, в свою очередь, состоят из множества узлов или управляющих точек, которые задают сегмент кривой. В случае объектов Text3d эти узлы всегда являются объектами BezTriple, и модуль Geometry Блендера предоставляет нам функцию BezierInterp(), которая возвращает список координат, интерполированных между двумя точками. Эти точки и направляющие кривой в этих точках (часто называемые handle, рукоять), можно взять из объектов BezTriple. Результирующий код выглядит так (полный код является частью нашего пакета разработчика в Tools.py) (Эта и последующие функции этого раздела, несмотря на заверения автора, отсутствуют в файле Tools.py, прилагаемом ко 2-й главе, найти их можно только в файле engrave.py — прим. пер.):
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 принимает меш и вектор как аргументы, и выдавит вершины на выбранных рёбрах в меше в направлении вектора, добавляя все необходимые новые рёбра и грани. Поскольку эта техника является расширением того, что мы уже видели раньше, код не показан здесь.