Вы находитесь на странице: 1из 192

Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Московский государственный технический университет


имени Н.Э. Баумана

И.П. Иванов, А.М. Чеповский

ПРОГРАММНЫЕ СРЕДСТВА ОБРАБОТКИ


РЕЗУЛЬТАТОВ РАСЧЕТОВ
В ИНЖЕНЕРНЫХ ПАКЕТАХ ANSYS CFX И ABAQUS
ДЛЯ ВЫСОКОПРОИЗВОДИТЕЛЬНЫХ
ВЫЧИСЛИТЕЛЬНЫХ УСТАНОВОК

Допущено учебно-методическим объединением вузов


по университетскому политехническому образованию
в качестве учебного пособия для студентов
высших учебных заведений, обучающихся по направлению
230100 «Информатика и вычислительная техника»

Москва
Издательство МГТУ им. Н.Э. Баумана
2009
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

УДК 681.3.041.048(075.8)
ББК 30.2-5-05
И20
Р е ц е н з е н т ы : д-р физ.-мат. наук С.О. Старков,
д-р физ.-мат. наук, проф. С.В. Клименко

Иванов И.П.
И20 Программные средства обработки результатов расчетов
в инженерных пакетах Ansys CFX и Abaqus для высокопроизво-
дительных вычислительных установок : учеб. пособие / И.П. Ива-
нов, А.М. Чеповский. — М.: Изд-во МГТУ им. Н.Э. Баумана,
2009. — 189, [3] с.
ISBN 978-5-7038-3321-6
Приведены подробные сведения по использованию программных
средств обработки результатов инженерных расчетов. Рассмотрены
возможности и описания функций интерфейса программных средств
Ansys CFX и Abaqus. Описаны методы визуализации результатов
расчетов на примерах высокоуровневых библиотек Avango и Open
Inventor. Приведены подробные примеры использования указанных
средств разработки.
Для студентов и аспирантов технических специальностей, изу-
чающих курсы «Параллельное программирование», «Компьютерная
графика», «Современные сетевые технологии», «Распределенные
системы обработки информации», «Моделирование». Пособие будет
полезно также для всех интересующихся возможностями использова-
ния инженерных пакетов на высокопроизводительных вычислитель-
ных установках.

УДК 681.3.041.048(0.75.8)
ББК 30.2-5-05

ISBN 978-5-7038-3321-6  МГТУ им. Н.Э. Баумана, 2009


Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ВВЕДЕНИЕ

Одним из ключевых направлений развития современного об-


щества является прогресс высоких технологий, в первую очередь
информационных. Высокие технологии — это один из наиболее
важных факторов, влияющих на формирование общества XXI ве-
ка. Воздействие технологий касается образа жизни людей, их об-
разования и профессиональной деятельности.
Выявление и обоснование стратегических направлений и пер-
спектив развития мирового и российского рынка технологий име-
ют определяющее значение на современном этапе развития эконо-
мики. Именно разработка и внедрение новых технологий
способствуют прогрессу промышленности, финансовой стабиль-
ности предприятий, подготавливают базу для эффективного функ-
ционирования экономики.
Практически в каждой отрасли экономики требуются серьезные
вычислительные мощности для проведения исследований, анализа
деятельности, внедрения новых технологических процессов, обнов-
ления производства и снижения рисков. Возникает необходимость в
освоении, развитии и внедрении наукоемких технологий на базе
высокопроизводительных мультипроцессорных вычислительных
систем (ВМВС) в промышленности и социально-экономической
сфере. Не менее важными являются создание системного про-
граммного обеспечения ВМВС на базе новых вычислительных мо-
делей, а также разработка и внедрение современных прикладных
программных сред для решения сложных вычислительных задач.
Программно-аппаратные комплексы на базе ВМВС становятся все
более востребованными как на Западе, так и в России.
Что же заставляет представителей различных отраслей и ком-
паний прибегать к использованию ВМВС? Дело в том, что в со-
временном мире компании вынуждены постоянно усложнять про-
3
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

изводственные модели продуктов, чтобы повысить надежность


изделий, точность их изготовления, а также снизить риски и избе-
жать брака. И в нашей стране компании начинают экономить на из-
держках, выводить на рынок более совершенные продукты, внед-
ряя в производство сложные вычислительные системы. Видимо,
этот путь является сегодня неизбежным. Ведь чем сложнее, со-
вершеннее модель, тем больше вычислительной мощности требу-
ется для ее расчета; кроме того, необходимо большее пространство
для хранения промежуточной информации и результатов. Таким
образом, развитие- любой индустрии, будь то геодезия, автомоби-
лестроение или металлургия, связано с необходимостью примене-
ния ВМВС.
Данное пособие создано по результатам работ 2005–2008 гг.
в рамках программного мероприятия «Исследование проблем аде-
кватности, точности и масштабируемости, возникающих при ре-
шении задач из области CAE-приложений, аэрогидродинамики и
электромагнитных расчетов на кластерных высокопроизводитель-
ных мультипроцессорных вычислительных системах с использо-
ванием пакетов мирового уровня» в соответствии с научно-
технической программой Союзного государства «Развитие и вне-
дрение в государствах — участниках Союзного государства нау-
коемких компьютерных технологий на базе мультипроцессорных
вычислительных систем» (шифр «Триада»).
В подготовке данного учебного пособия принимали участие
студенты кафедры ИУ 9 «Теоретическая информатика и компью-
терные технологии» Никита Нечаев, Павел Фокин, Михаил Жуков.

4
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1. ВОЗМОЖНОСТИ ПАКЕТА ANSYS CFX

1.1. Основные сведения о пакете

Пакет Ansys CFX — это профессиональный аналитический


программный комплекс, предназначенный для решения широкого
спектра задач вычислительной газо- и гидродинамики.
Область применения Ansys CFX — моделирование многофаз-
ных потоков, химической кинетики, горения, радиационного теп-
лообмена, жидкостно-структурного взаимодействия. Программ-
ный комплекс позволяет решать задачи с подвижной сеткой, в нем
можно применять адаптивное сеточное сгущение. Программный
комплекс Ansys CFX является признанным лидером в моделиро-
вании течений в роторных машинах.
Основой всей расчетной технологии Ansys CFX является реша-
тель Algebraic Coupled Multigrid. Используя неявную связанную
схему решения линеаризованной системы уравнений, решатель
обеспечивает быструю и устойчивую сходимость в задачах всех
типов, при этом время решения задачи линейно зависит от объема
расчетной сетки.
Преимущество Ansys CFX особенно проявляется при изучении
больших моделей с многокомпонентными течениями и сложной
структурой. Решатель Ansys CFX малочувствителен к отношениям
размеров элементов, временным шагам и релаксационным факто-
рам. Точность решения достигается как за счет высокой точности
расчетов в каждом узле, так и за счет применения схемы дискрети-
зации второго порядка, устанавливаемой по умолчанию. Эти же
свойства сохраняются при параллельных расчетах, обеспечивая
ускорение процессов расчета на многопроцессорных системах и
кластерах рабочих станций.

5
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1.2. API экспорта пакета Ansys CFX

API (от англ. Application Programming Interface) — интерфейс


программных средств — набор готовых констант, структур и
функций, используемых при программировании пользовательских
приложений и обеспечивающих правильное взаимодействие меж-
ду пользовательским приложением и операционной системой. API
определяет функциональность, которую предоставляет программа
(модуль, библиотека), при этом API позволяет абстрагироваться от
того, как именно эта функциональность реализована.

1.2.1. Используемые константы и структуры

Константы и структуры, описанные в этом подразделе, опреде-


лены в заголовочном файле cfxExport.h, входящем в состав
библиотеки экспорта, поставляемой вместе с пакетом Ansys CFX.

Типы элементов

В Ansys CFX определены четыре типа элементов расчетной


сетки: тетраэдры (4 вершины), пирамиды (5 вершин), призмы
(6 вершин) и шестигранники (8 вершин). Для идентификации этих
элементов определены следующие константы:
#define cfxELEM_TET 4
#define cfxELEM_PYR 5
#define cfxELEM_WDG 6
#define cfxELEM_HEX 8

Типы объемов

Объемы могут быть заданы либо с помощью списка узлов рас-


четной сетки, либо с помощью списка элементов в зависимости от
типа аргумента, переданного в функции экспорта объемов. Для
данного аргумента определены две константы:
#define cfxVOL_NODES 0
#define cfxVOL_ELEMS 1

6
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Типы областей поверхности

Области поверхности модели могут быть заданы либо с помо-


щью списка элементарных участков поверхности, либо с помощью
списка узлов расчетной сетки в зависимости от типа аргумента,
переданного в функции экспорта областей поверхности. Для дан-
ного аргумента определены две константы:
#define cfxREG_NODES 0
#define cfxREG_FACES 1
В случае задания поверхности модели с помощью списка эле-
ментарных участков поверхности используется идентификатор
участка, который является комбинацией глобального номера эле-
мента, содержащего данный участок, и локального номера участка
в пределах данного элемента. Представленные ниже макросы из-
влекают номер элемента и номер участка поверхности из иденти-
фикатора участка:
#define cfxFACENUM(face) ((face) & 7)
#define cfxELEMNUM(face) ((face) >> 3)

Счетчики

Функции cfxExportInit и cfxExportZoneSet прини-


мают аргумент counts, представляющий собой массив целых чи-
сел размером cfxCNT_SIZE. Указанные функции записывают в
данный массив количество узлов, элементов и областей поверхно-
сти модели, а также количество расчетных параметров. Ниже оп-
ределены индексы конкретных счетчиков в этом массиве:
enum cfxCounts {
// Число узлов сетки
cfxCNT_NODE = 0,
// Число элементов
cfxCNT_ELEMENT,
// Число объемов
cfxCNT_VOLUME,
// Число областей поверхности
cfxCNT_REGION,
// Число расчетных параметров

7
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

cfxCNT_VARIABLE,
// Число тетраэдров
cfxCNT_TET,
// Число пирамид
cfxCNT_PYR,
// Число призм
cfxCNT_WDG,
// Число шестигранников
cfxCNT_HEX,
// Размер массива счетчиков
cfxCNT_SIZE
};

Структура для представления узла сетки

Для представления узлов сетки в API экспорта используется


следующая структура:
typedef struct cfxNode
{
float x, y, z;
} cfxNode;
Здесь переменные x, y и z являются координатами узла. Функция
cfxExportNodeList возвращает указатель на массив узлов рас-
четной сетки.

Структура для представления элемента сетки

Для представления элементов сетки в API экспорта использу-


ется следующая структура:
typedef struct cfxElement
{
int type;
int *nodeid;
} cfxElement;
Здесь параметр type указывает на тип элемента (число вершин,
которым он задается), а параметр nodeid представляет массив с
номерами узлов сетки, являющихся вершинами элемента. Указа-

8
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

тель на массив элементов расчетной сетки возвращается функцией


cfxExportElementList.

1.2.2. Функции инициализации и обработки ошибок

Функция
int cfxExportInit
(char *resfile, int counts[cfxCNT_SIZE])
открывает файл с результатами расчетов в Ansys CFX. Имя этого
файла задано аргументом resfile и инициализирует API экспор-
та, возвращая число зон, определенных в модели. Если в аргумен-
те counts был передан ненулевой указатель, то после вызова
функции он будет указывать на массив счетчиков. Данная функция
должна быть вызвана перед остальными функциями экспорта.
Функция
void cfxExportDone ()
закрывает файл с результатами расчетов в Ansys CFX и освобожда-
ет ресурсы, выделенные для экспорта. Данная функция должна быть
вызвана после окончания работы остальных функций экспорта.
Функция
void cfxExportError
(void (*callback) (char *errmsg))
определяет пользовательскую функцию, которая будет вызвана до
завершения работы API экспорта в случае возникновения критиче-
ской ошибки. Через параметр errmsg в пользовательскую функ-
цию передается сообщение с кратким описанием возникшей
ошибки. По умолчанию сообщение об ошибке выводится в сис-
темный поток stderr.
Функция
void cfxExportFatal (char *errmsg)
закрывает файл с результатами расчетов в Ansys CFX и вызывает
пользовательскую функцию обработки критической ошибки, ес-
ли она была задана с помощью функции cfxExportError
(см. выше), после чего завершает работу всей программы с кодом
ошибки -1.

9
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1.2.3. Функции экспорта зон

Вся работа с данными в API экспорта основана на текущей зоне


модели, которая устанавливается функцией cfxExportZoneSet,
описанной ниже. Доступ к узлам, элементам, объемам, областям
поверхности модели, а также к значениям параметров осуществля-
ется в пределах текущей зоны.
Функция
int cfxExportZoneCount ()
возвращает общее число зон, определенных в модели.
Функция
int cfxExportZoneSet
(int zone, int counts[cfxCNT_SIZE])
устанавливает текущую зону, заданную параметром zone, значе-
ние которого должно лежать в пределах от нуля до общего числа
зон в модели. Если в качестве номера зоны задан нуль, все зоны
модели объединяются в одну и доступ к ним осуществляется как к
единому целому. Возвращаемым результатом является номер зо-
ны, установленной в качестве текущей, или минус единица, если в
параметре zone был передан неверный номер зоны. Если в аргу-
менте counts был передан ненулевой указатель, то после вызова
функции он будет указывать на массив счетчиков для текущей ус-
тановленной зоны.
Функция
int cfxExportZoneGet ()
возвращает номер текущей зоны.
Функция
void cfxExportZoneFree ()
освобождает ресурсы, выделенные для экспорта данных текущей зоны.

1.2.4. Функции экспорта узлов сетки

Функция
int cfxExportNodeCount ()
возвращает число узлов расчетной сетки в текущей зоне.

10
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Функция
cfxNode *cfxExportNodeList ()
возвращает указатель на массив структур cfxNode, содержащих
координаты узлов расчетной сетки в текущей зоне. Выделение па-
мяти под массив структур осуществляется самой функцией. Для
освобождения этой памяти необходимо вызвать функцию
cfxExportNodeFree (см. ниже).
Функция
int cfxExportNodeGet
(int nodeid, double *x, double *y, double *z)
позволяет получить координаты узла расчетной сетки (параметры
x, y и z), заданного параметром nodeid. Значение параметра дол-
жно лежать в пределах от единицы до числа узлов включительно.
Возвращаемым результатом является указанный номер узла или
нуль, если номер узла был указан неверно.
Функция
void cfxExportNodeFree ()
освобождает ресурсы, выделенные для экспорта узлов расчетной
сетки в текущей зоне.

1.2.5. Функции экспорта элементов сетки

Функция
int cfxExportElementCount ()
возвращает число элементов расчетной сетки в текущей зоне.
Функция
cfxElement *cfxExportElementList ()
возвращает указатель на массив структур cfxElement, содержа-
щих описания элементов расчетной сетки в текущей зоне. Выделе-
ние памяти под массив структур осуществляется самой функцией.
Для освобождения этой памяти необходимо вызвать функцию
cfxExportElementFree (см. ниже).
Функция
int cfxExportElementGet
(int elemid, int *elemtype, int *nodelist)

11
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

позволяет получить тип элемента (параметр elemtype) и указа-


тель на массив индексов вершин элемента (параметр nodelist)
по его номеру elemid. Значение этого параметра должно лежать
в пределах от единицы до числа элементов включительно. Воз-
вращаемым результатом является указанный номер элемента или
нуль, если номер элемента был указан неверно.
Функция
void cfxExportElementFree ()
освобождает ресурсы, выделенные для экспорта элементов рас-
четной сетки в текущей зоне.

1.2.6. Функции экспорта объемов

Объемы определяются как группы узлов или элементов, кото-


рые являются подмножеством узлов или элементов, содержащихся
в текущей зоне. Тип представления объема определяется констан-
тами cfxVOL_NODES и cfxVOL_ELEMS, которые задают пред-
ставление объема узлами или элементами соответственно.
Функция
int cfxExportVolumeCount ()
возвращает число объемов в текущей зоне.
Функция
int cfxExportVolumeSize (int volnum, int type)
возвращает размер объема, заданного номером volnum и типом
type (про типы представления объемов было сказано в начале под-
раздела), или нуль, если номер объема задан неверно (номер должен
лежать в пределах от единицы до числа объемов).
Функция
char *cfxExportVolumeName (int volnum)
возвращает имя объема, заданного номером volnum, или NULL,
если номер задан неверно.
Функция
int *cfxExportVolumeList (int volnum, int type)
возвращает указатель на массив значений, определяющих объем,
заданный номером volnum, или NULL, если номер задан неверно.

12
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Если в качестве типа объема (аргумент type) указан


cfxVOL_NODES, функция возвращает указатель на массив номе-
ров узлов сетки, определяющих данный объем. Если же указан тип
cfxVOL_ELEMS, результирующий массив содержит номера эле-
ментов, определяющих объем.
Функция
int cfxExportVolumeGet
(int volnum, int type, int index, int *id)
позволяет получить номер узла или элемента сетки по его индексу
(аргумент index) в объеме, заданном номером volnum. Тип объ-
екта (узел или элемент), для которого определяется номер, задает-
ся параметром type. Если номер определен, его значение записы-
вается в параметр id, а функция возвращает значение параметра
index. В случае ошибки функция возвращает нуль.
Функция
void cfxExportVolumeFree (int volnum)
освобождает ресурсы, выделенные для экспорта данных об объе-
ме, заданном номером volnum.

1.2.7. Функции экспорта областей поверхности

Области определяются как группы узлов сетки или участков по-


верхности, расположенных на внешних границах зоны. Тип пред-
ставления области определяется константами cfxREG_NODES и
cfxREG_FACES, которые задают представление области узлами
или участками поверхности соответственно.
Функция
int cfxExportRegionCount ()
возвращает число областей поверхности в текущей зоне.
Функция
int cfxExportRegionSize (int regnum, int type)
возвращает размер области, заданной номером regnum, или нуль,
если номер области задан неверно (номер должен лежать в преде-
лах от единицы до числа областей, определяемого функцией
cfxExportRegionCount, см. выше) Если в аргументе type
указан тип cfxREG_NODES, функция возвращает число узлов сет-
13
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ки, заключенных в данной области. Если же задан тип


cfxREG_FACES, функция возвращает число элементарных участ-
ков поверхности, образующих данную область.
Функция
char *cfxExportRegionName (int regnum)
возвращает имя области поверхности, заданной номером regnum,
или NULL, если номер области задан неверно.
Функция
int *cfxExportRegionList (int regnum, int type)
возвращает указатель на массив значений, определяющих область
поверхности, заданную номером regnum, или NULL, если номер
задан неверно. Если в аргументе type указан тип
cfxREG_NODES, функция возвращает указатель на массив номе-
ров узлов сетки, заключенных в данной области. Если же задан
тип cfxREG_FACES, результирующий массив содержит иденти-
фикаторы участков поверхности, образующих данную область.
Идентификатор участка поверхности является комбинацией гло-
бального номера элемента, содержащего данный участок, и ло-
кального номера участка в пределах данного элемента.
Функция
int cfxExportRegionGet
(int regnum, int type, int index, int *id)
позволяет получить номер узла сетки или идентификатор участка
поверхности по его индексу (аргумент index) в области, заданной
номером regnum. Тип объекта (узел или участок поверхности),
для которого определяется номер, задается параметром type. Зна-
чение номера записывается в параметр id, а функция возвращает
значение параметра index. В случае ошибки функция возвращает
нуль.
Функция
void cfxExportRegionFree (int regnum)
освобождает ресурсы, выделенные для экспорта данных об облас-
ти поверхности, заданной номером regnum.
Функция
int cfxExportFaceNodes (int faceid, int *nodes)
14
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

позволяет получить указатель на массив (аргумент nodes), содер-


жащий номера узлов сетки, определяющих участок поверхности,
заданный идентификатором faceid. Функция возвращает число
элементов в массиве номеров узлов, в случае ошибки функция воз-
вращает нуль. Выделение памяти под массив номеров осуществля-
ется вызывающей функцией. Память в массиве должна быть выде-
лена как минимум для четырех элементов.

1.2.8. Функции экспорта значений параметров

Функция
int cfxExportVariableCount (int usr_level)
возвращает число доступных параметров, соответствующих уров-
ню, заданному аргументом usr_level. Если задан нулевой уро-
вень, функция возвращает число всех параметров, определенных в
модели.
Функция
int cfxExportVariableSize (int varnum,
int *dim, int *length, int *bndflag)
позволяет получить размерность (аргумент dim) и длину массива
значений (аргумент length) параметра, заданного номером
varnum (номер должен лежать в пределах от единицы до числа па-
раметров, определяемого функцией cfxExportVariableSize,
см. выше). Длина массива значений параметра (аргумент length)
может быть равна либо единице, либо числу узлов расчетной сетки.
В случае если длина массива значений параметра равна единице,
параметр имеет интерпретируемые значения только в граничных
узлах модели, во внутренних областях значение параметра постоян-
но. Значение, возвращаемое аргументом bndflag, указывает на то,
содержит ли параметр скорректированные значения в граничных
узлах (bndflag = 1) или нет (bndflag = 0). В первом случае
функция возвращает значение номера параметра, во втором функ-
ция возвращает нуль.
Функция
char *cfxExportVariableName
(int varnum, int alias)

15
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

возвращает имя параметра по его номеру, заданному аргументом


varnum, или NULL, если номер задан неверно. Аргумент alias
позволяет указать тип имени: полное имя параметра (alias = 1)
или сокращенное имя (alias = 0).
Функция
float *cfxExportVariableList
(int varnum, int correct)
возвращает указатель на массив значений параметра, заданного
номером varnum, или NULL, если номер задан неверно. Аргумент
correct определяет, должен ли результирующий массив содер-
жать скорректированные значения в граничных узлах сетки
(correct = 1) или нет (correct = 0). Значения параметров в
массиве имеют тот же порядок, что и узлы сетки в массиве узлов,
возвращаемом функцией cfxExportNodeList. Для многомерных
параметров последовательность значений сохраняется, т. е. сначала
перечисляются значения параметра по всем размерностям для перво-
го узла, затем для второго и т. д. Память под массив значений выде-
ляется самой функцией при ее вызове. Эта память освобождается пу-
тем вызова функции cfxExportVariableFree (см. ниже).
Функция
int cfxExportVariableGet (int varnum,
int correct, int index, float *value)
позволяет получить значение параметра, заданного номером varnum
в точке, заданной индексом index. Аргумент correct определяет,
нужно ли корректировать значения в граничных узлах сетки
(correct = 1) или нет (correct = 0). В случае многомерного
параметра функция возвращает значения по всем его измерениям,
поэтому указатель value должен указывать на массив, число эле-
ментов которого не меньше, чем размерность параметра (память под
массив выделяется вызывающей функцией). В случае существования
многомерного параметра функция возвращает значение аргумента
index, в противном случае функция возвращает нуль.
Функция
void cfxExportVariableFree (int varnum)
освобождает ресурсы, выделенные для экспорта значений пара-
метра, заданного номером varnum.

16
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1.3. Использование библиотеки OpenSceneGraph


для трехмерной визуализации

1.3.1. Обзор библиотеки

OpenSceneGraph (далее OSG) — высокопроизводительная не


зависящая от платформы библиотека для создания интерактивных
графических приложений, используемая разработчиками прило-
жений в таких областях, как визуализация научных расчетов, вир-
туальная реальность, моделирование и др. Библиотека имеет от-
крытый исходный код, что позволяет разработчикам вносить
изменения и расширять текущую функциональность. На нижнем
уровне OSG использует функции OpenGL, благодаря чему она
может беспрепятственно работать под управлением большинства
современных операционных систем.
Библиотеку OSG можно разделить на четыре основные части:
• ядро OSG (обеспечивает основные функции построения и от-
рисовки графа сцены);
• OSG NodeKits (классы NodeKits расширяют функциональ-
ные возможности основных классов графа сцены для реализации
узлов графа высокого уровня и специальных эффектов);
• OSG Plugins (классы Plugins обеспечивают работу с раз-
личными форматами двух- и трехмерных изображений);
• функции интеграции (позволяют функциям OSG легко интег-
рироваться в различные окружения, включая скриптовые языки,
такие как Python и Lua).
Архитектура OSG представлена на рис. 1.1.

Рис. 1.1. Архитектура библиотеки OSG

17
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Ядро OSG

Ядро OSG обеспечивает ключевую функциональность графа


сцены и предоставляет классы и методы для работы с графом сце-
ны. Ядро состоит из четырех библиотек:
• osg (содержит классы, используемые для построения графа
сцены, а также классы для векторных и матричных вычислений,
классы геометрии и классы для задания объектов и управления их
состоянием);
• osgUtil (сервисная библиотека, содержащая классы для ра-
боты с графом сцены и его составляющими, а также для сбора ста-
тистики и оптимизации графа);
• osgDB (содержит классы для создания и поддержки специа-
лизированных графических баз данных для трехмерных сцен. Сю-
да же входят функции регистрации подключаемых модулей (OSG
Plugins) для работы с графическими форматами);
• osgViewer (появившаяся в OSG версии 2.0 библиотека содер-
жит классы, позволяющие управлять просмотром сцены и предостав-
ляющие средства интерактивного взаимодействия с приложениями
OSG. Позволяет применять OSG в различных оконных системах).

Граф сцены

Как было сказано выше, граф сцены — это иерархическая


структура данных, имеющая вид дерева, которая используется для
эффективного представления и обработки пространственных дан-
ных. Фактически граф сцены является промежуточным слоем, по-
строенным над низкоуровневым API для эффективной организа-
ции объектов графических приложений и, таким образом,
способствует увеличению производительности этих приложений.
На рис. 1.2 представлены архитектурные уровни, с которыми
взаимодействует библиотека OSG.
Граф сцены также обладает следующими отличительными осо-
бенностями:
• древовидная структура графа сцены приближена к интуитив-
ной пространственной организации;
• граф оптимизирует загрузку системы посредством отключе-
ния обработки всех объектов, которые являются невидимыми в
18
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

сцене. Это позволяет значительно повысить быстродействие при-


ложений;
• граф позволяет управлять степенью детализации в зависимо-
сти от расстояния до объекта от точки наблюдения;
• все объекты сцены отсортированы по глубине от точки на-
блюдения;
• граф сцены — эффективный инструмент для чтения и записи
трехмерных данных, поэтому он может быть использован для пре-
образования файлов одного формата в другой.

Рис. 1.2. Уровни взаимодействия библиотеки OSG

Основное предназначение графа сцены заключается в струк-


турировании геометрии сцены и выполнении обхода графа, в
течение которого объекты сцены отрисовываются низкоуровне-
вым графическим API. Для учета динамического обновления
сцены, библиотека OSG позволяет реализовать три вида обхода
графа:
• обновление (update traversal) — позволяет приложению изме-
нять граф сцены, обеспечивая таким образом поддержку динами-
ческих сцен. Обновления могут совершаться как самим приложе-
нием, так и функциями обратного вызова, назначенными узлам
графа сцены;
• отбор (cull traversal) — в течение обхода отбора библиотека
графа сцены проверяет граничные объемы всех объектов в узлах
графа на предмет включения их в сцену. Если узел находится в
19
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

области видимости, система добавляет описание геометрии узла в


итоговый список отрисовки;
• отрисовка (draw traversal) — во время обхода отрисовки
система обходит список отрисовки, созданный во время обхода
отбора, и вызывает функции низкоуровневого API для отрисовки
сцены.
Как правило, обходы этих типов выполняются каждый раз во
время построения очередного кадра. Однако в некоторых ситуаци-
ях требуется одновременно создать несколько отображений одной
и той же сцены (например, для создания стереоизображений в сис-
темах виртуального окружения). В таких случаях обход обновле-
ния выполняется один раз при построении кадра, а обходы отбора
и отрисовки выполняются при создании каждого отдельного пред-
ставления. Это позволяет многопроцессорным системам осущест-
влять параллельную обработку сцены.

Управление памятью в библиотеке OSG

Как правило, при использовании графа сцены приложение хра-


нит указатель только на корень графа, не сохраняя при этом ссылки
на другие узлы. Корень графа явно (напрямую) или неявно (через
другие узлы) ссылается на все оставшиеся узлы графа сцены. После
завершения использования графа память, отведенная под сохране-
ние всех его узлов, должна быть освобождена во избежание утечек
памяти.
Одним из вариантов освобождения памяти является написание
кода для обхода графа и удаления каждого узла и данных, связан-
ных с ним. Однако этот вариант влечет дополнительные трудоза-
траты и может приводить к ошибкам в программе. Библиотека OSG
предоставляет автоматический механизм освобождения памяти, в
котором используется метод подсчета числа ссылок (reference-
counting garbage collection). Все узлы графа сцены OSG содержат
счетчик ссылок на себя, и когда число ссылок уменьшается до нуля,
объект удаляет сам себя. Таким образом, для удаления всего графа
сцены достаточно удалить только его корень, что приведет к кас-
кадному удалению всех узлов графа (рис. 1.3).
Работа механизма автоматического управления памятью за-
ключается в следующем:

20
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1) все классы, описывающие узлы и данные графа сцены, унас-


ледованы от класса osg::Referenced, который инкапсулирует*
в себе счетчик ссылок и методы для изменения его значения;
2) библиотека OSG определяет шаблонный класс
osg::ref_ptr<> для специальных указателей. Они работают
так же, как и классические указатели в языке C++, однако при
присвоении такому указателю адреса объекта, класс которого
унаследован от osg::Referenced, значение счетчика ссылок
этого объекта автоматически увеличивается на единицу.

Рис. 1.3 Каскадное удаление узлов графа сцены

Таким образом, все указатели, ссылающиеся на объекты класса


osg::Referenced, должны быть созданы на основе шаблона
osg::ref_ptr<>. Если следовать этому правилу, память, отве-
денная под объект, будет автоматически освобождаться при уда-
лении последнего указателя на него. Надо отметить, что объекты
класса osg::Referenced не могут быть явно удалены в коде
программы, поскольку (за редким исключением) все классы, унас-
ледованные от osg::Referenced, имеют защищенные
(protected) деструкторы. Это гарантирует то, что объект класса
osg::Referenced может быть удален только в результате
уменьшения числа ссылок на него до нуля.
*
Инкапсуляция — свойство языка программирования, позволяющее объ-
единить данные и код в объект и скрыть реализацию объекта от пользователя.
При этом пользователю предоставляется только спецификация (интерфейс)
объекта. Пользователь может взаимодействовать с объектом только через
этот интерфейс.

21
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1.3.2. Создание моделей OSG


на основе результатов инженерных расчетов

Для построения моделей в формате OSG на основе данных,


экспортированных из результирующего файла пакета Ansys CFX,
были созданы программа, использующая API экспорта Ansys CFX
для экспорта данных, и API библиотеки OSG для создания графа
сцены, описывающего трехмерную модель. Ниже дано описание
ключевых отличий, реализованных для построения моделей OSG.

Использование графа сцены


Библиотека OSG использует концепцию графа сцены для оп-
тимизации создания, обработки и визуализации трехмерной сцены.
Ниже приведены некоторые основные типы узлов графа OSG, ис-
пользуемые для создания трехмерных моделей:
• osg::Group — группирующий узел общего назначения, по-
зволяющий присоединять к себе произвольное количество дочер-
них узлов. Именно узлы этого класса, а также классов, производ-
ных от него, позволяют организовывать иерархическую структуру
сцены. Класс обеспечивает двусторонний интерфейс взаимодейст-
вия родительских узлов с дочерними;
• osg::Geode — листовой узел графа, содержащий в себе
геометрию, готовую для визуализации. Для присоединения гео-
метрии класс предоставляет метод addDrawable();
• osg::Geometry — узел геометрии, содержащий набор
геометрических примитивов, таких как вершины, элементарные
участки поверхности, нормали. Для того чтобы геометрические
примитивы были включены в визуализацию сцены, узел геомет-
рии должен быть присоединен к узлу Geode, описанному в пре-
дыдущем пункте;
• osg::Vec3Array — массив трехэлементных векторов
(osg::Vec3). Используется для создания массива геометрических
примитивов, которые задаются тремя координатами: вершины, нор-
мали и др. Для задания цвета применяется аналогичный класс
osg::Vec4 и соответствующий ему массив osg::Vec4Array
(цвет задается тремя компонентами системы RGB и параметром про-
зрачности «альфа»);
22
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• osg::Switch — класс Switch является производным от


класса Group и используется для организации выборочной визуа-
лизации дочерних узлов. Типичным примером использования это-
го узла является включение/отключение отображения отдельных
элементов геометрии трехмерной модели. В приложении, описан-
ном ниже, данный узел используется для сокрытия отдельных уча-
стков поверхности модели.

Рис. 1.4. Структура графа сцены


визуализируемых инженерных моделей

Одной из главных особенностей программы построения моде-


лей OSG является раздельный экспорт областей поверхности мо-
дели и добавление каждой области в граф в виде самостоятельного
узла. Это позволяет организовать возможность переключения ви-
димости отдельных областей поверхности в приложении визуали-
зации с помощью клавиатуры для улучшения восприятия внутрен-
ней структуры модели.
Структура графа сцены визуализируемых инженерных моделей
представлена на рис. 1.4. Каждой области поверхности модели со-
ответствует пара узлов Geode — Geometry, родителем (Root)
которой является узел Switch, реализующий переключение ви-
димости областей поверхности. Узлы вершин (Vertex Array),
23
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

нормалей (Normal Array) и цветов (Color Array) являются


общими для всех узлов геометрии, поскольку участки поверхности
в этих узлах задаются индексами из массива вершин.

Расчет нормалей
и сглаживание поверхности модели

Для организации правильного освещения поверхности моде-


ли любой графической системе необходимо иметь координаты
нормалей к элементарным участкам этой поверхности. В отли-
чие от библиотеки Open Inventor, которая самостоятельно рас-
считывает координаты нормалей в случае, если они не указаны
явно, при работе с OSG необходимо явно указывать координаты
нормалей. К сожалению, API экспорта пакета Ansys CFX не по-
зволяет получить координаты нормалей из результирующего
файла пакета Ansys CFX. Поэтому необходимо самостоятельно
вычислить нормаль для каждого элементарного участка поверх-
ности.
Рассмотрим уравнение плоскости в пространстве V 3, проходя-
щей через три точки с координатами (x1, y1, z1), (x2, y2, z2) и (x3, y3, z3):
X  x1 Y  y1 Z  z1
x2  x1 y2  y1 z2  z1 . (1.1)
x3  x1 y3  y1 z3  z1

Для упрощения конечной формулы выполним следующую за-


мену: xi – xj = xij, yi – yj = yij, zi – zj = zij. Вычислив определитель
матрицы уравнения (1.1) и произведя необходимые алгебраиче-
ские преобразования, получим уравнение плоскости:

X (y21z31  y31z21 )  Y (x31z21  x21z31 ) 


 Z (x21y31  x31y21 )  0. (1.2)

В уравнении (1.2) разности, стоящие в скобках после каждой из


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

24
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

 x1 y1 z1 
 
N  x2 y2 z2  
x z3 
 3 y3
 (y31 z21  y21 z31 ; x21 z31  x31 z21 ; x31 y21  x21 y31 ). (1.3)

Формула (1.3) определяет координаты нормали к элементарному


плоскому участку поверхности, заданному точками (x1, y1, z1),
(x2, y2, z2) и (x3, y3, z3). После вычисления координат всех нормалей
можно связать каждый элементарный участок поверхности модели
с соответствующей ему нормалью.
Данный вид привязки («участок — нормаль») имеет сущест-
венный недостаток. Два соседних участка поверхности, располо-
женные под разными углами и заданные каждый одной норма-
лью, отражают свет каждый под своим углом, в результате чего
ребра, разделяющие эти участки, отчетливо видны на поверхно-
сти модели. Для предотвращения этого эффекта используют при-
вязку нормалей не к участкам поверхности, а к вершинам, по ко-
торым строятся эти участки. При этом нормаль для вершины
задается как векторная сумма нормалей участков поверхности, в
которые входит данная вершина. Таким образом происходит
сглаживание границ элементарных участков при отражении света
от поверхности модели.

1.3.3. Визуализация результатов расчета


реальных инженерных задач

Программа, описанная в подразд. 1.4, осуществляет построение


трехмерной модели в формате OSG на основе данных, экспорти-
рованных из результирующего файла Ansys CFX. Программа гене-
рирует файлы формата .osg, каждый из которых описывает мо-
дель с графическими результатами расчетов для одного параметра
(контур распределения или векторная диаграмма). Полученные
модели можно визуализировать с помощью утилиты osgviewer,
входящей в набор стандартных утилит библиотеки OSG.
В качестве основных результатов работы программы рассмот-
рим визуализацию результатов расчета двух инженерных задач:
расчет первой ступени двухступенчатого авиационного компрес-
25
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

сора и расчет течения теплоносителя через систему тепловыде-


ляющих стержней ТВЭЛ. На рис. 1.5–1.9 представлены результаты
визуализации.

Рис. 1.5. Контур распределения давления в модели компрессора

Рис. 1.6. Распределение значений числа Маха в модели компрессора

26
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.7. Контур распределения давления в модели стержня ТВЭЛ

Рис. 1.8. Распределение значений числа Куранта в креплении


стержня ТВЭЛ

27
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.9. Векторная диаграмма распределения скоростей


потоков теплоносителя в стержне ТВЭЛ

Анализируя трехмерные модели, полученные при визуализа-


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

28
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

1.4. Пример интеграции пакета Ansys CFX


с библиотекой OpenSceneGraph

1.4.1. Архитектура программного комплекса

Для визуализации результатов инженерных расчетов был создан


программный комплекс, ориентированный на использование биб-
лиотеки OSG, которая позволяет строить и отображать трехмерные
графические модели, разрабатывать интерактивные приложения для
работы с этими моделями, а также создавать и управлять стерео-
изображениями. Стереоизображения являются мощным механиз-
мом создания «реальных» трехмерных изображений при визуализа-
ции моделей, что позволяет достичь эффекта погружения
пользователя, характерного для систем виртуального окружения.
Схема архитектуры программного комплекса представлена на
рис. 1.10. Инженерный пакет, работающий в общем случае на уда-
ленной вычислительной установке, генерирует файл с результата-
ми расчета. Этот файл с помощью клиента удаленного доступа
(например, SSH-клиента) копируется на графическую станцию и
подается на вход модуля экспорта результатов расчета. Модуль
экспорта, используя API инженерного пакета или спецификацию
формата файла результатов, осуществляет экспорт описания гео-
метрии модели и результатов расчета. Результаты экспорта пода-
ются на вход модуля построения моделей, который осуществляет
создание трехмерных моделей в формате .osg, используя API
библиотеки OSG. Помимо файлов формата .osg могут быть соз-
даны также файлы значений расчетных параметров (.val) и фай-
лы легенды (.leg), которые используются модулем визуализации
для получения дополнительной информации о модели.
Для удобства работы модуль экспорта результатов и модуль по-
строения моделей объединены в одном приложении, осуществляю-
щем генерацию моделей OSG на основе файла с результатами рас-
чета. Это позволяет избежать использования промежуточных
файлов для передачи данных между этими модулями. Кроме того, в
случаях, когда размер файла результатов расчета значительно пре-
вышает суммарный размер файлов моделей, приложение генерации
может быть перенесено на вычислительную установку для умень-
шения объема информации, передаваемой на рабочую станцию.
29
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.10. Архитектура программного комплекса


визуализации результатов расчетов

Файлы, полученные на выходе приложения генерации моде-


лей, подаются на вход приложения визуализации, состоящего из
двух модулей. Ключевым является модуль визуализации и взаимо-
действия с пользователем. Он осуществляет создание и отрисовку
трехмерной сцены, включающей расчетную модель с представ-
ленными на ней графическими результатами расчета (контур рас-
пределения, векторная диаграмма), информативные панели (ле-

30
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

генда значений, список функциональных клавиш программы), а


также элементы управления пользовательского интерфейса (кноп-
ки, текстовые поля для редактирования параметров модели). Для
организации взаимодействия с пользователем применяется обра-
ботка событий от клавиатуры и мыши, позволяющая, например,
вращать и перемещать модель на экране указателем мыши, скры-
вать отдельные области поверхности модели, наблюдать значения
расчетных параметров в различных точках и осуществлять другие
операции, необходимые при работе с моделью.
Другим модулем, входящим в состав приложения визуализа-
ции, является модуль обратной связи с инженерным пакетом. Дан-
ный модуль используется для удаленного извлечения изменяемых
параметров расчетной модели из файла задачи инженерного паке-
та, предоставления этих параметров в удобном для пользователя
виде через модуль визуализации, записи измененных параметров в
файл задачи и запуск инженерного пакета на перерасчет изменен-
ной модели. Для выполнения операций на удаленной вычисли-
тельной установке используется клиент удаленного доступа, по-
зволяющий осуществлять копирование файлов с удаленного
сервера и обратно, а также запуск приложений на удаленном сер-
вере. Таким клиентом является, например, SSH-клиент, свободно
распространяемая версия которого (putty) и была использована в
данной реализации.
Таким образом, архитектура программного комплекса состоит
из четырех основных модулей, объединенных в два приложения, и
внешнего клиента для удаленного доступа к вычислительной ус-
тановке. В следующих подразделах будут подробно описаны все
эти модули, а также механизмы их взаимодействия.

1.4.2. Модуль экспорта результатов

Модуль экспорта результатов, входящий в приложение генера-


ции моделей OSG, использует функции API экспорта пакета Ansys
CFX, спецификация которых приведена в подразд. 1.2.
Основным отличием описываемой реализации является выде-
ление функций модуля в отдельный класс, наследуемый от абст-
рактного базового класса, который служит интерфейсом между
модулем экспорта и модулем построения моделей. Методы клас-
31
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

сов, производных от абстрактного базового, осуществляют вызов


функций API экспорта конкретного инженерного пакета, получе-
ние результатов экспорта и преобразование их в формат, удобный
для построения трехмерных моделей. При переходе от одного ин-
женерного пакета к другому в идеальном случае достаточно будет
просто реализовать методы описанного класса таким образом,
чтобы они вызывали API целевого пакета. Еще одной существен-
ной особенностью является то, что конкретная реализация данного
класса помещается в отдельную библиотеку динамической компо-
новки. Это позволяет избежать перекомпиляции всего приложения
при замене слоя экспорта. В идеальном случае достаточно просто
заменить библиотеку с реализацией, ориентированной на один
инженерный пакет, на библиотеку другого инженерного пакета в
рабочей папке программы, и весь программный комплекс будет
переориентирован на работу с моделями другого инженерного па-
кета. Это является существенным шагом в сторону расширения
областей применимости разработанного комплекса.
В листинге 1.1 представлено содержимое заголовочного файла
на языке C++, содержащего описание базового класса экспорта.
Листинг 1.1. Описание базового класса экспорта результатов
#ifdef DATAEXPORTER_EXPORTS
#define DATAEXPORTER_API __declspec(dllexport)
#else
#define DATAEXPORTER_API __declspec(dllimport)
#endif
// Структура, описывающая узел расчетной сетки
struct DATAEXPORTER_API NodeElement
{
double x, y, z;
};
// Структура, описывающая элементарный участок
// поверхности
struct DATAEXPORTER_API FaceElement
{
// Число узлов - вершин участка поверхности
int NodeCount;
// Индексы узлов - вершин участка поверхности
int* NodeIndices;
};
class DATAEXPORTER_API DataExporter

32
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
protected:
// Имя файла с данными для экспорта
char* exportFileName;
// Признак начала экспорта
bool exportStarted;
// Число временных шагов
int timestepCount;
// Номер текущего временного шага
int timestepNum;
// Выполнение инициализирующих действий
// перед началом экспорта данных
void initialize();
public:
// Конструктор
// ExportFileName - имя файла с данными для экспорта
DataExporter(char* ExportFileName);
// Деструктор
~DataExporter();
// Выполнение операций, необходимых
// для осуществления экспорта данных
// Возврат признака успешного старта
// (экспорт разрешен).
bool StartExport();
// Выполнение операций, необходимых
// для корректного завершения экспорта данных
void FinishExport();
// Вывод сводной информации о данных,
// доступных для экспорта
void PrintExportDataSummary();
// Признак того, что функции экспорта поддерживают
// раздельный экспорт данных, относящихся к разным
// временным шагам
bool HandlesTimesteps();
// Экспорт числа временных шагов
int GetTimestepCount();
// Установление текущего временного шага, для которого
// будут осуществляться операции экспорта,
// и возвращение признака успешной операции
// TimestepNum - номер временного шага
bool SetCurrentTimestep(int TimestepNum);
// Выполнение необходимых установок в случае,
// когда в данных отсутствует информация

33
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// о временных шагах (статичные по времени данные)


bool SetSingleTimestep();
// Экспорт числа узлов расчетной сетки
int ExportNodeCount();
// Экспорт узлов расчетной сетки
NodeElement* ExportNodes();
// Завершение экспорта узлов расчетной сетки
void FinishNodeExport();
// Экспорт числа областей поверхности модели
int ExportFaceRegionCount();
// Экспорт имени области поверхности модели
// RegionNum - номер области поверхности
char* ExportFaceRegionName(int RegionNum);
// Экспорт элементарных участков
// отдельной области поверхности
// RegionNum - номер области поверхности
// FaceCount - после завершения работы содержит
// число элементарных участков
FaceElement* ExportFaceRegionElements
(int RegionNum, int* FaceCount);
// Завершение экспорта участков области поверхности
// RegionNum - номер области поверхности
void FinishFaceRegionExport(int RegionNum);
// Экспорт числа расчетных параметров, значения
// которых доступны для экспорта
int ExportParameterCount();
// Экспорт названия расчетного параметра
// ParamNum - номер параметра
char* ExportParameterName(int ParamNum);
// Экспорт размерности (числа измерений)
// расчетного параметра
// ParamNum - номер параметра
int ExportParameterDimension(int ParamNum);
// Экспорт значения расчетного параметра
// ParamNum - номер параметра
// ValueCount – после завершения работы содержит
// количество значений в возвращаемом массиве
// (которое должно быть равно реальному размеру
// массива, деленному на размерность параметра)
float* ExportParameterValues
(int ParamNum, int* ValueCount);
// Завершение экспорта значений расчетного параметра
// ParamNum - номер параметра

34
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

void FinishParameterExport(int ParamNum);


// Возврат имени файла, из которого в данный момент
// осуществляется экспорт данных
char* GetExportFileName();
// Возврат номера текущего экспортируемого
// временного шага
int GetCurrentTimestep();
};
Приведем список аргументов командной строки приложения ге-
нерации моделей, позволяющих управлять экспортом результатов.
Аргумент
-info
При использовании этой опции программа выводит на экран свод-
ную текстовую информацию о данных, доступных для экспорта из
файла результатов, не генерируя при этом файлы моделей OSG. За
составление и вывод сводной информации отвечает функция
PrintExportDataSummary класса экспорта (см. листинг 1.1).
Аргумент
-tstep <номер>
позволяет экспортировать результаты расчетов, относящиеся к
конкретному временнóму шагу. По умолчанию экспорт результа-
тов осуществляется для всех временных шагов. Опцию имеет
смысл использовать для экспорта результатов расчетов, в которых
время является изменяемым параметром. За определение числа
временных шагов отвечает функция GetTimestepCount класса
экспорта (см. листинг 1.1). Фукция HandlesTimesteps возвра-
щает признак того, поддерживает ли в принципе API экспорта ин-
женерного пакета раздельный экспорт результатов, относящихся к
различным временным шагам.
Аргумент
-params <номера параметров, разделенные
пробелом>
позволяет экспортировать результаты расчета (и затем генериро-
вать файлы моделей) по конкретным параметрам, заданным свои-
ми номерами. Эта опция способствует значительному ускорению
процесса генерации моделей в тех случаях, когда пользователя ин-
тересуют лишь конкретные расчетные параметры (например,
35
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

только давление и температура) из всего списка параметров, дос-


тупных для экспорта. Полный перечень параметров с номерами и
названиями должен содержаться в сводной информации, выводи-
мой опцией -info.

1.4.3. Модуль построения моделей


Как было указано в подразд. 1.4.1, модуль построения моделей
осуществляет создание трехмерных моделей в формате OSG на ос-
нове экспортированных результатов расчета, используя API биб-
лиотеки OSG. Схемы работы модуля представлена на рис. 1.11. На
первом этапе осуществляется инициализация модуля, включающая
обработку аргументов командной строки, переданных приложению
генерации, создание объекта класса экспорта (см. подразд. 1.4.2) и
инициализация экспорта. На втором этапе осуществляется экспорт
координат узлов расчетной сетки и создание массива вершин моде-
ли. При этом функция экспорта координат узлов ExportNodes()
возвращает массив структур NodeElement, описывающих узел
расчетной сетки (см. листинг 1.1), которые преобразуются в массив
вершин модели, имеющий тип Vec3Array.
На третьем этапе осуществляется экспорт описания поверхно-
сти модели в виде массива структур FaceElement (см. листинг
1.1). Данная структура описывает элементарный участок поверх-
ности в виде массива индексов узлов (из массива узлов расчетной
сетки), которые являются вершинами для данного участка. При
этом массив индексов имеет переменный размер, зависящий от
того, каким многоугольником задается элементарный участок.
Наиболее частым является представление поверхности в виде на-
бора элементарных треугольников. Также могут использоваться
четырех-, шести- и восьмиугольники. Многоугольники остальных
видов применяются крайне редко.
Экспортированные структуры используются для формирова-
ния массива узлов графа типа DrawElementsUInt, которые опи-
сывают элементарный участок поверхности модели OSG в виде
массива индексов вершин. Вся поверхность модели может быть
разделена на области, представляющие собой поверхности конст-
руктивно выделенных элементов (например, торцы, боковые стен-
ки и крепление стержня ТВЭЛ). Если API экспорта инженерного
36
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

пакета поддерживает раздельный экспорт описания различных об-


ластей поверхности (как, например, в случае использования API
пакета Ansys CFX), то поверхность модели OSG также строится из
областей, которые являются самостоятельными узлами графа сце-
ны. Заключительным шагом в создании поверхности модели явля-
ется расчет нормалей элементарных участков поверхности для ор-
ганизации правильного освещения.

Рис. 1.11. Схема работы модуля построения моделей

37
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

После завершения создания поверхности геометрия модели яв-


ляется поностью сформированной — фактически в наличии ока-
зывается «чистая» модель, не отражающая каких-либо результатов
расчета. Данная модель сохраняется программой в отдельный
файл формата .osg (в том случае, если не указана опция –noprm
для приложения генерации, см. ниже). После этого начинается
этап экспорта значений расчетных параметров и построения соот-
ветствующих моделей. Этот этап включает в себя два цикла.
Внешний цикл (по временным шагам) используется в том случае,
если в файле результатов расчета определено несколько времен-
ных шагов, т. е. имеется несколько наборов результатов для раз-
личных моментов времени. В этом случае для установки экспорта
результатов по i-му временнóму шагу используется функция
SetCurrentTimestep(TimestepNum) (см. листинг 1.1). Если
файл результатов не содержит определения временных шагов, ис-
пользуется функция SetSingleTimestep(), а соответствую-
щий внешний цикл в программе отсутствует.
Внутренний цикл (по параметрам) используется для организа-
ции экспорта значений расчетных параметров и построения моде-
лей, отражающих результаты расчета по каждому параметру. По
умолчанию цикл проводится для всех параметров, доступных для
экспорта из файла результатов. Список параметров может быть
ограничен опцией –params (см. подразд. 1.4.3). Для определения
размерности (числа измерений) очередного параметра использует-
ся функция ExportParameterDimension(ParamNum). Для
скалярных параметров (размерность равна 11) осуществляется по-
строение контура распределения значений, цвета точек которого
характеризуют диапазон, в который попадают значения параметра
в данных точках. В листинге 1.2 приведен код функции, осуществ-
ляющей построение контуров распределения для моделей OSG:
Листинг 1.2. Функция построения контура распределения
для модели OSG
ref_ptr<Vec4Array> CreateScalarContour(float*
ValList, int ValCount, float min, float max)
{
ref_ptr<Vec4Array> color = new Vec4Array;
if (min == max)

38
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
for (int i = 0; i < ValCount; i++)
color->push_back(Vec4(0, 1, 0, 1));
}
else
{
// Длина диапазона значений
float range = max - min;
// Среднее значение
float middle = min + range / 2.0;
// Длина отрезка диапазона
float diap = range / 10.0;
// Номер отрезка диапазона
int dnum;
// Цикл по всем значениям параметра
for (int i = 0; i < ValCount; i++)
{
// Определение номера отрезка диапазона,
// в который попадает текущее значение
dnum = clrRangeNumberByValue(ValList[i], min,
middle, diap);
// определение составляющих цвета
float* clrcomp = clrComponentsByRangeNumber(dnum);
// Задаение цвета материала текущей точки
color->push_back(Vec4(clrcomp[0], clrcomp[1],
clrcomp[2], 1));
// Освобождение памяти
delete[] clrcomp;
}
}
return color.get();
}
Для векторных параметров (размерность больше 1, как правило,
равна 3) осуществляется построение векторной диаграммы. Цвет,
длина и направление каждого вектора на диаграмме характеризуют
значение векторного параметра в данной точке. Цвета векторов оп-
ределяются по тому же алгоритму, что и цвета точек контура рас-
пределения, только в качестве скалярной величины используется
модуль вектора. Длина вектора также пропорциональна модулю
значения. В листинге 1.3 приведен код функции, осуществляющей
построение векторных диаграмм для моделей OSG.

39
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Листинг 1.3. Функция построения векторной диаграммы


для модели OSG
ref_ptr<Geometry> CreateVectorPlot(Vec3Array*
ModelVertices, float* ValList,
int ValCount, int VecDimension, float MinModulus,
float MaxModulus)
{
ref_ptr<Geometry> vecGeom = new Geometry;
ref_ptr<Vec3Array> vecVerts = new Vec3Array;
ref_ptr<Vec4Array> vecColors = new Vec4Array;
// Длина диапазона значений
float range = MaxModulus - MinModulus;
// Среднее значение
float middle = MinModulus + range / 2.0;
// Длина отрезка диапазона
float diap = range / 10.0;
// Вектор значений
float* valVector = new float[3];
// Цикл по всем значениям параметра
for (int i = 0, vCounter = 0; i < ValCount;
i+= VecDimension, vCounter++)
{
// Вычисление модуля вектора, представляющего
// значение параметра
float vmod = arrVectorModulus(ValList, ValCount, i,
VecDimension);
// Определение номера отрезка диапазона,
// в который попадает текущее значение
int dnum = clrRangeNumberByValue(vmod, MinModulus,
middle, diap);
// Определение составляющих цвета
float* clrcomp = clrComponentsByRangeNumber(dnum);
// Задание цвета материала текущей точки
vecColors->push_back(Vec4(clrcomp[0], clrcomp[1],
clrcomp[2], 1));
// Освобождение памяти
delete[] clrcomp;
for(int vi = 0; vi < 3; vi++)
{
if(vi < VecDimension)
valVector[vi] = ValList[i + vi];
else

40
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

valVector[vi] = 0.0f;
}
float vx = (*ModelVertices)[vCounter].x();
float vy = (*ModelVertices)[vCounter].y();
float vz = (*ModelVertices)[vCounter].z();
float kmod = vmod / MaxModulus;
vecVerts->push_back(Vec3(vx, vy, vz));
vecVerts->push_back(Vec3(vx + valVector[0] * kmod,
vy + valVector[1] * kmod,
vz + valVector[2] * kmod));
vecGeom->addPrimitiveSet
(new DrawArrays(PrimitiveSet::LINES, vCounter * 2,2));
}
delete[] valVector;
vecGeom->setVertexArray(vecVerts.get());
vecGeom->setColorArray(vecColors.get());
vecGeom->setColorBinding
(Geometry::AttributeBinding::BIND_PER_PRIMITIVE);
return vecGeom;
}
На заключительном шаге итерации цикла по параметрам осу-
ществляется сохранение созданной модели в файл формата .osg.
Для обеспечения уникальности имен файлов моделей для различ-
ных параметров используется следующий формат имени:
<основа имени>[_ts<номер временного шага>]_
<s|v><номер параметра>.osg
В качестве основы имени по умолчанию используется имя
файла результатов без расширения (для задания другой основы
применяют опцию –osgname, см. ниже). Затем может следовать
номер временнóго шага (в том случае, если он задан функциями
экспорта). Далее пишут спецификатор размерности: s для скаляр-
ных параметров и v для векторных. Затем указывают номер рас-
четного параметра и, наконец, расширение файла .osg.
Помимо основного файла модели для каждого расчетного па-
раметра могут быть сгенерированы также два дополнительных:
файл легенды и файл значений. Файл легенды используется при-
ложением визуализации для создания и размещения на экране
цветной легенды значений параметра. Ниже приведен формат и
пример содержимого файла легенды:

41
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

[Имя параметра] Velocity


[Единицы измерения] [m s^-1]
[Минимальное значение] 5.462e-002
[Максимальное значение] 1.306e+000
В приведенном примере содержится информация для легенды
параметра «скорость» с единицами измерения «м/с» и минималь-
ным и максимальным значениями 0,055 м/с и 1,306 м/с соответст-
венно. На рис. 1.12 приведена легенда, созданная приложением
визуализации по описанным параметрам.
Для файлов легенды используется тот же формат имени, что и
для файлов моделей, только вместо расширения .osg использует-
ся расширение .leg.
Файл значений используется приложе-
нием визуализации для отображения зна-
чений расчетного параметра в различных
точках модели. Ниже представлен формат
файла значений:
[Количество значений]
[Размерность параметра]
[Значение 1 по измерению 1]
[Значение 1 по измерению 2]
...
[Значение 1 по измерению K]
[Значение 2 по измерению 1]
[Значение 2 по измерению 2]
...
[Значение 2 по измерению K]
...
...
[Значение N по измерению 1]
[Значение N по измерению 2]
...
[Значение N по измерению K]
Как видно из описания формата, под
значением параметра подразумевается на-
бор значений по всем его измерениям. Та-
Рис. 1.12. Внешний ким образом, реальное число записей в
вид легенды файле равно произведению числа значений
значений и размерности параметра. Для имен файлов

42
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

значений используется тот же формат, что и для файлов моделей,


только вместо расширения .osg используется расширение .val.
Ниже приведен список аргументов командной строки прило-
жения генерации моделей, позволяющих управлять построением
моделей OSG:
Аргумент
-osgname <имя>
служит для задания основы имени для генерируемых файлов (см.
выше). По умолчанию в качестве основы используется имя файла
результатов расчетов без расширения.
Аргумент
-noprm
отключает генерацию «чистой» модели, не отражающей никаких
результатов расчетов.
Аргумент
-noleg
отключает генерацию файлов легенды.
Аргумент
-pval
включает функцию генерации файлов значений расчетного пара-
метра (см. выше). По умолчанию генерация отключена, поскольку
во многих случаях файл имеет большой размер, и его запись зани-
мает много времени.
Аргумент
-inorm <номера областей поверхности, разде-
ленные пробелом>
позволяет изменить направление нормалей элементарных участков
для определенных областей поверхности модели. Эта опция ис-
пользуется в тех случаях, когда нормали, рассчитанные автомати-
чески, оказываются направленными «от наблюдателя» (т. е. от све-
тового потока), что приводит к отсутствию освещения данных
областей с внешней стороны.

1.4.4. Модули визуализации и обратной связи


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

43
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

мого набора функций (функционала) для взаимодействия с пользо-


вателем, а также создания средств поддержки обратной связи с ин-
женерным пакетом. Для этих целей в состав приложения входят два
модуля: визуализации и поддержки обратной связи. В данном под-
разделе будут подробно описаны каждый из этих модулей, а также
схема их совместной работы.

Использование класса osgViewer

Ключевым классом, используемым в модуле визуализации, яв-


ляется класс osgViewer, входящий в состав библиотеки OSG.
Данный класс является, по сути, полноценным средством визуали-
зации моделей OSG. Именно на базе этого класса построена ути-
лита osgviewer. Он позволяет полностью автоматизировать про-
цесс создания окна приложения, отрисовки в нем созданного графа
сцены и организацию простейших операций с моделью (переме-
щение, поворот, приближение/удаление). Помимо этого, он пре-
доставляет гибкий механизм обработки событий приложения, ко-
торый активно используется в модуле визуализации. Листинг 1.4
иллюстрирует код, используемый для подключения обработчиков
событий в приложении визуализации.
Листинг 1.4. Подключение обработчиков событий в приложении
визуализации
// Класс, реализующий обработчики событий,
// возникающих в приложении визуализации
class SceneEventHandler :
public osgGA::GUIEventHandler
{
protected:
ref_ptr<SceneManager> _sceneManager;
public:
SceneEventHandler(SceneManager* Manager)
{
_sceneManager = Manager;
}

// Метод обработки событий приложения


bool handle(const GUIEventAdapter& ea,
GUIActionAdapter& aa)

44
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
Viewer* viewer = dynamic_cast<Viewer*>(&aa);
switch(ea.getEventType())
{
// Нажатие кнопки клавиатуры
case(GUIEventAdapter::KEYDOWN):
{
_sceneManager->processKeyPress(ea.getKey());
return true;
}
// Движение указателя мыши
case(GUIEventAdapter::FRAME):
{
if (viewer)
_sceneManager->processMousePick(viewer, ea);
return false;
}
// Однократное нажатие левой кнопки мыши
case(GUIEventAdapter::PUSH):
{
if (viewer)
_sceneManager->processMouseClick(viewer, ea);
return false;
}
// Двухкратное нажатие левой кнопки мыши
case(GUIEventAdapter::DOUBLECLICK):
{
if (viewer)
_sceneManager->processMouseDoubleClick(viewer, ea);
return false;
}
default:
return false;
}
}
};
...
void main(int argc, char* argv[])
{
...
ref_ptr<SceneManager> Manager = new SceneManager();
ref_ptr<Group> ModelRoot =
(Group*)osgDB::readNodeFile(modelFileName.c_str());

45
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Manager->AttachModel(ModelRoot.get());
...
osgViewer::Viewer viewer;
viewer.addEventHandler
(new SceneEventHandler(Manager.get()));
viewer.setSceneData( Manager->GetScene() );
viewer.run();
}
Класс SceneEventHandler наследуется от библиотечного
класса osgGA::GUIEventHandler и реализует единственный
метод handle, в который передаются ссылка на объект класса
osgViewer::Viewer и аргументы события. Метод определяет
тип возникшего события и вызывает соответствующий метод класса
SceneManager. Класс SceneManager является ключевым клас-
сом модуля визуализации. Он осуществляет построения графа сце-
ны приложения, реализует необходимый функционал для работы с
моделью и изменения параметров модели. Указатель на объект это-
го класса передается в конструктор класса SceneEventHandler
для последующего вызова методов обработки событий.
Функция main иллюстрирует схему запуска приложения визуа-
лизации. Сначала создается объект класса SceneManager (далее —
менеджер сцены). После этого осуществляется загрузка графа визуа-
лизируемой модели из файла с расширением .osg с помощью
функции osgDB::readNodeFile, которая возвращает указатель
на корень графа модели. Этот указатель передается в метод
AttachModel менеджера сцены, который осуществляет присоеди-
нение модели к общему графу приложения. После этого могут быть
выполнены дополнительные операции присоединения легенды и за-
грузки значений параметра из файла. Затем создается объект класса
osgViewer. С помощью метода addEventHandler, в который
передается объект класса SceneEventHandler, осуществляется
присоединение обработчиков событий. Методом setSceneData в
объект класса osgViewer::Viewer передается указатель на пол-
ный граф сцены приложения, который возвращается методом
GetScene менеджера сцены. Завершающим действием является вы-
зов метода run() объекта osgViewer, который открывает окно
приложения и запускает цикл отрисовки сцены.

46
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Граф сцены приложения визуализации

Любой видимый объект в приложении OSG представляет со-


бой набор графических примитивов: точек, линий, закрашенных
многоугольников и пр. Каждый такой объект описывается подгра-
фом в общем графе сцены всего приложения. В такой ситуации
графа сцены модели OSG, создаваемого приложением генерации,
оказывается явно недостаточно для организации необходимого
пользовательского интерфейса, включающего элементы управле-
ния, информационные панели и другие объекты. Таким образом,
необходимо создать расширенный граф, в который визуализируе-
мая модель будет включена как подграф.
На рис. 1.13 представлен граф сцены приложения, создаваемый
модулем визуализации.

Рис. 1.13. Граф сцены приложения визуализации

47
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

