My-library.info
Все категории

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

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Michel Anders - Написание скриптов для Blender 2.49. Жанр: Программы издательство неизвестно, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
Написание скриптов для Blender 2.49
Автор
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
17 сентябрь 2019
Количество просмотров:
254
Читать онлайн
Michel Anders - Написание скриптов для Blender 2.49

Michel Anders - Написание скриптов для Blender 2.49 краткое содержание

Michel Anders - Написание скриптов для Blender 2.49 - описание и краткое содержание, автор Michel Anders, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info
Расширьте мощность и гибкость Блендера с помощью Питона: высокоуровневого, легкого для изучения скриптового языка

Написание скриптов для Blender 2.49 читать онлайн бесплатно

Написание скриптов для Blender 2.49 - читать книгу онлайн бесплатно, автор Michel Anders

import Blender

from Blender import Scene,Window,Draw

from Blender.Scene import Render


import struct

import wave

Мы начинаем, импортируя необходимые модули, включая модуль Питона wave, чтобы иметь доступ к нашему .wav-файлу и модуль struct, который предоставляет функции для манипулирования двоичными данными, которые мы получим из .wav-файла.

Затем, мы определяем вспомогательную функцию, показывающую всплывающее меню в середине нашего экрана. Она ведёт себя просто подобно стандартной функции PupMenu() из модуля Draw, но устанавливает курсор в позицию середины экрана с помощью функций GetScreenSize() и SetMouseCoords() из модуля Блендера Window:

def popup(msg):

   (w,h)=Window.GetScreenSize()

   Window.SetMouseCoords(w/2,h/2)

   return Draw.PupMenu(msg)

Основная часть работы будет осуществляться функцией sound2active(). Она принимает два аргумента - имя .wav-файла, для использования и имя ключа формы для анимации, основанной на информации из .wav-файла. Сначала, мы пытаемся создавать объект WaveReader, вызывая функцию open() модуля wave (выделено). Если это не удаётся, мы показываем ошибку во всплывающем окне и выходим:

def sound2active(filename,shapekey='Pop out'):

   try:

      wr = wave.open(filename,'rb')

   except wave.Error,e:

      return popup(str(e)+'%t|Ok')

