Книга: Написание скриптов для Blender 2.49

Привязка к вершинам в вершинной группе

Привязка к вершинам в вершинной группе

Что, если мы хотим определить конкретно те вершины, к которым мы можем привязать объект? Это можно достигнуть, определив группу вершин, и, затем, рассматривая только вершины из этой группы в качестве кандидатов, к которым можно привязывать. Код необходимый для этого, увеличится всего на несколько строк, и важная часть doConstraint() будет выглядеть примерно так (выделенный код показывает дополнительные строки, имеющие дело с проверкой на принадлежность к группе вершин):

# получаем целевой меш
to = Blender.Object.Get(idprop['target_object'])
me = to.getData(mesh=1)
# получаем положение целевого меша
tloc = targetmatrices[0].translationPart().resize3D()
# ищем ближайшую вершину в целевом объекте
smallest = 1000000.0
delta_ob=tloc-obloc
try:
    verts = me.getVertsFromGroup(idprop['VertexGroup'])
    for vi in verts:
        d = (me.verts[vi].co+delta_ob).length
        if d < smallest :
            smallest = d
            si = vi
        obloc = me.verts[si].co+tloc
        vnormal = me.verts[si].no
except AttributeError:
    for v in me.verts:
        d = (v.co+delta_ob).length
        if d < smallest:
            smallest=d
            sv=v
    obloc = sv.co + tloc
    vnormal = sv.no

Автор здесь нарушил одно из важнейших правил качественного программирования, которое гласит «Нет дублированию кода!» Текст после try желательно переписать, например, так:

try:
    verts = me.getVertsFromGroup(idprop['VertexGroup'])
except AttributeError:
    verts = range(len(me.verts))
for vi in verts:
    d = (me.verts[vi].co+delta_ob).length
    if d < smallest :
        smallest = d
        si = vi
    obloc = me.verts[si].co+tloc
    vnormal = me.verts[si].no

Примечание занудного и наглого переводчика Striver'а

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

def getSettings(idprop):
    if not idprop.has_key('VertexGroup'):
       idprop['VertexGroup'] = 'Zone'
    if not idprop.has_key('NormalAlign'):
       idprop['NormalAlign'] = True
    vgroup = Draw.Create(idprop['VertexGroup'])
    align = Draw.Create(idprop['NormalAlign'])
    block = []
    block.append("Additional restrictions: ")
    block.append(("Vertex Group: ",vgroup,0,30,"Vertex
                   Group to restrict location to"))
    block.append(("Alignment: ",align,
                  "Align along vertex normal"))
    retval = Draw.PupBlock("Zoning Constraint", block)
    if (retval):
        idprop['VertexGroup']= vgroup.val
        idprop['NormalAlign']= align.val

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



Заметьте, что скриптовое ограничение также обеспечивает пользователя полем ввода строки VG, которая может ссылаться на группу вершин, но это отличается от поля ввода группы вершин, которую мы показываем пользователю во всплывающих Опциях. Это поле VG будет изменять способ рассматриванияограничением цели. Если здесь задаётся корректная группа вершин, целевая матрица передаваемая в doConstraint(), будет усреднённой позицией вершин в вершинной группе.

Оглавление книги


Генерация: 1.204. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз