Написание скриптов для Blender 2.49 - страница 24

стр.


Схема и код выбора искривлённых граней

Вооружившись всей этой информацией, набросаем схему для нашего инструмента, она будет выглядеть так:

1. Показать всплывающий диалог для ввода минимального угла.

2. Проверить, что активный объект - это меш, и он в режиме

редактирования.

3. Включить режим выбора граней

4. Для всех граней проверить, является ли она четырёхугольником, и если так:

• Вычислить нормаль треугольника, определенного вершинами 0, 1, и 2

• Вычислить нормаль треугольника, определенного вершинами 1, 2, и 3

• Вычислить угол между нормалями

• Если угол > минимального угла, выбрать грань Это транслируется в следующий код для фактического обнаружения и выбора (полный скрипт предоставлен как

>warpselect.py):

>def warpselect(me,maxangle=5.0):

>    for face in me.faces:

>        if len(face.verts) == 4:

>            n1 = (face.verts[0].co - \

>                  face.verts[1].co ).cross( 

>                  face.verts[2].co - face.verts[1].co )

>            n2 = ( face.verts[1].co - \

>                  face.verts[2].co ).cross( 

>                  face.verts[3].co - face.verts[2].co )

>            a = AngleBetweenVecs(n1,n2)

>            if a > maxangle :

>                face.sel = 1

Как Вы можете видеть, наша схема почти взаимно-однозначно соответствует коду. Заметьте, что AngleBetweenVecs() возвращает угол в градусах, так что мы можем непосредственно сравнить его с maxangle, который тоже выражен в градусах. Также, нет необходимости самостоятельно выполнять само векторное произведение двух векторов, так как класс Vector в Блендере хорошо снабжен всеми видами операторов. Прежде, чем мы сможем вызвать эту функцию, мы должны позаботиться о важной детали: для того, чтобы выбирать грани, должен быть включен режим выбора граней. Это можно сделать следующим образом:

>selectmode = Blender.Mesh.Mode()

>Blender.Mesh.Mode(selectmode |

>Blender.Mesh.SelectModes.FACE)

Чтобы проиллюстрировать малоизвестный факт о том, что режимы выбора не являются взаимоисключающими, мы установили режим выбора граней дополнительно к любому уже выбранному режиму двоичным объединением величин или оператором (|). В конце скрипта мы восстанавливаем режим, который был активен.


Выбор слишком острых граней

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

Заметьте, что встроенный в Блендер инструмент выбора острых рёбер (sharp edges) (Ctrl + Alt + Shift + S) делает нечто другое, несмотря на свое название; он выбирает те рёбра, которые используются точно двумя гранями, и угол контакта между ними меньше, чем некоторая минимальная величина, или, другими словами, выбираются рёбра между гранями, которые сравнительно плоские.

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

>def sharpfaces(me,minimum_angle):

>   for face in me.faces:

>      n = len(face.verts)

>      edges = [face.verts[(i+1)%n].co - face.verts[i].co 

>               for i in range(n)]

>      for i in range(n):

>         a = AngleBetweenVecs(-edges[i],edges[(i+1)%n])

>         if a < minimum_angle :

>            face.sel = 1

>            break

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