Как ускорить загрузчик файлов .obj для HalfEdge Mesh?

Я работаю над приложением 3D OpenGl (C ++), в котором у меня есть собственная структура сетки, основанная на структуре данных Half-Edge. Я хочу создать простой способ загрузки файлов obj Wavefront в мою структуру сетки. Конечно, я могу делать это наивно построчно, но должен быть какой-то более эффективный способ (я знаю, что профессиональные приложения не загружают файл построчно наивно, это было бы слишком медленно для миллионов вершин).

Может ли кто-нибудь указать мне на учебник или пример действительно быстрого загрузчика OBJ? Было бы предпочтительнее, если бы это было связано со структурой данных Half Edge.

Редактировать:

Есть две основные проблемы, которые я пытаюсь решить.

1) Избегайте общей медлительности чтения чисел с плавающей запятой из файла.

2) Как на лету грамотно определять «смежную» половину кромки для каждого ребра. Я представляю себе какую-то хеш-функцию, чтобы определить, существует ли уже симметричное или следующее ребро для создаваемого ребра, и если да, то использовать этот указатель.


person Sam Stern    schedule 10.04.2012    source источник


Ответы (2)


Некоторое время назад у меня была аналогичная проблема с загрузкой файлов OBJ, хотя я искал общие вершины, а не ребра. Поскольку сам формат файла не содержит информации о подключении, лучше всего использовать std::set. Каждый раз, когда вы хотите добавить ребро в свою структуру данных, вы можете выполнить поиск в наборе, чтобы увидеть, существует ли он уже. Поиск по множеству имеет логарифмическую сложность, поэтому он хорошо масштабируется в зависимости от размера вашей структуры данных. Единственный способ избежать этого, о котором я могу думать, - это выбрать формат файла, который содержит необходимую информацию о подключении, или, как предложил Майкл Слейд, создать свой собственный формат и инструмент преобразования.

person PeddleSpam    schedule 13.04.2012
comment
std::unordered_set даст вам O (1) поиск. - person Adi Shavit; 29.07.2016
comment
Верно, но я стараюсь избегать хэш-карт, когда мне нужно часто вставлять или стирать элементы. При чтении большого количества данных ваша std::unordered_set (хеш-карта) должна часто перехешировать, что является довольно дорогостоящей операцией. Вы могли бы зарезервировать место, если бы знали, сколько примитивов используется совместно, но файлы OBJ этого не дают. Было бы интересно посмотреть, какой контейнер лучше всего подходит для файлов разных размеров. - person PeddleSpam; 19.09.2016

Чтение и декодирование файлов ascii происходит медленно, особенно если файлы содержат миллион чисел с плавающей запятой для преобразования.

Моя идея: написать программу на любом желаемом языке, чтобы перевести файлы .obj в двоичный формат, который ваша программа может более или менее читать прямо в память. Затем запустите эту программу для файлов .obj, которые вы хотите загрузить, и пусть ваша программа загрузит переведенные файлы.

В качестве дополнительных баллов вы можете попросить вашу программу opengl выполнять этот перевод на лету и кэшировать результаты, проверяя время модификации файлов и обновляя кеш по мере необходимости.

person Michael Slade    schedule 10.04.2012
comment
Что ты хочешь этим сказать? Разве эта программа не будет выполнять ту же работу, которой вы пытаетесь избежать? - person Sam Stern; 10.04.2012
comment
да, но тогда вы можете сделать это заранее, а не заставлять программу делать это каждый раз при запуске. - person Michael Slade; 10.04.2012
comment
Мне нужно загрузить любой файл OBJ во время работы моей программы. Проблема не в стоимости чтения чисел, а в том, как грамотно связать лица. - person Sam Stern; 10.04.2012
comment
Вы говорите о сворачивании совпадающих вершин в одну запись? Или что-то другое? - person Michael Slade; 10.04.2012
comment
Сначала схлопывающиеся вершины. Во-вторых (это будет иметь больше смысла, если вы знакомы со структурой данных половинных ребер), мне нужно найти симметричный край каждого ребра, когда я просматриваю файл. В точке, где встречаются две грани, есть ребро, которое должно быть представлено двумя половинными ребрами. - person Sam Stern; 10.04.2012
comment
Похоже, это намного больше, чем просто загрузка файла .obj для отображения. Пожалуйста, измените свой вопрос. вы просто хотите иметь возможность отображать объекты, определенные в файлах .obj? или что-то более изысканное? - person Michael Slade; 10.04.2012
comment
т.е. для какой цели вы хотите скомпилировать полуреберную структуру? - person Michael Slade; 10.04.2012
comment
Ты прав. Мой главный вопрос касается HalfEdge, а не File IO. - person Sam Stern; 10.04.2012