Научная статья на тему 'Генерация 3D-сетки с предопределенными регионами поверхности при помощи NetGen'

Генерация 3D-сетки с предопределенными регионами поверхности при помощи NetGen Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
368
99
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
МЕТОД КОНЕЧНЫХ ЭЛЕМЕНТОВ / СЕТКА ЭЛЕМЕНТОВ / ТРИАНГУЛЯЦИЯ / NETGEN / FINITE ELEMENT METHOD / THE MESH ELEMENTS / TRIANGULATION

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Васильев Артем Вячеславович

В статье рассматриваются практические приемы использования библиотеки NetGen для генерации 3-D сетки в программах пространственного моделирования.

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Васильев Артем Вячеславович

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

3-D MESH GENERATION WITH PREDETERMINED SURFACE REGION USING NETGEN LIBRARY

This article discusses practical ways to use library NetGen to generate 3-D mesh in spatial modeling programs.

Текст научной работы на тему «Генерация 3D-сетки с предопределенными регионами поверхности при помощи NetGen»

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

Васильев Артем Вячеславович,

кандидат технических наук, директор по производству, ООО «Фирма «Инрэко ЛАН», г. Владимир

artem.vasiliev@inrecolan.com

ГЕНЕРАЦИЯ 3D-CETKH С ПРЕДОПРЕДЕЛЕННЫМИ РЕГИОНАМИ ПОВЕРХНОСТИ ПРИ ПОМОЩИ NETGEN

Аннотация.

В статье рассматриваются практические приемы использования библиотеки NetGen для генерации 3-D сетки в программах пространственного моделирования.

Ключевые слова: NetGen, метод конечных элементов, сетка элементов, триангуляция

Введение

В работе [1] были рассмотрены особенности использования сторонних библиотек с открытым кодом Freefem++ и NetGen в программе моделирования аэродинамических процессов. Речь шла о возможности включения этих библиотек в коммерческий проект с позиции лицензирования, об особенностях выполнения функций и включения в программную архитектуру. Данная статья является дополнением к предыдущей, в ней более детально рассмотрим библиотеку NetGen. Интерес представляют функции генерации 3D-сетки конечных элементов с заданными регионами на поверхности модели.

Подключение NetGen в MS Visual Studio

Покажем, как можно подключить NetGen к программе на C++. С официального сайта проекта NetGen скачиваем архив. В нашем случае был доступен NetGen версии 4.9.13. Для подключения библиотеки нужны три папки из архива: libsrc, nglib, windows. В Visual Studio создаем проект и решение для демонстрационной программы и подключаем существующий файл проекта nglib.vcxproj из папки windows. Так как в нашем эксперименте проект nglib был создан в более ранней версии Visual Studio, то попутно выполняем конвертацию проекта под новую версию. В настройках проекта nglib добавляем include-папку libsrc\include, добавляем символ NO_PARALLEL_THREADS, удаляем pthreadVC2.lib из дополнительных зависимостей компоновщика, удаляем пост-событие компоновщика и настраиваем целевые папки так, чтобы проект собирался без ошибок.

Включение заголовочного файла nglib.h надо записывать следующим не очень привычным способом:

namespace nglib {

#include "nglib.h"

}

using namespace nglib;

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

Тестовая модель

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

1. В виде операторов конструктивной блочной геометрии (CSG).

2. В виде описания границы пространства в файле формата STL.

Здесь рассмотрим только второй вариант описания поверхности - описание трехмерной модели в текстовом формате STL. Графическое изображение тестовой модели показано на рисунке 1. Модель представляет собой параллелепипед размером 10 Х 10 Х 5. На одной из граней располагается прямоугольный регион размером 5 Х 2 со смещением (4;2), границы которого должны оставаться неизменными.

Рисунок 1. Триангуляция поверхности для формирования STL файла. Красным цветом выделен регион, границы которого должны оставаться без изменений

Ниже приводится содержимое STL-файла, описывающего тестовую модель:

solid facet normal 1 0 0 outer loop vertex 10

endloop endfacet facet normal 1 0 0 outer loop vertex 10

endloop endfacet facet normal 1 0 0 outer loop vertex 10

endloop endfacet facet normal 1 0 0 outer loop vertex 10

endloop endfacet facet normal 1 0 0 outer loop vertex 10