48
Рис. 1.14. Внешний вид сцены для работы с моделью на примере визуализации модели смесителя
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Как видно из рис. 1.13, модуль визуализации создает две


большие подсцены, объединенные в общий граф узлом переклю-
чателя osg::Switch. Первая подсцена предназначена для рабо-
ты непосредственно с визуализируемой моделью. В нее входят
собственно модель, загружаемая из файла с расширением .osg,
созданного приложением генерации, а также вспомогательные
информационные элементы: легенда, панель со списком функ-
циональных клавиш для подсказки пользователю, информацион-
ная строка для отображения значений расчетного параметра в
точках, соответствующих положению указателя мыши, а также
подграф для отображения значений параметра с выносками, фик-
сированными над поверхностью модели. Все перечисленные бло-
ки сцены объединены под одним переключателем («переключа-
тель сцены модели» на рисунке) для того, чтобы можно было
скрывать/показывать каждый из блоков по нажатию функцио-
нальных клавиш пользователем. Так, скрыть легенду можно на-
жатием кнопки <L>, скрыть панель со списком функциональных
клавиш нажатием кнопки <F1>. Это может быть полезно в тех
случаях, когда окно приложения перегружено информационными
элементами, отвлекающими пользователя от полноценного вос-
приятия модели.
На рис. 1.14 показан внешний вид сцены модели на примере
визуализации модели смесителя.
В следующих пунктах будут подробно описаны функции при-
ложения визуализации для работы с моделью.

Функции приложения для работы с моделью

Работа с поверхностью. В подразд. 1.4.3 была описана схема


работы модуля построения моделей, одним из этапов которой яв-
ляется раздельный экспорт областей поверхности модели и после-
дующее присоединение подграфов этих областей к единому узлу
osg::Switch. После загрузки модели из файла с расширением
.osg модуль визуализации, используя полученный указатель на
корень графа модели, сохраняет во внутренней переменной указа-
тель на узел переключения областей поверхности (он является
единственным дочерним узлом корня графа модели). После этого
функции модуля получают возможность скрывать и показывать
49
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

отдельные области поверхности, используя функцию setValue,


предоставляемую узлом Switch:
Switch::setValue
(<номер дочернего узла>,<true|false>)
Данная функция осуществляет включение или отключение ви-
зуализации дочерних подграфов, в зависимости от значения второ-
го параметра (true и false соответственно).
Области поверхности в приложении визуализации идентифи-
цируются своими номерами. Эти номера можно увидеть в сводной
информации о результатах расчета, запустив приложение генера-
ции моделей с опцией -info (см. подразд. 1.4.2). Скрытие или
отображение конкретной области осуществляется нажатием циф-
ровой кнопки клавиатуры, соответствующей номеру этой области.
Предусмотрено два режима ввода: для однозначных и двузначных
номеров. Переключение между этими режимами осуществляется
кнопкой < \ >. В режиме двухзначных номеров последовательное
нажатие клавиш с номерами n и m соответствует числу nm. Двух-
значные номера позволяют работать с поверхностью, число облас-
тей в которой достигает 99, а поскольку областью является гло-
бальный участок поверхности, этого числа достаточно для
подавляющего большинства моделей.
Пример использования данной опции приложения визуализации
приведен на рис. 1.15. Здесь отключено отображение боковых по-
верхностей стержня ТВЭЛ для детального изучения крепления,
скрытого внутри модели. Помимо изменения видимости отдельных
областей, есть возможность скрыть или показать всю поверхность
модели, используя клавишу <S>. Эта опция может быть полезна,
например, в случае, когда требуется быстро восстановить поверх-
ность после отключения отображения некоторых ее областей.
Еще одной функцией для работы с поверхностью модели явля-
ется изменение режима отрисовки многоугольников (полигонов).
Полигоном называется замкнутый контур, который может быть
закрашен каким-либо цветом (цветом заливки, возможно гради-
ентной). Каждый элементарный участок поверхности представляет
собой полигон. Библиотекой OSG поддерживаются три режима
отрисовки полигонов, которые и реализованы в приложении ви-
зуализации:

50
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.15. Пример использования функции отключения областей


поверхности

1) режим заливки, при котором полигоны отображаются пол-


ностью закрашенными, если для них установлен цвет заливки,
(рис. 1.16, а). Данный режим является основным при визуализации
модели;
2) контурный режим, при котором отображаются только линии,
ограничивающие полигоны (рис. 1.16, б). Данный режим может ис-
пользоваться для оценки структуры поверхности модели (набора и
расположения составляющих ее элементарных участков);
3) точечный режим, при котором отображаются только точки,
являющиеся вершинами полигонов (рис. 1.16, в). Как видно из ри-
сунка, при соответствующей разреженности узловых точек модели
результат визуализации в данном режиме просматривается с
большим трудом и зачастую не представляет большого интереса.
Единственным преимуществом этого режима является то, что мо-
дель, отображаемая точками, является наиболее «легкой» для гра-
фической подсистемы с точки зрения отрисовки, перемещения и
51
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

вращения. Это может оказаться весьма полезным, например, для


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

Рис. 1.16. Режимы отрисовки полигонов поверхности:


а — режим заливки; б — контурный режим; в — точечный режим

52
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Отображение значений расчетного параметра. Как было от-


мечено в подразд. 1.4.3, одним из двух дополнительных файлов,
создаваемых приложением генерации моделей, является файл зна-
чений расчетного параметра, содержащий массив значений пара-
метра в узлах расчетной сетки. Если такой файл был создан в ходе
генерации модели (была использована опция -pval приложения
генерации), то он может быть использован модулем визуализации
для отображения значений параметра в различных точках модели.
Поддерживаются два способа отображения значений (которые мо-
гут использоваться одновременно):
1) статическое отображение значений в фиксированных точ-
ках. В этом режиме значение параметра в точке поверхности вы-
водится двойным нажатием левой кнопки мыши на этой точке.
При этом создается выноска в виде отрезка, коллинеарного норма-
ли к поверхности в данной точке, первый конец которого совпада-
ет с данной точкой, а около второго отображается текст со значе-
нием параметра в экспоненциальной форме с тремя знаками после
запятой. Пример использования этой опции приведен на рис. 1.17.
При вращении модели плоскость текста подписей будет поворачи-
ваться таким образом, чтобы всегда оставаться «лицом» к наблю-
дателю. Есть возможность изменять длину выносок с помощью
кнопок <+> и <–> (длина соответственно увеличивается и умень-
шается в 2 раза по сравнению с текущей). Кнопка <V> позволяет
скрывать и показывать весь набор подписей значений вместе с вы-
носками. Кнопка <C> позволяет удалить все созданные подписи;
2) динамическое отображение значений в информационной
строке. В данном режиме значение параметра в точке поверхно-
сти, соответствующей указателю мыши, отображается в информа-
ционной строке, расположенной в правой нижней части окна при-
ложения (см. рис. 1.14). При движении указателя мыши вдоль
поверхности отображаемое значение автоматически изменяется.
Вместе со значением в информационной строке отображается и
название области поверхности, над которой в данный момент на-
ходится указатель мыши (названия областей поверхности задаются
в файле результатов расчета и экспортируются вместе с геометри-
ей модели).
Совместное использование этих двух режимов позволяет поль-
зователю водить курсором мыши по поверхности модели в поис-
53
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ках точек с интересующими его значениями параметра (например,


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

Рис. 1.17. Пример использования статического отображения


значений параметра

1) определение пересечения с геометрическими примитивами.


На данном этапе осуществляется поиск пересечений луча, выхо-
дящего из точки наблюдения сцены и проходящего через точку,
соответствующую указателю мыши, с геометрическими прими-
тивами сцены (полигонами элементарных участков поверхности).
Поиск пересечений осуществляется средствами библиотеки
OSG, а именно функцией computeIntersections класса
osgViewer::Viewer:
bool computeIntersections(float x,float y,
osgUtil::LineSegmentIntersector::
Intersections& intersections)

54
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

В качестве аргументов в функцию передаются координаты


указателя мыши, а также ссылка на объект Intersections, в
который записывается список примитивов, с которыми были най-
дены пересечения. Примитивы в списке отсортированы по глуби-
не, т. е. по степени удаления от точки наблюдения. Таким образом,
первым в списке всегда стоит примитив, на который, собственно, и
осуществлялось наведение указателя мыши. Остальные примити-
вы списка также пересекаются описанным выше лучом, но они
скрыты от наблюдателя первым примитивом и поэтому не пред-
ставляют интереса для пользователя;
2) определение значения параметра в точке пересечения. При
работе с поверхностью модели первый примитив в списке найден-
ных пересечений будет являться полигоном, представляющим со-
бой элементарный участок поверхности. Этот полигон в списке
будет задан списком индексов своих вершин, совпадающих с оп-
ределенными вершинами модели. А поскольку порядок перечис-
ления значений параметра в файле значений совпадает с порядком
перечисления вершин модели в графе сцены, используя найденные
индексы, можно получить значения расчетного параметра в вер-
шинах интересующего пользователя полигона. Усреднив значения
во всех вершинах и учитывая малую площадь элементарного уча-
стка поверхности, можно с хорошей точностью получить значение
расчетного параметра в точке пересечения луча указателя мыши с
найденным полигоном. Данный алгоритм наглядно иллюстрирует
рис. 1.18.
Необходимо отметить, что описанный алгоритм осуществляет
поиск пересечения луча указателя только с видимыми участками
поверхности. Если скрыть внешние области поверхности, взору
наблюдателя предстанут внутренние области (как в случае с креп-
лением стержня ТВЭЛ), и тогда первым в списке примитивов ока-
жется участок внутренней области.
Особенности работы с векторными диаграммами. В отли-
чие от контуров распределения значений скалярного параметра,
изображение которых возможно только на поверхности модели,
векторные диаграммы позволяют отображать значения векторного
параметра по всему объему модели с помощью векторов. Векторы
значений в графе сцены представлены отрезками, направление ко-
торых совпадает с направлением вектора значений, длина пропор-
55
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

циональна модулю вектора, а цвет характеризует диапазон, в кото-


рый попадает модуль значения.
Класс osgViewer не позволяет находить пересечения луча от
указателя мыши с отрезками на сцене, поскольку считается, что
отрезки имеют нулевую площадь. Поэтому в приложении визуали-
зации отсутствует возможность увидеть значение векторного па-
раметра при наведении указателя мыши на изображение вектора.

Рис. 1.18. Определение значение расчетного параметра


в точке участка поверхности

При запуске приложения для векторного параметра поверх-


ность модели по умолчанию скрывается для того, чтобы пользова-
тель смог сразу увидеть распределение векторов значений по все-
му объему модели. При скрытой поверхности значения параметра
не отображаются. Для отображения значений на поверхности
можно включить отображение поверхности модели кнопкой <S>.
Оптимальным в этом случае будет контурный режим отрисовки
полигонов, который позволит пользователю наблюдать векторы
внутри модели через «каркас» поверхности. На рис. 1.19 показан
внешний вид модели в описанном режиме на примере визуализа-
ции векторной диаграммы скоростей водных потоков в модели
смесителя.
56
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.19. Использование контурного режима отрисовки


полигонов поверхности при визуализации векторной диаграммы

Приложение позволяет изменять относительную длину изо-


бражений векторов на диаграмме с помощью кнопок <Page Up> и
<Page Down>. При этом длины векторов остаются пропорциональ-
ными модулям векторов значений, изменяется лишь коэффициент
пропорциональности. Во многих случаях эта опция может быть
полезна, поскольку коэффициент пропорциональности, исполь-
зуемый по умолчанию (единица), не всегда является оптимальным
для приемлемого изображения векторных диаграмм.

Изменение параметров модели


и модуль обратной связи
Второй большой подсценой приложения визуализации, изо-
браженной на рис. 1.13, является сцена для работы с изменяемыми
параметрами модели. Переключение между подсценами осущест-
вляется нажатием кнопки <M>, т. е. пользователь в текущий мо-
мент времени может работать либо с изображением модели, либо с
ее параметрами. Это было сделано для того, чтобы избежать пере-
груженности основной сцены модели элементами управления,
предназначенными для редактирования параметров.
57
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.20. Общий вид сцены для работы с параметрами модели

58
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Общий вид сцены для работы с параметрами представлен на


рис. 1.20. Основу сцены составляет набор элементов управления
(текстовых полей) для отображения и редактирования значений
параметров, а также кнопки для запуска операций загрузки и со-
хранения измененных параметров. Элементы управления и меха-
низм их взаимодействия с менеджером сцены описаны в следую-
щих подразделах. Также ниже детально описана работа модуля
обратной связи и его взаимодействие с модулем визуализации.
Командный язык CFX и изменяемые параметры модели. Под
изменяемыми параметрами модели понимаются параметры, которые
могут быть изменены без привлечения специализированных средств
инженерного пакета, таких как препроцессор, программы редактиро-
вания расчетных сеток и пр. Для моделей пакета Ansys CFX такие
параметры находятся внутри файла расчетной задачи (с расширением
.def) в виде текстового блока, составленного на командном языке
CFX (CFX Command Language — CCL). В листинге 1.5 приведен
пример содержимого такого блока для модели смесителя.
Листинг 1.5. Описание параметров модели смесителя на языке CCL
LIBRARY:
MATERIAL: Water
Material Description = Water (liquid)
Material Group = Water Data, Constant Property
Liquids
Option = Pure Substance
Thermodynamic State = Liquid
PROPERTIES:
Option = General Material
Thermal Expansivity = 2.57E-04 [K^-1]
DYNAMIC VISCOSITY:
Dynamic Viscosity = 8.899E-4 [kg m^-1 s^-1]
Option = Value
END
REFRACTIVE INDEX:
Option = Value
Refractive Index = 1.0 [m m^-1]
END
SCATTERING COEFFICIENT:
Option = Value
Scattering Coefficient = 0.0 [m^-1]
END

59
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ABSORPTION COEFFICIENT:
Absorption Coefficient = 1.0 [m^-1]
Option = Value
END
THERMAL CONDUCTIVITY:
Option = Value
Thermal Conductivity = 0.6069 [W m^-1 K^-1]
END
EQUATION OF STATE:
Density = 997.0 [kg m^-3]
Molar Mass = 18.02 [kg kmol^-1]
Option = Value
END
SPECIFIC HEAT CAPACITY:
Option = Value
Reference Pressure = 1 [atm]
Reference Specific Enthalpy = 0.0 [J/kg]
Reference Specific Entropy = 0.0 [J/kg/K]
Reference Temperature = 25 [C]
Specific Heat Capacity = 4181.7 [J kg^-1 K^-1]
Specific Heat Type = Constant Pressure
END
END
END
END
FLOW:
SOLUTION UNITS:
Angle Units = [rad]
Length Units = [m]
Mass Units = [kg]
Solid Angle Units = [sr]
Temperature Units = [K]
Time Units = [s]
END
SIMULATION TYPE:
Option = Steady State
END
OUTPUT CONTROL:
RESULTS:
File Compression Level = Default
Option = Full
END
END

60
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

DOMAIN: StaticMixer
Coord Frame = Coord 0
Domain Type = Fluid
Fluids List = Water
Location = B1.P3
DOMAIN MODELS:
DOMAIN MOTION:
Option = Stationary
END
BUOYANCY MODEL:
Option = Non Buoyant
END
REFERENCE PRESSURE:
Reference Pressure = 0 [atm]
END
END
FLUID MODELS:
HEAT TRANSFER MODEL:
Option = Thermal Energy
END
TURBULENCE MODEL:
Option = k epsilon
END
TURBULENT WALL FUNCTIONS:
Option = Scalable
END
THERMAL RADIATION MODEL:
Option = None
END
COMBUSTION MODEL:
Option = None
END
END
BOUNDARY: in1
Boundary Type = INLET
Location = in1
BOUNDARY CONDITIONS:
FLOW REGIME:
Option = Subsonic
END
MASS AND MOMENTUM:
Normal Speed = 2 [m s^-1]
Option = Normal Speed

61
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

END
HEAT TRANSFER:
Option = Static Temperature
Static Temperature = 315 [K]
END
TURBULENCE:
Option = Medium Intensity and Eddy Viscosity Ratio
END
END
END
BOUNDARY: in2
Boundary Type = INLET
Location = in2
BOUNDARY CONDITIONS:
FLOW REGIME:
Option = Subsonic
END
MASS AND MOMENTUM:
Normal Speed = 2 [m s^-1]
Option = Normal Speed
END
HEAT TRANSFER:
Option = Static Temperature
Static Temperature = 285 [K]
END
TURBULENCE:
Option = Medium Intensity and Eddy Viscosity Ratio
END
END
END
BOUNDARY: out
Boundary Type = OUTLET
Location = out
BOUNDARY CONDITIONS:
FLOW REGIME:
Option = Subsonic
END
MASS AND MOMENTUM:
Option = Average Static Pressure
Relative Pressure = 0 [Pa]
END
PRESSURE AVERAGING:
Option = Average Over Whole Outlet

62
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

END
END
END
BOUNDARY: StaticMixer Default
Boundary Type = WALL
Location=
F1.B1.P3,F2.B1.P3,F4.B1.P3,F5.B1.P3,F6.B1.P3,F8.B1.P3
BOUNDARY CONDITIONS:
HEAT TRANSFER:
Option = Adiabatic
END
WALL INFLUENCE ON FLOW:
Option = No Slip
END
WALL ROUGHNESS:
Option = Smooth Wall
END
END
END
END

SOLVER CONTROL:
ADVECTION SCHEME:
Option = Upwind
END
CONVERGENCE CONTROL:
Maximum Number of Iterations = 100
Physical Timescale = 2 [s]
Timescale Control = Physical Timescale
END
CONVERGENCE CRITERIA:
Residual Target = 1.E-4
Residual Type = RMS
END
DYNAMIC MODEL CONTROL:
Global Dynamic Model Control = Yes
END
END
END
COMMAND FILE:
Version = 5.7
END

63
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Как видно из листинга 1.5, описание на языке CCL представля-


ет собой иерархическую структуру вложенных друг в друга бло-
ков. Блок LIBRARY описывает библиотеку материалов и веществ,
используемых в модели, а также их свойств. В приведенном при-
мере в качестве рабочего материала используется обыкновенная
вода, для которой задаются значения ряда физических параметров:
коэффициента теплового расширения (Thermal Expansivity),
коэффициента динамической вязкости (Dynamic Viscosity),
коэффициента теплопроводности (Thermal Conductivity) и
др. Именно эти параметры и рассматриваются приложением ви-
зуализации в качестве изменяемых параметров модели. Другой
крупный блок FLOW содержит описание единиц измерения, типа
расчета (Steady State — расчет на установление), типов ис-
пользуемых моделей (модели теплопередачи, модели турбулент-
ности, модели горения и др.), а также описание специфических
условий на границах модели.
Для доступа к блоку описания параметров в файле задачи ис-
пользуется утилита cfx5cmds, которая входит в набор утилит
пакета Ansys CFX и находится, как правило, в рабочей папке ин-
женерного пакета. Для запуска утилиты, расположенной на уда-
ленной вычислительной установке, модуль обратной связи исполь-
зует клиент удаленного доступа. Ниже представлен формат
команды чтения и записи текстового блока описания параметров:
<Путь к рабочей папке>\cfx5cmds –[read|write] -def
<Имя файла задачи> -text <Имя текстового файла>
При использовании команды read осуществляется извлечение
блока параметров из файла задачи, указанного опцией –def, и его
сохранение в текстовый файл, заданный опцией -text. При ис-
пользовании команды write осуществляется чтение описания
параметров из текстового файла и запись его в файл задачи. Если
внимательно изучить содержимое файла задачи, можно обнару-
жить, что при записи блока описания параметров предыдущий
блок не стирается, а остается неизменным, тогда как новый блок
просто дописывается в конец файла. Таким образом, при каждой
новой записи размер файла задачи увеличивается. Препроцессор
пакета Ansys CFX при подготовке задачи к расчету использует по-
следний из блоков, находящихся в файле задачи.

64
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Схема работы модуля обратной связи. Общая схема обрат-


ной связи с инженерным пакетом выглядит следующим образом.
При переключении в режим работы с параметрами в приложении
визуализации пользователю предлагается ввести имя файла зада-
чи, соответствующей визуализируемой модели (рис. 1.21). После
ввода имени и нажатия кнопки <Загрузить> модуль обратной
связи формирует список команд для клиента удаленного доступа.
Первая команда осуществляет запуск на удаленном сервере ути-
литы cfx5cmds, которая извлекает из файла задачи блок описа-
ния параметров и записывает его в заданный текстовый файл.
Вторая команда осуществляет копирование текстового файла на
рабочую станцию пользователя. После этого модуль обратной
связи выполняет чтение и анализ содержимого файла. Поскольку
синтаксис языка CCL относительно прост, анализ дерева описа-
ния осуществляется на основе ключевых слов и термов без ис-
пользования специальных грамматик теории синтаксического
анализа.

Рис. 1.21. Ввод имени файла задачи для загрузки параметров модели

При анализе дерева описания необходимо представить объекты


этого дерева в программе таким образом, чтобы после изменения
значений параметров можно было восстановить текстовое пред-
ставление этого дерева, отличающееся от исходного только изме-
ненными значениями, для последующей записи измененного дере-
ва в файл задачи, для чего в состав модуля обратной связи входит
небольшая иерархия классов, описание которых представлено в
листинге 1.6.
65
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Листинг 1.6. Иерархия классов для представления дерева


параметров в приложении
// Базовый класс для всех CCL-объектов
class CustomObject
{
protected:
string Name;
public:
CustomObject(string ObjName);
virtual ~CustomObject();
virtual string GetName();
virtual string ToString();
virtual string ToString(string Prefix);
};
// Класс для представления контейнерных объектов,
// содержащих внутри себя дочерние объекты
class ContainerObject: public CustomObject
{
protected:
list<CustomObject*> ObjList;
list<CustomObject*>::iterator ListIterator;
string Value;
public:
ContainerObject(string ObjName);
ContainerObject(string ObjName, string ObjValue);
~ContainerObject();
void AddChild(CustomObject* Object);
CustomObject* ListStart();
CustomObject* ListNext();
string GetValue();
string ToString();
string ToString(string Prefix);
};
// Класс для представления объектов типа
// [Имя параметра] = [Значение]
class ValueProperty: public CustomObject
{
protected:
string Value, Dim;
public:
ValueProperty(string PropName, string PropValue);

66
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ValueProperty(string PropName, string PropValue,


string Dimension);
void SetDimension(string Dimension);
void SetValue(string Value);
string GetDimension();
string GetValue();
string ToString();
string ToString(string Prefix);
};
Иерархия состоит из следующих классов. Базовый класс
CustomObject определяет поля и методы, общие для всех объ-
ектов дерева параметров. Здесь можно отметить наличие поля
Name, представляющего имя блока или параметра, а также пере-
груженный метод ToString(), который восстанавливает тексто-
вое представление объекта в формате языка CCL. Класс
ContainerObject используется для представления объектов-
контейнеров, таких как блоки LIBRARY, PROPERTIES и др.
(см. листинг 1.5). Объекты данного класса хранят внутри себя спи-
сок дочерних объектов и предоставляют методы для перемещения
по этому списку. Класс ValueProperty представляет в про-
грамме значение определенного параметра. Помимо поля Name,
наследуемого от класса CustomObject, класс содержит поля
Value и Dim для хранения текстовых представлений значения
параметра и его единиц измерения соответственно.
После анализа дерева описания модуль обратной связи со-
ставляет список параметров блока LIBRARY (см. листинг 1.5) в
виде списка объектов класса ValueProperty и передает их мо-
дулю визуализации, который создает для каждого параметра эле-
мент управления, содержащий два текстовых поля: одно для ре-
дактирования его значения, другое — для редактирования единиц
измерения. Созданные элементы управления добавляются в сце-
ну работы с параметрами и выводятся на экран, после чего поль-
зователь получает возможность редактировать значения парамет-
ров (см. рис. 1.20).
После того как пользователь осуществил необходимые измене-
ния и нажал кнопку <Сохранить параметры>, модуль визуализации
проходит по списку текстовых полей и записывает их содержимое в
соответствующие поля объектов ValueProperty. Далее необхо-

67
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

димо сгенерировать текстовое представление измененного дерева


параметров в формате языка CCL. Для этого вызывается метод
ToString() корневого объекта дерева, имеющий тип
ContainerObject, который, в свою очередь, инициирует каскад-
ный вызов метода ToString() для всех дочерних объектов. Ре-
зультаты вызовов объединяются в единое представление (гриф) и
сохраняются в локальный текстовый файл. После этого модуль ви-
зуализации формирует список команд для клиента удаленного дос-
тупа. Первой командой осуществляется копирование текстового
файла с измененным деревом параметров на удаленную вычисли-
тельную установку. Второй командой осуществляется запуск ути-
литы cfx5cmds для записи текста описания параметров в файл за-
дачи. Третьей командой может быть запущен инженерный пакет на
перерасчет модели с измененными параметрами.
На рис. 1.22 представлена описанная выше схема работы модуля
обратной связи, а также его взаимодействия с модулем визуализации.
Необходимо отметить, что описанная выше схема позволяет
лишь изменять значения и единицы измерения тех параметров,
которые попали в список, созданный модулем обратной связи. До-
бавление или удаление параметров в приложении не предусмотре-
но. Кроме того, работа с параметрами ведется только на уровне их
текстового представления, т. е. программа не осуществляет преоб-
разование и проверку значений, вводимых пользователем. Это
значит, что ответственность за результат изменения параметров
целиком возлагается на пользователя программы.
Создание и организация работы элементов управления.
Для работы с изменяемыми параметрами модели в приложении
визуализации были созданы два элемента управления: кнопка и
текстовое поле. В классических оконных приложениях элементы
управления являются активными, т. е. они способны реагировать
на внешние события (нажатие кнопки мыши, перетаскивание и
пр.). В приложении OSG активным является лишь объект класса
osgViewer::Viewer (визуализатор), все остальные объекты
являются пассивными, включая менеджер сцены, методы которого
вызываются обработчиком событий, присоединенным к визуали-
затору. Не исключением являются и созданные элементы управле-
ния, которые умеют лишь отрисовывать себя, т. е. создавать набор
примитивов для своего графического представления.

68
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 1.22. Схема работы модуля обратной связи


и его взаимодействия с модулем визуализации

Для реализации функционирования элементов управления в


приложении необходимо организовать их реакцию как минимум
на два внешних события: нажатие левой кнопки мыши (установка
фокуса ввода для текстового поля и нажатие для кнопки) и нажа-
тие кнопки клавиатуры для изменения текста в текстовом поле.
Для этого был использован механизм ведущего объекта, которым
является менеджер сцены. При создании объекта элемента управ-
ления менеджер добавляет его графическое представление в граф
сцены, а сам объект помещает во внутренний список, предвари-

69
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

тельно присвоив ему уникальный идентификатор. В отдельном


поле менеджер хранит указатель на элемент управления, в котором
в данный момент установлен курсор. При нажатии левой кнопки
мыши менеджер осуществляет поиск пересечения луча указателя
мыши с геометрическими примитивами сцены. После этого анали-
зируются имя первого объекта сцены в списке найденных пересе-
чений. Для упрощения поиска имена всех элементов управления в
приложении (а точнее, узлы Geode, которые являются корнем
подграфа, описывающего графическое представление элемента
управления) начинаются с префикса VC_. Если первым в списке
оказался какой-либо элемент управления, менеджер сравнивает
его с элементом, обладающим в данный момент фокусом ввода.
Если они не совпадают, менеджер «отбирает» фокус ввода у ак-
тивного элемента управления и передает его элементу — кнопке,
которая была нажата. После этого менеджер инициирует обработ-
ку события нажатием кнопки мыши, вызывая соответствующий
метод нового активного элемента управления (OnMouseClick,
см. ниже).
При нажатии кнопки клавиатуры менеджер сцены сразу опре-
деляет, имеется ли в данный момент элемент управления, обла-
дающий фокусом ввода. Если такой элемент присутствует (в него
уже был установлен фокус ввода), менеджер инициирует обработ-
ку нажатием кнопки, вызывая соответствующий метод активного
элемента управления (OnKeyPressed, см. ниже). Таким образом
реализуется схема, при которой «ведущий» объект (менеджер сце-
ны) инициирует обработку событий «ведомыми» объектами (эле-
ментами управления) путем вызова их методов.
Для реализации элементов управления была создана иерархия
классов, описание которых показано в листинге 1.7.
Листинг 1.7. Иерархия классов для элементов управления
// Базовый класс для элементов управления
class CustomControl
{
protected:
string controlID;
public:
CustomControl(string ControlID);
virtual ~CustomControl();

70
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

virtual string GetControlID();


};
// Класс для элементов управления,
// поддерживающих установление фокуса ввода
class FocusableControl : public CustomControl
{
protected:
bool focused;
public:
FocusableControl(string ControlID);
virtual bool IsFocused();

virtual bool SetFocus();

virtual bool ReleaseFocus();


};
// Класс для элементов управления, создающих и поддер-
// живающих свое визуальное отображение в сцене
class VisualControl : public FocusableControl
{
protected:
ref_ptr<Geode> controlGeode;
ref_ptr<Geometry> controlGeom;

float posX;
float posY;
virtual void InitDefaultState();

virtual void RecountInnerControlsPosition();


virtual void UpdateInnerControls();
public:
VisualControl(string ControlID);
virtual Node* GetVisualPresentation();
virtual void SetPosition(float X, float Y);
virtual bool OnKeyPressed(int KeyCode);
virtual void OnMouseClick();
};
Базовым классом для элементов управления является класс
CustomControl, который фактически описывает только поле
controlID, содержащее идентификатор элемента управления, и
метод GetControlID() для его получения. На следующей сту-

71
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

пени иерархии находится класс FocusableControl, описы-


вающий элементы управления, поддерживающие работу с фоку-
сом ввода. К полю, наследуемому от базового класса, добавляется
защищенное поле focused, содержащее признак наличия фокуса
ввода, а также метод IsFocused(), возвращающий значение
этого поля, SetFocus(), элемент управления, информирующий
о необходимости установки фокуса ввода, и метод
ReleaseFocus(), дающий команду на освобождение фокуса.
Методы SetFocus() и ReleaseFocus() возвращают признак
успешного выполнения операции. Например, возможна ситуация,
при которой метод SetFocus(), вызванный для какого-то эле-
мента управления, вернет отрицательное значение, которое будет
свидетельствовать о том, что этот элемент в данный момент не
может принять фокус ввода (например, он заблокирован). В этом
случае менеджер сцены будет вынужден оставить фокус на теку-
щем активном элементе. Точно таким же образом метод
ReleaseFocus() может запретить освобождение фокуса (на-
пример, потому, что введенное значение не удовлетворяет каким-
либо условиям проверки и его необходимо исправить).
Наконец, последним базовым классом в этой иерархии являет-
ся класс VisualControl, описывающий элементы управления,
которые могут создавать и поддерживать свое визуальное отобра-
жение в приложении. Для этой цели в классе определены закрытые
поля controlGeode и controlGeom для хранения ссылок на
узлы геометрии, поля posX и posY для хранения оконных коор-
динат элемента управления, а также открытый метод
GetVisualPresentation(), который создает набор геометри-
ческих примитивов, необходимых для отображения элемента
управления, организует эти примитивы в подграф сцены и воз-
вращает указатель на корень этого подграфа. Метод
SetPosition(X,Y) позволяет установить элемент управления в
заданную позицию в окне приложения.
Двумя последними открытыми методами, описанными в
данном классе, являются методы пассивной обработки событий
в описанной выше схеме с ведущим объектом. Метод
OnKeyPressed(KeyCode) реализует реакцию элемента
управления на нажатие кнопки клавиатуры, код которой переда-
72
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ется в качестве параметра. При этом метод должен вернуть буле-


во значение, свидетельствующее о том, было ли обработано на-
жатие кнопки или нет. Метод OnMouseClick() реализует ре-
акцию на нажатие левой кнопки мыши в поле элемента
управления. Оба этих метода в базовом классе VisualControl
являются пустыми.
В следующих пунктах будут подробно описаны оба элемента
управления, реализованных на базе описанных выше классов для
организации работы с параметрами модели.
Элемент управления «текстовое поле». Внешне текстовое
поле представляет собой прямоугольник с цветом заливки, соот-
ветствующим наличию или отсутствию фокуса ввода, внутри ко-
торого отображается текст. Возможно также наличие заголовка,
расположенного слева от поля с текстом (рис. 1.23).

