Главная / Статьи / Ansys CFX / Ошибка визуализации в ANSYS CFX-Post, диагностика и пути решения

Ошибка визуализации в ANSYS CFX-Post, диагностика и пути решения

( 0 Голосов )
Кирилл “deLuther” Сергеев 22.04.2009

Возможно многие владельцы карт ATI с определённого времени сталкивались с подобными проблемами при отрисовке контуров (Contour) в Ansys CFX-Post:

глюки в cfx-post

 

Проблема связана с новыми картами и драйверами (в рамках примерно 2х лет), но старые драйвера, где проблемы нет, невозможно адекватно использовать с новыми картами.

Чем же она вызвана и можно ли это вылечить?

Чтобы понять суть этой проблемы я воспользовался инструментарием для отладки приложений OpenGL, а именно GLIntercept 0.5. Данный инструмент представляет собой библиотеку-транслятор для вызова функций из настоящей библиотеки OpenGL32.dll. В результате по логу можно понять как работает то или иное приложение, естественно для тех кто знает OpenGL. Получив такой лог для достаточно небольшой геометрии, я решил перенести проблемный код в своё приложение, где я мог бы методом исключения найти проблемные места. Сказано - сделано, мое собственное приложение продемонстрировало те же самые проблемы (http://malefice.fatal.ru/files/GLCFXTest.rar):

контура в cfx-post

В первую очередь была проверена гипотеза с дисплей-листами. Оказалось, что тот же самый код даёт другой результат при непосредственном выводе геометрии (без дисплей-листов):

конутра в cfx-post

Примечание:

Дисплей-листы представляет самый простой и эффективный способ вывода геометрии, при компиляции дисплей-листа (в момент создания) данные помещаются в видеопамять (во всяком случае у ATI, у NVidia встречаются некоторые неоднозначности). При необходимости нарисовать содержимое дисплей-листа он вызывается одной командой. Другие стандартные средства OpenGL (за исключением расширений) не помещают данные в видеопамять. Это даёт практически на порядок большую скорость вывода, особенно для больших моделей. Большинство продуктов ANSYS пользуются этим механизмом вывода (за исключением Fluent).

Дальше был проанализирован OpenGL-код. Оказалось, что проблемы заключаются в том, что внутри дисплей-листов (при создании) текущий цвет не устанавливается. И в некоторые моменты получается неопределённым, из-за чего и выплывают треугольники неправильной окраски. Все неправильные треугольники и квада (четырёхугольные примитивы) появляются после разрыва следующего вида:

glBegin(GL_TRIANGLES);
glColor4f(0.000000f,0.131579f,1.000000f,1.000000f);
glNormal3f(0.000000f,1.000000f,0.000000f);
glVertex3f(0.305661f,0.000000f,1.412402f);
...
glNormal3f(0.000000f,1.000000f,0.000000f);
glVertex3f(0.500620f,0.000000f,-0.180434f);
glEnd();
glBegin(GL_TRIANGLES);
glNormal3f(0.000000f,1.000000f,0.000000f);
glVertex3f(0.429916f,0.000000f,-0.129703f);
...
glNormal3f(0.000000f,1.000000f,0.000000f);
glVertex3f(-7.540471f,0.000000f,2.155247f);
glEnd();

Формально в подобных местах разрывать последовательность задания примитивов не обязательно т.к. количество вершин между glBegin()-glEnd() никак не ограничено спецификацией OpenGL. Кроме того, видно, что после последующего glBegin() нет задания цвета (glColor) и все треугольники (квады) задаваемые на этом участе (до следующего вызова glColor) имеют неправильный цвет.

Если удалить такое разделение (glEnd()-glBegin()) на стыке, то всё рисуется правильно.

После анализа ситуации видно, что с одной стороны проблема кроется в драйверах ATI и, частично, в стиле программирования.

Осознание проблемы наметило некоторые пути её решения. Решено было создать библиотеку-корректор действующую по аналогу с GLInterceptor, которая будет служить прослойкой между CFX-Post и системной OpenGL32.dll. Логика решения проста: отслеживать задание цвета внутри дисплей-листов, сохранять текущее значение и при вызове glBegin добавлять недостающий вызов glColor. В качестве основы был взят другой инструмент для отладки OpenGL - GLTrace, из которого было выкинуто всё относящееся к отладочной информации. В результате была получена библиотека http://malefice.fatal.ru/files/opengl32.dll которую можно расположить в каталоге проблемного приложения (моего теста или CFX-Post - ..\CFX\bin\winnt). Ошибки исчезли.

К сожалению, такой способ срабатывал только на 32х-разрядных ОС.

Но, имея на руках данные экспериментов, пользователю под ником Dick удалось вырвать секретную переменную VIEWER_CACHE_COLORS, которая позволяет исправить проблему в версии 12. Надо создать переменную с таким именем и приравнять её нулю.

Действительно, эта переменная решает все проблемы в CFD-Post (т.е. CFX-Post V12).

Анализ перехвата команд OpenGL показывает, что в данном случае просто для каждой вершины задаётся цвет.

Какие неудобства это может вызвать?

Так как геометрия в OpenGL задаётся вершинами то количество данных пропорционально количеству вершин. При задании 4х компонент цвета, 3х компонент нормали и 3х координат, получается 10 чисел одинарной точности на вершину. Для 1 миллиона треугольников это будет: (4 + 3 + 3)*4* 3*1000000/1024^2 ~ 114.4 Мб. Таким образом 4 миллиона треугольников практически полностью займут видеопамять объёмом 512 Мб.

Правда что делать с версией 11?

Вооружившись названием переменной VIEWER_CACHE_COLORS и открыв на просмотр PostGui_ogl.exe, рядышком я обнаружил две других переменных с интригующими названиями VIEWER_FACE_LIST и VIEWER_LINE_LIST. Найденные переменные были сразу же опробованы.

VIEWER_FACE_LIST, значение не важно (лишь бы была, я пробовал 0 и 1), заставляет CFD-Post отрисовывать всё с помощью полигональных примитивов (GL_POLYGON). Каждый полигон задаётся индивидуально и драйвер в этом случае правильно отрисовывает контура. Размер дисплей-листа существенно не вырастает.

VIEWER_LINE_LIST, значение не важно (0,1), заставляет CFD-Post отрисовывать линии индивидуальным заданием отрезка, т.е. вызов glBegin(GL_LINES)-glEnd() для каждой пары вершин. С точки зрения производительности это ничего не меняет т.к. в любом случае glBegin(GL_LINES) означает, что вершины трактуются парами. Размер дисплей-листа такой же. Но линии тоже становятся правильного цвета, в противном случае могли быть линии белого цвета.

Но, что самое важное, версия 11 тоже понимает две последние переменные!

Размер дисплей листа для 1 миллиона треугольников: (3 + 3)*4*3*1000000/1024^2 ~ 68.7 Мб.

Таким образом, на мой взгляд, для решения проблем с CFX-Post (CFD-Post) достаточно добавить две переменные: VIEWER_FACE_LIST и VIEWER_LINE_LIST.

VIEWER_CACHE_COLORS использовать не стоит, если только не будет каких-нибудь проблем с новыми версиями драйверов. Всё проверялось для Catalyst 9.4, но и более ранние версии (например 8.x) должны работать так же.

Как добавить переменные (названия для англоязычной версии XP)?

Открываем свойства My Computer (Properties, по правой кнопке). Щёлкаем на вкладке Advanced (Дополнительно?). Жмём кнопку Environment Variables. Далее имеют место две группы - User Variables и System Variables. В зависимости от того хотите ли вы, чтобы переменная была у данного пользователя или у всех пользователей выбираем место.

Пусть мы хотим установить системную переменную (для всех пользователей).

Жмём кнопку New в группе SystemVariables (нижняя). В диалоге в качестве имени переменной (Variable Name) указываем VIEWER_FACE_LIST, в качестве значения 0 или 1 (без разницы). Аналогично для VIEWER_LINE_LIST. Дело сделано.


Кирилл "deLuther" Сергеев
e-mail: Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Теги: CAE Ansys CFX Теория

Добавить комментарий


Защитный код
Обновить

© ProCae.ru 2007-2010 При полной или частичной перепечатке редакционных и авторских материалов гиперссылка на «ProCae.ru» обязательна