Выбрать главу

   for l in range(len(loop)):

      points = expand.expand(me,loop[l],

                             0.02,loop[:l]+loop[l+1:])

      offset=len(me.verts)

      me.verts.extend(points)

      edgeoffset=len(me.edges)

      me.edges.extend([(i+offset,i+offset+1) 

                        for i in range(len(points)-1)])

      me.edges.extend([(len(points)-1+offset,offset)])

      eloop=[me.edges[i] for i in

range(edgeoffset,len(me.edges))]

      me.assignVertsToGroup('Outline',

                             range(offset,len(me.verts)),

                             1.0,

                             Blender.Mesh.AssignModes.ADD)

      faces=[]

      for e1,e2 in zip( expand.ordered_edgeloop(loop[l]),

                        expand.ordered_edgeloop(eloop)):

         f1=(e1.v1.index,e1.v2.index,

             e2.v2.index,e2.v1.index)

         f2=(e1.v2.index,e1.v1.index,

             e2.v2.index,e2.v1.index)

         faces.append(least_warped(me,f1,f2))

      me.faces.extend(faces)

Мы опустили код выдавливания рёберной петли символа, но следующие строки содержательны, так как они показывают, как заполняется рёберный цикл. Сначала мы выбираем все важные рёбра, используя две вспомогательные функции (это - выдавленные рёбра символов). Затем, мы вызываем метод fill(). Этот метод будет заполнять любой набор замкнутых рёберных циклов до тех пор, пока они лежат в одной плоскости. Он даже позаботится об отверстиях (подобно небольшому острову в букве e):

   deselect_all_edges(me)

   select_edges(me,'TextBottom')

   me.fill()

Дополнение cartouche - просто вопрос добавления прямоугольного рёберного цикла вокруг наших символов. Если этот рёберный цикл выбрать вместе с вершинами в группе вершин Outline, можно снова использовать метод fill() для заполнения этого cartouche. Это не показано здесь. Несколько заключительных штрихов: мы по возможности преобразуем треугольники в нашем меше в четырехугольники, используя метод triangleToQuad(), затем подразделяем меш. Мы также добавляем модификатор subsurface, устанавливаем атрибут сглаживания (smooth) на всех гранях и пересчитываем нормали всех граней, чтобы они согласованно указывали наружу.

   me.triangleToQuad()

   me.subdivide()

   mod = ob.modifiers.append(

                      Blender.Modifier.Types.SUBSURF)

   mod[Blender.Modifier.Settings.LEVELS]=2

   select_all_faces(me)

   set_smooth(me)

   select_all_edges(me)

   me.recalcNormals()

Скрытый модификатор Захвата:

Мы видели, что модификаторы, доступные в Блендере, можно добавлять к объекту в Питоне. Есть, тем не менее, один модификатор, который может быть добавлен, но создаётся впечатление, что он не имеет эквивалента в графическом интерфейсе Блендера. Это - так называемый модификатор Hook (Захват). Захват в Блендере - способ сделать родителем вершин объект (так что это противоположно vertex parenting, где мы родителем объекта назначаем вершины), и в приложении самостоятельно может быть доступно через меню Mesh | Vertex | Add Hook в режиме редактирования. После добавления он появится в списке модификаторов. С точки зрения программиста, модификатор Захвата никак не отличается из других модификаторов, но увы, ни его тип, ни параметры, не документированы в API.

Добавление переводчика к разделу Гравировка:

К сожалению, опробованная мной программа engrave.py (с необходимым ей модулем expand.py), скачанная с сайта издательства, работала далеко не так красиво, как это описано в тексте. В очередной раз придётся набраться наглости и указать на недоработки автора.

1. Простая ошибка в программе: ближе к концу есть такие строки:

me.subdivide()

me.triangleToQuad()

me.subdivide()

перед преобразованием в четырёхугольники, и тем более, перед подразделением необходимо было выделить все вершины, а к этому моменту они выделены все, кроме основного контура букв. В результате, меш подразделяется на устрашающее количество лишних треугольников. Я заменил первое подразделение на выбор всех рёбер.