内容发布更新时间 : 2024/11/8 4:34:35星期一 下面是文章的全部内容请认真阅读。
参数switch是一个命令行参数字符串。在这个字符串中,不要求有初始化破折号。Q选项建议在最终的代码中,选项I(没有迭代数值),g(.mesh文件输出),G(.msh文件输出)是没有效果的。 参数in,out是两个指向tetgenio对象的指针,描述输入和输出。In和out可能是空指针。
5.3 tetgenio数据类型
Tetgenio结构是用来传入数据和四面体的输出。它可以用一个数组集代替tetgen的输入和输出文件,这些数组用来保存点,四面体,标识符等。它被声明作为一个C++类,包括一些数据域和函数,tetgenio的数据域如下:
int firstnumber; // 0 or 1, default 0. int mesh_dim; // must be 3. REAL *pointlist;
REAL *pointattributelist; REAL *addpointlist; int *pointmarkerlist; int numberofpoints;
int numberofpointattributes; int numberofaddpoints; int *tetrahedronlist;
REAL *tetrahedronattributelist; REAL *tetrahedronvolumelist; int *neighborlist;
int numberoftetrahedra; int numberofcorners;
int numberoftetrahedronattributes; facet *facetlist; int *facetmarkerlist; int numberoffacets; REAL *holelist; int numberofholes; REAL *regionlist; int numberofregions;
REAL *facetconstraintlist; int numberoffacetconstraints; REAL *segmentconstraintlist; int numberofsegmentconstraints; int *trifacelist;
int *trifacemarkerlist; int numberoftrifaces; int *edgelist;
int *edgemarkerlist; 49
int numberofedges;
5.4 数组描述
就一般情况而言,数组中的第一项的索引是0.然而,如果使用了选项z的话,这个项的项索引从firstnumber开始,在这种情况下它的项号是0.下面是对于这些数组的描述。
Poinlist 顶点左边数组。第一个顶点的x坐标是index[0],y坐标是index[1],z坐标是index[3]。接下来是其他顶点的坐标。每一个顶点占三个REALs。
Pointattributelist 顶点属性数组。
每一个顶点的属性占用“numberofpointattributes” REALs.
Pointmarkerlist 顶点标识符数组,每一个点的标识符为一个整数。
Addpointlist 额外顶点坐标数组,当使用-i选项时,这些点将被读入然后插入到网格中。结构跟pointlist一样,每一个点占三个REALs
Tetrahedronlist 四面体角数组。第一个四面体的第一个角为index[0],接下来是其他的三个角,如果使用了-o2选项的话,接下来便是其他的节点。每一个四面体占用numberofcorners整型。
Tetrahedronattributelist 四面体属性数组。每一个四面体属性占用“numberoftetrahedronattributes” REALs。
Tetrahedronvolumelist 四面体体积列表,四面体体积约束数组;每一个四面体占一个REAL,只用在输入。
Neighborlist 四面体邻居数组。每一个四面体占四个整数。只输出。
Facetlist PLC面数组。每一个面都是一个面类型的对象(见章节5.4.2)。
Facetmarkerlist 面标识符数组。每一个面一个占一个整数。
Holelist 洞数组。第一个洞的x,y,z坐标分别在index[0],index[1],index[2],接下来是其他洞的坐标。每一个洞占三个REALs。
Regionlist 区域属性和体积约束数组。第一个约束的x,y,z坐标在inde[0],index[1],index[2],区域属性在index[3],接着是最大体积在index[4],再接下来就是其他区域的约束。每一个体积约束占5个REALs。每一个区域属性只有在A选项使用时才有效,每一个体积约束只有在a选项时才有效,但省略其中一个选项不会改变内存布局。
Facetconstraintlist面的最大面积约束数组。每一个约束占两个REALs。第一个为面的标识符,第二个是它的最大面积限制。注意facetconstraintlist只有在开启选项q时才能够用。
Segmentconstraintlist 段长度约束数组。每一个约束占两个REALs。第一个是节点的索引(指向pointlist),第二个是最大长度限制。注意segmentcon-straintlist只有在q选项开启使用。
Trifacelist 三角形面数组。第一个面的角是在index[0],index[1],index[2],接下来是其他的面。每一个面占三个整数。
Trifacemarkerlist 面标识符数组。每一个面一个整数。
Edgelist 段终端店数组。第一个段的终端点位于index[0],index[1],接下来是其他的段。每段占两个整数。
Edgemarkerlist 段标识符数组。每一段一个整数。
5.4.1 内存管理
Tetgenio定义两个柜子用于内存的初始化和释放。他们是:
void initialize(); void deinitialize();
initialize()初始化所有内容。也就是说,所有指向数组的指针都为空。除了变量numberofcorners(它的值为4),其他的变量初始化为0.初始化工作由tetgenio的构造函数完成。例如,下面一行创建了一个名为io的tetgenio对象,io所有的域都被初始化了: tetgenio io;
下一步是为每一个将要使用的数组分配内存。C++的内存分配与释放可以通过new和delete关键字。另一对函数是malloc()与free()。无论你用什么,你必须使用两个函数中的一个。New/delete和malloc/free不能混淆。例如,下面一行为io.pointlist分配了内存。 io.pointlist = new REAL[io.numberofpoints * 3];
deinitialize通过用delete为已经分配的tetgenio对象释放内存。它是自动调用tetgenio对象的delete。如果内存是通过malloc函数分配的,用户应该手动去释放它。在释放所有内存之后,initialize()函数的一个调用将没有自动内存释放的功能。
重新使用一个对象是可能的:首先调用d einitialize(),然后在下一次用之前调用initialize();
5.4.2 facet数据结构
在tetgenio里面定义了面的数据结构,facet可以用来表示一个PLC的任意面。然而,为了保持灵活性,不用直接用它。
下面展示的Facet结构由一个多边形列表和一个洞点列表组成。
typedef struct { polygon *polygonlist; int numberofpolygons; REAL *holelist; int numberofholes; } facet;
A polygon也是一个polygon类型的对象。它由一列角点组成。结构如下:
typedef struct { int *vertexlist; int numberofvertices; } polygon;
实际上,facet的结构是poly文件格式的直接翻译,章节3.2.2描述了。图20前面的面作为设定一个PLC面作为facet对象的例子。它有两个多边形。一个有六个顶点,另外一个是一个segment,没有洞,ACSII码数据如下: 2
6 412859 1# front side 2129
下面的C++代码做了介绍。这里假定已经创建了一个tetgenio对象io。
tetgenio::facet *f; // Define a pointer of facet. tetgenio::polygon *p; // Define a pointer of polygon. // All indices start from 1. io.firstnumber = 1;
...
// Use ’f’ to point to a facet of ’facetlist’. f = &io.facetlist[i];
// Initialize the fields of this facet. // There are two polygons, no holes. f->numberofpolygons = 2;
// Allocate memory for polygons.
f->polygonlist = new tetgenio::polygon[2]; f->numberofholes = 0; f->holelist = NULL;
// Set the data of the first polygon into facet. p = &f->polygonlist[0]; p->numberofvertices = 6;
// Allocate memory for vertices. p->vertexlist = new int[6]; p->vertexlist[0] = 4; p->vertexlist[1] = 12; p->vertexlist[2] = 8; p->vertexlist[3] = 5; p->vertexlist[4] = 9; p->vertexlist[5] = 1;
// Set the data of the second polygon into facet. 53
p = &f->polygonlist[1]; p->numberofvertices = 2;
p->vertexlist = new int[2]; // Alloc. memory for vertices. p->vertexlist[0] = 12; p->vertexlist[1] = 9;
5.5 一个例子
这一节给出了一个其他程序怎么样通过使用tetgeio数据结构和函数“tetrahedralize()”来调用tetgen的例子。章节4.3.1的例子再一次被用到。
下面给出了完整的C++代码。用户可以从链接http://tetgen.ber lios .de /fil es/t etca ll. Cxx下载。这个代码说明了下面的基本步骤:
第一步创建一个tetgenio的输入对象in,其中包含bar的数据。
然后调用函数“tetrahedralize()”创建一个四面体网格,结果输出到对象out中。
另外,它把对象in中的PLC输出到barin.node and barin.poly文件中,并且把对象out中的网格输出到barout.node, barout.ele, and barout.face。这些文件可以通过tetview显示出来。
这个例子可以编译成一个可执行程序。 把tetgen编译成一个名为libtet.a的库
把文件“tetcall.cxx”保存到文件“tetgen.h” and “libtet.a”相同的目录。 使用下面的命令编译它
g++ -o test tetcall.cxx -L./ -ltet 此时将会产生一个可执行文件test
完整源代码如下: