- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Написание скриптов для Blender 2.49 - Michel Anders
Шрифт:
Интервал:
Закладка:
dstfilename = os.path.basename(filename)
while dstfilename in files:
dstfilename = nextfile(dstfilename)
Затем, мы выгружаем наш файл изображения, вызывая метод storbinary(). Этот метод принимает имя целевого файла с префиксом STOR, как первый аргумент, и открытый файловый дескриптор как второй аргумент. Мы предоставляем последний, вызывая встроенную функцию Питона open() с именем нашего файла изображения в качестве единственного аргумента. (Если нужна дополнительная информация о довольно диковинном поведении модуля ftplib, ссылка на его документацию: http://docs.python.org/library/ftplib.html.) Мы грациозно заканчиваем связь в FTP-сервером, вызывая метод quit(), и сообщаем пользователю о завершении задачи, показывая сообщение с упоминанием имени целевого файла, так как оно может отличаться от ожидаемого, если существует файл с аналогичным именем:
ftp.storbinary('STOR '+dstfilename,open(filename))
ftp.quit()
Draw.PupMenu('Render result stored as "%s"%s|Ok'
%(dstfilename,'%t'))
Полный код доступен как ftp.py в файле ftp.blend. Его можно запустить из текстового редактора, но в общем случае, несомненно, значительно удобнее поместить ftp.py в каталог скриптов Блендера. Скрипт сконфигурирован так, чтобы он был доступен в меню Файл | Экспорт (File | Export).
Весенняя уборка - архивация неиспользуемых изображений
Через некоторое время у любого долгоживущего проекта набирается много хлама. Например, изображения текстур, которые Вы пытались применить, но они были отвергнуты в пользу более подходящих. Этот скрипт поможет нам найти все файлы в выбранном каталоге, на которые нет ссылок в нашем .blend файле, и упаковать их в ZIP-архив.
Мы позаботимся о том, чтобы не переносить никаких .blend файлов в ZIP-архив (в конце концов, мы, как правило, хотим быть в состоянии рендерить), ни самого ZIP-архива (для предотвращения бесконечной рекурсии). Любой файл, который мы архивируем, мы затем попытаемся удалить, и если удаление файла оставляет пустой каталог, мы удалим также этот каталог, если он не является тем каталогом, где находится наш .blend файл.
Функции работы с файлами предоставляются модулями Питона os и os.path, а ZIP-файлами, которые могут использоваться как в Windows так и на открытых платформах, можно манипулировать с помощью модуля zipfile. ZIP-файл, в который мы перемещаем неиспользованные файлы, мы назовём Attic.zip:
import Blender
from os import walk,remove,rmdir,removedirs
import os.path
from zipfile import ZipFile
zipname = 'Attic.zip'
Первой задачей будет сгенерировать список всех файлов в каталоге, где находится наш .blend-файл. Функция listfiles() использует функцию walk() из модуля Питона os, чтобы рекурсивно обойти дерево каталогов и построить список файлов при обходе.
По умолчанию, функция walk() проходит по дереву каталогов первой глубины, что позволяет нам изменять список каталогов на лету. Эта возможность используется здесь, чтобы удалить любые каталоги, которые начинаются с точки (выделено). Это не необходимо для текущего и родительского каталогов (они представлены посредством .. и . соответственно), поскольку walk() уже фильтрует их, но это позволяет нам, например, также отфильтровать любые .svn каталоги, которые могут нам встретиться.
Строка, содержащая оператор yield, возвращает как результат один файл за один раз, так что наша функция может быть использована как итератор. (Для дополнительной информации об итераторах, смотрите online-документацию по адресу http://docs.python.org/reference/simple_stmts.html#yield) Мы соединяем соответствующее имя файла и путь, чтобы сформировать полное имя, и нормализуем его (то есть, удаляем двойные разделители пути и тому подобное); хотя нормализация здесь не строго необходима, поскольку walk() должна возвращать любые пути в нормализованной форме:
def listfiles(dir):
for root,dirs,files in walk(dir):
for file in files:
if not file.startswith('.'):
yield os.path.normpath(
os.path.join(root, file))
for d in dirs:
if d.startswith('.'):
dirs.remove(d)
Прежде, чем мы сможем сравнить список файлов, которые используются нашим .blend-файлом со списком файлов, присутствующих в каталоге, мы убеждаемся, что любой упакованный файл распакован на свое первоначальное местоположение. Не строго необходимо, но позволяет удостовериться, что мы не перемещаем в архив никаких файлов, которые непосредственно не используются, но имеют копию в .blend-файле:
def run():
Blender.UnpackAll(Blender.UnpackModes.USE_ORIGINAL)
Функция GetPaths() из модуля Blender выдаёт список всех файлов, используемых .blend-файлом (за исключением самого этого .blend-файла). Мы передаем ей аргумент absolute установленным в Истину, чтобы извлекать имена файлов с полным путём вместо относительных путей от текущего каталога для того, чтобы сравнить их должным образом со списком, произведённым функцией listfiles().
Снова мы также нормализуем эти имена файлов. Выделенная строка показывает, как мы извлекаем абсолютный путь текущего каталога, передавая условное обозначение для текущего каталога Блендера ( // ) в функцию expandpath():
files = [os.path.normpath(f) for f in
Blender.GetPaths(absolute=True)]
currentdir = Blender.sys.expandpath('//')
Затем мы создаём объект ZipFile в режиме write (записи). Это отбросит любой существующий архив с тем же именем, и позволит нам добавлять файлы в архив. Полное имя архива строится соединением текущего каталога Блендера и имени, которое мы хотим использовать для архива. Использование функции join() из модуля os.path обеспечивает нам создание полного имени платформо-независимым образом. Мы установили аргумент debug (отладка) объекта ZipFile в значение 3, чтобы сообщать о чём-либо необычном на консоль при создании архива:
zip = ZipFile(os.path.join(currentdir,zipname),'w')
zip.debug = 3
В переменную removefiles (удаление файлов) записываются имена файлов, которые мы хотим удалить после того, как мы создали архив. Мы можем безопасно удалить файлы и каталоги только после того, как мы создали архив, иначе может оказаться, что мы ссылаемся на каталоги, которые больше не существуют.
Архив создаётся проходом цикла по списку всех файлов в текущем каталоге Блендера и сравниванием их со списком файлов, использованных нашим .blend-файлом. Любой файл с таким расширением, как например, .blend или .blend1 пропускается (выделено), как и сам архив. Файлы добавляются к ZIP-файлу использованием метода write(), который принимает в качестве параметра имя файла с путём относительно архива (и, следовательно, текущего каталога). Этот путь удобнее для распаковки архива в новом месте. Любые ссылки на файлы за пределами текущего дерева каталогов не затрагиваются функцией relpath(). Любой файл, который мы добавляем к архиву, помечается для удаления добавлением его к списку removefiles. Наконец, мы закрываем архив - важный шаг, поскольку, если его опустить, мы можем остаться с запорченным архивом:
removefiles = []
for f in listfiles(currentdir):
if not (f in files
or os.path.splitext(f)[1].startswith('.blend')
or os.path.basename(f) == zipname):
rf = os.path.relpath(f,currentdir)
zip.write(rf)
removefiles.append(f)
zip.close()
Последней задачей будет удаление файлов, которые мы переместили в архив. Функция remove() из модуля Питона os выполнит это, но мы также хотим удалить любой каталог, который остался пустым после удаления файлов. Следовательно, для каждого файла, который мы удаляем, нам надо определить имя его каталога. Мы также удостоверяемся, этот каталог не указывает на текущий каталог, потому что мы хотим быть абсолютно уверены, что мы не удаляем его, так как это место, где находятся наши .blend-файлы. Хотя это маловероятный сценарий, что можно открыть .blend-файл в Блендере и удалить сам этот .blend файл, что могло бы оставить каталог пустым. Если мы удалим этот каталог, любое последующее (авто) сохранение должно потерпеть неудачу. Функция relpath() возвращает точку, если каталог, переданный как первый аргумент, указывает на тот же каталог, что и каталог, переданный как второй аргумент. (Функция samefile() является более надежной и прямой, но не доступна в Windows.)

