Процедурная генерация великолепна! В
этом уроке мы рассмотрим создание меша с использованием блендеровского Python
API.Создание мешей
программными способами открывает множество возможностей. Вы можете создавать
параметрические объекты, которые отвечают размерам реального мира, генеративное
искусство, формы на основе математических формул или даже процедурный контент
для игр. Blender – отличный выбор для такого рода работ, поскольку он сочетает
в себе полномасштабный набор инструментов моделирования и анимации с мощным (и
достаточно хорошо документированным) Python API.
В этой серии мы
рассмотрим создание нескольких примитивов и некоторых базовых преобразований, а
также рассмотрим некоторые ухищрения, которые упростят процесс разработки
дополнений. Я предполагаю, что вы уже знаете Python на базовом уровне и
достаточно знакомы с Blender. Поэтому мы пропустим введение в мир 3D и
сосредоточимся на создании простой плоской сетки.Совет для
профессионалов: Сохраняйтесь как можно чаще! Blender может вылететь неоднократно :)Настройка.В системе данных
Blender существует различие между данными меша и объектами в сцене. Мы должны
добавить меш и связать его с объектом, а затем связать этот объект со сценой,
прежде чем мы сможем увидеть какие-либо результаты.Начнем с импорта bpy
(сюрприз!) и создания некоторых переменных.
import bpy
# Settings
name = 'Gridtastic'
rows = 5
columns = 10
|
verts = []
faces = []
# Create Mesh Datablock
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(verts, [], faces)
# Create Object and link to scene
obj = bpy.data.objects.new(name, mesh)
bpy.context.scene.objects.link(obj)
# Select the object
bpy.context.scene.objects.active = obj
obj.select = True
|
verts = [(0, 0, 0)]
|
verts = [(x, 0, 0) for x in range(columns)]
|
verts = [(x, y, 0) for x in range(columns) for y in range(rows)]
|
Мы можем приступать к
созданию граней, но сначала нам нужно понять, как это делать.Разбираемся с гранями.Каждая вершина,
которую мы добавили имеет свой индекс. Индексы устанавливаются в том порядке, в
котором мы создаем наши вершины, поэтому у первой вершины индекс 0, у второй 1
и т.д.Чтобы создать грань,
нам нужно добавить кортеж индексов вершин в список граней. Этот кортеж может
состоять из 3 (треугольник), 4 (четырехугольник) или большего (многоугольник)
количества индексов. Кстати, это все целые числа. Поскольку мы будем создавать
четырехугольные грани, нам необходимо будет указать 4 индекса для каждой из
них. Но как? Вы можете попытаться угадать их, но есть лучший способ. Мы можем
включить режим отладки в Blender. Откройте консоль Python в Blender и введите
следующее:
bpy.app.debug = True
|
Давайте сосредоточимся
на первой грани. Как видите, она состоит из вершин 0, 1, 5 и 6. Попробуем
сделать одну грань с этими индексами:
faces = [(0, 1, 5, 6)]
Попробуйте запустить скрипт еще раз и… подождите, что-то не так! Похоже, мы связали неправильные вершины.
|
Ну, мы соединили правильные вершины, но в неправильном порядке. Да, при создании граней необходимо соблюдать порядок: против часовой стрелки, начиная с нижней левой вершины.
Поэтому порядок для грани будет 0, 5, 6, 1. Исправьте это и
снова запустите скрипт.
Теперь мы в деле.
Каждый раз, когда вы видите подобные проблемы, попробуйте поменять первый или
два последних набора индексов между собой. Хорошо, это то место, где все
становится интересным. Нам нужно выяснить, как вычислить все индексы, чтобы
создать целый ряд граней. Если мы внимательно посмотрим на индексы вершин, мы
увидим закономерность:- Все индексы увеличиваются на 5 по оси X. Их количество равно количеству столбцов.
- Первый индекс начинается с 0, второй на 1 больше.
for x in range(columns - 1):
print(x * rows)
print(x * rows + 1)
|
for x in range(columns - 1):
print('first:', x *
rows)
print('second:', x * rows + 1)
print('third:', (x + 1) * rows + 1)
print('fourth:', (x + 1) * rows)
print('---')
|
def face(column, row):
""" Create a single face """
return (column * rows + row,
column * rows + 1 + row,
(column + 1) * rows
+ 1 + row,
(column + 1) * rows
+ row)
|
faces = [face(x, y) for x in range(columns - 1) for y in range(rows - 1)]
|
Вот теперь сетка завершена. Вы создали скрипт, который может создавать
2D-сетки! Похлопайте себя по плечу и продолжайте читать, чтобы немного улучшить
и расширить наш скрипт.Масштабирование.Мы можем
контролировать количество вершин нашей сетки, но квадраты всегда равны 1 BU
(или 1 метр). Давайте изменим это.Все, что нам нужно
сделать, это умножить координаты X и Y на коэффициент масштаба. Начните с
добавления переменной размера (size). Мы можем добавить это непосредственно к
выражению verts, но опять же, будет лучше и чище, если мы сделаем это в своей
собственной функции.
size = 1
def vert(column, row):
""" Create a single vert """
return (column * size, row * size, 0)
verts = [vert(x, y) for x in range(columns) for y in range(rows)]
Попробуйте установить размер
во что-то отличное от 1 и проверьте сетку.
Финальный код.
Завершение.
Надеюсь, вам
понравилось это введение в создание мешей на Python. Это только самый простой
пример и есть много других интересных вещей. Вот несколько простых вещей,
которые вы можете попытаться реализовать самостоятельно:
|

Комментариев нет:
Отправить комментарий