endfacet facet normal 1 0 0 outer loop vertex 10

endfacet facet normal 1 0 0 outer loop vertex 10

endfacet facet normal 1 0 0 outer loop vertex 10

endfacet facet normal 1 0 0 outer loop vertex 10

endfacet facet normal 1 0 0 outer loop vertex 10

endloop endfacet facet normal 1 0 0 outer loop vertex 10

endfacet

4 2 vertex 10 6.5 3 vertex 10 4 4 6.5 3 vertex 10 9 4 vertex 10 4 4 9 2 vertex 10 6.5 3 vertex 10 4 2

9 2 vertex 10 9 4 vertex 10 6.5 3

0 5 vertex 10 0 0 vertex 10 4 2 endloop

4 2 vertex 10 4 4 vertex 10 0 5 endloop

10 5 vertex 10 0 5 vertex 10 4 4 endloop

9 4 vertex 10 10 5 vertex 10 4 4 endloop

9 2 vertex 10 10 5 vertex 10 9 4 endloop

10 0 vertex 10 10 5 vertex 10 9 2

10 0 vertex 10 9 2 vertex 10 4 2 endloop

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

facet normal 1 0 0 outer loop vertex 10 10 0 vertex 10 4 2 vertex 10 0 0 endloop endfacet

facet normal -1 0 0 outer loop vertex 0 10 5 vertex 0 10 0 vertex 0 0 5 endloop endfacet

facet normal -1 0 0 outer loop vertex 0 0 0 vertex 0 0 5 vertex 0 10 0 endloop endfacet

facet normal 0 -1 0 outer loop vertex 0 0 5 vertex 0 0 0 vertex 10 0 5 endloop endfacet

facet normal 0 -1 0 outer loop vertex 10 0 0 vertex 10 0 5 vertex 0 0 0 endloop endfacet

facet normal 0 1 0 outer loop vertex 10 10 5 vertex 10 10 0 vertex 0 10 5 endloop endfacet

facet normal 0 1 0 outer loop vertex 0 10 0 vertex 0 10 5 vertex 10 10 0 endloop endfacet

facet normal 0 0 1 outer loop vertex 0 0 5 vertex 10 0 5 vertex 0 10 5 endloop endfacet

facet normal 0 0 1 outer loop vertex 10 10 5 vertex 0 10 5 vertex 10 0 5 endloop endfacet

facet normal 0 0 -1 outer loop vertex 10 0 0 vertex 0 0 0 vertex 10 10 0 endloop endfacet

facet normal 0 0 -1 outer loop vertex 0 10 0 vertex 10 10 0 vertex 0 0 0 endloop

endfacet

endsolid

Информация в STL-файле имеет следующий формат. В начале и конце файла указываются ключевые слова solid и endsolid, между которыми перечисляются треугольники, задающие требуемую поверхность в формате:

facet normal nx ny nz

outer loop

vertex v1x v1y v1z

vertex v2x v2y v2z

vertex v3x v3y v3z

endloop

endfacet

где nx, ny, nz - составляющие вектора нормали по осям X, Y, Z, направленного наружу из моделируемого объекта; (v1x, v1y, v1z), (v2x, v2y, v2z), (v3x, v3y, v3z) - координаты трех вершин треугольника.

Пример программы, генерирующей сетку конечных элементов

Ниже приведен текст программы, выполняющей все действия, необходимые для получения сетки конечных элементов. Данная программа читает STL-файл OneRegionBar.stl и записывает сетку конечных элементов в файл OneRegionBar.vol.

#include "stdafx.h"

#include <iostream>

#include <fstream>

namespace nglib {

#include "..\NetGen\nglib\nglib.h"

}

using namespace std; using namespace nglib;

void main()

{

const char *stlFileName = "..\\Data\\OneRegionBar.stl"; const char *volFileName = "..\\Data\\OneRegionBar.vol";

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

// Ребра на поверхности const int EDGES_NUM = 4; const int POINTS_NUM = 4; typedef double Point[3];

Point points[POINTS_NUM] = {{10, 4, 2}, {10, 9, 2}, {10, 9, 4}, {10, 4,

4}};

typedef pair<int, int> Edge;

Edge edges[EDGES NUM] = {Edge(0,1), Edge(1, 2), Edge(2,3), Edge(3, 0)};

// Параметры генерации сетки Ng Meshing Parameters ngMeshParameters;

ngMeshParameters.maxh = 10; ngMeshParameters.fineness = 0.4; ngMeshParameters.secondorder = 0; ngMeshParameters.quad dominated = 0;

ngMeshParameters.grading = 0.0; ngMeshParameters.optsurfmeshenable = false; ngMeshParameters.optsteps 2d = 0; ngMeshParameters.closeedgeenable = false;

// Результат выполнения операций Ng Result ng res;

//

// Начало построения сетки //

// Чтение STL-файла, создание объекта "STL-геометрии"

Ng STL Geometry *stlGeometry = Ng STL LoadGeometry(stlFileName);

// Добавление в "геометрию" неизменяемых ребер for(int i = 0; i < EDGES_NUM; i++)

{

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

double* p1 = points[edges[i].first]; double* p2 = points[edges[i].second];

Ng STL AddEdge(stlGeometry, p1, p2);

}

// Инициализация объекта с описанием STL ng res = Ng STL InitSTLGeometry(stlGeometry); if(ng res != NG OK)

{

cout << "Error in Ng STL InitSTLGeometry" << endl;

}

// Пока что пустой объект сетки элементов Ng Mesh *mesh = Ng NewMesh();

// Формировать ребра на поверхности модели

ng res = Ng STL MakeEdges(stlGeometry, mesh, &ngMeshParameters); if(ng res != NG OK)

{

cout << "Error in Ng STL MakeEdges" << endl;

}

// Генерировать поверхность пространства ng res = Ng STL GenerateSurfaceMesh(stlGeometry, mesh, &ngMeshParameters);

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

if(ng res != NG OK)

{

cout << "Error in Ng STL GenerateSurfaceMesh" << endl;

}

// Генерировать сеть конечных элементов

ng res = Ng GenerateVolumeMesh(mesh, &ngMeshParameters); if(ng res != NG OK)

{

cout << "Error in Ng GenerateVolumeMesh" << endl;

}

// Сохранить сетку конечных элементов в файл Ng SaveMesh(mesh,volFileName);

}

Далее дадим подробные комментарии к тексту программы:

1. Координаты точек, являющихся границами ребер, находятся в массиве points[POINTS_NUM]. В массиве edges[EDGES_NUM] заданы ребра региона поверхности в виде соответствующих пар номеров точек. Эти ребра надо будет указать NetGen, чтобы они сохранились на поверхности модели.

2. Управление процессом генерации сетки осуществляется при помощи параметров, собранных в объекте ngMeshParameters класса Ng_Meshing_Parameters. Один из параметров - maxh ограничивает максимальный размер элементов сетки. С помощью других параметров можно делать тонкую настройку процесса генерации: ограничить минимальный размер элементов, инициировать оптимизацию сетки и т.д.

3. STL-файл считывается функцией Ng_STL_LoadGeometry(), а возвращается объект STL-геометрии:

Ng STL Geometry *stlGeometry = Ng STL LoadGeometry(stlFileName);

где Ng_STL_Geometry следует понимать как тип указателя на объект с STL-геометрией. На самом деле Ng_STL_Geometry, как и некоторые другие типы, является синонимом void*. Авторы NetGen таким способом полностью скрыли особенности реализации сложных объектов.

4. Далее в объект STL-геометрии надо добавить ребра. Они добавляются в цикле при помощи функции Ng_STL_AddEdge():

Ng STL AddEdge(stlGeometry, p1, p2);

где stlGeometry - объект STL-геометрии; pi и p2 - вершины ребра. Каждая вершина задается массивом из компонент по осям X, Y, Z. Эти вершины выбираются из массива ребер edges, который был сформирован ранее.

5. Выполнить вызов функции Ng_STL_InitSTLGeometry() для инициализации объекта STL- геометрии:

ng res = Ng STL InitSTLGeometry(stlGeometry);

6. Создать пустой объект сетки элементов, на который указывает mesh. Для этого выполняется функция Ng_NewMesh():

Ng Mesh *mesh = Ng NewMesh();

7. Формировать ребра на поверхности модели в соответствии с STL-геометрией и параметрами генерации:

= Ng STL MakeEdges(stlGeometry, mesh, &ngMeshParameters);

ng_res

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

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