Затем мы делаем некоторые разумные проверки: мы сначала проверяем, является ли .wav-файл МОНО файлом. Если Вы хотите использовать стерео файл, преобразуйте его сначала в моно, например   с   помощью   свободного   пакета   Audacity (http://audacity.sourceforge.net/). Затем мы проверяем, имеем ли мы дело с несжатым .wav-файлом, поскольку модуль wave не может работать с другими типами. (большинство .wav-файлов являются несжатыми, но если нужно, Audacity также может их преобразовать), и мы проверяем, что сэмплы 16-битовые. Если любая из этих проверок терпит неудачу, мы выводим соответствующее сообщение об ошибке:

   c = wr.getnchannels()

   if c!=1 : return popup('Only mono files are '+

                          'supported%t|Ok')

   t = wr.getcomptype()

   w = wr.getsampwidth()

   if t!='NONE' or w!=2 :

     return popup('Only 16-bit, uncompresses files '+

                  'are supported%t|Ok')

Теперь, когда мы можем работать с файлом, мы получаем его частоту дискретизации (frame rate, количество аудио сэмплов в секунду) и общее число байт (как ни странно, используя неуклюже названную функцию getnframes() из модуля wave). Затем, мы считываем все эти байты и сохраняем их в переменной b.

   fr= wr.getframerate()

   n = wr.getnframes()


   b = wr.readframes(n)

Наша следующая задача в том, чтобы получить контекст рендера у текущей сцены, чтобы извлечь количество видеокадров в секунду. Время в секундах нашей проигрываемой анимации будет определено длиной нашего аудио сэмпла, которое мы можем вычислить, разделив общее число аудио кадров в .wav-файле на количество аудио кадров в секунду (выделено в следующей части кода). Затем мы определяем константу sampleratio - количество аудио кадров в течение видео кадра:

   scn         = Scene.GetCurrent()

   context     = scn.getRenderingContext()

   seconds     = float(n)/fr

   sampleratio = fr/float(context.framesPerSec())

Как упомянуто раньше, модуль wave дает нам доступ ко множеству свойств .wav-файла и к сырым (raw) аудио сэмплам, но не предоставляет никаких функций для преобразования этих сырых сэмплов в удобные для использования целые величины. Следовательно, нам нужно сделать это самостоятельно. К счастью, это не так уж трудно, как это может показаться. Поскольку мы знаем, что 16-битовые аудио сэмплы представлены как 2-х байтовое целое в формате "меньший-в-конце" ("little-endian"), мы можем использовать функцию unpack() из модуля Питона struct, чтобы эффективно преобразовывать список байтов в список целых, передавая подходящую спецификацию формата. (Вы можете прочитать больше о .wav-файлах здесь  https://ccrma.stanford.edu/courses/422/ проекты/WaveFormat/,  на русском здесь:  http://www.fpga-cpld.ru/wave.html, работа с модулем struct описана здесь: http://world-python.org/article/tutorialmodules/32-modul-struct.html — прим. пер.)

   samples  = struct.unpack('<%dh'%n,b)

Теперь мы можем начать анимацию ключей формы. Мы получаем стартовый кадр из контекста рендера и вычисляем конечный кадр, умножая время в секундах в .wav-файле на частоту видеокадров. Заметьте, что он может оказаться  дальше или ближе, чем конечный кадр, который мы можем получить из контекста рендера. Последний определяет конечный кадр, который будет отрендерен, когда пользователь нажмёт на кнопку Anim, но мы будем анимировать движение нашего активного объекта независимо от этой величины.

Затем для каждого кадра мы вычисляем от стартового кадра до последнего кадра (исключительно) среднее значение аудио сэмплов, которые попадают на каждый видеокадр суммированием этих аудио сэмплов (находятся в списке samples) и деля на количество этих аудио сэмплов за видеокадр (выделено в следующем куске кода).

Мы задаём выбранный ключ формы в величину в дипазоне [0:1], так что мы должны нормализовать рассчитанные средние числа, определяя минимальную и максимальную величины, и вычислить масштаб:

   staframe = context.startFrame()

   endframe = int(staframe +

                  seconds*context.framesPerSec())


   popout=[]

   for i in range(staframe,endframe):

      popout.append(sum(samples[int(

      (i-1)*sampleratio):int(i*sampleratio)])/sampleratio)

   minvalue = min(popout)

   maxvalue = max(popout)

   scale = 1.0/(maxvalue-minvalue)

Наконец, мы получаем активный объект в текущей сцене и получаем его IPO Формы (выделено). Мы заканчиваем, устанавливая величину ключа формы для каждого кадра в рассматриваемом нами диапазоне в масштабированное среднее аудио сэмплов:

   ob=Blender.Scene.GetCurrent().objects.active


   ipo = ob.getData().getKey().getIpo()


   for i,frame in enumerate(range(staframe,endframe)):

      ipo[shapekey][frame]=(popout[i]-minvalue)*scale

Остальной скрипт теперь довольно прост. Он выбирает активный объект, затем пытается извлечь список имен ключей формы из него (выделено в следующей части). Это действие может потерпеть неудачу (следовательно, применяется  try … except), если, например, активный объект - не меш или он не имеет связанных ключей формы, в этом случае мы предупреждаем пользователя с помощью всплывающего сообщения:

if __name__ == "__main__":

   ob=Blender.Scene.GetCurrent().objects.active


   try:

      shapekeys = ob.getData().getKey(

                  ).getIpo().curveConsts

      key = popup(('Select a shape key%t|'+

                  '|').join(shapekeys))

      if key>0:

          Window.FileSelector (lambda f:sound2active(f,

            shapekeys[key-1]),

           "Select a .wav file",

           Blender.Get('soundsdir'))

   except:

      popup('Not a mesh or no shapekeys defined%t|Ok')

Если мы смогли извлечь список ключей формы, мы предоставляем пользователю всплывающее меню для выбора из этого списка. Если пользователь выбирает один из пунктов, переменная key будет положительной и мы предоставляем пользователю диалог выбора файлов (выделено). В этот диалог передаётся  lambda-функция, которая будет вызвана, если пользователь выберет файл, с передачей имени этого выбранного файла в качестве аргумента. В нашем случае мы создаём эту lambda-функцию, чтобы вызвать функцию  sound2active(), определённую ранее с этим именем файла и выбранным ключом формы.

Начальный каталог, который будет представлен пользователю в выборе файлов, определяется последним аргументом в функции FileSelector(). Мы задали его параметром Блендера soundsdir. Это обычно // (то есть, относительный путь, указывающий на тот же каталог, где находится .blend-файл, с которым пользователь работает), но может быть установлен в окне Пользовательских настроек (секция File Paths) на нечто другое.


Анимация меша .wav-файлом: последовательность действий

Теперь, когда у нас есть наш скрипт Sounds.py, мы можем применить его следующим образом:

1. Выбрать Меш-объект

2. Добавить ключ формы "Basis" к нему (окно Кнопок, контекст редактирования, панель Shapes). Он будет соответствовать наименее искаженной форме меша.

3. Добавить второй ключ формы и дать ему значимое имя.

4. Отредактировать этот меш, чтобы он представлял наиболее искаженную форму.

5. В режиме объектов, запустить Sound.py из текстового редактора, нажимая Alt + P.


Michel Anders читать все книги автора по порядку

Michel Anders - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


Написание скриптов для Blender 2.49 отзывы

Отзывы читателей о книге Написание скриптов для Blender 2.49, автор: Michel Anders. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.