Скачать 483.19 Kb.
|
2. Работа с файлами формата *.3ds Для удобства загрузки трехмерных объектов в данной работе используется 3ds формат. Этот формат поддерживается большинством распространенных пакетов моделирования. 3ds формат является закрытым, т.е. нет точного указания места хранения нужной информации, что немного усложняет работу с ним. Формат 3ds-файла имеет следующую особенность: все данные разделены на блоки – чанки.[9] Каждый чанк описывается именем и длиной. Чанки образуют древовидную структуру: один чанк может содержать внутри себя несколько других подчанков. Каждый чанк имеет следующий формат:
Т.о., чанк 3DS-Version (будет рассмотрен далее) в двоичном виде будет иметь вид: Рисунок 20 где 1 – это 0002, заголовок чанка 2 – это число 10, длина чанка (2[имя чанка] + 4[длина информационной части] + 4[сама информационная часть]) 3 - информационная часть, может содержать подчанки 3ds-файл содержит очень много информации об объекте: координаты вершин, информация о гранях объекта, текстурные координаты, данные о материале, освещении и т.д. Но в поставленной задаче важна только геометрия объекта, т.о. необходимо учитывать информацию только о вершинах и гранях трехмерного объекта. Объект в 3ds формате имеет специфичное представление: координаты вершин хранятся отдельно, а грани представляют собой три указателя на индекс каждой из трех вершин. Все вершины обходятся по часовой стрелке, исключая хранение нормалей (об этом говорилось выше). Именно с учетом этого в данной работе используется аналогичное представление трехмерного объекта. Для работы с геометрией объекта достаточно знать информацию о нескольких чанках. Их структура представлена ниже: Рисунок 21 Как уже говорилось выше, чанки, помимо подчанков, могут содержать некоторую информацию. Для данной задачи необходима только информация, содержащаяся в CHUNK_VERTLIST и CHUNK_FACELIST. Ниже они рассматриваются более детально. CHUNK_VERTLIST (0x4110):
На каждую координату выделяется 4 байта. Всего у вершины три координаты, значит, на каждую вершину 12 байт. Учитывая количество вершин легко посчитать количество необходимых байт. Следует заметить, что в 3ds-формате координаты вершины идут не в порядке (x, y, z), а в порядке (x, z, y). CHUNK_FACELIST (0x4120):
Флаги позволяют манипулировать с отображением граней:
В 3ds-файле может содержаться информация о нескольких экспортированных в него объектах. Поэтому (если такая ситуация возможна), нужно в CHUNK_OBJBLOCK извлечь имя нужного объекта. Оно представляет собой строку, оканчивающуюся нулем (C-string). 2.1. Функция импорта из *.3ds-файла Идея алгоритма импорта из *.3ds-файла состоит в том, чтобы побитово считывать информацию, строго придерживаясь структуры файла. Т.е. нельзя искать идентификатор нужного чанка, не найдя идентификатор родителя. Так для извлечения информации о вершинах и гранях объекта необходимо пройти следующие этапы:
2.2. Функция экспорта в *.3ds файл В данной работе из 3ds-файла извлекается минимальное количество информации, нужное для дальнейшей работы: геометрия объекта. При записи в файл нужно внести немного больше информации, чтобы другие приложения могли использовать файл. Данная работа ориентирована прежде всего для содействия с 3D Studio Max, поэтому в файл записываются минимально достаточные для работы в этой среде с файлом данные. Функция экспорта представляет собой побитовую запись информации в файл. При экспорте, помимо структуры формата, важно помнить о границе каждого чанка. Если при импорте (считывание из 3ds-файла) приходилось искать нужный чанк по имени и длина чанка, хоть и играла роль, но отступ на несколько байт не был критичным, то при экспорте (запись в 3ds-файл) важен каждый байт. Что касается четкой границы каждого чанка, то важно помнить, что в файл записывается длина всего чанка, т.е. данные + длина + название [6]. Кроме того, байты пишутся в обратном порядке см. Рисунок 20. Помимо чанков, которые просматривались для извлечения информации из файла, при записи необходимо знать точные данные следующих чанков: Обозначения: Chunk # : кодовое имя Name : название чанка Level : уровень в дереве чанков Size : длина Father : кодовое имя родительского чанка Чанки: ________________________________________________________ 0x0002 : 3DS-Version Chunk # : 0x0002 Name : 3DS-Version Level : 1 Size : 4 Father : 0x4D4D (Main chunk) ________________________________________________________ 0x3D3E : Mesh version Chunk # : 0x3D3E Name : Mesh version Level : 2 Size : 4 Father : 0x3D3D (3D editor chunk) ________________________________________________________ 0x0100 : One unit Chunk # : 0x0100 Name : One unit Level : 2 Size : 4 Father : 3D Editor chunk В данной работе для них используются стандартные для 3D Studio Max 8.0 значения: 3DS-Version: (int) 3 Mesh version: (int) 3 One unit: 0x0000803F Остальные чанки описывают различные особенности сцены. Для данной задачи их использование не обязательно. В Приложении Г находится пример 3ds файла в двоичном виде. Алгоритм экспорта объекта в *.3ds-файл состоит в подсчете длины чанка не в тот момент, когда чанк пишется в файл, а в тот, когда он полностью записан. Это связано с тем, что изначально длины чанков неизвестны (они зависят от длин самых «глубинных» чанков). Удобно изначально оставить место (4 байта) для длины текущего чанка, а потом, подсчитав его длину, на оставленное место записать точное значение. 3. Разработка динамически подключаемой библиотеки классов (DLL) Библиотека классов (DLL) - это один или несколько объединенных общим назначением классов или функций, скомпилированных в форму разделяемой библиотеки с расширением dll. Код из разделяемой библиотеки может использоваться в различных программах с помощью динамического связывания на этапе выполнения программы. Процедуры и функции, содержащиеся в динамической библиотеке, можно разделить на два типа: те, которые могут быть вызваны из других приложений и те, которые используются только внутри самого файла библиотеки. Чтобы функции были доступны из внешних приложений, их необходимо объявлять рассмотренным ниже способом. 3.1. Функция экспорта в dll-файл В приложении, в котором будет «собираться» библиотека классов, т.е. будет происходить экспорт в dll-файл, нужно указать следующее: … extern "C" //здесь хранятся функции, видимые из внешних приложений { _declspec (dllexport) type NameFunction (parametres) { … } … } … <здесь могут быть функции, видимые только внутри библиотеки> Экспорт классов осуществляется несколько сложнее. В dll нет понятия класса как такового. Альтернативой является структура. Поэтому, при необходимости экспорта некоторого класса, для него нужно реализовать интерфейс, представленный структурой с основными переменными класса. Во внешнем приложении также необходимо объявить этот интерфейс. В данной работе для успешного выполнения задачи необходимо лишь задать объекты. Следовательно, необходим интерфейс для класса OBJECT3D, реализованного в библиотеки классов. Но для описания объекта используется также класс POINT3D. Значит и для этого класса нужен интерфейс: typedef struct point_type { double x, y, z; }point_3d; typedef struct object_type { vector vertexes; vector }object_3d; Эти 2 структуры также нужно объявить во внешнем приложении, использующем данную библиотеку. Так как приложение, экспортирующее в dll функции, работает с классами, а приложение, импортирующее функции – со структурами, необходимо реализовать переход от класса к структуре и обратно. Все это сделано в библиотеке классов. В Приложении Б приведен код объявления функций, экспортирующих данные в dll. 3.2. Функция импорта из *.dll - файла Для использования dll из внешнего приложения, следует придерживаться следующих этапов: сначала нужно объявить, как уже говорилось выше, все интерфейсы для классов. Затем нужно подгрузить библиотеку. Сделать это можно двумя способами: статически и динамически.[2] При статическом использовании библиотека будет подгружаться и храниться в памяти сразу при запуске приложения. Это наиболее легкий способ использования кода, помещенного в dll . Недостаток метода заключается в том, что если файл библиотеки, на который имеется ссылка в приложении, отсутствует, программа откажется загружаться. При динамической загрузке библиотека подгружается не при старте приложения, а когда это действительно необходимо. Преимуществом такого метода является быстрота работы приложения, т.к. библиотека не хранится в памяти все время. Выгрузить ее можно также вручную, либо она выгрузится сама при завершении работы приложения. Еще одним преимуществом такого способа является быстрый старт приложения, а также, что необходим только один файл *.dll. при статической загрузке нужен также *.lib файл, скомпонованный одновременно с *.dll файлом. В демонстрационной программе используется динамическая загрузка dll. Синтаксис следующий: HINSTANCE hinstLib = LoadLibrary("graphics3d.dll"); if (hinstLib == NULL) { printf("ERROR: unable to load DLL\n"); getchar(); } Нужная функция из файла dll импортируется следующим образом: 1) Объявления типа: typedef object_3d* (*JoinObjects)(object_3d *, object_3d *); 2)Объявление переменной: JoinObjects JoinObj; 3)Получение адреса функции: JoinObj = (JoinObjects)::GetProcAddress (hinstLib, "JoinObjects"); С этого момента можно использовать функцию JoinObj: object3 = JoinObj (object1, object2); В Приложении Е размещен фрагмент кода из внешнего приложения, иллюстрирующий импорт из dll 4. Разработка плагина для 3D Studio Max 8.0 Для того, чтобы удобнее использовать результат вышеизложенных алгоритмов, было разработано расширение (далее плагин) для 3D Studio Max. Под плагином (англ. plug-in) понимают независимо компилируемый программный модуль динамически подключаемый к основной программе, предназначенный для расширения или использования её возможностей [4] Разработка плагинов под 3dmax возможна двумя способами: 1. с помощью языка скриптов (MAXScript)
Возможна еще реализация, совмещающая в себе оба пункта. Под скриптом (сценарием) понимают программу, которая автоматизирует некоторую задачу, которую без сценария пользователь делал бы вручную, используя интерфейс программы [4] MAXScript – объектно-ориентированный скриптовый язык программирования, встроенный в 3D Studio Max. Он очень удобен для написании небольших скриптов, позволяющих автоматизировать какие-либо действия в среде 3dmax. Разрабатывать на нем сложные плагины нецелесообразно ввиду относительно медленной скорости выполнения команд. Но MAXScript имеет заметное преимущество по сравнению со вторым методом: простота разработки кода. Большая часть плагинов для 3dmax – это плагины, реализованные с помощью 3D Studio MAX SDK [10]. Главным преимуществом такого подхода является высокая скорость исполнения команд. Удобным для разработки кода является способ, при котором интерфейс приложения реализован на MAXScript, а логика с помощью SDK. Это связано с тем, что в среде 3D Studio Max все плагины загружаются в память при запуске приложения. В данном случае интерфейс будет «зафиксирован» средой при запуске, а логика будет подгружаться при выполнении каких-либо действий с формой. Т.о. плагин (plug-in) обычно понимают как динамически подключаемую библиотеку (DLL), которая экспортирует несколько функций, распознающихся тем приложением, для которого пишется плагин. Единого стандарта типов экспортируемых функций нет, для каждого приложения требуются строго определенные функции, однако, приложения, предназначенные для одного типа задач, могут «понимать» плагины друг друга [11] В 3D Studio Max существует огромное множество типов плагинов. Это могут быть экспортеры и импортеры геометрии, утилиты, модификаторы, плагины текстур и материалов и многие другие. Принято соглашение об именовании *.dll файлов согласно их предназначению. Например, для экспортеров характерно расширение *.dle. При этом файл не меняет своей структуры, а является все тем же *.dll-файлом. Для утилит характерно именование *.dlu . Далее рассмотрены основные моменты реализации утилиты для 3D Studio Max, позволяющей работать с трехмерными объектами. Структура плагина Для того, чтобы 3D Studio Max мог распознать плагин, необходимо реализовать несколько, определенных в классах SDK, функций [13] 1. DllMain Стандартная main-функция используемая Windows для инициализации DLL 2. LibNumberClasses В одной библитекеDLL может быть реализовано несколько плагинов. Каждый плагин описывается специальным классом (об этом рассказано ниже) Данная функция возвращает их количество. 3. LibVersion Возвращает версию 3D Max, для которой предназначен плагин. Ее можно получить из глобальной константы VERSION_3DSMAX, прописанной в Max SDK 4. LibDescription Если при запуске среды файл плагина не доступен, то строка, возвращаемая данной функцией, будет показан пользователю 5. LibClassDesc Возвращает указатель на экземпляр класса-описателя конкретного плагина. Все эти функции должны быть экспортируемыми. Базовый класс Если реализуется утилита, то класс, описывающий подобный плагин, должен быть порожден от базового класса UtilityObj, описанного в SDK. Именно с помощью этого класса ведется работа с формой. Этот класс является виртуальным и имеет пять методов, три из них разработчик должен реализовать в своём порожденном классе [13]
Используется для удаления экземпляра класса плагина.
Два последних метода используются для панели управления. Первый – загружает ее в память в тот момент, когда пользователь открывает плагин. Второй – удаляет ее при завершении пользователем работы с плагином. Панель управления представляет собой обычное диалоговое окно, созданное средствами Visual Studio (см. Рисунок 22). Рисунок 22. Слева – диалоговое окно, открытое в редакторе Visual Studio, справа – в 3D Studio Max Все объекты, которые должны реагировать на события (кнопки, поля вывода), являются объектами Custom Controls, что позволяет более удобную обработку событий [13]. Для работы с панелью управления используется класс Interface. Указатель на экземпляр этого класса передается средой в аргументы функций BeginEditParams и EndEditParams. Т.к. панель является обычным диалоговым окном, для обработки действий пользователя необходимо использовать стандартную для Windows-программирования функцию обработки сообщений. Класс-описатель плагина Этот класс необходим для того, чтобы сообщить сведения системе о типе плагина. Он должен быть порожденным от класса ClassDesc2 (который порожден от класса ClassDesc), описанном в MAX SDK. Для указания типа плагина используется уникальный общий идентификатор. Для плагинов утилитного типа его значение хранится в константе UTILITY_CLASS_ID. Кроме того, каждый конкретный плагин должен иметь свой уникальный идентификатор. Для его генерации можно воспользоваться файлом gencid.exe, который поставляется со стандартным набором MAX SDK. Ниже приведен фрагмент кода, где показан класс-описатель. //получение уникального идентификатора #define PLUGIN_CLASS_ID Class_ID(0x1218491c, 0x405444d4) class PlaginClassDesc : public ClassDesc2 { public: SClass_ID SuperClassID(); Class_ID ClassID(); void * Create(BOOL loading); const TCHAR * ClassName(); const TCHAR * Category(); int IsPublic(); }; Функция SuperClassID возвращает идентификатор UTILITY_CLASS_ID. Функция ClassID возвращает идентификатор PLUGIN_CLASS_ID. Функция Create возвращает указатель на экземпляр базового класса. Функция ClassName возвращает строку, которая будет отображаться на кнопке вызова скрипта. Функция Category возвращает строку, которая указывает принадлежность плагина к одной из категорий. Категории можно посмотреть в стандартном окне Configure Button Sets Рисунок 23. Категории плагинов Логическая часть плагина основана на классах, написанных ранее. Плагин поддерживает выбор объектов из окон трехмерного вида по щелчку мыши, вывод объекта полученного в результате пересечений двух других объектов в сцену, работу с алгоритмом определения положения точки относительно трехмерного объекта в сцене. Руководство пользователя 3D Studio Max 40 находится в Приложении А, руководство прикладного программиста в Приложении Б, руководство разработчика в Приложении В. |
Министерство образования и науки российской федерации томский государственный... Целью дисциплины является ознакомление студентов с базовыми понятиями следующих разделов информатики: теория информации, технические... | Красноярский государственный педагогический университет факультет информатики Задание: Разработать требования к оборудованию и оснащению кабинета информатики с заданным количеством персональных эвт в учебном... | ||
Минобрнауки томский государственный университет факультет информатики утверждаю Задача учебного курса – освоение психолого-педагогических знаний, вопросов методики преподавания, современных методов обучения | Молдавский Государственный Университет Факультет Математики и Информатики.... За последние 9 лет (c 1993) в мире персональных компьютеров появился новый участник – персональный карманный компьютер (кпк). Большую... | ||
Программа по формированию навыков безопасного поведения на дорогах... Московский Государственный Университет Приборостроения и Информатики, Факультет "Технологическая информатика", кафедра "Компьютерный... | Министерство образования и науки РФ новосибирский государственный... Когда появляется изображение цепи ордена Андрея Первозванного на российском гербе | ||
Министерство образования и науки российской федерации томский государственный... Государственное общеобразовательное учреждение-средняя общеобразовательная школа | Государственное образовательное учреждение высшего профессионального... Аннотация умкд… | ||
Государственное образовательное учреждение высшего профессионального... Аннотация умкд… | Государственное образовательное учреждение высшего профессионального... Аннотация умкд… | ||
Российской Федерации Федеральное государственное бюджетное образовательное... «Московский государственный университет экономики, статистики и информатики (мэси)» | Российской Федерации Федеральное государственное бюджетное образовательное... «Московский государственный университет экономики, статистики и информатики (мэси)» | ||
Министерство сельского хозяйства российской федерации Е образовательноЕ учреждениЕ высшего профессионального образования «Московский государственный университет экономики, статистики... | Российской Федерации Карельский государственный педагогический университет... В 1962 году на факультете физической культуры была создана первая специальная кафедра теоретических основ физического воспитания.... | ||
Методические рекомендации по подготовке и выполнению вкр министерство... Фгбоу впо «Московский Государственный Университет экономики, статистики и информатики (мэси)» | О. В. Артюшкин Хакасский государственный университет им. Н. Ф. Катанова... При рассмотрении информатики с позиций гуманитарной, технической, естественной и фундаментальных наук даются ее определения. В заключительной... |