Рис. 1.23. Внешнее представление текстового поля


в приложении визуализации

При нажатии левой кнопкой мыши на текстовом поле (на пря-


моугольнике с текстом или на заголовоке) осуществляется вызов
метода SetFocus(), который подсвечивает прямоугольник с
текстом зеленым цветом, обозначая таким образом, что элемент
управления принял фокус ввода (рис. 1.24).

Рис. 1.24. Текстовое поле с установленным в него фокусом ввода

После вызова метода SetFocus() осуществляется вызов об-


работчика OnMouseClick() нажатия мыши, но в текстовом поле
этот обработчик пуст, поскольку никаких дополнительных дейст-
вий мышью этот элемент управления не поддерживает.

73
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Основным обработчиком текстового поля является обработчик


OnKeyPressed(), который в общем случае осуществляет изме-
нение текста в поле. Добавление текстового символа происходит
при нажатии следующих кнопок клавиатуры: цифровые клавиши
(0 – 9), латинские символы в нижнем (a – z) и в верхнем (A – Z)
регистрах, а также символы «.», «,», «+», «-», «(», «)», «#», «$»,
«%», «^», «&», «*», «~», «_», «\», «/», «=», «|», «?», «!» и «пробел».
Этого набора символов вполне достаточно для того, чтобы вводить
численные и текстовые значения параметров, а также выражения
для единиц размерности. Элемент управления не поддерживает
позицию курсора в поле текста, поэтому символ всегда добавляет-
ся в конец строки. Нажатие кнопки <BackSpace> приводит к уда-
лению последнего символа строки в поле текста.
Для улучшения качества визуализации элемент управления
поддерживает методы для установки ширины заголовка и поля с
текстом. Если при вводе в поле ширина текста превышает ширину
текстового поля, оно автоматически растягивается (рис. 1.25).

Рис. 1.25. Автоматическое растягивание текстового поля


под текущее значение

Для установки и чтения строки в текстовом поле используется


пара методов SetText() и GetText(), для установки текста
заголовка — метод SetCaption().
Элемент управления «кнопка». Внешне кнопка представляет
собой закрашенный заданным цветом прямоугольник с текстом
внутри (заголовком кнопки) — рис. 1.26.

Рис. 1.26. Внешний вид кнопки в приложении

74
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Основным отличием кнопки как элемента управления от текстово-


го поля является наличие описанного в классе кнопки события Click:
__event void Click();
Данное событие активизируется объектом кнопки в обработчи-
ке нажатия мыши по кнопке:
void Button::OnMouseClick()
{
__raise Click();
}
Присоединение обработчиков события Click() осуществля-
ется в менеджере сцены с помощью стандартного механизма пере-
хвата событий, используемого в языке C++:
__hook(&Button::Click, _btnLoadCCLTree,
&SceneManager::loadCCLParameters);
Здесь первым аргументом служит ссылка на метод класса, иниции-
рующий возникновение события, вторым аргументом является ука-
затель на объект класса, инициирующий событие, а третьим аргу-
ментом — ссылка на функцию, которая является обработчиком
события. Несмотря на то что как подключение обработчиков собы-
тия Click(), так и вызов метода кнопки OnMouseClick(), ини-
циирующего возникновение события, осуществляются внутри одно-
го объекта и того же объекта менеджера сцены, данная схема имеет
ряд преимуществ. Во-первых, при нажатии кнопкой мыши на кноп-
ке приложения менеджеру сцены не нужно сопоставлять идентифи-
катор нажатой кнопки с собственным методом, который нужно вы-
звать. Во-вторых, можно динамически подключать и отключать
обработчики нажатия кнопки по мере необходимости.
Метод OnKeyPressed() также определен для кнопки, но в от-
личие от текстового поля он содержит обработку единственной кла-
виши <Enter>, нажатие которой на кнопке с установленным фоку-
сом ввода приводит к эффекту, аналогичному нажатию мыши, —
генерации события Click().
Для управления визуальным представлением кнопки в классе
определены методы SetHeight() и SetWidth() для установки
соответственно высоты и ширины кнопки, а также метод
SetText() для задания текста, отображаемого внутри кнопки.
75
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

2. ПРОГРАММИРОВАНИЕ В ABAQUS

2.1. Описание пакета

Программный конечно-элементный комплекс Abaqus —


универсальная система, предназначенная для проведения много-
целевого инженерного многодисциплинарного анализа, решения
научно-исследовательских и учебных задач в различных сферах
деятельности, в числе которых:
• автомобилестроение;
• авиастроение и оборонная промышленность;
• электроника;
• металлургия;
• производство электроэнергии;
• нефтедобыча и нефтепереработка;
• производство товаров народного потребления;
• общая механика и геомеханика.
С помощью имеющихся средств моделирования может быть
решен широкий спектр прикладных задач: расчет прочности тур-
бомашин и проектирование двигательных установок, анализ ра-
боты шасси и трансмиссий, определение поведения шин, расчет
сварных соединений, проведение анализа аварийных столкнове-
ний (краш-тесты), моделирование сверхпластического формиро-
вания, учет контактного взаимодействия тел, анализ сейсмиче-
ских и взрывных воздействий, проведение расчета надежности
ядерных реакторов, анализ прочности электронных компонентов
и т. д.

2.2. Объектная модель Abaqus

2.2.1. Типы объектов

Объектная модель Abaqus содержит два вида объектов:


• единичные объекты, определяющие единственный экземпляр
сущности объектной модели (например, объекты типов MDB и
Session; в объектной иерархии Abaqus содержится по одному объ-
екту перечисленных выше типов);

76
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• объекты-контейнеры, содержащие в себе объекты опреде-


ленного типа. В свою очередь, объекты-контейнеры могут быть
двух типов:
◦ репозиториии, которые позволяют хранить объекты опреде-
ленного типа и получать к ним доступ по имени. Для навигации по
таким объектам созданы специальные «обертки» — итераторы*.
Большинство объектов-репозиториев и их содержимое создаются
ядром, пользователь только получает доступ к ним и по необходи-
мости извлекает данные;
◦ последовательности, созданные для хранения упорядоченно-
го списка объектов определенного типа. При необходимости ин-
формация может быть извлечена из последовательности или до-
бавлена в нее.

2.2.2. Корневые объекты

Объектная модель Abaqus на верхнем уровне содержит следую-


щие объекты (рис. 2.1): Session (сессия), MDB (Model Database —
база данных модели), ODB (Output Database — база данных резуль-
татов расчета).

Рис. 2.1. Корневые объекты иерархии Abaqus

*
Итератор (от англ. iterate) — объект, позволяющий перебирать все элемен-
ты коллекции без учета особенностей ее реализации.

77
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Объект Session

Сессия в пакете Abaqus представляет собой набор характери-


стических параметров среды в текущем сеансе работы (рис. 2.2).

Рис. 2.2. Объект Session

78
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Объекты типа Session не сохраняются для последующих се-


ансов работы в Abaqus (например, области просмотра, пути, пара-
метры вывода на печать, цвет и т. п.). Но эти объекты могут быть
созданы заново (к примеру, в случае некорректного завершения
работы) с помощью файла перезапуска с расширением .rpy.

Объект MDB

Объекты MDB сохраняются в базе данных модели (в ранних


версиях Abaqus — в файле с расширением .mdb, а впоследствии
.cae) и могут быть восстановлены из предыдущего сеанса работы
в Abaqus. Объекты MDB содержат объекты Model и JOB. Объект
Model включает в себя объекты PART, SECTION, MATERIAL,
STEP и т. п. Некоторые из них изображены на рис. 2.3.

Рис. 2.3. Объект Model


79
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Объект ODB

Объект ODB сохраняется в базе данных результатов расчета


(файл с расширением .odb) и содержит данные модели и данные
результатов (рис. 2.4).

Рис. 2.4. Объект ODB

2.2.3. Импорт модулей для расширения объектной модели

Для доступа к объектам, дочерним для объекта Model, таким


как Part или Section, пакет Abaqus позволяет расширять (до-
полнять) объектную модель посредством импорта дополнитель-
ных модулей. Например, для доступа к объекту PART пакету
Abaqus необходимо импортировать модуль part. При создании
объекта Sesion все модули пакета Abaqus импортируются авто-
матически. Но при выполнении собственных сценариев бывает
необходимо получить доступ к определенному объекту, т. е. им-
портировать модуль вручную. Это можно сделать командой
import <module_name>
Например, для импорта модуля part запись команды имеет вид
import part

80
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

2.3. База данных результатов расчета

2.3.1. Общие сведения

База данных результатов расчета Abaqus (job-name.odb)


представляет собой независимый от платформы двоичный файл,
используемый для сохранения информации о модели и результа-
тов анализа в терминах экземпляров частей сборки. Модуль визуа-
лизации Abaqus/Viewer использует выходной файл данных для
обработки результатов анализа, а также для просмотра диагности-
ческой информации.
В выходной файл данных по запросу могут быть записаны раз-
личные стандартные выходные переменные Abaqus. Доступен вы-
вод следующих типов: вывод элементов, узлов, контактных по-
верхностей, энергий, приращений, излучения, времени,
интегрированный вывод, модальный вывод и др. Часть диагности-
ческой информации, записанная в стандартный файл сообщений
Abaqus/Standard, включается в выходной файл данных.
В выходном файле данных сохраняется информация трех ти-
пов. Возможен пространственный вывод (field output), вывод
истории нагружения и диагностическая информация. Пространст-
венный вывод предназначен для использования относительно ред-
ких выводов больших объемов данных модели. В пакете Abaqus он
используется для генерации кривых контуров, кривых деформиро-
ванных фигур, символьных кривых и графиков в координатах X–Y
в модуле визуализации. Вывод истории нагружения предназначен
для вывода небольших порций данных модели, запрашиваемой
достаточно часто. Диагностическая информация предназначена
для предоставления информации о сходимости данных расчета.

2.3.2. Объектная модель базы данных результатов расчета

Объектная модель для выходного файла данных построена для


чтения и записи данных в файл. Для примера на рис. 2.5 изображено
соглашение объектной модели для пространственного вывода. Объ-
ект odb в верхней части рисунка создается при выполнении ко-
манды/функции открытия или создания выходного файла данных.

81
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Объект steps, находящийся уровень ниже, является частью объ-


екта odb, также как объект frames — членом объекта OdbStep.
Объект FieldOutput включает два объекта — fieldValue
и fieldLocation. Модель напрямую отражена в структуре ко-
манд интерфейса пакета Abaqus на языке C++ (Abaqus API C++).
Таким образом, доступ к данным в выходном файле осуществляет-
ся по шагам объектной иерархии.

Рис. 2.5. Объектная модель выходного файла данных

Рассмотрим компоненты объектной модели более подробно.


Выходной файл данных, генерируемый на основе анализа дан-
ных пакета Abaqus, содержит данные модели и данные результа-
тов (показанные на рис. 2.4).

Данные модели

Данные модели описывают детали и экземпляры деталей, ко-


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

82
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

файле данных Abaqus сохраняются не все данные модели; напри-


мер, нет информации о нагружениях и взаимодействиях.
Компоненты данных модели более подробно описаны ниже.
Деталь представляет собой конечно-элементное представле-
ние объекта. Детали являются составными частями сборки и могут
быть деформируемыми или недеформируемыми. Детали допуска-
ют многократное использование; они могут быть объявлены в
сборке много раз. Детали не анализируются напрямую, поскольку
представляют собой как бы эталон экземпляров деталей. Данные о
детали сохраняются в выходном файле данных как коллекция уз-
лов, элементов, поверхностей и наборов.
Корневая сборка — это коллекция позиционированных в про-
странстве экземпляров деталей. Анализ ведется через определение
граничных условий, ограничений, взаимодействий и истории на-
гружений для сборки. Объект выходного файла данных может со-
держать только одну корневую сборку.
Экземпляр детали представляет собой реализацию детали в
сборке. Все характеристики (такие как сетка и определение сек-
ций), определенные для детали, становятся характеристиками ка-
ждого экземпляра детали — наследуются экземплярами. Внутри
корневой сборки экземпляры детали размещаются независимо
друг от друга.
Для примера рассмотрим реализацию модели петли. Петля
может быть представлена как набор из двух фланцев с осью
(стержнем) посередине. Геометрия петли определяется созданием
детали «фланец», два экземпляра которой объявляются в сборке
«петля», и детали «стержень», единожды определенной в этой же
сборке. «стержень» определяется как неподвижная деталь.
Результаты визуализации показаны на рис. 2.6.
Материалы содержат модели материалов, включающие один
или несколько определений свойств материала. Одни и те же мо-
дели материалов можно повторно использовать в модели; для всех
компонентов, для которых используется одна и та же модель мате-
риала, определения свойств идентичны. Множество материалов
может быть указано в файле модельных данных, но только исполь-
зуемые в сборке из их числа копируются в выходной файл данных.
Секции добавляют описание свойств, которые необходимо за-
дать, чтобы завершить определение геометрических и физических
83
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

свойств элементов. Для завершения определения элементов раз-


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

Рис. 2.6. Сборка «петля»

Присваивания секций соединяют определения секций с облас-


тями экземпляров деталей. Это соединение используется в выход-
ном файле данных. Секции присваиваются каждой детали в моде-
ли. Присваивания секций распространяются на каждый экземпляр
детали.
Категории секций используются для группирования областей мо-
дели, определения секций которых одинаковы, например, областей, в
которых используется оболочная секция с пятью точками секций.
Рис. 2.7 иллюстрирует объектную иерархию данных модели и
данных результатов.
84
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 2.7. Объектная иерархия данных модели и данных результатов

Данные результатов

Данные результатов содержат итоговую информацию анализа.


Abaqus организует результаты анализа в выходном файле данных с
помощью перечисленных ниже компонентов.
Шаги. Анализ в Abaqus представляет собой последователь-
ность из одного или более шагов анализа. Каждый шаг ассоцииро-
ван с соответствующей процедурой анализа и содержит последо-
вательность фреймов.
Фреймы. Каждое состояние расчета, помеченное к выводу в
базу данных результатов расчета, называется фреймом.
Пространственный вывод. Этот вывод предназначен для от-
носительно редких запросов больших порций данных модели и
используется для вывода эпюров, деформированных поверхно-
стей, анимации в модуле Abaqus/Viewer. Возможно также ото-
85
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

бражение графиков. Только полные множества стандартных вы-


ходных переменных (к примеру, все значения напряжений или его
компонентов) могут быть отображены как пространственный вы-
вод. Пространственный вывод состоит из «облаков значений дан-
ных» (например, значения напряжения каждой точке интегрирова-
ния для всех элементов). Каждый элемент данных имеет свое
местонахождение, тип и значение. Подмножества (области), объ-
явленные в модели (например, наборы элементов или секции), по-
зволяют получить подмножества пространственного вывода. На
рис. 2.8 изображен фрагмент объекта пространственного вывода из
выходного файла данных.

Рис. 2.8. Объект пространственного вывода

Вывод истории нагружения. Это вывод, определенный для


отдельного элемента или значения, вычисленных для части моде-
ли как для целого (например, энергия). Вывод истории нагруже-
ния предназначен для относительно частых запросов небольших
порций данных и отображается с помощью плоских графиков в
модуле Abaqus/Viewer. Могут быть запрошены отдельные
(individual) переменные (например, специфические
(particular) компоненты напряжения).
В зависимости от предполагаемого типа вывода объект
HistoryRegion (область истории нагружения) может быть объ-
явлен для следующих элементов объектной иерархии:

86
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• узел;
• точка интегрирования;
• область;
• вся модель.
Вывод от всех запросов, которые относятся к определенному
элементу или области будет сохранен в одном объекте
HistoryRegion. На рис. 2.9 изображена иерархия объектов для
истории нагружения.

Рис. 2.9. Иерархия объектов для истории нагружения

2.4. Программные интерфейсы Abaqus


После выполнения расчетного задания модули Abaqus/
Standard или Abaqus/Explicit сохраняют результаты анали-
за в выходной файл с расширением .odb.
Существует несколько способов доступа к данным результатов,
сохраненных в выходном файле данных (рис. 2.10):
1) файл может быть открыт для просмотра в модуле
Abaqus/Viewer;
2) для доступа к данным выходного файла результатов можно
применять программные интерфейсы:
• интерфейс сценариев (Abaqus Scripting Interface);
• интерфейс программных средств (Application Programming In-
terface — API).

87
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 2.10. Схема взаимодействия с программными интерфейсами Abaqus

Программные интерфейсы характеризуются следующими


свойствами:
• интерфейс прикладных программ:
◦ язык программирования — C++;
◦ уровень абстракции — низкий;
◦ позволяет получить доступ (чтение/изменение/запись) к ре-
зультатам расчета в файле с расширением .odb;
◦ высокая производительность (используются прямые вызовы
ядра Abaqus);
88
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

◦ в соответствии с лицензией пользовательские программы за-


пускаются только из пакета Abaqus и не могут распространяться
отдельно;
◦ выходные файлы представляют собой пользовательские при-
ложения (*.exe);
• интерфейс сценариев:
◦ язык программирования — Python;
◦ уровень абстракции — высокий;
◦ доступна полная функциональность комплекса Abaqus;
◦ возможность создавать как GUI-, так и CLI-сценарии;
◦ возможность изменять текущую графическую оболочку или
создавать свою собственную над ядром Abaqus;
◦ выходные файлы — сценарии на языке Python (*.py).
Изменение расчетных параметров, создание и запуск новых
расчетных задач, гибкие средства для экспорта модели, неограни-
ченные возможности расширения функциональности — все эти
возможности интерфейса сценариев Abaqus позволяют использ-
вать его для создания различных программных комплексов.

2.4.1. Интерфейс прикладных программ

Интерфейс прикладных программ (Abaqus С++ API) представ-


ляет собой набор функций на языке C++ для доступа к данным
выходного файла. По своей функциональности Abaqus С++ API
практически идентичен интерфейсу сценариев, однако интерак-
тивная среда интерфейса сценариев и его интеграция с пакетом
Abaqus делает его более простым в использовании и программиро-
вании. Abaqus C++ API ориентирован на случаи, когда целесооб-
разно не применять интерфейс сценариев из соображений произ-
водительности (это прямые вызовы функций ядра Abaqus,
документированных только для работы с результатами расчета).
Abaqus С++ API позволяет осуществлять более быстрый доступ к
базе данных результатов, особенно когда необходимо обрабаты-
вать большие объемы информации.
Доступ к Abaqus С++ API осуществляется посредством под-
ключения заголовочного файла odb_API.h в пользовательской
программе. Необходимо указать точку входа в программу:

89
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ABQmain(int argc, char** argv)


Компиляция такой программы осуществляется посредством
вызова процедуры abaqus make:
abaqus make job=<program_name.c>
Команда запуска такой программы имеет вид
abaqus <program_name.exe>
Подобная схема выбрана для унификации процедуры компиляции
от версии к версии и для соблюдения лицензионного соглашения
пользователями.
Недостатки предложенной схемы заключаются в том, что он
позволяет осуществлять компиляцию только одного файла с ко-
дом, при этом визуальная среда разработки отсутствует.

2.4.2. Работа с Abaqus C++ API

Abaqus предоставляет API для доступа к данным, сохраненным


в файле с расширением .odb. Именно этот интерфейс использует
ядро Abaqus для операций с файлом результатов расчета. Набор
API позволяет получить полный доступ к любому элементу объ-
ектной модели. Как описано ранее, объектная модель представляет
собой иерархическую структуру с элементами различных типов,
составляющих базу данных результатов расчета. Для доступа к
данным на определенном уровне иерархии необходимо пройти от
корня (ODB) до нужного объекта на этом уровне.

2.4.3. Вспомогательные классы Abaqus C++ API

Abaqus C++ API предоставляет набор классов для расширения


функциональности или обеспечения удобного интерфейса для ра-
боты с объектами.

Строки (odb_String)

Класс odb_String предоставляет удобный способ для сохра-


нения и передачи строк. Использование его также позволяет избе-
жать ошибок при небезопасной работе с памятью, часто встре-

90
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

чающихся при программировании на C++. Также odb_String пре-


доставляет базовые средства для обработки строк, что позволяет
эффективно и удобно пользоваться строками в программе. Пример
использования класса показан ниже.
odb_String type =
stressField.baseElementTypes()[0];
odb_String elementType =
odb_String("Element type is ") + type;
cout << elementType.CStr() << endl;

Последовательность (odb_Sequence)
Этот класс создан для хранения упорядоченного списка объек-
тов определенного типа. Информация может быть извлечена из
последовательности или добавлена в нее.
Последовательности для базовых типов некоторых объектов:
• odb_SequenceInt;
• odb_SequenceFloat;
• odb_SequenceString;
• odb_SequenceInvariant;
• odb_SequenceElementFace.
Для вложенных последовательностей также существует набор
классов (аналог двухмерных массивов):
• odb_SequenceSequenceFloat;
• odb_SequenceSequenceSequenceFloat;
• odb_SequenceSequenceInt;
• odb_SequenceSequenceElementFace.
Для базовых объектов Abaqus определены следующие классы
последовательностей:
• odb_SequenceNode;
• odb_SequenceElement;
• odb_SequenceFieldValue;
• odb_SequenceFrame;
• odb_SequenceSectionPoint;
• odb_SequenceLoadCase;
• odb_SequenceFieldOutput.
Пример работы с последовательностями показан в листинге 2.1.

91
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Листинг 2.1. Работа с последовательностями


odb_Set& mySurface = rootAssy.surfaces()["TARGET"];
const odb_String instanceName = "PART-1-1";
const odb_SequenceElementFace allFaces =
mySurface.faces(instanceName);
odb_SequenceSequenceElementFace newFaces;
int allFaces_size = allFaces.size();
for (int i=0; i<allFaces_size; i++)
{
const odb_SequenceElementFace fList = allFaces[i];
odb_SequenceElementFace newList;
int fList_size = fList.size();
for (int j=0; j<fList_size; j++)
{
const odb_Enum::odb_ElementFaceEnum face = fList[j];
newList.append(face);
}
newFaces.append(newList);
}
Репозиторий (Repository)
Этот класс предоставляет возможность хранить объекты опре-
деленного типа и получать к ним доступ по имени.
Предоставляются следующие классы репозиториев:
• odb_PartRepository;
• odb_FieldOutputRepository;
• odb_SectionCategoryRepository;
• odb_HistoryRegionRepository;
• odb_SetRepository;
• odb_HistoryOutputRepository;
• odb_StepRepository;
• odb_InstanceRepository.
Пример работы с репозиториями приведен в листинге 2.2.
Листинг 2.2. Работа с репозиториями
odb_StepRepository stepCon = odb.steps();
// Репозиторий
odb_StepRepositoryIT iter (stepCon);
// Итератор
for (iter.first(); !iter.isDone(); iter.next())

92
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
cout << "step name:"<< iter.currentKey().CStr()
<< endl;
const odb_Step& step = iter.currentValue();
// Извлечение и доступ
cout << "step description:"<<
step.description().CStr();
cout << endl;
}

Обработка исключительных ситуаций (Exception)

Поддержка исключений языка C++ используется в Abaqus C++


API. Пример изменения стандартного сообщения при неудачном
открытии файла базы ODB в пользовательской программе дан в
листинге 2.3.
Листинг 2.3. Обработка исключительных ситуаций
odb_String invalidOdbName = "invalid.odb";
try
{
odb_Odb& odb = openOdb(invalidOdbName);
}
catch(odb_BaseException& exc)
{
cerr << "odbBaseException caught\n";
cerr << "Abaqus error message: "
<< exc.UserReport() << endl;
cerr << "Customized error message here\n";
}
catch(...)
{
cerr << "Unknown Exception.\n";
}

2.4.4. Объект класса odb

Объект класса odb является корневым элементом иерархии,


с его создания начинается работа с базой данных результатов
расчета.
Пример создания объекта класса odb рассмотрен выше.

93
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

2.4.5. Чтение данных модели

Корневая сборка (Root assembly)

Корневая сборка создается в базе данных результатов расчета в


единственном экземпляре и содержит экземпляры деталей, для
которых были рассчитаны и переданы для вывода данные. Корне-
вая сборка получена следующим образом:
odb_Assembly& rootAssy = odb.rootAssembly();

Экземпляры деталей (Part instances)

Экземпляры деталей сохраняются в объекте-репозитории


Instance. Экземпляры деталей — это ориентированные копии объ-
ектов деталей из класса odb, унаследовавшие их свойства и, воз-
можно, определившие свои. Экземпляры деталей также задают
положение объектов в пространстве:
odb_InstanceRepositoryIT
instIter(rootAssy.instances());
for (instIter.first(); !instIter.isDone();
instIter.next())
cout << instIter.currentKey().CStr() << endl;

Области (Region)

Области в базе данных результатов расчета представляют со-


бой экземпляры класса OdbSet. Области могут относиться как к
объектам деталей, так и к объектам экземпляров деталей. В первом
случае эти области также будут наследоваться каждым экземпля-
ром детали. Области представлены следующими классами:
• node set;
• element set;
• surface.
Пример вывода названий областей для узлов показан ниже:
cout << "Node set keys:" << endl;
odb_SetRepositoryIT setIter( rootAssy.nodeSets());
for (setIter.first(); !setIter.isDone(); setIter.next())
cout << setIter.currentKey().CStr() << endl;

94
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Материалы (Materials)

Данные о материалах хранятся в объекте-репозитории


material и являются частью объекта класса odb.
Для расширения Abaqus API командами работы с материалами
необходимо выполнить следующие команды:
odb_MaterialApi materialApi;
odb.extendApi(odb_Enum::odb_MATERIAL, materialApi);
Пример доступа к репозиторию, содержащему материалы, по-
казан в листинге 2.4.
Листинг 2.4. Работа с материалами
odb_MaterialContainer& materialContainer =
materialApi.materials();
odb_MaterialContainerIT matIT(materialContainer);
for (matIT.first(); !matIT.isDone(); matIT.next())
{
cout << "Material Name:"<< matIT.currentKey() << endl;
const odb_Material& myMaterial =
matIT.currentValue();
}

Секции (Sections)
Секции в Abaqus позволяют задать для элементов свойства ма-
териалов или дополнить их определение.
Данные о секциях хранятся в объекте-репозитории section, яв-
ляются частью объекта odb. Для расширения Abaqus API командами
работы с секциями необходимо выполнить следующие команды:
odb_SectionApi sectionApi;
odb.extendApi(odb_Enum::odb_SECTION, sectionApi);
Пример доступа к секциям показан в листинге 2.5.
Листинг 2.5. Работа с секциями
odb_SectionContainer& sectionContainer =
sectionApi.sections();
odb_SectionContainerIT scIT(sectionContainer);
for (scIT.first(); !scIT.isDone(); scIT.next())
{
cout << "Section Name:"<< scIT.currentKey() << endl;
}

95
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Объект Section может быть нескольких типов. Метод


odb_isA (реально это макрос С++) позволяет определить тип сек-
ции (листинг 2.6).
Листинг 2.6. Определение типа секции
for (scIT.first(); !scIT.isDone(); scIT.next())
{
const odb_Section& mySection = scIT.currentValue();
if (odb_isA(odb_HomogeneousSolidSection,mySection))
{
odb_HomogeneousSolidSection homogeneousSolidSection =
odb_dynamicCast(odb_HomogeneousSolidSection,
ySection);
odb_String material =
homogeneousSolidSection.material();
cout << "material name="<< material << endl;
float thickness = homogeneousSolidSection.thickness();
cout << "thickness="<< thickness << endl;
}
}

Присваивания секций (Section assignments)

Присваивания секций хранятся в объекте sectionAssign-


ments, являющимся частью объекта OdbAssembly (корневая
сборка).
Все элементы в расчетах Abaqus должны быть ассоциированы
с материалами и секциями. Присваивания секции позволяют ус-
танавливать отношения между элементами в экземплярах деталей
и секциями. Свойства секций включают в себя информацию о
материале.
В листинге 2.7 показано, как осуществляется доступ к объекту
sectionAssigments.
Листинг 2.7. Присваивания секций
odb_InstanceRepository& instanceRepository =
odb.rootAssembly().instances();
odb_InstanceRepositoryIT instIT(instanceRepository);
for(instIT.first(); !instIT.isDone(); instIT.next())
{
const odb_Instance& instance = instIT.currentValue();

96
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

odb_SequenceSectionAssignment sectionAssignmentSeq =
instance.sectionAssignments();
int sects = sectionAssignmentSeq.size();
cout << "Instance:"<< instance.name() << endl;
for(ints=0;s< sects; ++s)
{
odb_SectionAssignment sa = sectionAssignmentSeq[s];
odb_Section section = sa.section();
cout << " Section:"<< section.name() << endl;
odb_Set set = sa.region();
const odb_SequenceElement& elements = set.elements();
int size = elements.size();
cout << " Elements associated with this section : "
<< endl;
for(inte=0;e< size; ++e)
cout << elements[e].label() << endl;
}
}

2.4.6. Чтение данных результатов

Для чтения данных результатов, как и данных модели, удобно


использовать вспомогательные классы, описанные выше. Данные
результатов представлены шагами расчета и фреймами.

Шаги (Steps)
Шаги расчета представлены объектом-репозиторием steps и
хранятся в объекте odb. Ключом к репозиторию является название
шага расчета. Следующий пример демонстрирует вывод всех на-
званий шагов расчета:
odb_StepRepositoryIT stepIter( odb.steps() );
for (stepIter.first();
!stepIter.isDone();stepIter.next())
cout << stepIter.currentKey().CStr() << endl;

Фреймы (Frame)
Фрейм — это любое состояние расчета, помеченное к выводу.
Каждый шаг расчета содержит последовательность фреймов,
соответствующих времени расчета.
97
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Следующий пример демонстрирует доступ к последнему


фрейму шага расчета:
odb_Step& step = odb.steps()["Step-1"];
odb_SequenceFrame& allFramesInStep =
step.frames();
int numFrames = allFramesInStep.size();
odb_Frame& lastFrame =
allFramesInStep[numFrames-1];

2.4.7. Чтение данных пространственного вывода

Данные пространственного вывода представлены объектом


fieldOutputs, являющимся частью объекта OdbFrame. Клю-
чом к репозиторию служит название выходной переменной. Сле-
дующий пример демонстрирует вывод всех названий выходных
переменных для последнего фрейма в шаге расчета (переменная
lastFrame определяется выше):
odb_FieldOutputRepository& fieldOutputRep =
lastFrame.fieldOutputs();
odb_FieldOutputRepositoryIT
fieldIter( fieldOutputRep );
for (fieldIter.first(); !fieldIter.isDone();
fieldIter.next())
cout << fieldIter.currentKey().CStr() << endl;
Результаты:
S
U
LE
CSHEAR1 ASURF/BSURF
CSLIP1 ASURF/BSURF
CPRESS ASURF/BSURF
COPEN ASURF/BSURF
UR3
Различные переменные могут быть записаны во фреймы с раз-
ной периодичностью. В итоге не все фреймы могут содержать
полный набор выходных переменных.
Объект fieldOutput имеет метод values(), возвращаю-
щий ссылку на последовательность объектов типа FieldValue,

98
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

которые содержат данные. Каждый из элементов типа


FieldValue в последовательности соответствует определенному
местонахождению в модели. Доступ к данным, соответствующим
каждому объекту типа FieldValue, осуществляется с помощью
метода data(), который возвращает указатель на массив резуль-
татов для текущей позиции:
const odb_SequenceFieldValue& displacements =
lastFrame.fieldOutputs()["U"].values();
int numValues = displacements.size();
int numComp = 2;
for (int i=0; i<numValues; i++)
{
const odb_FieldValue val = displacements[i];
cout << "Node="<< val.nodeLabel();
const float* const U = val.data(numComp);
cout << " U=";
for (int comp=0;comp<numComp;comp++)
cout << U[comp] << " ";
cout << endl;
}
Результаты:
Node = 1 U[x] = 0.0000, U[y] = -76.4580
Node = 3 U[x] = -0.0000, U[y] = -64.6314
Node = 5 U[x] = 0.0000, U[y] = -52.0814
Node = 7 U[x] = -0.0000, U[y] = -39.6389
Node = 9 U[x] = -0.0000, U[y] = -28.7779
Node = 11 U[x] = -0.0000, U[y] = -20.3237...
Доступ к данным пространственного вывода через объект
FieldValue в следующих версиях Abaqus C++ API будет закрыт.
Его окончательно заменит метод пакетного доступа к данным ре-
зультатов (bulk data access).