ng res = Ng STL GenerateSurfaceMesh(stlGeometry, mesh,

&ngMeshParameters);

9. И, наконец, выполняется непосредственно генерация сетки элементов функцией Ng_GenerateVolumeMesh() с учетом параметров генерации:

ng res = Ng GenerateVolumeMesh(mesh, &ngMeshParameters);

10. В данной программе результат генерации сетки выводится в VOL-файл посредством функции Ng_SaveMesh(), которой передается указатель на сетку и имя файла:

Ng SaveMesh(mesh,volFileName);

Результат генерации сетки

Результатом генерации сетки является программный объект по указателю типа Ng_Mesh, в демонстрационной программе это указатель mesh. Имеется набор функций, обеспечивающих программный доступ к свойствам сетки элементов: получить количество точек в сетке Ng_GetNP(), получить количество треугольников на поверхности Ng_GetNSE(), получить количество конечных элементов Ng_GetNE(), получить координаты точки Ng_GetPoint(), получить элемент поверхности Ng_GetSurfaceElement(), получить конечный элемент Ng_GetVolumeElement(), сохранить сетку в файл Ng_SaveMesh.

VOL-файл, сохраненный в программе, может быть открыт в визуализаторе netgen.exe. Результат просмотра файла показан на рисунке 2. Как видно на рисунке, границы региона поверхности остались неизменными.

Рисунок 2. Поверхность модели после генерации сетки элементов

VOL-файл, формируемый NetGen, имеет следующий формат:

1. В начале файла указывается код формата (mesh3d), размерность модели (dimension 3), код геометрии (geomtype 0):

mesh3d

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

dimension

3

geomtype

0

2. Далее после ключевого слова surfaceelements указывается количество и

перечисляются элементы поверхности. Для каждого элемента записаны номер поверхности, номер «материала» поверхности, зарезервированное целочисленное поле, количество точек, которыми описывается элемент поверхности (для треугольников — 3), номера трех точек вершин элемента поверхности. Здесь и далее точки нумеруются от 1.

# surfnr bcnr surfaceelements 546 domin domout np p1 p2 p3

2 1 1 0 3 3 4 13

2 #... 1 1 0 3 4 5 107

3. В файле перечисляются конечные элементы, для каждого из которых записаны номер «материала», количество вершин одного элемента (для тетраэдров их четыре) и номера точек, являющихся вершинами:

# matnr np volumeelements 1009 p1 p2 p3 p4

1 4 213 85 153 214

1 4 #... 298 307 301 305

4. Указывается информация о ребрах на поверхности:

# surfid 0 pi p2 trignuml trignum2 domin/surfnrl domout/surfnr2

ednrl distl ednr2 dist2

edgesegmentsgi2

220 1 0 1 2 1 1 0 0 1

0 1 2

2 0 2 1 6 6 0 0 1

2 1 0

#...

5. Перечисляются точки, являющиеся узлами сетки:

# X Y Z

points

333

10.0000000000000000 4.0000000000000000 4.0000000000000000

10.0000000000000000 4.0000000000000000 2.0000000000000000

#...

6. В конце файла записаны компоненты цвета для поверхностей, идентифицируемых номерами. Эти цвета используются визуализатором для раскрашивания поверхности. Здесь для поверхности с номером 2 задан цвет так, чтобы выделить прямоугольный регион на рис. 2.

# Surfnr Red Green Blue

face colours

7

2 1.00000000 1.00000000 0.00000000

3 0.00000000 1.00000000 0.00000000

#...

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

Формирование 2D-ceTKH при помощи NetGen

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

В NetGen имеется функция построения 2D-ceTKH элементов. В частном случае эта функция может быть полезна, например, для формирования STL файла для 3D-модели, имеющей плоские грани. Г еометрия модели описывается во входном файле в виде границ областей пространства. Границы подобластей разбиения задаются либо с помощью отрезков прямых, либо с помощью квадратических сплайнов. При описании границы надо указывать номер области слева и справа от границы. Область вне сетки кодируется номером 0.

Рисунок 3. Кодирование точек и областей для генерации 2D-сетки элементов Приведем пример входного файла, соответствующего рисунку 3.

splinecurves2dv2

2

points

1 0 0

2 3 0

3 3 2

4 0 2

5 1 0

6 2 0

7 2 1

