2021-05-17 12:03:17
Пора нам придумать свой бинарный формат
В качестве примера я запишу в файл анимационный канал из объекта
Autodesk Maya.
Можете открыть мой код и следить по тексту.
Если у вас есть
Maya, то можно даже запустить код и посмотреть на результат.
Начнём запись!
Сначала запишем имя канала, это будет имя атрибута, с которого пишется анимация. Сделаем предел в 64 байта.
struct.pack('=64s', channel_name.encode())
Далее диапазон кадров, это два числа типа long
struct.pack('=2L', start_frame, end_frame)
Потом пишем анимацию в виде массива
float значений. В примере запись идёт покадрово, то есть мы не загружаем весь массив ключей в память.
for i in range(start_frame, end_frame + 1):
val = obj.attr(channel_name).get(t=i)
f.write(struct.pack('=f', val))
Всё, файл готов! Итого у нас получился такой формат "=64s2L{N}f", где {N} это количество записанных значений.
Теперь чтение.
Считываем первые 64 байта, это имя канала.
Первое с чем столкнёмся, это нулевые байты в имени канала, которые заполняют свободное пространство в выделенных 64 байтах. Просто удаляем их.
struct.unpack('=64s', f.read(64))[0].rstrip(b'\x00')
Читаем диапазон кадров, записанный в этот файл.
frange_len = struct.calcsize('=2L')
Функция
struct.calcsize() возвращает размер данных в зависимости от указанного формата. Используем это чтобы прочитать нужное количество байт из файла.
start_frame, end_frame = struct.unpack('=2L', f.read(frange_len))
Из диапазона рассчитаем длину анимации и забираем массив
float значений. В коде есть вариант чтения по одному значению и полностью весь массив.
key_count = end_frame - start_frame + 1
frmt = f'={key_count}f'
keys = struct.unpack(frmt, f.read(struct.calcsize(frmt)))
Всё, данные прочитаны! Остальной код примера связан с манипуляцией объектами в Maya, чтобы визуально можно было увидеть, что анимация корректно восстановилась из файла.
Вот таким образом мы придумали свой бинарный формат данных.
Возможно, такие сложности вам покажутся излишними, но представьте когда данных действительно много, и один кадр содержит миллионы позиций 3D точек, и записать требуется 50000 кадров!
Всё это в оперативку явно не поместится, придётся для каждого кадра делать отдельный файл. Если же мы можем писать данные постепенно, то это не проблема. Можно постепенно заполнять файл или писать несколько файлов паралельно.
#libs #tricks
651 views09:03