Шрифт:
Интервал:
Закладка:
Для каждой камеры в словаре cameras мы проверяем, существует ли она уже как объект Блендера. Если это так, мы проверяем, имеет ли этот объект Блендера связанный с ним объект Камеры. Если последнее не является истиной, мы создаем перспективную камеру с тем же именем, как объект верхнего уровня (выделено), и ассоциируем его с объектом верхнего уровня посредством метода link():
for cam in cameras:
try:
ob = Object.Get(cam)
camob = ob.getData()
if camob == None:
camob = Camera.New('persp',cam)
ob.link(camob)
Если там ещё не было объекта верхнего уровня, мы создаем его и связываем с ним новый объект перспективной Камеры:
except ValueError:
ob = Object.New('Camera',cam)
Scene.GetCurrent().link(ob)
camob = Camera.New('persp',cam)
ob.link(camob)
Мы выставляем позицию, поворот, и атрибут lens. Заметьте, что углы поворота выражаются в радианах, так что мы преобразуем их из более понятных градусов, которые мы использовали в нашей таблице (выделено). Мы заканчиваем, вызывая функцию Redraw() (обновление изображения), чтобы изменения появились в интерфейсе пользователя:
ob.setLocation(cameras[cam][0])
ob.setEuler([radians(a) for a in cameras[cam][1]])
camob.lens=cameras[cam][2]
Blender.Redraw()
Наконец, мы определяем метод run(), который связывает все компоненты вместе. Он определяет активный объект, затем проходит циклом по списку имен камер, чтобы отрендерить каждый вид и добавить результирующее имя файла в список (выделено):
def run():
ob = Scene.GetCurrent().objects.active
cameras = ('Top','Right','Front','Free')
frame(cameras,ob.getBoundBox())
files = []
for cam in cameras:
files.append(render(cam))
Мы поместим скомбинированное изображение в тот же каталог, что и отдельные виды, и назовём его result.png:
outfile = os.path.join(os.path.dirname(
files[0]),'result.png')
Мы затем называем нашу функцию paste(), передавая список имён файлов компонентов, развёрнутый в индивидуальные аргументы оператором звездочка (*), и, последний штрих, загружаем файл результата как изображение Блендера и показываем его в окне редактора изображений (выделено ниже). Функция reload (перегрузка) необходима чтобы удостовериться, что предыдущее изображение с тем же самым именем будет обновлено:
paste(*files, output=outfile)
im=Image.Load(outfile)
bpy.data.images.active = im
im.reload()
Window.RedrawAll()
Функция run() умышленно не создаёт никаких камер, поскольку пользователь может захотеть сделать это сам. Сам окончательный скрипт заботится о создании камер, но это можно изменить довольно легко, достаточно закомментировать строку. После проверки, если скрипт работает автономно, он просто создает камеры и вызывает метод run:
if __name__ == "__main__":
createcams()
run()
Полный код доступен как combine.py в файле combine.blend.
Рабочий процесс - как продемонстрировать вашу модельСкрипт можно использовать следующим образом:
1. Поместите ваш предмет в начало координат (позиция (0, 0, 0)).
2. Создайте подходящие условия освещения.
3. Запустите combine.py.
Скрипт можно загрузить в текстовый редактор, чтобы запустить его с помощью Alt + P, но Вы также можете поместить его в каталог scripts Блендера, чтобы сделать его доступным из меню Scripts | Render.
Now, strip — создание киноленты из анимации
Монтаж нескольких камер для разных точек зрения в одном изображении - просто один из примеров, где многочисленные изображения могут быть эффективно объединены в единственное. Другой пример - когда мы хотели бы показать кадры из анимации, в то время как у нас нет доступа к к средствам для воспроизведения анимации. В таких ситуациях мы хотели бы показать что-то похожее на киноленту, где мы объединяем небольшие изображения, например, каждого десятого кадра, на единственном листе. Пример показан на следующей иллюстрации.
Хотя тут больше изображений для объединения, чем при нескольких видах камер, код для создания такой киноплёнки довольно похож.
Первой функцией, которую мы разрабатываем, будет strip() (лента), которая берет список имён файлов изображений для объединения, и необязательное имя, которое будет дано комбинированному изображению. Третий дополнительный аргумент - cols, количество колонок в комбинированном изображении. По умолчанию он равен четырём, но для длинных последовательностей может быть более естественным печатать их на горизональной бумаге, и использовать здесь большую величину. Функция возвращает объект Image Блендера, содержащий комбинированное изображение.
Мы снова используем модуль pim, который будет или псевдонимом для модуля PIL, если он доступен, или ссылкой на нашу собственную реализацию, если PIL не доступен. Важные отличия от нашего предыдущего кода комбинирования изображений выделены. Первая выделенная часть показывает, как вычислять размер комбинированного изображения, исходя из количества строк и колонок плюс количество пикселей, необходимое для цветных окантовок вокруг изображений. Вторая выделенная строка показывает, где мы вставляем картинки в целевое изображение:
def strip(files,name='Strip',cols=4):
rows = int(len(files)/cols)
if len(files)%int(cols) : rows += 1
im = pim.open(files.pop(0))
w,h= im.size
edge=2
edgecolor=(0.0,0.0,0.0)
comp = pim.new(im.mode,
(w*cols+(cols+1)*edge,
h*rows+(rows+1)*edge),
edgecolor)
for y in range(rows):
for x in range(cols):
comp.paste(im,(edge+x*(w+edge),edge+y*(h+edge)))
if len(files)>0:
im = pim.open(files.pop(0))
else:
comp.save(name,format='png')
return Image.Load(name)
Функция render(), которую мы определяем, принимает количество пропускаемых кадров в виде аргумента и рендерит любое количество кадров между начальным и конечным кадрами. Эти начальный и конечный кадры могут быть заданы пользователем в панели кнопок рендера. Эти кнопки рендера также содержат величину шага, но эта величина не доступна в API Питона. Это означает, что наша функция будет несколько избыточнее, чем нам хотелось бы, так как мы должны создать цикл, который рендерит каждый отдельный кадр (выделено в следующем коде) вместо прямого вызова renderAnim(). Следовательно, мы должны манипулировать атрибутами startFrame и endFrame контекста рендера (как и раньше), но мы будем осторожными и восстановим эти атрибуты перед возвратом списка имён файлов отрендеренных картинок. Если бы мы не нуждались в каком-либо программном контроле значения величины пропуска, мы могли бы просто заменить вызов render() вызовом renderAnim():
def render(skip=10):
context = Scene.GetCurrent().getRenderingContext()
filenames = []
e = context.endFrame()
s = context.startFrame()
context.displayMode=0
for frame in range(s,e+1,skip):
context.currentFrame(frame)
context.startFrame(frame)
context.endFrame(frame)
context.renderAnim()
filenames.append(context.getFrameFilename())
context.startFrame(s)
context.endFrame(e)
return filenames
После определения этих функций сам скрипт теперь просто вызывает render(), чтобы создавать изображения, и strip(), чтобы объединить их. Результирующее изображение Блендера перезагружается (reload) для его обновления на экране, если изображение с таким именем уже присутствовало, затем все окна перерисовываются (выделено):
def run():
files = render()
im=strip(files)
bpy.data.images.active = im
im.reload()
Window.RedrawAll()
if __name__ == "__main__":
run()
Полный код доступен как strip.py в файле combine.blend.
Рабочий процесс — использование strip.pyСоздать ленту анимационных кадров можно следующим образом:
1. Создать вашу анимацию. (Ага, это, конечно самый простой пункт ;) -прим. пер.)
2. Запустить strip.py из текстового редактора.
3. Комбинированное изображение появится в окне редактора UV/image.
4. Сохранить изображение с именем по вашему выбору.
- 33 лучшие программы для ноутбука. Популярный самоучитель - Владимир Пташинский - Программы
- Защита вашего компьютера - Сергей Яремчук - Программы
- Delphi. Трюки и эффекты - Валерий Борисок - Программы
- Google Таблицы. Это просто. Функции и приемы - Евгений Намоконов - Программы
- 200 лучших программ для Linux - Сергей Яремчук - Программы