8 1 1

segments

1 0 2 1 5 -bc=1

2 0 2 5 6 -bc=1

1 0 2 6 2 -bc=1

1 0 2 2 3 -bc=1

1 0 2 3 4 -bc=1

1 0 2 4 1 -bc=1

2 1 2 6 7 -bc=1

2 1 2 7 8 -bc=1

2 1 2 8 5 -bc=1

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

materials

1 domainl -maxh=1

2 domain2 -maxh=1

В начале этого файла указывается ключевое слово splinecurves2dv2. Следом за ним коэффициент перестроения сетки (здесь - 2). После ключевого слова points перечисляются точки описания модели: номер точки и координаты по осям X, Y.

Далее после ключевого слова segments следует перечень сегментов границ в следующем формате:

1. Номер области слева от границы.

2. Номер области справа от границы.

3. Количество точек для описания сегмента границы (в примере 2).

4. Номер начальной точки границы.

5. Номер конечной точки границы.

6. Флаги управления генерацией. Флаг bc (номер граничного условия) приходится указывать даже тогда, когда он не используется.

После ключевого слова materials перечисляются области («материалы») в следующем формате:

1. Номер области.

2. Название материала.

3. Флаги управления генерацией. Здесь может быть указан флаг maxh, ограничивающий максимальный размер сетки элементов.

Ниже приведена программа, генерирующая 2D-сетку:

#include "stdafx.h"

namespace nglib {

#include "..\NetGen\nglib\nglib.h"

}

using namespace nglib; void main(){

const char *in2DFileName = "..\\Data\\triangulation.in2d"; const char *volFileName = "..\\Data\\triangulation.vol";

Ng_Geometry_2D * geom;

Ng Init();

geom = Ng LoadGeometry 2D(in2DFileName);

Ng Meshing Parameters mp; mp.maxh = 10000; mp.fineness = 1; mp.secondorder = 0;

Ng_Mesh * mesh;

Ng GenerateMesh 2D (geom, &mesh, &mp);

Ng SaveMesh(mesh, volFileName);

}

Для генерации 2D-сетки используется объект описания 2D-геометрии по указателю geom. Результат генерации сетки находится в объекте по указателю mesh. В

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

примере для вывода результата генерации используется та же самая функция Ng_SaveMesh(), что и в примере генерации 3D-сетки. Поэтому в данном случае выходной файл имеет структуру для 3D-сетки, но значение координаты Z в нем везде равно нулю. Программный интерфейс для работы с 2D-сеткой содержит функции Ng_GetNP_2D() - получить количество узлов сетки, Ng_GetNE_2D() - получить количество элементов в сетке, Ng_GetPoint_2D() - получить координаты узла сетки по номеру узла, Ng_GetElement_2D() - получить координаты вершин элемента по номеру элемента. Визуализация результата генерации 2D-сетки показана на рисунке 4. Как видно из рисунка, границы региона не искажены.

Заключение

В данной статье дано краткое представление NetGen, из которого следует, что эта библиотека удобным образом может быть использована в приложениях, требующих генерацию 3D-сетки элементов. Функции библиотеки могут быть изучены и использованы и без написания кода. В поставку NetGen входит приложение netgen.exe, которое реализует визуальный интерфейс ко всем функциям библиотеки. Рисунки в данной статье, изображающие сетки элементов, получены с помощью этого приложения.

Ссылки на источники

1. Дубов И.Р. Опыт использования freefem++ и netgen в программе моделирования аэродинамических процессов [Электронный ресурс] // Инноватика.- 2014.- №1 (01.04.2014).- URL: http://innovatika.net/articles/201401/DubovIR.pdf

Инноватика. Научный электронный журнал. 2014 № 2

Свидетельство о регистрации ЭЛ № ФС 77-5722, ISSN 2312-2765

Vasiliev Artem Vyacheslavovich,

PhD, Production director, Inreco LAN, Vladimir artem.vasiliev@inrecolan.com

3-D MESH GENERATION WITH PREDETERMINED SURFACE REGION USING NETGEN LIBRARY

Abstract.

This article discusses practical ways to use library NetGen to generate 3-D mesh in spatial modeling programs.

Keywords: NetGen, finite element method, the mesh elements, triangulation.

i Надоели баннеры? Вы всегда можете отключить рекламу.