2.4.8. Пакетный доступ к данным результатов

Для получения доступа ко всему объему данных в базе резуль-


татов расчета применяют метод bulkDataBlocks() объекта
FieldOutput, который возвращает данные в пакетной форме
(массив) — листинг 2.8.

99
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Листинг 2.8. Пакетный доступ к данным результатов


odb_FieldOutput& disp =
lastFrame.fieldOutputs()["U"];
const odb_SequenceFieldBulkData& seqDispBulkData =
disp.bulkDataBlocks();
int numDispBlocks = seqDispBulkData.size();
for (int iblock=0; iblock<numDispBlocks; iblock++)
{
const odb_FieldBulkData& bulkData =
seqDispBulkData[iblock];
int numNodes = bulkData.length();
int numComp = bulkData.width();
float* data = bulkData.data();
int* nodeLabels = bulkData.nodeLabels();
for (int node=0,pos=0; node<numNodes; node++)
{
int nodeLabel = nodeLabels[node];
cout << "Node="<< nodeLabel;
cout << "U=";
for (int comp=0;comp<numComp;comp++)
cout << data[pos++] << " ";
cout << endl;
}
}

2.5. Интерфейс сценариев

С помощью интерфейса сценариев можно осуществлять раз-


личные действия как над моделью из базы данных модели, так и
над данными, сохраненными в базе данных результатов расчета.
Среди этих действий можно выделить:
• чтение данных модели, описывающих геометрию составных
частей сборки, например узловых координат, связей между эле-
ментами, типов и формы элементов;
• чтение данных модели, описывающих секции и материалы, а
также использование их в сборке;
• чтение данных пространственного вывода (field output) для
выбранных шагов, фреймов и областей;
• чтение выходных данных истории нагружения (history
output);

100
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• выполнение действий с данными пространственного вывода и


истории нагружения;
• запись перечисленных выше данных в текущую базу резуль-
татов расчета или создание новой базы;
• запуск решения расчетных задач.

2.5.1. Abaqus и интерфейс сценариев

При использовании графического пользовательского интерфейса


Abaqus (Graphical user interface — GUI) для создания модели или ви-
зуализации результатов после каждой операции генерируются внут-
ренние команды Abaqus. Эти команды отображают созданную поль-
зователем геометрию в соответствии с выбранными параметрами и
настройками в диалоговом окне. Интерфейс генерирует команды на
объектно-ориентированном языке Python. Команды, выдаваемые
GUI, передаются ядру Abaqus. Ядро интерпретирует команды и, ис-
пользуя текущие параметры и настройки, создает внутреннее пред-
ставление модели. Ядро Abaqus можно назвать «мозгом» системы, а
GUI — интерфейсом между пользователем и ядром.
Интерфейс сценариев Abaqus позволяет обойти Abaqus GUI и
взаимодействовать напрямую с ядром. Файлы, содержащие коман-
ды интерфейса сценариев Abaqus, называются скриптами (от англ.
script — сценарий) или командными сценариями. Скрипты позво-
ляют осуществлять следующие действия:
• автоматизацию часто повторяющихся действий. Напри-
мер, создание сценария, автоматически запускаемого при старте
Abaqus. Такой скрипт может, к примеру, генерировать библиотеку
стандартных материалов. В результате при работе с модулем
Property эти материалы будут доступны. Подобным образом
сценарий может быть использован при создании удаленных очере-
дей для запуска расчетных задач. Эти очереди будут доступны в
модуле Job;
• проведение параметрического анализа, например, создание
скрипта, который пошагово изменяет геометрию детали и прово-
дит расчет. Также скрипт может считывать результаты, отобра-
жать результаты и генерировать аннотированные документальные
копии проведенного расчета;

101
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• создание и изменение модельных баз данных и моделей,


созданных в Abaqus GUI (см. подразд. 2.2);
• доступ к базам данных результатов (выходному файлу ре-
зультатов). Например, проведение собственной постобработки ре-
зультатов расчета. Результаты могут быть записаны в выходной файл
результатов и отображены с помощью модуля Abaqus/Viewer.
Интерфейс сценариев Abaqus является расширением языка
Python, в нем используются его синтаксис и операторы. Поэтому
описываемые возможности и особенности интерфейса сценариев в
равной степени относятся к самому языку Python.

2.5.2. Язык Python

Python является базовым объектным языком для продуктов


Abaqus и широко используется для решения разнообразных задач:
• создание конфигурации пакета Abaqus (abaqus_v6.env);
• определение параметров в секциях *PARAMETER во входном
файле расчета (*.inp);
• проведение параметрического анализа;
• запись всех команд текущей сессии в файл перезапуска (*.rpy);
• создание и запуск пользовательских командных сценариев;
• доступ к выходному файлу результатов (*.odb).

Описание языка Python


О языке Python (принято произносить «питон», хотя некоторые
говорят «пайтон») лучше всего говорит создатель этого языка про-
граммирования, голландец Гвидо ван Россум (Guido van Rossum):
«Python — интерпретируемый, объектно-ориентированный высо-
коуровневый язык программирования с динамической семантикой.
Встроенные высокоуровневые структуры данных в сочетании с
динамическими типизацией и связыванием делают язык привлека-
тельным для быстрой разработки приложений. Кроме того, его
можно использовать в качестве сценарного языка для связи про-
граммных компонентов. Синтаксис Python прост в изучении, в нем
придается особое значение читаемости кода, а это сокращает за-
траты на сопровождение программных продуктов. В языке Python
поддерживаются модули и пакеты, поощряется модульность и по-
102
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

вторное использование кода. Интерпретатор Python и большая


стандартная библиотека доступны бесплатно в виде исходных и
исполняемых кодов для всех основных платформ и могут свобод-
но распространяться».
Python, как и любой язык программирования, имеет свои пре-
имущества и недостатки, а также сферы применения. В поставку
Python входит обширная стандартная библиотека для решения широ-
кого круга задач. В Интернете доступны качественные библиотеки
для Python по различным предметным областям: средства обработки
текстов и технологии Интернета, обработка изображений, инстру-
менты для создания приложений, механизмы доступа к базам дан-
ных, пакеты для научных вычислений, библиотеки построения гра-
фического интерфейса и т. п. Кроме того, Python имеет достаточно
простые средства для интеграции с языками C, C++ (и Java) как путем
встраивания (embedding) интерпретатора в программы на этих язы-
ках, так и наоборот, посредством использования библиотек, написан-
ных на этих языках, в Python-программах. Язык Python поддерживает
несколько парадигм программирования: императивное (процедур-
ный, структурный, модульный подходы), объектно- и аспектно-
ориентированное, а также функциональное программирование.
Создание Python было начато Гвидо ван Россумом в 1991 г.,
когда он работал над распределенной операционной системой
Ameba. Ему требовался расширяемый язык, который обеспечил бы
поддержку системных вызовов. За основу были взяты ABC и Мо-
дула-3. В качестве названия он выбрал Python в честь комедийного
сериала BBC «Летающий цирк Монти-Питона», а вовсе не по на-
званию змеи. С тех пор Python развивался при поддержке тех ор-
ганизаций, в которых работал автор. Особенно активно язык со-
вершенствуется в настоящее время, когда над ним трудится не
только команда создателей, но и целое сообщество программистов
со всего мира. И все-таки последнее слово о направлении развития
языка остается за ван Россумом.

Использование интерпретатора Python

Как уже было сказано выше, Python является интерпрети-


руемым языком. Напечатав выражение в интерпретаторе, можно
увидеть результат без компиляции и сборки скрипта. Экспери-

103
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ментировать с выражениями Python быстро и просто. Учебные


примеры, описываемые здесь или в официальной документации,
могут быть практически опробованы на пользовательской рабо-
чей станции. Интерпретатор Python доступен в следующих ва-
риантах:
• на рабочей станции под управлением операционных систем
UNIX или Windows с установленным Abaqus достаточно в ко-
мандной строке набрать:
abaqus python
Python переходит в режим интерпретатора и отображает окно при-
глашения >>>. Выражения можно вводить прямо в этой строке,
и результат будет отображен здесь же. Для выхода из интерпретато-
ра в системе UNIX следует нажать комбинацию клавиш <Ctrl + D>,
в Windows — <Ctrl + Z>;
• скрипты могут быть интерпретированы из командной строки:
abaqus python scriptname.py
Abaqus обработает скрипт интерпретатором и выдаст результат(ы)
в командную строку;
• доступ к интерпретатору Python можно получить прямо из
графической среды Abaqus. В нижней части окна наряду с обла-
стью сообщений находится командная строка интерпретатора.

2.6. Создание пользовательских оболочек над ядром Abaqus

Для создания пользовательской графической оболочки ис-


пользуется инструментарий Abaqus GUI Toolkit, который предо-
ставляет программные средства для создания или изменения ком-
понентов графического интерфейса пользователя (GUI). Иерар-
хия объектов пользовательской оболочки в Abaqus показана на
рис. 2.11.
Инструментарий Abaqus GUI Toolkit позволяет выполнять сле-
дующие действия:
• создание нового модуля GUI. Модуль представляет собой
объединенные по функциональному признаку элементы про-
граммы;
• создание нового набора инструментов. Набор инструмен-
тов — более специализированный набор элементов программы.

104
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Может разделяться (использоваться совместно) несколькими мо-


дулями (например, Datum tools);
• создание новых диалоговых окон. Abaqus GUI Toolkit пре-
доставляет широкий набор функций и элементов управления для
создания пользовательских диалоговых окон;
• удаление неиспользуемых модулей и наборов инструмен-
тов, элементов меню или отдельных пунктов меню. Можно
гибко настраивать пользовательскую оболочку.

Рис. 2.11. Иерархия объектов пользовательской оболочки в Abaqus

Работа GUI-приложения основана на механизме передачи со-


общений между ядром ABAQUS и процессом GUI. Схема процес-
са передачи сообщения изображена на рис. 2.12.
Команда ядра осуществляет работу, связанную с моделью. Ко-
манду ядра можно представить в виде составных частей:
объект + метод + аргументы (ключевые слова)

105
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 2.12. Механизм передачи сообщений

Ниже приведены примеры записи различных команд:


session.viewports['Viewport: 1'].setValues
(width=50, height=100)
|----------- объект ------------ | метод |---
------------------------------------ аргументы ----|
mdb.models[Model-1'].PointSection
(name='Section-3', mass=1.0)
|----- объект ------|-- метод --|---
-------------------------------- аргументы --------|
session.viewports['Viewport: 1']. bringToFront()
|--------—- объект -------------|-- метод --|

106
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

LeafFromElementSets(elementSets='PART-1-1.E1')
|------ метод -----|------- аргументы -------|
Команда интерфейса класса AFXGuiCommand представляет
собой действие, совершаемое после выхода из состояния (mode), и
содержит следующие аргументы:
• состояние (mode). Состояние активируются по нажатию
пользователем элемента управления в пользовательском интер-
фейсе (чаще всего кнопка или пункт меню). Как только состояние
активировано, можно считывать параметры ввода, передавать ко-
манду ядру и обрабатывать ошибки в процессе работы;
◦ состояния форм (Form modes). Являются интерфейсами к
диалоговым окнам и осуществляют сбор данных из одного или
нескольких диалоговых окон;
◦ процедурные состояния (Procedure modes). Позволяют
считывать последовательные цепочки пользовательского ввода и
генерировать команду ядру на основании полученных данных;
• метод (method). Строка, представляющая собой название
метода команды ядру;
• название объекта (objectName). Строка — название объек-
та ядра;
• регистрирация запроса (registerQuery). Логическое зна-
чение, обусловливающие необходимость получения информации
(флаг подписки) на изменение определенных параметров ядра.
Пример, иллюстрирующий создание команды на изменение
графических параметров:
cmd = AFXGuiCommand(self, 'setValues',
'session.graphicsOptions', TRUE)
Элементы графического интерфейса взаимодействуют между
собой посредством механизма передачи сообщений. Любой эле-
мент может запрашивать сообщения от других элементов и ста-
вить в соответствие обрабатывющую функцию. Схема процесса
взаимодействия элементов графического интерфейса представлена
на рис. 2.13.
В роли объектов могут выступать как элементы графического
интерфейса (виджеты), так и диалоговые окна.

107
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 2.13. Передача сообщений между объектами GUI

108
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

3. ИСПОЛЬЗОВАНИЕ БИБЛИОТЕК AVANGO


И OPEN INVENTOR ДЛЯ ТРЕХМЕРНОЙ ВИЗУАЛИЗАЦИИ

3.1. Обзор системы разработки


виртуальных приложений Avango

3.1.1. Программная среда Avango

Avango — это среда программирования для создания распре-


деленных интерактивных приложений виртуального окружения.
Для определения двух категорий объектных классов в ней исполь-
зуется язык программирования C++. Узлы предоставляют интер-
фейс графов сцены, который обеспечивает создание и обработку
объектов со сложной геометрией. Датчики позволяют системе
Avango поддерживать связь с реальным миром и используются для
ввода данных с внешних устройств.
Все объекты Avango представляют собой полевые контейнеры,
содержащие информацию о состоянии объекта как набор полей.
Они поддерживают универсальный потоковый интерфейс, позво-
ляющий записывать объекты и информацию об их состояниях в
поток, и впоследствии изменять объект, выбирая его из потока.
В системе Avango используются связи между полями для фор-
мирования графа потоков данных, независимого от графа сцены,
который необходим для задания взаимодействия объектов в инте-
рактивных приложениях.
В качестве основы для построения среды Avango выбран про-
граммный комплекс OpenGL Performer, предоставляющий расши-
ренные графические возможности, такие как отбор видимых по-
верхностей, переключение между уровнями детальности и
взаимодействие с графическим оборудованием.
В дополнение к интерфейсу на языке C++ характерной чертой
пакета Avango является полная привязка к интерпретируемому
языку Scheme. Это универсальный язык программирования, про-
изошедший от языков Algol и Lisp. Это язык высокого уровня,
поддерживающий операции со структурными данными типа строк,
списков и векторов. Все объекты высокого уровня в Avango могут
быть созданы и управляемы посредством языка Scheme.

109
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Интерфейс сценариев Avango предлагает двухуровневый под-


ход к разработке приложений. Дополнительные классы реализу-
ются на языке C++, расширяя существующие классы Avango. Само
приложение в этом случае — только набор сценариев на языке
Scheme, которые создают требуемые объекты Avango, вызывают
их методы, устанавливают значения их полей и определяют отно-
шения между ними. Сценарии могут быть написаны, проверены и
отлажены прямо во время работы приложения. Это значительно
уменьшает время разработки и обеспечивает очень мощную среду
для создания прототипа приложения.

3.1.2. Поля и полевые контейнеры

Эффективная реализация универсального потокового интер-


фейса для разнородных объектов требует дополнительной мета-
информации об атрибутах объектов и их типах, а также о способе
обращения к этим атрибутам без точного знания типа объекта. В
языке программирования C++ эта метаинформация труднодоступ-
на. Например, в системе OpenGL Performer для обращения к атри-
бутам состояния объекта используется функция интерфейса. Сим-
метричная пара функций установки и взятия значения существует
для каждого атрибута. В результате побочного эффекта при уста-
новке одного атрибута заменить его может другой атрибут этого
объекта. Однако информация о числе атрибутов, их типе и их зна-
чениях не может быть получена от объекта через интерфейс
Performer. Чтобы устранить этот недостаток, в Avango использован
подход, принятый системой Inventor, который также можно найти
в спецификации VRML*. Здесь поля используются как контейнеры
для атрибутов состояния объекта. Поля содержат основные типы
данных и предоставляют универсальный потоковый интерфейс.
Они реализованы как общедоступные члены класса и таким обра-
зом унаследованы производными классами. Они непосредственно
доступны клиентским классам и являются главным интерфейсом
Avango к атрибутам состояния объекта.

*
VRML (от англ. Virtual Reality Modeling Language — язык моделирования
виртуальной реальности) — стандартный формат файлов для демонстрации трех-
мерной интерактивной векторной графики.

110
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Поля бывают двух типов. Однозначные поля содержат одно


значение, в то время как мультиполя содержат вектор произволь-
ного числа значений. В среде Avango обширно используется стан-
дартная библиотека шаблонов (Standart Templane Library — STL).
Мультиполевые значения реализованы как STL-векторы полевого
типа. Поля реализованы посредством шаблонов языка C++, кото-
рые допускают параметризацию класса avField<> требуемым
типом данных. В качестве примера полевого интерфейса расмот-
рим фрагмент определения шаблона класса для однозначного поля
(листинг 3.1).
Листинг 3.1. Определение шаблона класса для однозначного поля
template<class T>
class avSingleField : public avField {
public:
void setValue(const T& value);
const T& getValue() const;
};
template<class T>
ostream& operator<<(ostream& stream,
const avSingleField<T>& field);
template<class T>
istream& operator>>(istream& stream,
avSingleField<T>& field);
Доступ к полевому значению обеспечивается методами
getValue() и setValue().
Объекты Avango являются полевыми контейнерами, которые
представляют состояния объекта как набор полей. Можно опреде-
лить число полей полевого контейнера и их ссылки (листинг 3.2).
Листинг 3.2. Интерфейс полевых контейнеров
class avFieldContainer {
public:
int getNumFields();
avFieldPtrVec& getFields();
protected:
virtual void notify(avField& field);
virtual void evaluate();
};
ostream& operator<<(ostream& stream,

111
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

avLink<avFieldContainer>& fc);
istream& operator>>(istream& stream,
avLink<avFieldContainer>& fc);
Этот интерфейс вместе с универсальным потоковым интерфей-
сом полей позволяет системе Avango обеспечивать потоковые функ-
циональные возможности на уровне полевых контейнеров без знания
точного типа основного объекта. Этот механизм распространяется на
все классы, выведенные из класса avFieldContainer.
Адаптируемые поля используются для соединения интерфейса,
основанный на методах Performer, с полевым интерфейсом
Avango. Они передают запросы getValue() и setValue() со-
ответствующим функциям взятия и установки значения интерфей-
са Performer. Это гарантирует, что связанная с Performer информа-
ция о состоянии графа будет правильным образом обновлена в
соответствии с изменениями значения поля и возможные побоч-
ные эффекты будут должным образом обработаны.
В качестве примера можно показать процедуру подклассифи-
кации для узла pfGroup, который имеет частично унаследован-
ный интерфейс:
class pfGroup {
int setName(const char *name);
const char* getName(void);
int addChild(pfNode *child);
int insertChild(int index, pfNode *child);
int replaceChild(pfNode *old,pfNode *new);
int removeChild(pfNode *child);
int searchChild(pfNode *child);
pfNode* getChild(int index);
int getNumChildren(void);
};
Класс avGroup получен из классов pfGroup и
avFieldContainer и снабжен подходящим набором адапти-
руемых полей:
class avGroup : public pfGroup,
public avFieldContainer
{
public:
avMultiAdaptorField<avLink<avGroup>> Parents;

112
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

avSingleAdaptorField<string> Name;
avMultiAdaptorField<avLink<avGroup>> Children;
};
Поле Name реализует методы getValue() и setValue() в
терминах запросов pfGroup::getName() и pfGroup::
setName(). Поле Children является адаптацией мультиполя к
целому диапазону функций доступа Performer, используемых для
управления дочерними узлами узла группы. Возвращаемый тип
Children.getValue() — STL-вектор avLink<avNode>.
Шаблонный класс avLink<> определяет указатель на объекты
Avango, который скрывает детали подсчета ссылок от разработчи-
ка и существенно уменьшает сложность написания кода, не прове-
ряя исключительные ситуации.
Интерфейс полевых контейнеров Avango позволяет организо-
вывать потоки данных и создавать сценарии. Эти возможности
унаследованы любыми специфичными для приложения объектами,
добавленными разработчиком. Поскольку узлы Avango унаследо-
ваны от узлов Performer, узлы обоих типов могут быть свободно
объединены при построении графа сцены.

3.1.3. Полевые связи


В среде Avango используется понятие полевых связей. Поля
совместимого типа могут быть связаны таким образом, что если
значение исходного поля изменяется, оно немедленно передается
другому полю. Посредством полевых связей может быть создан
граф потоков данных, независимый от графа сцены. В Avango этот
механизм используется для того, чтобы определить дополнитель-
ные отношения между узлами, которые не могут быть выражены в
терминах стандартного графа сцены. Это облегчает реализацию
интерактивного приложения и ввод данных в граф сцены.
Обработка графа потоков данных выполняется один раз за
кадр. Полевые связи немедленно передают изменения значений,
поэтому задержка не распространяется по связям в графе. Циклы
обнаруживаются и должным образом разрешаются. Полевой кон-
тейнер может включать побочные эффекты изменений поля, пере-
гружая функции notify() и evaluate(). Всякий раз, когда в
поле записывается новое значение, метод notify() вызывается
113
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

полевым контейнером со ссылкой на измененное поле в качестве


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

3.1.4. Узлы

Для всех узловых классов Performer (pfGroup, pfDCS,


pfLOD и т.п.) и для большинства объектных классов Performer
(pfGeoState, pfMaterial, pfTexture и т. п.), существуют
адаптации полевых контейнеров. В соответствии с соглашением
для узлов Avango префикс pf Performer заменен на префикс fp.
Возможность совместного использования узлов Avango с уз-
лами Performer при построении графа сцены позволяет опреде-
лять новые узлы с дополнительными функциональными возмож-
ностями. Узел avFile, например, получен из адаптированного
узла avDCS. Он наследует интерфейс avDCS, который в основ-
ном состоит из полей Children и Matrix. В узел avFile добав-
лено поле URL строкового типа. При помощи перегруженного
метода notify() узел avFile реагирует на изменения поля
URL, получая геометрическике параметры из данного URL и до-
бавляя их в список своих дочерних полей. Таким образом
avFile импортирует геометрические параметры в граф сцены.
При последующих изменениях поля URL параметры заменяются
на новые.

3.1.5. Датчики

Датчики необходимы для восприятия внешних воздействий.


Они представлены в классе avFieldContainer, а не унаследо-
ваны от какого-либо узла Performer, поэтому они не могут быть
включены в граф сцены. Датчики содержат код, необходимый для
обращения к устройствам ввода данных различных видов. Данные,
переданные устройством, отображаются в полях датчика:
114
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

class avTrackerSensor : public avDeviceSensor {


public:
avSingleField<string> Station; // inherited
avSingleField<avMatrix> Transform;
avSingleField<bool> Button;
};
Всякий раз, когда устройство генерирует новые значения дан-
ных, поля соответствующего датчика модифицируются. Соедине-
ния полей датчиков и узлов в графе сцены используются для того,
чтобы ввести данные из устройства в приложение. Класс
avTrackerSensor, например, обеспечивает доступ к простран-
ственным системам слежения, обладающим шестью степенями
свободы (например, Polhemus Fastrak).
В Avango используется фоновый процесс (демон), который
осуществляет прямое взаимодействие с устройствами через после-
довательный порт или сетевые подключения. Демон обновляет зна-
чения данных устройства в общедоступной области памяти, где
классы avDeviceSensor могут их прочитать. Имя Station ис-
пользуется для идентификации запрашиваемых из устройства дан-
ных в общедоступной области памяти, и каждый класс
avDeviceSensor определяет этот идентификатор в своем поле
Station. После соединения с демоном устройства класс
avTrackerSensor предоставляет текущую информацию о поло-
жении и ориентации выбранного устройства слежения как матрицу,
содержащуюся в его поле Transform. Посредством подключения
поля Matrix узла avDCS к полю Transform координаты эле-
ментов поддерева, исходящего из узла avDCS, будут изменяться в
соответствии с движением устройства слежения.

3.1.6. Модель общедоступной памяти

В системе Avango используется модель общедоступной памя-


ти, которая позволяет объектам разных процессов взаимодейство-
вать и использовать общие данные.
Процессы Avango могут присоединяться к одной или несколь-
ким общедоступным группам памяти. Объекты могут быть созданы
либо локально, либо в одной из общедоступных групп. Локальные
объекты существуют только в адресном пространстве порождающе-
115
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

го процесса, в то время как общедоступный объект явно создает ко-


пии в адресном пространстве каждого процесса, присоединенного к
общедоступной группе. Последующие изменения состояния объек-
та будут переданы всем его копиям. Общедоступные объекты могут
переходить от одной группы к другой, но при этом одновременно
они могут принадлежать только одной из них.

3.1.7. Граф сцены

Как было описано ранее, объекты Avango являются полевыми


контейнерами, которые содержат состояния объекта в наборе по-
лей. Потоковый интерфейс классов полей и полевых контейнеров
допускает изящную реализацию общедоступной объектной се-
мантики.
Создание общедоступных объектов в Avango — двухуровне-
вый процесс. Сначала создается локальный объект, который за-
тем связывается с определенной общедоступной группой. Связы-
вание включает объявление нового объекта в общедоступной
группе и распространение текущего состояния объекта на всех
членов группы. Потоковый интерфейс полевого контейнера ис-
пользуется для преобразования информации о состоянии объекта
в последовательную форму и помещения ее в сетевой буфер дан-
ных, который затем передает ее всем членам группы. Члены
группы создают копию объекта из последовательной информа-
ции о состоянии. Только что созданный общедоступный объект
будет затем существовать как локальная копия в каждом из уча-
ствующих процессов.
В Avango состояние объекта можно изменить посредством
изменения значений его полей. Всякий раз, когда полевое значе-
ние общедоступного объекта локально изменилось, новое значе-
ние отправляется в сетевой буфер и посылается всем членам об-
щедоступной группы, чтобы копии этого объекта остались
корректными.
Отношения между дочерними и родительскими объектами в
графе сцены представлены мультиполем значений ссылок в роди-
тельском узле. Поскольку все полевые значения являются потоко-
выми, описанная выше схема будет распределять и синхронизиро-
вать не только обособленные объекты, но и отношения

116
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

«родительский объект — дочерний объект» между ними. Таким


образом, полный граф сцены воспроизводится во всех процессах
общедоступной группы.
Способность распределять полный граф сцены между объек-
тами является ключевым шагом к разработке общедоступных при-
ложений. Однако этого недостаточно. Рассмотрим случай обще-
доступной группы, состоящей из двух процессов A и B. Оба
процесса уже создали несколько общедоступных объектов в этой
группе. Пусть теперь к группе присоединяется третий процесс C.
С этого времени все три процесса будут уведомлены о созданых
объектах и их изменениях, но процесс C не будет знать об объек-
тах, которые A и B создали прежде, чем он присоединился.
В Avango эта проблема решена с помощью атомарной (неде-
лимой) передачи состояния каждому присоединившемуся члену.
Когда новый процесс присоединяется к уже заполненной обще-
доступной группе, один из старших членов группы берет на себя
обязанность передать текущее состояние общедоступной группы
новому члену. Эта операция включает посылку всех объектов, в
настоящее время находящихся в группе, со всеми их полевыми
значениями, вновь прибывшему объекту. После передачи состоя-
ния группы новый член будет иметь надлежащий набор копий
объектов для этой общедоступной группы. Чтобы предотвратить
проблемы согласования, передача состояния выполняется как одно
атомарное действие, во время которого все другие изменения при-
останавливаются. Новые члены могут присоединиться к сущест-
вующей общедоступной группе в любое время, — они немедленно
получат свою локальную копию графа сцены, уже созданного в
общедоступной группе.

3.2. Среда для создания графических сцен Open Inventor

3.2.1. Обзор среды Open Inventor

Сегодня широкое распространение в качестве графического


стандарта получил 3D-графический интерфейс OpenGL, предна-
значенный для создания и отрисовки сцен (визуализации) в трех-
мерном пространстве. Его реализации доступны практически на
всех графических системах, работающих в операционных систе-

117
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

мах Unix и Microsoft Windows. Однако в OpenGL имеются только


базовые средства для 3D-визуализации, но нет аппарата для ввода
и структурного описания сцены, который необходим для разра-
ботки интерактивных графических приложений. Следующим ша-
гом в развитии открытых графических стандартов должен быть
инструментарий более высокого уровня, обеспечивающий разра-
ботчика средствами структуризации, визуализации и интерактив-
ного взаимодействия. Такой инструментарий предложен в системе
Open Inventor.
Open Inventor содержит набор строительных блоков (объектов),
позволяющих создавать интерактивные приложения с минималь-
ными усилиями. Объект Open Inventor — это экземпляр класса
С++, инкапсулирующий данные и методы. Набор объектов — биб-
лиотека классов C++, которую можно расширять по мере необхо-
димости.
Приложение, созданное средствами Open Inventor, работает с
трехмерной сценой (совокупностью геометрических примитивов),
отображаемой в окне на экране. Для организации интерактивного
взаимодействия с пользователем приложение должно иметь опи-
сание отображаемой сцены. Для повышения эффективности ви-
зуализации применяются средства структуризации сцены. Наибо-
лее простым и естественным принципом структуризации является
иерархический, при котором отдельные примитивы, имеющие
пространственную или функциональную близость, образуют груп-
пы, в свою очередь объединяющиеся в группы более высокого
уровня, и т. д. Применение иерархического принципа структури-
зации сцены восходит к графическому стандарту PHIGS.
Именно этот принцип и был положен в основу Open Inventor.
Иерархическая сцена представлена в виде графа — дерева, тер-
минальные узлы (листья) которого — объекты Open Inventor,
описывающие геометрические примитивы и устанавливающие
режимы построения примитивов. В граф также включаются объ-
екты, задающие общие условия визуализации (камера и источни-
ки света). Вообще говоря, граф сцены является не деревом в чис-
том виде, а ориентированным графом без циклов, поскольку
любой его узел может быть подчинен более чем одному выше-
стоящему узлу, что позволяет компактно описывать повторяю-
щиеся структуры.
118
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Описанная в графе сцена отображается на экран средствами


визуализации OpenGL. Применение любого действия сводится к
обходу графа в соответствии с иерархией (от корня к листьям).
Для каждого действия создается состояние обхода. В каждом тер-
минальном узле выполняется инкапсулированный в нем метод,
имеющий доступ к состоянию обхода. При визуализации состоя-
ние обхода включает состояние визуализации OpenGL, а терми-
нальный узел вызывает изменение определенного элемента со-
стояния обхода или выполнение той или иной команды
визуализации OpenGL. Например, узел, задающий характеристики
поверхности, заменяет соответствующий элемент состояния обхо-
да, а узел, описывающий геометрический примитив, выполняет
команды визуализации этого примитива с учетом текущего со-
стояния визуализации. С этой точки зрения граф сцены можно
трактовать как непроцедурное представление программы в среде
OpenGL, а его обход при визуализации — как выполнение этой
программы.
Данные объектов Open Inventor хранятся в полях, которые
представляют собой не просто переменные, а объекты языка C++,
инкапсулирующие методы setValue и getValue для установ-
ки и извлечения значений. Таким образом обеспечивается меха-
низм, с помощью которого Open Inventor отслеживает изменения в
описании сцены. Имеется возможность связывать поля направлен-
ной связью так, чтобы значение одного поля в случае его измене-
ния передавалось в другое. Помимо полей, входящих в состав объ-
ектов Open Inventor, существуют глобальные поля, которые не
входят в граф сцены, но которые можно с ним связать. Еще один
вид специальных объектов, не входящих в граф сцены, — это ин-
струменты (engines), определенным образом преобразующие зна-
чения соединенных полей.
Граф сцены вместе с глобальными полями и инструментами,
соединенными с ним, составляет базу данных сцены. Порядок на-
полнения базы данных может быть произвольным. Ее можно на-
полнять «вручную» — конструируя объекты и включая их в ие-
рархию. Любой фрагмент сцены, описанный в формате передачи
данных Open Inventor (текстовом или бинарном), может быть из-
влечен из файла или подготовлен в памяти как строка (что иногда
проще, чем программный способ) и включен в состав базы дан-
119
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ных. Базу в любой момент можно редактировать: добавлять и ис-


ключать объекты, связывать их друг с другом или модифициро-
вать. Механизм отслеживания изменений в базе данных использу-
ется для немедленной перерисовки сцены в случае наличия
изменений. В результате визуальный образ сцены всегда соответ-
ствует состоянию базы данных, редактируя которую определен-
ным образом, можно получить эффект анимации.
Отслеживание применяется не только для перерисовки — оно
необходимо для реализации кэширования*. Кроме того, разработ-
чику приложений предоставлена возможность соединять с базой
данных сенсоры — объекты Open Inventor, реагирующие на изме-
нения путем обращения к callback-функциям (функциям обратного
вызова), произвольным образом редактирующим базу данных, в
том числе и с помощью включения новых объектов. Сенсоры мо-
гут использоваться для контроля взаимного расположения прими-
тивов в сцене.
Open Inventor имеет набор готовых средств интерактивного
взаимодействия, базирующихся на структурном описании сцены и
реализующих обратную связь через частичное редактирование
сцены, создавая тем самым эффект анимации. С помощью этих
средств пользователь может выбирать примитивы в сцене, указы-
вая их мышью (выбранные примитивы выделяются), манипулиро-
вать группой примитивов (перемещать, масштабировать). Инте-
рактивное взаимодействие реализуется обработчиками событий —
объектами Open Inventor, включенными в граф сцены. Когда про-
исходит событие, в графе находится объект, который будет обра-
батывать именно это событие. Для подключения того или иного
средства интерактивного взаимодействия достаточно ввести соот-
ветствующий объект Open Inventor в граф. Разработчик приложе-
ния может расширить предлагаемый набор, создав собственный
класс объектов, реализующий специфическую прикладную реак-
цию на события. При этом разработчику предоставлена возмож-
*
Кэширование (от англ. cache — тайник) — запись данных в промежуточ-
ный буфер с быстрым доступом, содержащий копию той информации, которая
хранится в памяти с менее быстрым доступом, но с наибольшей вероятностью
может быть оттуда запрошена. Доступ к данным в кэше идет быстрее, чем выбор-
ка исходных данных из медленной памяти или их перевычисление, за счет чего
уменьшается среднее время доступа.

120
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ность применять различные вспомогательные операции (дейст-


вия), например поиск в графе примитива, указанного мышью, или
вычисление параметров параллелепипеда, ограничивающего груп-
пу примитивов.
Подобно среде OpenGL, среда Open Inventor независима от
конкретной оконной системы, для связи с которой применяется
библиотека компонентов, разработанная для среды X Window. В
число компонентов входят область визуализации (объект, связы-
вающий базу данных с окном), утилиты для работы с окнами и
запуска основного цикла обработки событий, транслятор собы-
тий в формат Open Inventor, интерактивные редакторы и визуали-
заторы сцены, встраиваемые в приложение. Имеются также сред-
ства для разработки библиотеки компонентов в любой другой
оконной системе.

Граф сцены

Сцена имеет иерархическую структуру, описываемую в виде


графа. Объекты Open Inventor, составляющие граф сцены, называ-
ются узлами. Узел, не имеющий родителей, называется корнем.
Существуют следующие виды узлов: узлы группирования (Group
nodes), камера и источники света, узлы преобразований, формы,
свойства и, наконец, комплекты узлов (Node kits) — подграфы,
составленные по заранее подготовленным шаблонам.

Иерархия сцены и обход графа

Узлы группирования (класс SoGroup) используются для


группирования дочерних узлов, способствуя тем самым созданию
иерархии объектов в сцене. Дочерний узел приписывается к роди-
телю (узлу класса SoGroup) в определенном порядке (методы
аddChild или insertChild). Порядок очень важен, потому что
именно от него зависит маршрут обхода дочерних узлов при вы-
полнении действия.
Можно изолировать влияние узлов, составляющих группу, на
состояние обхода для остальных узлов. Для этого применяют раз-
делитель — узел класса SoSeparator (подкласс SoGroup). При
входе в группу, содержащую разделитель, текущее состояние об-
121
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

хода запоминается, а на выходе — восстанавливается. Таким обра-


зом, обход узлов, составляющих эту группу, не влияет на обход
остального графа.
Имеются средства описания альтернативных подграфов. Для
этого используется переключатель — узел класса SoSwitch (под-
класс SoGroup), имеющий поле whichChild, где содержится по-
рядковый номер дочерних узлов, подлежащих обходу. Остальные
узлы игнорируются. Изменяя содержимое этого поля, можно пере-
ключать направление обхода от одного подграфа к другому. Этот
прием можно использовать, например, для простой анимации.
При быстрой визуализации сложных сцен очень важно изо-
бражать различные части сцены с различной степенью детализа-
ции в зависимости от удаленности их от наблюдателя. Узел класса
SoLevelOfDetails (подкласс SoGroup) позволяет выполнять
такое описание. Как и в случае переключателя, обходится только
один из дочерних узлов этого узла. Критерием выбора служит
размер проекции объектов, представленных в подграфе. В поле
screenArea дочернего узла хранится диапазон значений площа-
ди проекции объекта, сравниваемый с площадью ограничивающе-
го прямоугольника. Если площадь проекции попадает в диапазон
значений, то она изображается при визуализации, а остальные уз-
лы игнорируются.
Возможность подчинения узла более чем одной группе позво-
ляет компактно описывать повторяющиеся структуры. Например,
для представления объектов, одинаковых по форме, но располо-
женных в разных местах, достаточно создать единственный экзем-
пляр подграфа, описывающего объект, и подчинить его разным
группам, причем в каждой группе он должен следовать за узлом
соответствующего геометрического преобразования. Визуализа-
цию таких разделяемых экземпляров можно существенно ускорить
за счет кэширования.
Таким образом, разделяемые узлы одновременно представляют
несколько различных объектов сцены. В связи с этим возникает
проблема однозначной идентификации объектов, поскольку про-
стого указания на узел недостаточно. Объект в графе сцены одно-
значно идентифицируется цепочкой указателей на узлы, располо-
женные на всем пути от корня к данному узлу.

122
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Системы координат, геометрические


преобразования, источники света

Все примитивы в графе сцены задаются в системе координат


объекта. При обходе графа все координаты преобразуются в миро-
вую систему координат с помощью текущего геометрического
преобразования. Узел SoTransform задает геометрическое пре-
образование, которое применяется после текущего преобразования
(а не заменяет его, в отличие от остальных элементов состояния
обхода). Этот узел должен быть размещен в графе перед теми
примитивами, к которым он относится. На каждом уровне иерар-
хии, ограниченном узлом-разделителем, рекомендуется иметь
свою локальную систему координат. Это нужно для того, чтобы
узел SoTransform задавал преобразование в локальную систему
на вышестоящем уровне. Текущее геометрическое преобразование
в этом случае будет суперпозицией всех преобразований, установ-
ленных в вышестоящих по иерархии уровнях.
Узел класса SoCamera определяет видимый объем и преобра-
зование проецирования из трехмерного мирового пространства на
двухмерную картинную плоскость. Имеется два вида проецирова-
ния: перспективное и параллельное. В этом узле задаются место-
положение камеры и ее ориентация, параметры видимого объема,
фокусное расстояние. Обычно единственный узел камеры распо-
лагают рядом с вершиной графа таким образом, чтобы при обходе
он был первым из содержательных узлов.
Чтобы увидеть сцену, описываемую графом, необходимо раз-
местить в графе хотя бы один источник света — узел класса
SoLight. Источник освещает все узлы в графе, которые обходятся
после него (с учетом узлов-разделителей). Освещенность от не-
скольких источников аккумулируется. Класс SoLight имеет поля,
определяющие расположение источника света, его яркость и цвет.

Формы примитивов

Узлы форм описывают геометрию примитивов, в основном со-


ответствующих примитивам OpenGL (включая библиотеку утилит
OpenGL Utility Library — GLU) в объектной системе координат.
При визуализации обход такого узла вызывает визуализацию при-

123
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

митива, выполняемую средствами OpenGL с учетом текущего со-


стояния. Формы делятся на простые, комплексные, тексты и неод-
нородные рациональные B-сплайны — NURBS (от англ. Non-
uniform rational B-spline).
Простая форма описывает элементарное твердое тело, заданное
своими размерами и расположенное фиксированно в объектной
системе координат. К телу применяется текущее геометрическое
преобразование. Имеется четыре класса простых форм: SoCube
(прямоугольный параллелепипед), SoCone (конус), SoSphere
(сфера), SoCylinder (цилиндр).
В узлах комплексных форм, в основном соответствующих при-
митивам OpenGL и описываемых набором вершин, хранятся только
описания их структуры. Координаты вершин при обходе графа из-
влекаются из текущего набора координат (одного из элементов со-
стояния обхода) и подвергаются текущему геометрическому преоб-
разованию. Набор координат выбирается в узле координат (класс
SoCoordinate3) и становится текущим при обходе этого узла.
Трактовка набора координат определяется типом формы. Имеются
следующие классы комплексных форм: набор поверхностей, пред-
ставленных независимыми многоугольниками; набор групп смеж-
ных треугольников; сетка, составленная из смежных четырехуголь-
ников; набор независимых отрезков; набор точек.
Узлы SoText2 и SoText3 описывают 2D- и 3D-изображения
одной или нескольких строк текста. Текст отображается с исполь-
зованием текущего цвета и текущего шрифта, устанавливаемого
узлом SoFont. Текст позиционируется в точке начала координат,
подвергнутой текущему геометрическому преобразованию. Текст
может быть выровнен влево или вправо или центрирован относи-
тельно точки позиционирования. Плоский текст изображается в
плоскости, параллельной картинной, с размерами, не зависящими
от расстояния до камеры. Символы 3D-текста — замкнутые твер-
дые тела, имеющие переднюю, боковую и заднюю поверхности, —
подвергаются визуализации как обычные твердые тела с учетом
текущего состояния визуализации. Плоскость передней поверхно-
сти может располагаться произвольно. Профиль боковой поверх-
ности может быть сколь угодно сложным и устанавливается в уз-
лах SoLinearProfile и SoNurbsProfile.

124
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Узлы SoNurbsCurve и SoNurbsSurface описывают кри-


вые и поверхности NURBS. Текущий набор координат трактуется
как вектор или прямоугольная матрица управляющих точек. Веса
управляющих точек (для рациональных кривых и поверхностей)
устанавливаются в узле SoCoordinate4. Чтобы ограничить изо-
бражаемую поверхность, необходимо описать замкнутую линию в
параметрическом пространстве (узлами SoLinearProfile или
SoNurbsProfile).

Свойства элементов

Узлы свойств содержат информацию, соответствующую от-


дельным элементам состояния визуализации OpenGL. При обходе
узла свойств эта информация заменяет текущее значение соответ-
ствующего элемента. Чтобы узлы свойств использовались при ви-
зуализации, они должны быть помещены перед узлами форм, к
которым относятся.
Узел SoNormal устанавливает набор нормалей, используемых
для определения ориентации поверхностей и учитываемых при
визуализации с моделью освещения PHONG. Узел SoMaterial
определяет набор характеристик поверхности, включающих цвет,
отражающие способности, гладкость и прозрачность. Узел
SoDrawStyle позволяет выбирать стиль рисования (невидимый,
точечный, линейный, заливкой областей). Узел LightModel по-
зволяет выбрать одну из двух моделей освещения: BASE_COLOR
игнорирует источники света, принимая во внимание только
цвет/прозрачность поверхности; модель PHONG учитывает все ис-
точники света. Модель затенения в Open Inventor устанавливается
неявно с учетом модели освещения и характеристик поверхности.
Узел SoEnvironment позволяет моделировать различные атмо-
сферные явления — туман, дымку, смог. Узел SoShapeHints
определяет, описывает ли объект границу твердого тела, является
ли поверхность выпуклой, задает порядок обхода вершин, отмечая
наружную сторону, разрешает автоматическую генерацию норма-
лей. Узел SoTexture2 задает 2D-карту текстуры и устанавливает
модель наложения текстуры на поверхность. Модель определяет,
каким образом значения текстуры взаимодействуют с цветом и

125
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

прозрачностью поверхности. Текущая карта текстуры до наложе-


ния на поверхность подвергается 2D-геометрическому преобразо-
ванию, устанавливаемому узлом SoTexture2Transform.

Комплекты узлов

Комплекты узлов (node kits) позволяют создавать и вклю-


чать в граф сцены подграфы, содержащие несколько связанных
узлов, повышая тем самым уровень языка описания сцены. Каж-
дый класс комплекта узлов имеет каталог — шаблон, представ-
ляющий собой наиболее полный граф комплекта. Конкретный
экземпляр может содержать связный подграф каталога. При соз-
дании экземпляра комплекта узлов первоначально получается
минимальный (базовый) подграф, который можно расширять в
соответствии с каталогом, а составляющие его узлы модифици-
ровать, в том числе и изменяя их тип (например, заменяя куб ко-
нусом).
В Open Inventor имеется несколько готовых к употреблению
комплектов узлов. Например, комплект узлов SoShapeKit при-
меняется для правильного встраивания в граф любой формы.
Шаблон содержит узел SoCube, который при желании можно за-
менить на любую форму, и правильно расположенные узлы коор-
динат, материалов, геометрических преобразований и другие узлы
свойств.
Кроме того, имеются средства для создания пользовательских
комплектов. Например, пакет для создания авиатренажеров дол-
жен включать множество объектов, представляющих самолеты.
Каждый из них содержит одну и ту же общую структуру графа
сцены (фюзеляж, крылья, шасси) и общие методы (например, для
выпуска шасси). Можно создать комплект узлов, включающий эту
структуру и инкапсулирующий соответствующие методы.

Сенсоры

Сенсоры — специальный класс (SoSensor) объектов, прикреп-


ленных к базе данных. Они реагируют на изменения в базе данных
(сенсоры данных) или на определенные события таймера (сенсоры
таймера) путем обращения к функциям обратного вызова.

126
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Имеется три типа сенсоров данных, прикрепленных соответ-


ственно к полю, узлу и пути и получающих извещение об изме-
нении поля, узла или подграфа под этим узлом. Сенсор пути из-
вещается при изменении узлов, принадлежащих пути. При
получении извещения сенсоры данных включаются в очередь
отложенного запуска в соответствии со своим приоритетом. За-
пуск функции обратного вызова откладывается до того момента,
когда процессор освободится от всех других работ. Например,
область визуализации автоматически прикрепляет к корню гра-
фа сенсор, функция обратного вызова которого запускает про-
цесс визуализации, что приводит к перерисовке всей сцены при
изменениях графа.
В отличие от сенсоров данных, привязанных к графу сцены,
сенсоры таймера явно включаются в очередь, где они упорядочи-
ваются не по приоритету, а по времени их запуска. Перед включе-
нием в очередь устанавливаются временные параметры — когда и
сколько раз следует обращаться к функции обратного вызова.

Инструменты и соединения полей

Инструменты (engines) — классы объектов, которые можно


соединять с полями узлов графа сцены или глобальными полями и
использовать для анимации частей сцены или для взаимного огра-
ничения элементов сцены. Это средство позволяет инкапсулиро-
вать и геометрию, и движение в единственном графе. В отличие от
сенсоров инструменты используют не функции обратного вызова,
а встроенные функции, поэтому их можно сохранить в файле и
прочитать из него.
Инструмент имеет входные и выходные поля, которые можно
соединить с любыми полями (в частности, с входами и выходами
других инструментов). Инструмент запускается, когда изменяются
значения полей, соединенных с его входами, выполняет над вход-
ными значениями некоторые операции и выдает несколько резуль-
татов, попадающих в поля, соединенные с его выходами. Таким
образом может возникнуть волна изменений.
Поля можно соединять друг с другом и минуя инструменты —
результат будет тот же. При изменении значения некоторого поля
поле, соединенное с ним, получит такое же значение. Один выход

127
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

может соединяться с несколькими входами, но каждый вход может


быть соединен только с одним выходом.
Существует несколько типов инструментов:
• анимационные инструменты, вход которых соединен с выхо-
дом поля realTime, имеющие на выходе дискретный поток зна-
чений. Предопределенное глобальное поле realTime содержит
текущее время и служит источником изменений для анимации,
зависящей от времени;
• шлюзы, позволяющие управлять потоком значений посредст-
вом полей enable и trigger. Первое открывает или закрывает
непрерывный поток значений, проходящий через шлюз, а второе
при закрытом поле enable позволяет пропустить одно значение;
• арифметические инструменты, производящие булевы и
арифметические операции.
В Open Inventor имеются несколько классов узлов со встроен-
ными инструментами, позволяющими создавать простую цикличе-
скую анимацию: SoRotor — вращение объекта; SoPendulum —
эффект маятника; SoShuttle — эффект челнока; SoBlinker —
эффект мерцания.

Действия
К созданному графу сцены можно применить разнообразные
действия. Действие — это объект соответствующего подкласса
класса SoAction. Применение действия — это выполнение мето-
да apply над любой частью графа. Действия содержат методы для
управления режимами своего выполнения, поэтому, хотя некото-
рые действия не следует запускать явно, доступ к ним открыт. В
Open Inventor имеются следующие действия: перестройка сцены,
обработка событий, указка, вычисление ограничивающего прямо-
угольника, аккумулирование матрицы преобразований, запись в
файл, действие обратного вызова.
Нет необходимости применять действие перестройки сцены
явно, поскольку оно вызывается автоматически при изменении
сцены. Но оно имеет несколько методов, устанавливающих гло-
бальные характеристики визуализации OpenGL: уровень качества
прозрачности, определяющий использование компонента прозрач-
ности; метод устранения лестничного эффекта (antialiasing).
128
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Действие «указка» находит примитивы, лежащие на луче, ис-


ходящем от наблюдателя и проходящем через заданную точку на
ближней плоскости видимого объема, и возвращает список узлов-
форм, соответствующих найденным примитивам, упорядоченный
по их удаленности. Оно применяется в основном при обработке
событий.
Действие обратного вызова позволяет обойти граф сцены и ак-
кумулировать состояние обхода. При обходе узлов определенного
типа происходит обращение к функциям обратного вызова,
имеющим доступ к состоянию обхода. Это действие обеспечивает
удобный механизм для создания собственных прикладных дейст-
вий без расширения классов Open Inventor, например, для расчета
массы тел, представленных примитивами сцены.

Обработка событий
и интерактивное взаимодействие

Модель обработки событий в Open Inventor не основана ни на


какой конкретной оконной системе. Произошедшее в оконной сре-
де событие транслируется в формат Open Inventor — создается
объект класса SoEvent, содержащий все необходимые данные о
событии. Затем к корневому узлу графа сцены применяется дейст-
вие обработки событий. Обход графа осуществояется точно так
же, как и для других действий. В каждом узле выполняется метод
isHandled, определяющий, берется ли узел за обработку этого
события. Узел — обработчик события — должен иметь метод
setHandled, который, собственно, и реализует взаимодействие.
Чтобы начать интерактивное взаимодействие, необходимо в граф
сцены включить соответствующий узел — обработчик событий —
так, чтобы он обходился первым среди узлов, реагирующих на
данное событие. Узел может потребовать, чтобы все последующие
события направлялись непосредственно ему до особого указания.
Такой запрос называется захватом (grabbing). Например, мани-
пулятор после нажатия кнопки мыши захватывает все последую-
щие события, пока кнопка не будет отпущена. Когда взаимодейст-
вие заканчивается, узел следует удалить из графа.
В Open Inventor имеется несколько типов узлов — обработчи-
ков событий, реализующих готовые средства взаимодействия:
129
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

SoSelection (реализующий выбор), буксировщики и манипуляторы.


Узел SoEventCallback (обращающийся к функциям обратного
вызова в методах isHandled и setHandled) реализует специ-
фическое прикладное интерактивное взаимодействие.

Выбор

Узел класса SoSelection, обычно прикрепляемый к верши-


не графа, реагирует на нажатие левой кнопки мыши и реализует
выбор графических примитивов. Выбранные примитивы выделя-
ются (highlighted) либо их изображением в каркасном виде
линиями определенного цвета и типа, либо изображением ограни-
чивающего параллелепипеда вокруг них. SoSelection включает
методы для управления списком выбора, выделения выбранных
примитивов, использования функций обратного вызова при изме-
нении списка выбора.

Буксировщики и манипуляторы

Буксировщик — это специальный комплект узлов, предназна-


чен для организации интерактивного взаимодействия. Его интер-
фейс основан на встраиваемых в граф сцены геометрических при-
митивах, используемых для указания и обратной связи с
пользователем. Буксировщик реагирует на буксировку мышью из-
менением значений полей, отражающих его текущее состояние.
Поля буксировщика можно соединять с другими полями или
инструментами и таким образом устанавливать зависимость графа
сцены от буксировки. Можно создать функции обратного вызова,
обращение к которым происходит при нажатии, отпускании или
перемещении мыши или при изменении полей буксировщика. И
наконец, можно использовать простые буксировщики как строи-
тельные блоки для создания более сложных буксировщиков.
В Open Inventor имеется большой набор буксировщиков, осу-
ществляющих управление разнообразными поворотами, перено-
сами, масштабированиями в 2D- и 3D-измерениях с предоставле-
нием различных пользовательских интерфейсов, включая трекбол
(сферу, ограниченную тремя взаимно перпендикулярными лента-
ми) или управляющий параллелепипед (Handle Box). Поскольку

130
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

буксировщик — это комплект узлов, можно изменить внешний


вид буксировщика, изменив геометрию его примитивов, создавае-
мых по умолчанию. С каждым буксировщиком связан файл ресур-
сов, в котором в формате Open Inventor описана конфигурация по
умолчанию.
Манипулятор представляет собой интерактивно редактируе-
мую версию (подкласс) некоторого узла (преобразования или ис-
точника света), в которой буксировщик используется для реагиро-
вания на инициируемые пользователем события и редактирования
собственных полей. При создании манипулятора задают геометри-
ческие параметры его буксировщика в локальной системе коорди-
нат. Обычно их выбирают так, чтобы группа примитивов, подвер-
гающаяся манипулированию, помещалась внутри буксировщика.
Манипулятор обеспечивает непосредственное взаимодействие
пользователя с объектом в 3D-пространстве. Так, манипулятор, за-
меняющий источник света, позволяет пользователю интерактивно
перемещать источник, освещая сцену с разных сторон. Манипуля-
тор, заменяющий узел преобразования, применяемого к некоторой
группе геометрических примитивов, позволяет пользователю интер-
активно менять параметры преобразования и тем самым поворачи-
вать, перемещать или масштабировать сам буксировщик и эту груп-
пу. Например, манипулятор SoTrackBallManip вставляет в сце-
ну трекбол, позволяя изменять поля узла SoTransform,
масштабируя и поворачивая объект внутри трекбола. Манипулятор
SoHandleBoxManip вставляет в сцену управляющий параллеле-
пипед, окружающий объект и имеющий управляющие метки на уг-
лах и сторонах. Указывая на метки и буксируя их, пользователь ме-
няет масштаб и положение параллелепипеда и соответственно
объекта внутри него.
Типовой метод интерактивного взаимодействия с использова-
нием манипулятора реализуется следующим образом. К корню
графа подключается узел SoSelection, с помощью которого
пользователь может выбрать группу примитивов. Если выбор за-
вершен и поступила команда начать манипулирование, то узел
SoSelection исключается из графа, вычисляется ограничиваю-
щий параллелепипед для выбранной группы и создается манипу-
лятор, буксировщик которого содержит вычисленный параллеле-

131
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

пипед. Созданный манипулятор заменяет узел SoTransform,


управляющий выбранной группой, после чего начинается манипу-
лирование. Когда взаимодействие с пользователем заканчивается,
происходит обратная замена, а значения полей манипулятора ко-
пируются в узел, который он заменял.

Интерактивные редакторы и визуализаторы

В состав библиотеки компонентов для X Window входят мно-


гократно используемые модули со встроенным интерфейсом для
интерактивного редактирования сцены. Каждый компонент пред-
ставляет собой примитив графического интерфейса в стиле Motif и
может использоваться сам по себе или в комбинации с другими.
Компонент может иметь свое собственное окно или размещаться в
одном из имеющихся. Он обладает методами для управления сво-
им поведением. Существует два способа передачи данных из ком-
понента в приложение: привязать компонент к узлу в графе сцены
или задать функции обратного вызова, чтобы извещать приложе-
ние об изменениях в компоненте. Два основных класса компонен-
тов — редакторы и визуализаторы (viewers).
Интерфейс редактора позволяет интерактивно модифицировать
поля того узла, к которому он прикреплен (например, узла мате-
риалов или источника света), с немедленным отражением измене-
ний в окне визуализации.
Визуализатор всегда прикрепляется к корневому узлу и позво-
ляет интерактивно менять параметры камеры, создавая эффект ее
движения. Если в графе отсутствует узел камеры, то визуализатор
его создает и размещает у корня графа. По умолчанию визуализа-
тор добавляет направленный источник света, непрерывно сле-
дующий за камерой. Все визуализаторы имеют область визуализа-
ции, в которой отображается сцена; полосы прокрутки по краям
окна, управляющие горизонтальным и вертикальным перемещени-
ем камеры и ее наездом; контекстное меню, управляющее поведе-
нием компонента, например, позволяющее изменить стиль рисова-
ния всей сцены (каркасный, с удалением скрытых линий, без
текстур и т. д.); иконки с правой стороны, сокращающие время
доступа к некоторым операциям; дополнительные иконки прило-
жения в левом верхнем углу.

132
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Средства расширения

Одним из наиболее важных аспектов Open Inventor является


возможность программирования новых объектов и операций с ис-
пользованием дополнительных инструментальных средств. Один
из способов расширения возможностей Open Inventor — создание
новых классов как подклассов существующих. Другой способ —
использование функций обратного вызова, созданных разработчи-
ком и вызываемых при определенных условиях.
Таким образом, простые и удобные средства структуризации
сцен, возможность создания собственных прикладных структур,
наличие готовых средств интерактивного взаимодействия и воз-
можность их неограниченного расширения, возможность подклю-
чения к любой оконной среде, ориентация на графический стан-
дарт OpenGL — все это обусловливает рост популярности Open
Inventor.
Сегодня реализации Open Inventor доступны на большинстве
платформ Unix и Microsoft Windows. На базе Open Inventor разра-
ботано множество приложений в самых различных областях. Сто-
ит отметить, что среда Open Inventor использована в качестве ос-
новы для построения файлов формата VRML-3D.

3.2.2. Формат файлов описания графических сцен

Рассмотрим формат файлов Open Inventor, используемых для


хранения графа сцены в текстовом виде. В данном формате файла
пробелы, табуляции и переход на новую строку игнорируются.
Комментарии обозначаются символом «#» в любом месте строки и
продолжаются до конца строки.

Заголовок файла

Файл Open Inventor должен иметь стандартный заголовок. За-


головок является первой строкой файла и имеет следующий вид:
#Inventor V2.0 ascii
или
#Inventor V2.0 binary

133
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Для того чтобы определить, является ли произвольный файл


файлом Open Inventor, достаточно использовать метод
SoDB::isValidHeader(). Конечно, заголовок может меняться
от версии к версии, но он гарантированно будет начинаться сим-
волом «#», будет содержать не более 80 символов и заканчиваться
переходом на новую строку. Метод isValidHeader() возвра-
щает значение True, если файл содержит заголовок Inventor.
Система Open Inventor, безусловно, позволяет читать файлы ста-
рых версий формата V1.0 и конвертировать их.

Описание узла

Для описания узла используется следующая конструкция:


• имя узла (без префикса So);
• открывающая скобка «{»;
• поля узла (если есть), сопровождаемые дочерними узлами
(если есть);
• закрывающая скобка «}».
Например:
DrawStyle {
style LINES
lineWidth 3
linePattern 255
}

Присвоение значений полям узла

Поле узла идентифицируется своим именем и значением (зна-


чениями). Если значение поля не было изменено по отношению к
значению по умолчанию, то поле не прописывается в файле. Поля
в узле могут быть определены в любом порядке. В листинге 3.3
представлен пример присвоения значения полю узла.
Листинг 3.3. Присвоение значения полю узла
Transform {
translation 0 -4 0.2
}
LightModel {
model BASE_COLOR

134
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

}
Material {
ambientColor .3 .1 .1
diffuseColor [.8 .7 .2,
1 .2 .2,
.2 1 .2,
.2 .2 1]
specularColor .4 .3 .1
emissiveColor .1 0 .1
}
Имеется также возможность определить многозначные поля.
Значения этих полей заключаются в квадратные скобки и перечис-
ляются через запятую, как это показано в предыдущем примере в
поле diffuseColor. После последнего значения также может
стоять запятая:
[value1, value2, value3,]
Однозначные поля не содержат в описании скобок и запятых.
Значения многозначных полей обычно заключают в квадратные
скобки, но в этом нет необходимости, если полю присваивается
только одно значение:
specularColor .4 .3 .1
или
specularColor [.4 .3 .1]
Существующие типы полей описаны в табл. 3.1.

Таблица 3.1
Типы полей узла в файлах Open Inventor
Тип поля Допустимые форматы Пример
Longs (длинные Целые числа в десятичной, 255
0xff
целые), shorts шестнадцатеричной 0177
(короткие це- или восьмеричной системе
лые), unsigned
shorts (беззна-
ковые целые)
Floats (числа Целые числа или числа 13
13.0
с плавающей с плавающей запятой 13.123
запятой) 1.3e-2

135
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Продолжение табл. 3.1

Тип поля Допустимые форматы Пример


Names, strings Имя заключается в двойные label "front left
leg"
(имена, строки) кавычки, если оно состоит label car
больше чем из одного слова,
в противном случае — без
кавычек. Можно использо-
вать любые символы в коди-
ровке ASCII, включая пере-
ход на новую строку и
обратный слеш, если имя
заключается в двойные
кавычки. Чтобы использовать
в имени символ «”», необхо-
димо поставить перед ним
обратный слэш (\”)
Enums Либо мнемоническая (сим- MaterialBinding {
value PER_FACE
(перечисления) вольная) форма перечисле- }
ния, либо целочисленная
(для удобочитаемости кода
рекомендуется мнемони-
ческая форма)
Bit mask Один или несколько мнемо- Cylinder {
parts SIDES
(битовая маска) нических флагов, разделен- }
ных символом | и заключен- Cylinder {
ных в круглые скобки, parts (SIDES | TOP)
если флагов несколько }

Vectors N чисел с плавающей PerspectiveCamera {


components
(векторы) запятой, разделенных of the position
пробелом 0 0 9.5
vector
}
Colors (цвета) Три значения с плавающей BaseColor {
запятой (формат RGB), rgb 0.3 0.2 0.6
}
разделенные пробелом
Rotation Три вектора по осям и значе- Transform { rota-
tion 0 1 0
(поворот) ние угла в радианах, отделен- 1.5708
ное пробелом # y axis ...
pi\xb9 /2 radians
}

136
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Окончание табл. 3.1

Тип поля Допустимые форматы Пример


Matrix 16 чисел с плавающей запя- —
(матрица) той, разделенных пробелом
Path (путь) SFPath содержит только один [first_path,
second_path, ...,
указатель на путь. Для запол- nth_path]
нения этого поля необходимо
указать путь. MFPath содер-
жит много указателей на пу-
ти. Для заполнения этого поля
список путей следует запи-
сать в квадратных скобках,
разделив их запятыми
Node (узел) SFNode содержит указатель [node1, node2,
..., noden]
на узел. Для заполнения этого
поля необходимо указать
узел. MFNode может содер-
жать несколько указателей
на узлы. Для заполнения это-
го поля список указателей на
узлы следует записать
в квадратных скобках,
разделив их запятыми

Флаг игнорирования

Существует возможность задать полю флаг игнорирования.


Флаг игнорирования для поля записывается в виде тильды «~».
Он находится либо после описания поля, либо на месте значе-
ния поля.
transparency [ .9, .1 ] ~
или
transparency ~
В первом случае значение поля игнорируется. Во втором случае
используется значение поля по умолчанию, но само поле игнориру-
ется. Флаг игнорирования используется только для свойств. Он не
может быть использован для камер, источников света или форм.

137
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Полевые связи

При формировании связи сначала указывают объект, содержа-


щий поле или данные, связанные с полем, а затем через точку пи-
шут имя поля или имя данных:
Separator {
DEF Trans Translation
{ translation 1 2 3 }
Cube {}
}
Separator {
Translation
{ translation 0 0 0 = USE Trans.translation }
Cone {}
}
Значение присоединенного поля (в данном случае 0 0 0) оп-
ционально и может быть не указано, как в следующем примере:
Translation { translation = USE Trans.translation }
Если присоединяется игнорируемое поле, то пишут
translation 000 ~ = USE Trans.translation
или
translation ~ = USE Trans.translation

Глобальные поля

Глобальное поле должно иметь, по крайней мере, одну связь.


Формат описания глобального поля имеет вид
GlobalField{
type
value
}
В фигурных скобках указываются тип и значение поля. Имя
глобального поля (global field) аналогично имени значаще-
го поля (value field). Например, узел Text3 может быть
соединен с глобальным полем (в данном случае с полем
currentFile), которое содержит текущее имя файла работаю-

138
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

щего приложения. Узел Text3 всегда будет отображать текущее


имя файла:
Text3 {
string "" = GlobalField {
type SFString
currentFile "aircar.iv"
} . currentFile
}

Создание инструмента

Синтаксис описания инструмента (engine) похож на синтак-


сис описания негруппового узла (nongroup node):
EngineType{
input_fields
}
Инструменты не могут быть описаны сами по себе; они
должны быть связаны, по крайней мере, с одной частью графа
схемы. Связь «поле — инструмент» описывается следующим
образом:
fieldname value = engine . outputname
Ниже представлен пример, демонстрирующий как можно из-
менить радиус сферы, используя инструмент SoOneShort:
Sphere {
radius 0.5 = OneShot { duration 3.0 } . ramp
}

Описание пути в графе сцены

Инициализация пути включает следующие элементы:


• слово Path;
• открывающую скобку «{»;
• подграф главного узла для пути;
• число индексов в оставшейся части пути;
• непосредственно сами индексы;
• закрывающую скобку «}».
Когда обработчик Open Inventor сталкивается с группами сепа-
ратора в пределах подграфа, он игнорирует их, если они не содер-
139
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

жат узлы, имеющиеся в пути. Создание индексов для дочерних


узлов в подграфе служит для выделения неиспользуемых групп
сепаратора. В графе, показанном на рис. 3.1, узел N получил ин-
декс, равный единице, так как предыдущие два узла образуют
группу сепаратора, которая не влияет на данный узел (индекс в
пути остается неизменным).

Рис. 3.1. Расстановка индексов узлов графа сцены

Если путь содержит связи с узлами, которые не входят в путь,


то такие узлы не будут записываться в путь. Например, если путь
содержит инструмент, соединенный с узлом, который не входит в
путь, то инструмент будет включен в путь, а узел нет. В листинге
3.4 представлен код графа сцены, описывающий бледно-зеленую,
цвета ржавчины и фиолетовую сферы.
Листинг 3.4. Код графа сцены
Separator {
PerspectiveCamera {
position 0 0 9.53374
aspectRatio 1.09446
nearDistance 0.0953375
farDistance 19.0675
focalDistance 9.53374
}

140
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

DirectionalLight {
}
Transform {
rotation -0.189479 0.981839 -0.00950093 0.102051
center 0 0 0
}
DrawStyle {
}
Separator {
LightModel {
model BASE_COLOR
}
Separator {
Transform {
translation -2.2 0 0
}
BaseColor {
rgb .2 .6 .3 # бледно-зеленый
}
Sphere { }
}
Separator {
BaseColor {
rgb .6 .3 .2 # цвет ржавчины
}
Sphere { }
}
Separator {
Transform {
translation 2.2 0 0
}
BaseColor {
rgb .3 .2 .6 # фиолетовый
}
Sphere { }
}
}
На рис. 3.2 представлен описанный граф сцены.
При выборе третьей сферы путь будет аналогичен представлен-
ному в листинге 3.5. В нем описан подграф главного узла, включая
индексы узлов (4 1 2) и их число (3), как показано на рис. 3.3.

141
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 3.2. Граф сцены, содержащей три разноцветные сферы

Листинг 3.5. Код подграфа главного узла


Path {
Separator {
PerspectiveCamera {
position 0 0 9.53374
aspectRatio 1.09446
nearDistance 0.0953375
farDistance 19.0675
focalDistance 9.53374
}
DirectionalLight {
}
Transform {
rotation -0.189479 0.981839 -0.00950093 0.102051
}
DrawStyle {
}
Separator {
LightModel {

142
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

model BASE_COLOR
}
Separator {
Transform {
translation 2.2 0 0
}
BaseColor {
rgb 0.3 0.2 0.6
}
Sphere {
}
}
}
}
3
4
1
2
}

Рис. 3.3. Путь (4 1 2) в графе сцены

143
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Определение и использование разделяемых узлов

В формате файла ключевое слово DEF описывает именованный


узел, путь или инструмент. Его можно использовать позже в коде,
используя ключевое слово USE. Приведенный ниже листинг 3.6
демонстрирует пример использования ключевых слов DEF и USE.
Листинг 3.6. Использование ключевых слов DEF и USE
Separator {
DEF A Translation { translation -4 0 0 }
Cube { }
}
Separator {
DEF B Translation { translation 4 5 6 }
Cube { }
}
Separator {
Translation { translation 0 0 0 =
InterpolateVec3f {
input0 0 0 0 = USE A.translation
input1 0 0 0 = USE B.translation
alpha 0.5
} . output
}
Cone { }
}
В некоторых случаях Open Inventor добавляет несколько сим-
волов к имени. В следующем примере представлен граф сцены,
содержащий одинаковые имена узлов:
Separator{
Separator{
DEF beachball+0
DEF beachball+1
}
Separator{
USE beachball+0
USE beachball+1
}
}

144
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

После прочтения графа оригинальные названия остаются не-


изменными (рис. 3.4).

Рис. 3.4. Граф, содержащий узлы с одинаковыми именами

Описание коллекции узлов

Коллекция узлов содержит по одному полю для каждого узла:


AppearanceKit {
lightModel
LightModel { model PHONG }
drawStyle
DrawStyle { style LINES }
material
Material { diffuseColor .5 .5 .5 }
complexity
Complexity { value .5 }
}
В данном формате имя поля (lightModel) сопровождается
именем узла (LightModel), затем следуют поля узла и их значе-
ния (каждая часть содержит поле SoSFNode). Если часть коллек-
ции не была создана или ее значение равно NULL, она не указыва-
ется в файле. Но если часть была создана по умолчанию

145
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

(например, SoShapeKit) или объявлена как NULL, она записыва-


ется в код.
Приведенный ниже пример демонстрирует описание вложен-
ной коллекции узлов. Здесь AppearanceKit является значением
для поля appearance. Узел AppearanceKit содержит поле
material:
SeparatorKit {
appearance AppearanceKit {
material Material
{ diffuseColor 1 1 1 }
}
}
Open Inventor создает коллекцию узлов по частям. При само-
стоятельном создании коллекции узлов можно использовать метод
стенографии или пропускать промежуточные части. Например,
если опустить узел AppearanceKit, то SeparatorKit автома-
тически добавить узел AppearanceKit и вставит узел
Material. Так, можно просто написать:
SeparatorKit {
material Material
{ diffuseColor 1 1 1 }
}
Описание списка коллекции узлов стандартизовано. Каждая
часть должна содержать три поля:
• containerTypeName (сепаратор, или переключатель; в
строковом формате);
childTypeName (допустимые типы дочерних узлов);
containerNode (узел, содержащий дочерний узел).
В представленном ниже листинге 3.7 узел childList являет-
ся частью SoSeparatorKit.
Листинг 3.7. Части коллекции узлов
SeparatorKit {
childList
NodeKitListPart {
containerTypeName "Separator"
childTypeNames "SeparatorKit"
containerNode

146
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Separator {
SeparatorKit {
transform
Transform { translation 1 0 0 }
}
SeparatorKit {
transform
Transform { translation 0 1 0 }
}
SeparatorKit {
transform
Transform { translation 0 0 1 }
}
}
}
}
По умолчанию Open Inventor не создает внутренние части, та-
кие как сепаратор, группа или поле со значением по умолчанию.
Но если коллекция узлов стоит в пути, все элементы прописыва-
ются так, как показано в следующем примере. Вообще, Inventor
создает все части в обратном порядке по отношению к порядку,
описанному в каталоге, начиная с листов узла (листинг 3.8).
Листинг 3.8. Создание коллекции узлов
SeparatorKit {
appearance DEF +0 AppearanceKit {
material DEF +1 Material {
diffuseColor 1 0 1
}
}
childList DEF +2 NodeKitListPart {
containerTypeName "Separator"
childTypeNames "SeparatorKit"
containerNode DEF +3 Separator {
ShapeKit {
appearance DEF +4 AppearanceKit {
material DEF +5 Material {}
}
transform DEF +6 Transform {}
shape DEF +7 Cube {}
topSeparator Separator {

147
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

USE +4
USE +6
DEF +8 Separator {
USE +7
}
}
shapeSeparator USE +8
}
}
}
topSeparator Separator {
USE +0
USE +2
}
}

Подключение внешних файлов


Для подключения внешнего файла необходимо использовать
узел SoFile. Этот узел полезен, когда необходимо построить
граф сцены, включающий много объектов. Объекты могут нахо-
диться в их собственных файлах, и узел SoFile можно использо-
вать, чтобы обратится к ним, избегая копирования их в новый
файл. Узел SoFile создается следующим способом:
File {
name "myFile.iv"
}
Здесь поле name — имя включаемого файла.
Файл myFile.iv в этом случае является скрытым дочерним
узлом SoFile, но объект в узле SoFile нельзя изменить. Содер-
жание узла SoFile можно скопировать, используя функцию
SoFile::copyChildren(). Можно также модифицировать
поле name узла SoField. Всякий раз, когда значение поля name
изменяется, идет чтение нового файла. Если имя не является пол-
ным путем до файла, список директорий для поиска файла берется
из узла SoInput.
Предположим, что имеется файл /usr/tmp/myFile.iv, в
котором находится файл windmill.iv. Тогда содержание файла
myFile.iv:
148
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

#Inventor V2.0 ascii


File { name "myObjects/windmill.iv" }
Содержание файла windmill.iv:
#Inventor V2.0 ascii
// Содержание файла
При чтении файла с полным именем /usr/tmp/myFile.iv
директория /usr/tmp добавляется к списку директорий поиска. Ко-
гда узел SoFile в файле myFile.iv вызовет метод SoDB::read,
узел SoInput найдет и прочитает файл /usr/tmp/myObjects/
windmill.iv и директория /usr/tmp/myObjects добавится к
директориям списка поиска. После завершения чтения директории
/usr/tmp/myObjects и /usr/tmp будут удалены из списка ди-
ректорий поиска.

3.2.3. Основные классы, входящие в состав API


среды Open Inventor

В данном подразделе описываются основные классы и функ-


ции, входящие в состав API, предоставляемого средой Open
Inventor. Средства API Inventor позволяют строить геометрические
примитивы (линии, поверхности, многоугольники), объединять их
в сложные фигуры, перемещать вдоль осей координат, вращать,
определять цвет, материал и текстуру модели, строить нормали и
выполнять множество других действий.
Объекты API Inventor разделены на классы. Каждый класс объ-
ектов ассоциирован с определенным типом узлов графа сцены и
предназначен для решения конкретных задач. У каждого класса
имеется набор атрибутов и функций для решения каждой задачи.

Класс SoSearchAction

Класс SoSearchAction (рис. 3.5) содержит методы для по-


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

149
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

При использовании более одного критерия, указываемого ме-


тодами setNode(), setType() и setName(), необходимо
помнить, что при поиске данные критерии будут соединены логи-
ческим «и».

Рис. 3.5. Класс Рис. 3.6. Класс


SoSearchAction SoWriteAction

Класс SoWriteAction
Класс SoWriteAction (рис. 3.6) служит для записи графа
сцены в файл. При этом содержание сцены записывается в поток,
содержащийся в объекте SoOutput. Это может быть файл, буфер
или системный поток, такой как stdout.
Вся информация, содержащаяся в графе сцены, будет записана
в файл (не только узлы графа, но и значения полей узла, глобаль-
ные поля, связи полей внутри сцены, к которой применяется дан-
ная операция, механизмы (engines) сцены, пути и т. д).
Для класса определен метод void SoAction::apply
(SoNode * root ) [virtual], который выполняет действие
для графа сцены с корневым узлом root.

Класс SoBaseColor
Класс SoBaseColor (рис. 3.7) предназначен для указания
цвета материала. Этот класс используется, например, для задания
рассеивающего цвета для исходной геометрии сцены.

Класс SoCoordinate3
Класс SoCoordinate3 (рис. 3.8) содержит координаты уз-
лов-фигур (shape nodes). Когда при обходе графа встречаются
узлы-фигуры, координаты, содержащиеся в нем, помещаются в
стек и позднее используются узлами-фигурами, тип которых тре-
150
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

бует задания координат (такими как SoFaceSet или


SoPointSet). По умолчанию описание выглядит так:
Coordinate3 {
point 0 0 0
}
Необходимо помнить о том, что узел SoCoordinate3 запи-
сывает координаты поверх уже имеющихся.
Общедоступный атрибут класса SoMFVec3f SoCoordinate3::
point задает координаты 3D-точки.

Рис. 3.7. Класс Рис. 3.8. Класс


SoBaseColor SoCoordinate3

Класс SoFaceSet

Класс SoFaceSet (рис. 3.9) используется для формирования и


визуализации неиндексированных граней многоугольников. Грани
определяются с помощью полей numVertices. Координаты,
нормали, материалы и текстуры выбираются в определенном по-
рядке в соответствии с текущим состоянием или из полей узла
vertexProperty. Например, если numVertices инициализи-
рован как [3, 4, 5, 3], этот узел будет определять треугольник по
координатам 0, 1 и 2, четырехугольник по координатам 3, 4, 5 и 6,
пятиугольник по координатам 7, 8, 9, 10 и 11 и треугольник по ко-
ординатам 12, 13, 14.
Общедоступные атрибуты класса:

151
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• SoSFNode SoVertexShape::vertexProperty (теку-


щие координаты, нормали, материалы и текстуры);
• SoSFInt32 SoNonIndexedShape::startIndex (это
поле устарело и существует только для обратной совместимости;
поле задает стартовый индекс для создания поверхности);
• SoMFInt32 SoFaceSet::numVertices (каждая состав-
ляющая поля numVertices — число координат поверхности,
которые соответствуют текущему состоянию обхода графа или
берутся из узла vertexProperty).
По умолчанию описание класса выглядит так:
FaceSet {
vertexProperty NULL
startIndex 0
numVertices -1
}

Класс SoIndexedFaceSet
Класс SoIndexedFaceSet (рис. 3.10) используется для
управления индексируемыми коллекциями граней.
Грани определяются с помощью поля coordIndex. Коорди-
наты, нормали, материалы и текстуры выбираются в определенном
порядке в соответствии с текущим состоянием или из полей узла
vertexProperty и могут быть проиндексированы для создания
треугольников, черырехугольников или многоугольников. Далее
представлен пример простого использования узла для отображе-
ния одной грани многоугольника:
#Inventor V2.1 ascii
Separator {
Coordinate3 {
point [ 0 0 0, 1 0 0, 1 1 0 ]
}
IndexedFaceSet {
coordIndex [ 0, 1, 2, -1 ]
}
}
Общедоступные атрибуты класса:
• SoSFNode SoVertexShape::vertexProperty (теку-
щие координаты, нормали, материалы и текстуры);

152
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• SoMFInt32 SoIndexedShape::coordIndex (индексы


координат граней);
• SoMFInt32 SoIndexedShape::materialIndex (ин-
дексы материалов граней);
• SoMFInt32 SoIndexedShape::normalIndex (индексы
нормалей);
• SoMFInt32 SoIndexedShape::textureCoordIndex (ин-
дексы координат текстур граней).

Рис. 3.9. Класс Рис. 3.10. Класс


SoFaceSet SoIndexedFaceSet

По умолчанию описание класса выглядит так:


IndexedFaceSet {
vertexProperty NULL
coordIndex 0
materialIndex -1
normalIndex -1
textureCoordIndex -1
}

153
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Класс SoIndexedLineSet

Класс SoIndexedLineSet (рис. 3.11) используется для фор-


мирования и визуализации индексируемых строк. В нем индекси-
руется дубликат узла SoLineSet. Линии задаются при помощи
индексов координат, нормалей, материалов и текстур.
Если в стеке или в поле vertexProperty нормаль не задана,
то линия будет отрисована с отключенным освещением.

Класс SoMaterial

Класс SoMaterial (рис. 3.12) предоставляет возможность ус-


тановить значение материала для геометрии сцены. После прохо-
ждения узла SoMaterial, последующие узлы-фигуры в сцене
графа будут использовать значения из резерва материалов
(material pool) текущего состояния обхода графа.

Рис. 3.11. Класс Рис. 3.12. Класс


SoIndexedLineSet SoMaterial

154
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Необходимо помнить о том, что значения, взятые из узла-


материала, заменяют старые значения материалов текущего со-
стояния обхода графа, а не накапливаются. Это имеет место даже
тогда, когда изменение значений материалов происходит неявно в
iv-файле:
#Inventor V2.1 ascii
Material { ambientColor 1 0 0 }
Cone { }
Translation { translation 5 0 0 }
Material { }
Sphere { }
Узел SoSphere не будет в данном случае наследовать значение
SoMaterial::ambientColor из первого узла SoMaterial,
даже в том случае, когда это явно не установлено во втором узле-
материале. Будет использовано значение, установленное по умолча-
нию для SoMaterial::ambientColor.
Общедоступные атрибуты класса:
• SoMFColor SoMaterial::ambientColor (значения со-
ставляющих цвета материала (RGB));
• SoMFColor SoMaterial::diffuseColor (значения со-
ставляющих рассеянного цвета материала (RGB));
• SoMFColor SoMaterial::specularColor (значения
составляющих отраженного цвета материала (RGB));
• SoMFColor SoMaterial::emissiveColor (цвет све-
та, «испускаемого» поверхностью независимо от освещения);
• SoMFFloat SoMaterial::shininess. Блеск материала
определяет, как свет из источника света распределяется по по-
верхности геометрии;
• SoMFFloat SoMaterial::transparency (значения про-
зрачности).
По умолчанию описание класса имеет следующий вид:
Material {
ambientColor 0.2 0.2 0.2
diffuseColor 0.8 0.8 0.8
specularColor 0 0 0
emissiveColor 0 0 0
shininess 0.2

155
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

transparency 0
}

Класс SoMaterialBinding

Класс SoMaterialBinding (рис. 3.13) предназначен для со-


единения параметров материала и геометрических параметров.
Привязка материала, определенная в узлах данного типа, опреде-
ляет, как выбранные материалы, указанные в узле SoMaterial,
связываются с узлами-фигурами. Точное значение данной привяз-
ки зависит от типа фигуры, для которой назначается материал
(листинг 3.9).
Листинг 3.9. Класс SoMaterialBinding
#Inventor V2.1 ascii
Separator {
Coordinate3 {
point [ 0 0 0, 1 0 0, 1 1 0 ]
}
Material {
diffuseColor [ 1 0 0, 1 1 0, 0 0 1 ]
}
MaterialBinding {
value PER_VERTEX_INDEXED
}
IndexedFaceSet {
coordIndex [ 0, 1, 2, -1 ]
materialIndex [ 0, 1, 0 ]
}
}
Общедоступный атрибут класса SoSFEnum SoMaterial
Binding::value (значение материала помещается в поле
value и позднее использует в узлах-фигурах графа сцены).
Если полю SoMaterialBinding::value присвоено значе-
ние PER_VERTEX_INDEXED, то при связывании индексы материа-
лов будут выбираться из поля SoIndexedFaceSet::
materialIndex.
Если полю SoMaterialBinding::value присвоено значение
PER_VERTEX_INDEXED, и поле SoIndexedFaceSet::

156
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

materialIndex не определено или пусто, то индексы материалов


будут выбираться из поля SoIndexedFaceSet::coordIndex.
По умолчанию описание класса имеет следущий вид:
MaterialBinding {
value OVERALL
}

Рис. 3.13. Класс Рис. 3.14. Класс


SoMaterialBinding SoNormal

Класс SoNormal

Класс SoNormal (рис. 3.14) предназначен для формирования


нормалей к фигурам геометрии. Если в графе сцены не описаны
узлы SoNormal, то они строятся автоматически. Также имеется
возможность задать нормали самостоятельно, это может обеспечи-
вать потенциальное увеличение производительности и позволяет
задавать «неправильные» нормали для создания различных специ-
альных эффектов.
Общедоступным атрибутом класса является атрибут
SoMFVec3f SoNormal::vector, который сохраняет набор
векторов нормалей в стек текущего состояния обхода графа.
По умолчанию описание имеет следущий вид:
Normal {
vector [ ]
}

157
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Класс SoNormalBinding
Класс SoNormalBinding (рис. 3.15) предназначен для опре-
деления привязки вектора нормали.
Узлы данного класса определяют, как вектор нормали узла
SoNormal связан в графе сцены с узлами-фигурами.

Рис. 3.15. Класс


SoNormalBinding Рис. 3.16. Класс SoSeparator

Класс SoSeparator
Класс SoSeparator (рис. 3.16) ассоциирован с типом груп-
повых узлов и сохраняет текущее состояние обхода графа. Под-
графы узлов SoSeparator не изменяют состояние обхода графа,
поскольку они помещают и извлекают из стека состояние обхода
до и после обхода своих дочерних узлов. Узлы SoSeparator
также содержат опции для оптимизации процесса обхода графа,
используя механизм кэширования.
Общедоступные атрибуты класса:
• SoSFEnum SoSeparator::renderCaching (кэширова-
ние инструкций);
158
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

• SoSFEnum SoSeparator::boundingBoxCaching (кэ-


ширование вычислений);
• SoSFEnum SoSeparator::renderCulling (выбор окна
просмотра во время отрисовки графа сцены);
• SoSFEnum SoSeparator::pickCulling (выбор окна
просмотра во время выборки узлов графа сцены).

Класс SoPath

Класс SoPath (рис. 3.17) — класс-контейнер для описания пу-


тей обхода графа. Объекты SoPath содержат список указателей
SoNode и список индексов дочерних узлов. Индексы необходимы
для устранения неоднозначности, когда среди дочерних узлов уз-
ла-родителя неоднократно встречаются узлы одного типа. Имеется
возможность импорта из файла (экспорта в файл) пути графа.

Рис. 3.17. Класс Рис. 3.18. Класс


SoPath SoCube

Класс SoCube

Класс SoCube (рис. 3.18) предназначен для создания фигуры


куба. При вставке куба в граф сцены он связывается с текущим
материалом, текстурой и настройками стиля рисования, если тако-
вые имеются, иначе будут использованы стандартные значения.
159
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Узел SoCube — это удобная абстракция для программиста при


создании сложных (complex) фигур без необходимого выполне-
ния расчета для сторон многоугольника и других видов програм-
мирования низкого уровня.
Общедоступные атрибуты класса:
• SoSFFloat SoCube::width (размер куба по оси Х);
• SoSFFloat SoCube::height размер куба по оси Y);
• SoSFFloat SoCube::depth (размер куба по оси Z).
По умолчанию описание класса имеет следующий вид:
Cube {
width 2
height 2
depth 2
}

Класс SoTranslation

Класс SoTranslation (рис. 3.19) предназначен для осущест-


вления передвижения геометрии сцены.
Общедоступный атрибут класса SoSFVec3f SoTranslation::
translation задает значения сдвига геометрии вдоль осей ко-
ординат X, Y и Z.
По умолчанию описание имеет следующий вид:
Translation {
translation 0 0 0
}

Класс SoRotation

Класс SoRotation (рис. 3.20) предоставляет механизм пово-


рота геометрии.
Общедоступный атрибут класса SoSFRotation SoRotation::
rotation определяет вектор и угол поворота.

Класс SoFont

Класс SoFont (рис. 3.21) предназначен для описания шрифта


текста. Для текста, связанного с узлом (например, SoText2,

160
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

SoText3, SoAsciiText и т. д.), при визуализации используется


шрифт, описанный в узле SoFont.

Рис. 3.19. Класс Рис. 3.20. Класс


SoTranslation SoRotation

Имя шрифта представлено в виде family:style. Типичное


семейство шрифтов — Arial или Times New Roman; стили —
Bold, Italic или Bold Italic. Пробелы до и после двоеточия
игнорируются.
Общедоступные атрибуты класса:
• SoSFName SoFont::name (имя шрифта);
• SoSFFloat SoFont::size (размер шрифта).
По умолчанию описание класса имеет следующий вид:
Font {
name "defaultFont"
size 10
}

Класс SoText2
Класс SoText2 (рис. 3.22) предназначен для визуализации 2D-
текста, выровненного с учетом положения камеры.
161
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Текст SoText2 не изменяется в зависимости от расстояния до


камеры и не привязан к вращению или изменению, как в 3D-
примитивах. Для изменения данных своиств текста используют уз-
лы SoText3, SoAsciiText. Но несмотря на то, что размер 2D-
текста не зависит от расстояния до камеры, он все же подчиняется
общим законам расположения объектов в сцене соответственно бу-
феру глубины и будет закрыт близлежащими объектами в сцене.
Размер шрифта текста выбирается из поля SoFont::size
предшествующего в графе сцены узла SoFont.

Рис. 3.21. Класс Рис. 3.22. Класс


SoFont SoText2

Общедоступные атрибуты класса:


• SoMFString SoText2::string (инициализирует строку
текста);
• SoSFFloat SoText2::spacing (определяет интервал
между соседними вертикальными линиями);
• SoSFEnum SoText2::justification (определяет го-
ризонтальное расположение строк текста).
По умолчанию описание класса имеет следующий вид:
Text2 {
string ""
spacing 1
justification LEFT
}

162
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Класс SoLineSet

Класс SoLineSet (рис. 3.23) используется для создания неин-


дексируемых ломаных линий. Ломаные линии используют поле
numVertices. Координаты, нормали, координаты материалов и
текстур берутся либо из текущего состояния обхода графа, либо из
узла vertexProperty, если он определен. Например, если
numVertices определен как [3, 4, 2], то он задает три ломаных,
проходящих соответственно через следующие координаты: 0 1 2,
3 4 5, 6 7 8:
#Inventor V2.1 ascii
Separator {
Coordinate3 {
point [ 0 0 0, 1 1 1, 2 1 1, 2 2
1, 2 2 2, 2 2 3, 2 3 2, 2 3 3, 3 3
3 ]
}
LineSet {
numVertices [ 3, 4, 2 ]
}
}
Ширина линии может быть задана с по-
мощью узла SoDrawStyle, помещаемого
перед узлом (узлами) SoLineSet в графе
сцены.
Общедоступные атрибуты класса:
• SoSFNode SoVertexShape::
vertexProperty (текущие координаты,
нормали, материалы и текстуры);
• SoSFInt32 SoNonIndexedShape::
startIndex (это поле устарело и существу-
ет только для обратной совместимости; оно
задает стартовый индекс для создания линии);
• SoMFInt32 SoLineSet::num
Vertices (каждая составляющая векто-
ра — число координат линии). Рис. 3.23. Класс
По умолчанию описание класса имеет SoLineSet
следующий вид:

163
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

LineSet {
vertexProperty NULL
startIndex 0
numVertices -1
}

3.2.4. Использование моделей Open Inventor в среде Avango

Avango строит трехмерные графические сцены на основе гео-


метрических моделей Open Inventor. Объединение объектов в граф
сцены и задание их интерактивного поведения производится с по-
мощью сценариев на языке Scheme, которые представляют собой
последовательное описание структуры сцены. В листинге 3.10
представлен пример такого сценария.
Листинг 3.10. Пример сценария
; Определение оптимального расположения объекта в сцене
(define obj1_dcs (make-instance-by-name "fpDCS"))
(-> (-> obj1_dcs 'Matrix) 'set-value (mult-mat
(make-scale-mat 0.3 0.3 0.3) (make-rot-mat 0 1 0 0)
(make-trans-mat 0 0.5 -0.1)))
(-> (-> obj1 'Children) 'add-1value obj1_dcs)
; Определение и размещение на панели невидимого
; элемента взаимодействия с активной областью
; текста, нажатие на который приводит к переключению
(define obj1_icon (make-instance-by-name "fpDCS"))
(-> (-> obj1_icon 'Children) 'add-1value button_geom)
(-> (-> obj1_icon 'Matrix) 'set-value (mult-mat
(make-scale-mat 1.3 0.01 2)
(make-trans-mat -0.85 0 -0.53)))
(-> (-> panel 'Children) 'add-1value obj1_icon)
(define obj1_dragger
(make-instance-by-name "fpScriptDragger"))
(-> (-> obj1_dragger 'PushCB)
'set-value "(obj1_script)")
(-> (-> obj1_icon 'Dragger) 'add-1value obj1_dragger)
; Определение основного объекта сцены
(define stanok (make-instance-by-name "fpDCS"))
(-> (-> obj1_dcs 'Children) 'add-1value stanok)
(-> (-> stanok 'Matrix) 'set-value
(make-rot-mat -90 0 0 1))

164
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

; Определение составных частей данного объекта


(define geom01 (make-instance-by-name "fpLoadFile"))
(-> (-> stanok 'Children) 'add-1value geom01)
(define geom02 (make-instance-by-name "fpLoadFile"))
(-> (-> stanok 'Children) 'add-1value geom02)
; Загрузка составных частей из файлов "*.iv"
(-> (-> geom01 'Filename) 'set-value "stanok.iv")
(-> (-> geom02 'Filename) 'set-value "babka.iv")
Последние две строки представленного сценария определяют
загрузку составных частей объекта (станка) из файлов Open
Inventor: задняя бабка загружается из файла babka.iv, а осталь-
ная часть станка загружается из файла stanok.iv. Таким обра-
зом, в среде Avango использутся файлы Open Inventor для пред-
ставления трехмерных геометрических моделей, из которых
состоит виртуальная сцена.

3.3. Построение моделей Open Inventor


на основе численных данных, экспортированных
из файла результатов работы пакета Ansys CFX

Пакет Ansys CFX предоставляет API для экспорта геометричес-


ких данных модели и результатов расчета из файлов с результата-
ми работы пакета Ansys CFX (.res). Функции этого API позво-
ляют экспортировать координаты узлов и объемных элементов
расчетной сетки, описание поверхности модели, а также значения
расчетных параметров в узлах сетки модели.
Для построения моделей в формате Open Inventor на основе
данных, экспортированных из результирующего файла Ansys CFX,
была создана программа, использующая API экспорта пакета An-
sys CFX для экспорта данных и API среды Inventor для создания
графа сцены, определяющего трехмерную модель в формате
Inventor (классы и функции API среды Open Inventor, использован-
ные в программе, описаны в подразд. 3.4). Программа получает
данные из файла результатов пакета Ansys CFX (.res) и создает
набор файлов в формате Open Inventor (.iv), каждый из которых
содержит трехмерную модель с графическими результатами рас-
четов для одного расчетного параметра (давления, температуры,
скорости и др.) Графические результаты расчетов представляют
165
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

собой контуры распределения для скалярных величин и векторные


диаграммы для векторных величин. Этапы работы программы под-
робно описаны ниже.

3.3.1. Экспорт геометрических параметров


и построение поверхности модели

На первом этапе программа осуществляет экспорт геометриче-


ских параметров модели. Основой для построения трехмерной мо-
дели служат узлы расчетной сетки. Каждый узел описывается
структурой cfxNode, инкапсулирующей в себе координаты узла:
typedef struct cfxNode
{
double x, y, z;
};
Для получения массива узлов расчетной сетки используются
две функции API:
int NodeCount = cfxExportNodeCount();
// Получение числа узлов
cfxNode *Nodes = cfxExportNodeList();
// Получение указателя на массив узлов
Следующим этапом является создание узла графа Open
Inventor, содержащего координаты точек будущей модели. Данный
узел описывается объектом Open Inventor типа SoCoordinate3.
В листинге 3.11 приведен код функции, создающей узел графа с
координатами точек модели.
Листинг 3.11. Создание узла графа с координатами точек модели
// Функция принимает указатель на массив узлов
// расчетной сетки, создает узел графа SoCoordinate3,
// содержащий координаты точек модели,
// и возвращает указатель на него
SoCoordinate3* CreateModelVertexes
(cfxNode *Nodes, int NodeCount)
{
SoCoordinate3 *coord = new SoCoordinate3;
cfxNode *curNode;
// Инициализация базы данных Open Inventor,
// содержащей граф сцены

166
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

SoDB::init();
// Цикл по каждому узлу расчетной сетки
for (int i = 0; i < NodeCount; i++)
{
curNode = &(Nodes[i]);
// Добавление в узел графа точки с координатами
// текущего узла сетки
coord->point.set1Value
(i, curNode->x, curNode->y, curNode->z);
}

return coord;
}
После экспорта узлов сетки программа переходит к экспорту
описания поверхности модели. Поверхность модели Ansys CFX
строится из элементарных участков, каждый из которых задается
массивом индексов узлов расчетной сетки, являющихся вершина-
ми участка. В большинстве случаев массив содержит три индекса,
т. е. поверхность строится из элементарных треугольников, вер-
шинами которых являются узлы сетки. Для представления участка
поверхности в программе используется специальная структура
elemFace, инкапсулирующая в себе указатель на массив индек-
сов и число элементов в этом массиве:
struct elemFace{
int* nodes;
int ncount;
};
Вся поверхность модели Ansys CFX разделена на области
(regions). API экспорта Ansys CFX позволяет экспортировать
описания участков поверхности отдельно по каждой области. В
листинге 3.12 представлен код, осуществляющий экспорт поверх-
ности модели.
Листинг 3.12. Экспорт поверхности модели
// Получение числа областей поверхности
int regnum = cfxExportRegionCount();
int facenum = 0;
// Подсчет суммарного числа элементарных
// участков поверхности во всех областях
for(int i = 1; i <= regnum; i++)

167
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
facenum += cfxExportRegionSize(i, cfxREG_FACES);
}
// Выделение массива для хранения описателей
// участков поверхности
elemFace *faces = new elemFace[facenum];
// Массив для хранения индексов узлов текущей
// поверхности
int inodes[10];
// Индекс текущей поверхности
int FaceIndex = 0;
// Цикл экспорта участков поверхности по каждой облаcти
for(int i = 1; i <= regnum; i++)
{
// Получение размера области
// (числа элементарных участков)
int regsize = cfxExportRegionSize
(regnum, cfxREG_FACES);
// Получение массива идентификаторов участков
// поверхности
int* reglist = cfxExportRegionList(regnum,
cfxREG_FACES);
// Цикл по каждому участку поверхности
for(int j = 0; j < regsize; j++)
{
// Идентификатор текущего участка
int faceid = reglist[j];
// Получение массива индексов узлов расчетной сетки,
// задающих текущий участок поверхности
int facesize = cfxExportFaceNodes(faceid, inodes);
// Сохранение размера массива индексов
faces[FaceIndex].ncount = facesize;
// Выделение массива индексов заданного размера
faces[*FaceIndex].nodes = new int[facesize];
// Сохранение индексов узлов сетки
// в текущем узле описания участка поверхности
for(int k = 0; k < facesize; k++)
faces[FaceIndex].nodes[k] = inodes[k];
FaceIndex++;
}
}

168
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

После получения информации о поверхности модели необхо-


димо создать узел графа, задающий поверхность модели в формате
Open Inventor. Для этой цели служит узел SoIndexedFaceSet,
описывающий элементарные участки поверхности аналогично
описанию поверхности в Ansys CFX: каждый элементарный уча-
сток описывается массивом индексов ограничивающих его точек
модели (точки модели задаются узлом SoCoordinate3, см. вы-
ше). В листинге 3.13 приведен код функции, создающей узел гра-
фа, определяющий поверхность модели.
Листинг 3.13. Создание узла графа, определяющего поверхность
модели
// Функция принимает указатель на массив узлов
// описания участков поверхности, создает узел графа
// SoIndexedFaceSet, задающий поверхность модели,
// и возвращает указатель на него
SoIndexedFaceSet* CreateModelFaceset
(elemFace *Faces, int FaceCount)
{
SoIndexedFaceSet *ifaceSet = new SoIndexedFaceSet;
elemFace *curFace;
int pntIndex = 0;
// Цикл по каждому участку поверхности
for(int i = 0; i < FaceCount; i++)
{
curFace = &(Faces[i]);
// Добавление в узел графа индексов точек модели,
// задающих текущий участок поверхности
for(int j = 0; j < curFace->ncount; j++)
ifaceSet->coordIndex.set1Value(pntIndex++,
curFace->nodes[j]-1);

// Добавление в узел графа индекса "-1", который


// свидетельствует об окончании описания текущего
// участка поверхности
ifaceSet->coordIndex.set1Value(pntIndex++, -1);
}
return ifaceSet;
}
Заключительным шагом в создании «чистой» модели (модели,
пока еще не содержащей графических результатов расчетов) явля-
169
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ется добавление созданных узлов координат и поверхностей в


один общий граф, который и задает будущую трехмерную модель.
В листинге 3.14 приведен код функции, создающей граф экспор-
тированной модели.
Листинг 3.14. Создание графа экспортированной модели
// Функция принимает указатели на узел, содержащий
// координаты точек модели, узел, содержащий
// описание участков поверхности модели, добавляет
// эти узлы в общий граф модели и возвращает
// указатель на него
SoSeparator* CreateEmptyModel
(SoCoordinate3 *coord, SoIndexedFaceSet *ifaceSet)
{
// Создание узла геометрических преобразований,
// задающего поворот модели для ее лучшего
// отображения на экране
SoTransform *transform = new SoTransform;
transform->rotation.setValue(0.27, -0.86, 0.44, 0.5);
// Создание узла, определяющего свойства
// формы модели
SoShapeHints *shapeHints = new SoShapeHints;
// Вершины участков поверхности обходят против
// движения часовой стрелки
shapeHints->vertexOrdering =
SoShapeHints::COUNTERCLOCKWISE;
// Тип поверхности - выпуклый
shapeHints->faceType = SoShapeHints::CONVEX;
// Угол перегиба участков поверхности
shapeHints->creaseAngle = 1.309;
// Создание узла, являющегося корнем графа
SoSeparator *root = new SoSeparator;
// Добавление в граф узла геометрических
// преобразований
root->addChild(transform);
// Добавление в граф узла свойств формы модели
root->addChild(shapeHints);
// Добавление в граф узла с координатами
// точек модели
root->addChild(coord);
// Добавление в граф узла с описанием
// поверхности модели

170
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

root->addChild(ifaceSet);
return root;
}
Для сохранения созданного графа в файл используется функ-
ция, которая осуществляет запись в файл с использованием объек-
та SoWriteAction. В листинге 3.15 приведен код этой функции.
Листинг 3.15. Сохранение созданного графа в файл
// Функция принимает указатель на корень графа,
// имя файла, и сохраняет граф в файл
// с указанным именем
void SaveIvGraph(SoNode* GraphRoot, char* IvFileName)
{
// Объект, описывающий выходной поток
SoOutput *out = new SoOutput;
// Объект для записи графа сцены в поток
SoWriteAction writeAction(out);
// тип файла - текстовый (ASCII)
out->setBinary(false);
// Открытие файла для записи
out->openFile(IvFileName);
// Запись графа сцены в файл
writeAction.apply(GraphRoot);
// Закрытие файла
out->closeFile();
}
На рис. 3.24 представлен результат работы данного этапа про-
граммы на примере модели смесителя, входящей в комплект при-
меров, поставляемых вместе с пакетом Ansys CFX (Static Mixer).
Просмотр модели в формате Inventor осуществляется с помощью
утилиты ivview, входящей в набор инструментов Open Inventor.
На рисунке показана «чистая» модель смесителя, не содержащая
пока никаких графических результатов расчета.

3.3.2. Экспорт значений расчетных параметров

API экспорта пакета Ansys CFX предоставляет возможность


экспортировать результаты расчетов в виде значений параметров в
узлах расчетной сетки модели. Для этой цели используются четы-
ре функции API экспорта: cfxExportVariableCount,
171
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

cfxExportVariableSize, cfxExportVariableName и
cfxExportVariableList. В листинге 3.16 представлен код,
осуществляющей экспорт значений расчетных параметров.

Рис. 3.24. Модель смесителя

Листинг 3.16. Экспорт значений расчетных параметров


// Получение числа параметров на уровне
// интересов "usr_level"
int VarNumber = cfxExportVariableCount(usr_level);
// Цикл по каждому параметру
for (int i = 1; i <= VarNumber; i++)
{
// Получение размерности текущего параметра
cfxExportVariableSize
(i, &dim, &length, &bndflag);
// Получение указателя на массив значений
// параметра в узлах сетки

172
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

float *varlist = cfxExportVariableList (i, bndfix);


if(dim == 1)
{
// Для параметров размерностью 1 (скалярные величины)
// осуществляется построение контура распределения
}
else if(dim == 3)
{
// Для параметров размерностью 3 (векторные величины)
// осуществляется построение векторной диаграммы
}
// Освобождение ресурсов, выделенных
// для экспорта значений текущего параметра
cfxExportVariableFree (i);
}

3.3.3. Построение контура распределения


для скалярных параметров

Контур распределения скалярного параметра представляет со-


бой цветной контур на поверхности модели, каждая точка которо-
го своим цветом обозначает определенный диапазон значений, в
который попадает значение параметра в данной точке модели. В
постпроцессоре Ansys CFX весь диапазон значений параметра раз-
бивается на 10 отрезков, каждый из которых отображается своим
цветом: точки с минимальными значениями параметра отобража-
ются различными оттенками синего цвета, с максимальными зна-
чениями — оттенками красного цвета, а точки со средними значе-
ниями — оттенками зеленого цвета.
Для построения аналогичного контура распределения значений
параметра на основе результатов, экспортированных из файла ре-
зультатов работы пакета Ansys CFX, необходимо определить цвета
точек поверхности модели на основе значений параметра в этих
точках. Для этого диапазон значений параметра разбивают на
10 отрезков (как это делается в постпроцессоре Ansys CFX) и для
каждого отрезка определяют значения цветовых компоент таким
образом, чтобы полученные цвета максимально соответствовали
цветам, отображаемым в постпроцессоре Ansys CFX. Результат
назначения цветов представлен в табл. 3.2.

173
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Таблица 3.2
Цветовые составляющие отрезков диапазона значений параметра
1 2 3 4 5 6 7 8 9 10
Номер
отрезка Минимальные Средние Максимальные
значения значения значения
Компонента R 0 0 0 0 0 0 0,5 1 1 1
Компонента G 0 0,5 1 1 1 1 1 1 0,5 0
Компонента B 1 1 1 0,5 0 0 0 0 0 0

Таким образом, процесс определения цветов точек поверхно-


сти модели при построении контура распределения состоит из
следующих шагов:
1) определение диапазона значений параметра как разности
между максимальным и минимальным значениями параметра.
2) определение значения параметра в текущей точке;
3) определение отрезка диапазона значений, в который попада-
ет текущее значение;
4) присваивание текущей точке цвета, соответствующего от-
резку диапазона значений.
Пункты 2–4 выполняют для всех точек поверхности.
Для добавления цветовой информации в граф используют узел
SoMaterial, который позволяет задавать цвет материала точек
поверхности модели. В листинге 3.17 приведен код функции, осу-
ществляющей построение цветного контура распределения значе-
ний скалярного параметра.
Листинг 3.17. Построение цветного контура распределения значе-
ний скалярного параметра
// Функция принимает указатель на массив значений
// скалярного параметра, минимальное и максимальное
// значения параметра, осуществляет построение
// контура распределения параметра и возвращает
// указатель на корень графа, задающего модель
// с контуром распределения
SoSeparator* CreateScalarContour
(float* ValList, int ValCount, float min, float max,
SoCoordinate3 *coord, SoIndexedFaceSet *ifaceSet)

174
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

{
// Создание узла, описывающего свойства
// материала поверхности
SoMaterial *material = new SoMaterial;
// Создание узла, описывающего тип привязки
// материала
SoMaterialBinding *mtlBind = new SoMaterialBinding;
// Тип привязки - к каждой вершине индексированно
// (данный тип необходим для того, чтобы
// каждая вершина имела свой цвет)
mtlBind->value =
SoMaterialBinding::PER_VERTEX_INDEXED;
// Задание начального поворота модели
SoTransform *transform = new SoTransform;
transform->rotation.setValue(0.27, -0.86, 0.44,
0.5);
// Задание свойств формы модели
SoShapeHints *shapeHints = new SoShapeHints;
shapeHints = new SoShapeHints;
shapeHints->vertexOrdering =
SoShapeHints::COUNTERCLOCKWISE;
shapeHints->shapeType =
SoShapeHints::UNKNOWN_SHAPE_TYPE;
shapeHints->faceType = SoShapeHints::CONVEX;
shapeHints->creaseAngle = 1.309;
// Цветовые компоненты
float r, g, b;
// Длина диапазона значений
float range = max - min;
// Среднее значение
float middle = min + range / 2.0;
// Длина отрезка диапазона
float diap = range / 10.0;
// Номер отрезка диапазона
int dnum;
// Цикл по всем значениям параметра
for (int i = 0; i < ValCount; i++)
{
// Определение номера отрезка диапазона,
// в который попадает текущее значение
dnum = GetDiapasonNumByValue
(ValList[i], min, max, middle, diap);

175
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// Определение компоненты r (красный)


r = GetColorComponentByDiapasonNum(dnum, 'r');
// Определение компоненты g (зеленый)
g = GetColorComponentByDiapasonNum(dnum, 'g');
// Определение компоненты b (синий)
b = GetColorComponentByDiapasonNum(dnum, 'b');
// Задание цвета материала текущей точки
material->diffuseColor.set1Value(i, r, g, b);
}
// Создание узла, являющегося корнем графа
SoSeparator* root = new SoSeparator;
// Добавление в граф узла геометрических
// преобразований
root->addChild(transform);
// Добавление в граф узла свойств формы модели
root->addChild(shapeHints);
// Добавление в граф узла с координатами
// точек модели
root->addChild(coord);
// Добавление в граф узла, задающего
// тип привязки материала
root->addChild(mtlBind);
// Добавление в граф узла с цветами точек
root->addChild(material);
// Добавление в граф узла с описанием
// поверхности модели
root->addChild(ifaceSet);
return root;
}
На рис. 3.25 представлен результат работы данной функции. В
качестве примера выбран контур распределения температуры в
модели смесителя.

3.3.4. Построение векторной диаграммы


для векторных параметров

В отличие от скалярных параметров, значения векторных па-


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

176
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 3.25. Модель смесителя с контуром распределения температуры

< Vector1.X, Vector1.Y, Vector1.Z, Vector2.X,


Vector2.Y, Vector2.Z, … >
или
  
v1 , v2 ,..., vN .
Значение параметра в точке модели на векторной диаграмме

изображается в виде вектора qi , выходящего из данной точки,

коллинеарного вектору vi и имеющего длину, определяемую мо-

дулем вектора vi с учетом масштабов модели. Для определения
масштаба модели введем понятие «радиус модели» (Rm), который
будет равен радиусу сферы, описанной вокруг модели. Радиус мо-
дели определяется координатами точки, наиболее удаленной от
воображаемого центра модели по одной из координатных осей.
Пусть x, y, z — координаты точки, в которой необходимо постро-
ить вектор значения параметра; vx, vy, vz — координаты вектора,
определяющего значение параметра в данной точке, vmax — модуль
самого длинного из всех векторов, определяющих значения пара-

метра. Тогда координаты направленного отрезка q , изображаю-

177
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

щего данное значение векторного параметра на векторной диа-


грамме, будут иметь следующий вид:
vx Rm v y Rm v R
qx  ; qy  ; qz  z m ,
vmax k vmax k vmax k
где k — некоторый масштабный коэффициент. Таким образом,

длина вектора q , изображающего текущее значение, будет опре-

деляться, во-первых, длиной вектора v текущего значения и, во-
вторых, радиусом модели (вектор, изображающий наибольшее
значение, будет иметь длину Rm/k). В описываемой программе
масштабный коэффициент k имеет значение 10.
В отличие от контура распределения, изображаемого на поверх-
ности модели, векторы значений на векторной диаграмме изобра-
жаются по всему объему модели. Для открытия обзора всего объема
поверхность модели необходимо скрыть. Для задания направлен-
ных отрезков в графе модели Open Inventor используется узел
SoIndexedLineSet, определяющий отрезок через индексы огра-
ничивающих его точек, аналогично узлу SoIndexedFaceSet.
Цвет отрезка определяется тем же способом, что и цвет точки
контура распределения, только значением параметра в точке яв-
ляется модуль вектора значения в данной точке. В листинге 3.18
приведен код функции, осуществляющей построение векторной
диаграммы.
Листинг 3.18. Построение векторной диаграммы
// Функция принимает указатель на массив значений
// векторного параметра, указатель на массив узлов
// сетки модели, осуществляет построение векторной
// диаграммы параметра и возвращает указатель
// на корень графа, задающего модель с векторной
// диаграммой
SoSeparator* CreateVectorPlot
(float* ValList, int ValCount, float min, float max,
cfxNode *Nodes, float ModelRadius)
{
// Создание узла, описывающего свойства материала
// поверхности
SoMaterial *material = new SoMaterial;

178
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// Создание узла, который будет содержать


// координаты концов направленных отрезков
SoCoordinate3 *vcoord = new SoCoordinate3;
// Создание узла, описывающего направленные отрезки
SoIndexedLineSet *ilineset = new SoIndexedLineSet;
// Задание начального поворота модели
SoTransform *transform = new SoTransform;
transform->rotation.setValue(0.27, -0.86, 0.44,
0.5);
// Задание типа привязки материала поверхности
SoMaterialBinding *mtlBind = new SoMaterialBinding;
mtlBind->value =
SoMaterialBinding::PER_VERTEX_INDEXED;
float r, g, b, x, y, z, val, vlen =
ModelRadius / 10.0, knorm;
float range = max - min;
float middle = min + range / 2.0;
float diap = range / 10.0;
int dnum, ncount = 0, vcount = 0, ilscount = 0;
// Цикл по каждому вектору из массива
// векторных значений
for(int i = 0; i < ValCount; i += 3)
{
// Определение модуля вектора текущего значения
val = sqrt(pow(ValList[i], 2) + pow(ValList[i+1], 2)
+ pow(ValList[i+2], 2));
// Определение номера отрезка диапазона, в который
// попадает текущее значение
dnum = GetDiapasonNumByValue
(val, min, max, middle, diap);
// Определение компоненты r (красный)
r = GetColorComponentByDiapasonNum(dnum, 'r');
// Определение компоненты g (зеленый)
g = GetColorComponentByDiapasonNum(dnum, 'g');
// Определение компоненты b (синий)
b = GetColorComponentByDiapasonNum(dnum, 'b');
// Координаты начала вектора
// (координаты текущего узла сетки)
x = Nodes[ncount].x;
y = Nodes[ncount].y;
z = Nodes[ncount].z;
ncount++;

179
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// Добавление в узел с координатами концов отрезков


// координат начала текущего отрезка
vcoord->point.set1Value(vcount, x, y, z);
// Задание цвета точки начала отрезка
material->diffuseColor.set1Value
(vcount, r, g, b);
// Добавление в узел, описывающий отрезки,
// индекса точки начала отрезка
ilineset->coordIndex.set1Value
(ilscount++, vcount);
vcount++;
// Вычисление масштабного коэффициента для задания
// координат конца направленного отрезка
knorm = vlen / max;
// Добавление в узел с координатами концов отрезков
// координат конца текущего отрезка
vcoord->point.set1Value(vcount, x +
ValList[i]*knorm, y + ValList[i+1]*knorm, z +
ValList[i+2]*knorm);
// Задание цвета точки конца отрезка
material->diffuseColor.set1Value
(vcount, r, g, b);
// Добавление в узел, описывающий отрезки,
// индекса точки конца отрезка
ilineset->coordIndex.set1Value
(ilscount++, vcount);
vcount++;
// Добавление в узел, описывающий отрезки, значения
// "-1" как признака окончания описания текущего
// отрезка
ilineset->coordIndex.set1Value(ilscount++, -1);
}
// Создание узла, являющегося корнем графа
SoSeparator* root = new SoSeparator;
root->ref();
// Добавление в граф узла геометрических
// преобразований
root->addChild(transform);
// Добавление в граф узла с координатами точек модели
root->addChild(vcoord);
// Добавление в граф узла, задающего тип привязки
// материала

180
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

root->addChild(mtlBind);
// Добавление в граф узла с цветами отрезков
root->addChild(material);
// Добавление в граф узла с описанием направленных
// отрезков
root->addChild(ilineset);
return root;
}
На рис. 3.26 представлен результат работы данной функции. В
качестве примера выбрана векторная диаграмма скоростей водных
потоков в модели смесителя.

Рис. 3.26. Векторная диаграмма скоростей водных потоков


в модели смесителя

3.3.5. Дополнительные возможности программы

Итак, описываемая программа принимает на вход файл с ре-


зультатами работы пакета Ansys CFX, экспортирует из него гео-
метрические данные модели и результаты расчетов и генерирует
для каждого расчетного параметра модель в формате Open
Inventor, содержащую контур распределения значений или вектор-
181
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ную диаграмму, в зависимости от размерности параметра. По


умолчанию для каждого параметра генерируются три файла: файл
с контуром распределения или векторной диаграммой, файл с ле-
гендой значений и файл с подписями значений параметра в неко-
торых точках модели. Легенда и подписи значений сохраняются в
отдельные файлы для того, чтобы затем в программе на языке
Scheme, используемом Avango для описания структуры сцены,
можно было по отдельности прикрепить их к переключателям ви-
димости и при необходимости скрывать или показывать нажатием
кнопки в приложении Avango. Кроме того, легенду, загруженную
из отдельного файла, можно закрепить в сцене таким образом,
чтобы она не вращалась при вращении модели.
Формат запуска программы из командной строки имеет вид
CfxToIv <имя файла с результатами CFX>
[дополнительные опции]
Ниже приведено описание дополнительных опций, которые
можно использовать при запуске прогораммы.

Опции экспорта

Опция
-info
При использовании этой опции программа выводит на экран пол-
ную информацию о данных, содержащихся в файле с результатами
работы пакета Ansys CFX, не генерируя iv-файлы. В листинге 3.19
показана информация, полученная из файла StaticMixer.res
(файл, содержащий результаты расчета модели смесителя), с исполь-
зованием данной опции.
Листинг 3.19. Результаты расчета модели смесителя
// Описание всех зон модели
domain 1 - "StaticMixer"
// Первая зона – «StaticMixer»
// Информация о зоне
2786 nodes
// Число узлов расчетной сетки
1 volumes
// Число объемов
13761 elements:

182
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// Число элементов
13761 tetrahedron elements (4 vertices)
// Число тетраэдров
0 pyramid elements (5 vertices)
// Число пирамид
0 prism elements (6 vertices)
// Число призм
0 hexahedron elements (8 vertices)
// Число шестигранников

9 face regions
// Число областей поверхности
// Имена областей поверхности и число
// элементарных участков в каждой области
region 1 - "Region1" (540 faces)
region 2 - "Region2" (276 faces)
region 3 - "Region3" (20 faces)
region 4 - "Region4" (132 faces)
region 5 - "Region5" (356 faces)
region 6 - "Region6" (142 faces)
region 7 - "Region7" (14 faces)
region 8 - "Region8" (136 faces)
region 9 - "Region9" (14 faces)
***************************************************
// Статистика по всей модели
Number of timesteps: 0
// Число временных шагов
Total number of domains: 1
// Общее число зон
Total number of nodes: 2786
// Общее число узлов сетки
Total number of volumes: 1
// общее количество объемов
Total number of elements: 13761
// общее число элементов
Total number of tetrahedrons: 13761
// общее количество тетраэдров
Total number of pyramids: 0
// общее число пирамид
Total number of prisms: 0
// общее количество призм
Total number of hexahedrons: 0

183
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

// Общее число шестигранников


Total number of face regions: 9
// Общее число областей поверхности
Total number of faces: 1630
// Общее число элементарных участков поверхности
// Список доступных параметров с указанием
// номера параметра, его имени и типа
// (скалярный/векторный)
Available parameters:
1 - Bulk Energy Flow Rate (scalar)
2 - Bulk Momentum Flow Rate (vector)
3 - Eddy Viscosity (scalar)
4 - Pressure (scalar)
5 - Temperature (scalar)
6 - Total Pressure (scalar)
7 - Total Temperature (scalar)
8 - Turbulence Eddy Dissipation (scalar)
9 - Turbulence Kinetic Energy (scalar)
10 - Velocity (vector)
11 - Absolute Pressure (scalar)
12 - Density (scalar)
13 - Dynamic Viscosity (scalar)
14 - Shear Strain Rate (scalar)
15 - Solver Yplus (scalar)
16 - Specific Heat Capacity
at Constant Pressure (scalar)
17 - Static Enthalpy (scalar)
18 - Static Entropy (scalar)
19 - Thermal Conductivity (scalar)
20 - Turbulence Eddy Frequency (scalar)
21 - Wall Adjacent Temperature (scalar)
22 - Wall Heat Flux (scalar)
23 - Wall Heat Transfer Coefficient (scalar)
24 - Yplus (scalar)
25 - Pressure.Gradient (vector)
26 - Velocity u.Gradient (vector)
27 - Velocity v.Gradient (vector)
28 - Velocity w.Gradient (vector)
29 - Volume of Finite Volumes (scalar)
30 - Wall Shear (vector)

184
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Опция
-domain <номер>
позволяет экспортировать геометрические данные модели и ре-
зультаты расчетов из конкретной зоны, заданной своим номером.
По умолчанию экспорт осуществляется из всех зон, определенных
в модели.
Опция
-tstep <номер>
Позволяет экспортировать результаты расчетов, относящиеся к
конкретному временнóму шагу. По умолчанию экспорт результа-
тов осуществляется для всех временных шагов. Если для модели
определено более одного временного шага, то созданные графиче-
ские модели (контуры распределения и векторные диаграммы) за-
писываются в отдельные iv-файлы для каждого шага.
Опция
-plevel <номер>
позволяет задавать уровень интереса для экспорта значений пара-
метров. По умолчанию используется первый уровень, при котором
экспортируются значения первых 10 параметров.
Опция
-params <номера параметров, разделенные
пробелом>
позволяет экспортировать значения и строить модели для кон-
кретных параметров, заданных своими номерами.
Опция
-region <номер>
позволяет экспортировать геометрические данные конкретной
области поверхности модели, заданной своим номером. При ис-
пользовании данной опции контуры распределения значений
скалярных параметров строятся только для экспортированной
области поверхности. По умолчанию экспортируется вся по-
верхность модели.
Опция
-ex-reg <номера областей поверхности,
разделенные пробелом>

185
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

позволяет исключить из экспорта конкретные области поверхно-


сти модели, заданные своими номерами. На рис. 3.27 приведен
пример результата использования данной опции.

Рис. 3.27. Контур распределения температуры в модели смесителя


с отсутствующими областями поверхности

Опции создания моделей Open Inventor

Опция
-ivname <имя>
позволяет задать имя, которое будет являться основой для имени
всех генерируемых файлов. По умолчанию в качестве основы ис-
пользуется имя файла с результатами работы пакета Ansys CFX.
Графическая модель, содержащая результаты расчетов по одному
параметру, сохраняется в файл, имеющий следующий формат
имени:
<основа имени>_<s|v><номер параметра>.iv
Символы s и v обозначают соответственно скалярный (контур
распределения) и векторный (векторная диаграмма) параметры.

186
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Рис. 3.28. Контур распределения суммарного давления в модели смесителя с легендой и подписями значений

187
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Пример: файл с контуром распределения температуры, создан-


ный на основе результатов из файла mixer.res, будет иметь имя
mixer_s5.iv (предполагается, что параметр «температура» сто-
ит в результатах под номером 5). При сохранении легенды в от-
дельный файл к указанному имени добавляется постфикс _leg,
при сохранении подписей значений — постфикс _capt.
Опция
-attleg
позволяет присоединить легенду к модели путем добавления ее
графа к графу модели и сохранения в один файл. По умолчанию
легенда сохраняется в отдельный файл.
Опция
-attcapt
позволяет присоединить подписи значений к модели путем добав-
ления их графа к графу модели и сохранения в один файл. По
умолчанию подписи значений сохраняются в отдельный файл.
На рис. 3.28 приведен пример результата использования опций
-attleg и –attcapt.
Опция
-captnum <число>
позволяет задать число точек, для которых создаются подписи
значений параметра. По умолчанию подписи значений создаются
для 20 точек.
Опция
-noleg
позволяет отключить генерацию легенды значений.
Опция
-nocapt
позволяет отключить генерацию подписей значений.

188
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

СПИСОК ЛИТЕРАТУРЫ

Клименко С.В., Никитин И.Н., Никитина Л.Д. Аванго: система разра-


ботки виртуальных окружений. Протвино: ИФТИ, 2006.
Wernecke J. Open Inventor Architecture Group: The Inventor Mentor:
Programming Object-Oriented 3D Graphics with Open Inventor: Release 2.
Reading, Massachusetts: Addison-Wesley, 1994.

ИНТЕРНЕТ-РЕСУРСЫ

http://www.openscenegraph.org — официальный сайт инструментария


OpenSceneGraph.
http://www.python.org — описание языка Python.
http://mysopromat.ru/uchebnye_kursy/mehanika_razrusheniya/ — описа-
ние J-интеграла.

РУКОВОДСТВА ПОЛЬЗОВАТЕЛЯ

ABAQUS Scripting User's Manual — руководство программиста


Abaqus.
ABAQUS Scripting Reference Manual — алфавитный справочник
функций интерфейса сценариев Abaqus.
ABAQUS GUI Toolkit User's Manual — руководство по созданию
пользовательских расширений в Abaqus.
ABAQUS GUI Toolkit Reference Manual — алфавитный справочник
по функциям и классам пользовательских расширений в Abaqus.
ABAQUS Analysis User's Manual — руководство пользователя по рас-
четам в Abaqus.
ABAQUS Example Problems Manual — руководство пользователя с
примерами решения возможных проблем.

189
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ОГЛАВЛЕНИЕ
Введение ..........................................................................................................3
1. Возможности пакета Ansys CFX................................................................5
1.1. Основные сведения о пакете ...............................................................5
1.2. API экспорта пакета Ansys CFX .........................................................6
1.3. Использование библиотеки OpenSceneGraph для трехмерной
визуализации.......................................................................................17
1.4. Пример интеграции пакета Ansys CFX с библиотекой
OpenSceneGraph..................................................................................29
2. Программирование в Abaqus ...................................................................76
2.1. Описание пакета.................................................................................76
2.2. Объектная модель Abaqus .................................................................76
2.3. База данных результатов расчета......................................................81
2.4. Программные интерфейсы Abaqus ...................................................87
2.5. Интерфейс сценариев.......................................................................100
2.6. Создание пользовательских оболочек над ядром Abaqus ............104
3. Использование библиотек Avango и Open Inventor для трехмерной
визуализации...........................................................................................109
3.1. Обзор системы разработки виртуальных приложений Avango ..109
3.2. Среда для создания графических сцен Open Inventor ...................117
3.3. Построение моделей Open Inventor на основе численных
данных, экспортированных из файла результатов работы
пакета Ansys CFX .............................................................................165
Список литературы .....................................................................................189
Интернет-ресурсы .......................................................................................189
Руководства пользователя..........................................................................189

190
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

Учебное издание

Иванов Игорь Потапович


Чеповский Андрей Михайлович

ПРОГРАММНЫЕ СРЕДСТВА ОБРАБОТКИ РЕЗУЛЬТАТОВ


РАСЧЕТОВ В ИНЖЕНЕРНЫХ ПАКЕТАХ ANSYS CFX
И ABAQUS ДЛЯ ВЫСОКОПРОИЗВОДИТЕЛЬНЫХ
ВЫЧИСЛИТЕЛЬНЫХ УСТАНОВОК

Редактор С.А. Серебрякова


Корректор Р.В. Царева
Компьютерная верстка С.А. Серебряковой

Подписано в печать 04.09.2009. Формат 6084/16.


Усл. печ. л. 11,04. Изд. № 169. Тираж 100 экз. Заказ .

Издательство МГТУ им. Н.Э. Баумана.


Типография МГТУ им. Н.Э. Баумана.
105005, Москва, 2-я Бауманская ул., 5.

191
Copyright ОАО «ЦКБ «БИБКОМ» & ООО «Aгентство Kнига-Cервис»

ДЛЯ ЗАМЕТОК

192

Вам также может понравиться