Skip to content
Snippets Groups Projects
Commit 71cd330a authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

switch to Hang's new experimental version
parent 727b6a40
No related branches found
No related tags found
No related merge requests found
Showing with 22520 additions and 36411 deletions
......@@ -7,10 +7,22 @@ include ../../variables
LIB = ../../lib/libGmshTetgen${LIBEXT}
# Do not optimize (same as Triangle...)
# Don't optimize Tetgen
CFLAGS = ${FLAGS} ${DASH}DTETLIBRARY
SRC = predicates.cxx tetgen.cxx
SRC = behavior.cxx\
constrain.cxx\
delaunay.cxx\
flip.cxx\
geom.cxx\
io.cxx\
main.cxx\
memorypool.cxx\
meshio.cxx\
meshstat.cxx\
predicates.cxx\
surface.cxx
OBJ = ${SRC:.cxx=${OBJEXT}}
.SUFFIXES: ${OBJEXT} .cxx
......@@ -37,5 +49,16 @@ depend:
rm -f Makefile.new
# DO NOT DELETE THIS LINE
behavior${OBJEXT}: behavior.cxx tetgen.h
constrain${OBJEXT}: constrain.cxx tetgen.h
delaunay${OBJEXT}: delaunay.cxx tetgen.h
flip${OBJEXT}: flip.cxx tetgen.h
geom${OBJEXT}: geom.cxx tetgen.h
io${OBJEXT}: io.cxx tetgen.h
main${OBJEXT}: main.cxx tetgen.h
memorypool${OBJEXT}: memorypool.cxx tetgen.h
meshio${OBJEXT}: meshio.cxx tetgen.h
meshstat${OBJEXT}: meshstat.cxx tetgen.h
predicates${OBJEXT}: predicates.cxx tetgen.h
surface${OBJEXT}: surface.cxx tetgen.h
tetgen${OBJEXT}: tetgen.cxx tetgen.h
This is TetGen version 1.4.2 (released on April 16, 2007)
This is an EXPERIMENTAL version of TetGen provided by Hang Si for Gmsh
Please see the documentation of TetGen (available at the following link) for
compiling and using TetGen.
......@@ -13,4 +13,4 @@ Please send bugs/comments to Hang Si <si@wias-berlin.de>
Thank you and enjoy!
Hang Si
April 16, 2007
#ifndef behaviorCXX
#define behaviorCXX
#include "tetgen.h"
static REAL PI = 3.14159265358979323846264338327950288419716939937510582;
///////////////////////////////////////////////////////////////////////////////
// //
// tetgenbehavior() Initialize veriables of 'tetgenbehavior'. //
// //
///////////////////////////////////////////////////////////////////////////////
tetgenbehavior::tetgenbehavior()
{
// Initialize command line switches.
plc = 0;
quality = 0;
refine = 0;
coarse = 0;
metric = 0;
minratio = 2.0;
goodratio = 0.0;
minangle = 20.0;
goodangle = 0.0;
maxdihedral = 165.0;
mindihedral = 5.0;
varvolume = 0;
fixedvolume = 0;
maxvolume = -1.0;
regionattrib = 0;
bowyerwatson = 1;
convexity = 0;
insertaddpoints = 0;
diagnose = 0;
conformdel = 0;
zeroindex = 0;
facesout = 0;
edgesout = 0;
neighout = 0;
voroout = 0;
meditview = 0;
gidview = 0;
geomview = 0;
order = 1;
nojettison = 0;
nobound = 0;
nonodewritten = 0;
noelewritten = 0;
nofacewritten = 0;
noiterationnum = 0;
nobisect = 0;
steiner = -1;
nomerge = 0;
docheck = 0;
quiet = 0;
verbose = 0;
useshelles = 0;
epsilon = 1.0e-8;
object = NONE;
// Initialize strings
commandline[0] = '\0';
infilename[0] = '\0';
outfilename[0] = '\0';
addinfilename[0] = '\0';
bgmeshfilename[0] = '\0';
}
///////////////////////////////////////////////////////////////////////////////
// //
// versioninfo() Print the version information of TetGen. //
// //
///////////////////////////////////////////////////////////////////////////////
void tetgenbehavior::versioninfo()
{
printf("Develop Version (Started on August 9, 2008).\n");
printf("\n");
printf("Copyright (C) 2002 - 2008\n");
printf("Hang Si\n");
printf("Mohrenstr. 39, 10117 Berlin, Germany\n");
printf("si@wias-berlin.de\n");
}
///////////////////////////////////////////////////////////////////////////////
// //
// syntax() Print list of command line switches and exit the program. //
// //
///////////////////////////////////////////////////////////////////////////////
void tetgenbehavior::syntax()
{
printf(" tetgen [-prq_Ra_AiMYS_T_dzo_fenvgGOJBNEFICQVh] input_file\n");
printf(" -p Tetrahedralizes a piecewise linear complex (PLC).\n");
printf(" -r Reconstructs a previously generated mesh.\n");
printf(" -q Quality mesh generation (adding new mesh points to ");
printf("improve mesh quality).\n");
printf(" -R Mesh coarsening (deleting redundant mesh points).\n");
printf(" -a Applies a maximum tetrahedron volume constraint.\n");
printf(" -A Assigns attributes to identify tetrahedra in different ");
printf("regions.\n");
printf(" -i Inserts a list of additional points into mesh.\n");
printf(" -M Does not merge coplanar facets.\n");
printf(" -Y Suppresses boundary facets/segments splitting.\n");
printf(" -S Specifies maximum number of added points.\n");
printf(" -T Sets a tolerance for coplanar test (default 1e-8).\n");
printf(" -d Detects self-intersections of facets of the PLC.\n");
printf(" -z Numbers all output items starting from zero.\n");
printf(" -o2 Generates second-order subparametric elements.\n");
printf(" -f Outputs all faces to .face file.");
printf("file.\n");
printf(" -e Outputs all edges to .edge file.\n");
printf(" -n Outputs tetrahedra neighbors to .neigh file.\n");
printf(" -v Outputs Voronoi diagram to files.\n");
printf(" -g Outputs mesh to .mesh file for viewing by Medit.\n");
printf(" -G Outputs mesh to .msh file for viewing by Gid.\n");
printf(" -O Outputs mesh to .off file for viewing by Geomview.\n");
printf(" -J No jettison of unused vertices from output .node file.\n");
printf(" -B Suppresses output of boundary information.\n");
printf(" -N Suppresses output of .node file.\n");
printf(" -E Suppresses output of .ele file.\n");
printf(" -F Suppresses output of .face file.\n");
printf(" -I Suppresses mesh iteration numbers.\n");
printf(" -C Checks the consistency of the final mesh.\n");
printf(" -Q Quiet: No terminal output except errors.\n");
printf(" -V Verbose: Detailed information, more terminal output.\n");
printf(" -h Help: A brief instruction for using TetGen.\n");
}
///////////////////////////////////////////////////////////////////////////////
// //
// usage() Print a brief instruction for using TetGen. //
// //
///////////////////////////////////////////////////////////////////////////////
void tetgenbehavior::usage()
{
printf("TetGen\n");
printf("A Quality Tetrahedral Mesh Generator and 3D Delaunay ");
printf("Triangulator\n");
versioninfo();
printf("\n");
printf("What Can TetGen Do?\n");
printf("\n");
printf(" TetGen generates exact Delaunay tetrahedralizations, exact\n");
printf(" constrained Delaunay tetrahedralizations, and quality ");
printf("tetrahedral\n meshes. The latter are nicely graded and whose ");
printf("tetrahedra have\n radius-edge ratio bounded, thus are suitable ");
printf("for finite element and\n finite volume analysis.\n");
printf("\n");
printf("Command Line Syntax:\n");
printf("\n");
printf(" Below is the command line syntax of TetGen with a list of ");
printf("short\n");
printf(" descriptions. Underscores indicate that numbers may optionally\n");
printf(" follow certain switches. Do not leave any space between a ");
printf("switch\n");
printf(" and its numeric parameter. \'input_file\' contains input data\n");
printf(" depending on the switches you supplied which may be a ");
printf(" piecewise\n");
printf(" linear complex or a list of nodes. File formats and detailed\n");
printf(" description of command line switches are found in user's ");
printf("manual.\n");
printf("\n");
syntax();
printf("\n");
printf("Examples of How to Use TetGen:\n");
printf("\n");
printf(" \'tetgen object\' reads vertices from object.node, and writes ");
printf("their\n Delaunay tetrahedralization to object.1.node and ");
printf("object.1.ele.\n");
printf("\n");
printf(" \'tetgen -p object\' reads a PLC from object.poly or object.");
printf("smesh (and\n possibly object.node) and writes its constrained ");
printf("Delaunay\n tetrahedralization to object.1.node, object.1.ele and ");
printf("object.1.face.\n");
printf("\n");
printf(" \'tetgen -pq1.414a.1 object\' reads a PLC from object.poly or\n");
printf(" object.smesh (and possibly object.node), generates a mesh ");
printf("whose\n tetrahedra have radius-edge ratio smaller than 1.414 and ");
printf("have volume\n of 0.1 or less, and writes the mesh to ");
printf("object.1.node, object.1.ele\n and object.1.face.\n");
printf("\n");
printf("Please send bugs/comments to Hang Si <si@wias-berlin.de>\n");
}
///////////////////////////////////////////////////////////////////////////////
// //
// parse_commandline() Read the command line, identify switches, and set //
// up options and file names. //
// //
// 'argc' and 'argv' are the same parameters passed to the function main() //
// of a C/C++ program. They together represent the command line user invoked //
// from an environment in which TetGen is running. //
// //
// When TetGen is invoked from an environment. 'argc' is nonzero, switches //
// and input filename should be supplied as zero-terminated strings in //
// argv[0] through argv[argc - 1] and argv[0] shall be the name used to //
// invoke TetGen, i.e. "tetgen". Switches are previously started with a //
// dash '-' to identify them from the input filename. //
// //
// When TetGen is called from within another program. 'argc' is set to zero. //
// switches are given in one zero-terminated string (no previous dash is //
// required.), and 'argv' is a pointer points to this string. No input //
// filename is required (usually the input data has been directly created by //
// user in the 'tetgenio' structure). A default filename 'tetgen-tmpfile' //
// will be created for debugging output purpose. //
// //
///////////////////////////////////////////////////////////////////////////////
bool tetgenbehavior::parse_commandline(int argc, char **argv)
{
int startindex;
int increment;
int meshnumber;
int scount;
int i, j, k;
char workstring[1024];
// First determine the input style of the switches.
if (argc == 0) {
startindex = 0; // Switches are given without a dash.
argc = 1; // For running the following for-loop once.
commandline[0] = '\0';
} else {
startindex = 1;
strcpy(commandline, argv[0]);
strcat(commandline, " ");
}
// Rcount used to count the number of '-R' be used.
scount = 0;
for (i = startindex; i < argc; i++) {
// Remember the command line switches.
strcat(commandline, argv[i]);
strcat(commandline, " ");
if (startindex == 1) {
// Is this string a filename?
if (argv[i][0] != '-') {
strncpy(infilename, argv[i], 1024 - 1);
infilename[1024 - 1] = '\0';
// Go to the next string directly.
continue;
}
}
// Parse the individual switch from the string.
for (j = startindex; argv[i][j] != '\0'; j++) {
if (argv[i][j] == 'p') {
plc = 1;
} else if (argv[i][j] == 'r') {
refine = 1;
} else if (argv[i][j] == 'R') {
coarse = 1;
} else if (argv[i][j] == 'q') {
quality++;
if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.')) {
k = 0;
while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.')) {
j++;
workstring[k] = argv[i][j];
k++;
}
workstring[k] = '\0';
if (quality == 1) {
minratio = (REAL) strtod(workstring, (char **) NULL);
} else if (quality == 2) {
mindihedral = (REAL) strtod(workstring, (char **) NULL);
} else if (quality == 3) {
maxdihedral = (REAL) strtod(workstring, (char **) NULL);
}
}
} else if (argv[i][j] == 'm') {
metric++;
} else if (argv[i][j] == 'a') {
if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.')) {
fixedvolume = 1;
k = 0;
while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') ||
(argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) {
j++;
workstring[k] = argv[i][j];
k++;
}
workstring[k] = '\0';
maxvolume = (REAL) strtod(workstring, (char **) NULL);
} else {
varvolume = 1;
}
} else if (argv[i][j] == 'A') {
regionattrib++;
} else if (argv[i][j] == 'b') {
bowyerwatson = 0;
} else if (argv[i][j] == 'c') {
convexity++;
} else if (argv[i][j] == 'i') {
insertaddpoints = 1;
} else if (argv[i][j] == 'd') {
diagnose = 1;
} else if (argv[i][j] == 'z') {
zeroindex = 1;
} else if (argv[i][j] == 'f') {
facesout = 1;
} else if (argv[i][j] == 'e') {
edgesout++;
} else if (argv[i][j] == 'n') {
neighout++;
} else if (argv[i][j] == 'v') {
voroout = 1;
} else if (argv[i][j] == 'g') {
meditview = 1;
} else if (argv[i][j] == 'G') {
gidview = 1;
} else if (argv[i][j] == 'O') {
geomview = 1;
} else if (argv[i][j] == 'M') {
nomerge = 1;
} else if (argv[i][j] == 'Y') {
nobisect++;
} else if (argv[i][j] == 'J') {
nojettison = 1;
} else if (argv[i][j] == 'B') {
nobound = 1;
} else if (argv[i][j] == 'N') {
nonodewritten = 1;
} else if (argv[i][j] == 'E') {
noelewritten = 1;
if (argv[i][j + 1] == '2') {
j++;
noelewritten = 2;
}
} else if (argv[i][j] == 'F') {
nofacewritten = 1;
} else if (argv[i][j] == 'I') {
noiterationnum = 1;
} else if (argv[i][j] == 'o') {
if ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
k = 0;
while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
j++;
workstring[k] = argv[i][j];
k++;
}
workstring[k] = '\0';
order = (int) strtol(workstring, (char **) NULL, 0);
}
} else if (argv[i][j] == 'S') {
if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.')) {
k = 0;
while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') ||
(argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) {
j++;
workstring[k] = argv[i][j];
k++;
}
workstring[k] = '\0';
steiner = (int) strtol(workstring, (char **) NULL, 0);
}
} else if (argv[i][j] == 'D') {
conformdel++;
} else if (argv[i][j] == 'T') {
if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.')) {
k = 0;
while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
(argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') ||
(argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) {
j++;
workstring[k] = argv[i][j];
k++;
}
workstring[k] = '\0';
epsilon = (REAL) strtod(workstring, (char **) NULL);
}
} else if (argv[i][j] == 'C') {
docheck++;
} else if (argv[i][j] == 'Q') {
quiet = 1;
} else if (argv[i][j] == 'V') {
verbose++;
// } else if (argv[i][j] == 'v') {
// versioninfo();
// terminatetetgen(0);
} else if ((argv[i][j] == 'h') || (argv[i][j] == 'H') ||
(argv[i][j] == '?')) {
usage();
terminatetetgen(0);
} else {
printf("Warning: Unknown switch -%c.\n", argv[i][j]);
}
}
}
if (startindex == 0) {
// Set a temporary filename for debugging output.
strcpy(infilename, "tetgen-tmpfile");
} else {
if (infilename[0] == '\0') {
// No input file name. Print the syntax and exit.
syntax();
terminatetetgen(0);
}
// Recognize the object from file extension if it is available.
if (!strcmp(&infilename[strlen(infilename) - 5], ".node")) {
infilename[strlen(infilename) - 5] = '\0';
object = NODES;
} else if (!strcmp(&infilename[strlen(infilename) - 5], ".poly")) {
infilename[strlen(infilename) - 5] = '\0';
object = POLY;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 6], ".smesh")) {
infilename[strlen(infilename) - 6] = '\0';
object = POLY;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 4], ".off")) {
infilename[strlen(infilename) - 4] = '\0';
object = OFF;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 4], ".ply")) {
infilename[strlen(infilename) - 4] = '\0';
object = PLY;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 4], ".stl")) {
infilename[strlen(infilename) - 4] = '\0';
object = STL;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 5], ".mesh")) {
infilename[strlen(infilename) - 5] = '\0';
object = MEDIT;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 4], ".vtk")) {
infilename[strlen(infilename) - 4] = '\0';
object = VTK;
plc = 1;
} else if (!strcmp(&infilename[strlen(infilename) - 4], ".ele")) {
infilename[strlen(infilename) - 4] = '\0';
object = MESH;
refine = 1;
}
}
plc = plc || diagnose;
useshelles = plc || refine || coarse || quality;
goodratio = minratio;
goodratio *= goodratio;
// Detect improper combinations of switches.
if (plc && refine) {
printf("Error: Switch -r cannot use together with -p.\n");
return false;
}
if (refine && (plc || noiterationnum)) {
printf("Error: Switches %s cannot use together with -r.\n",
"-p, -d, and -I");
return false;
}
if (diagnose && (quality || insertaddpoints || (order == 2) || neighout
|| docheck)) {
printf("Error: Switches %s cannot use together with -d.\n",
"-q, -i, -o2, -n, and -C");
return false;
}
// Be careful not to allocate space for element area constraints that
// will never be assigned any value (other than the default -1.0).
if (!refine && !plc) {
varvolume = 0;
}
// Be careful not to add an extra attribute to each element unless the
// input supports it (PLC in, but not refining a preexisting mesh).
if (refine || !plc) {
regionattrib = 0;
}
// If '-a' or '-aa' is in use, enable '-q' option too.
if (fixedvolume || varvolume) {
if (quality == 0) {
quality = 1;
}
}
// Calculate the goodangle for testing bad subfaces.
goodangle = cos(minangle * PI / 180.0);
goodangle *= goodangle;
increment = 0;
strcpy(workstring, infilename);
j = 1;
while (workstring[j] != '\0') {
if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) {
increment = j + 1;
}
j++;
}
meshnumber = 0;
if (increment > 0) {
j = increment;
do {
if ((workstring[j] >= '0') && (workstring[j] <= '9')) {
meshnumber = meshnumber * 10 + (int) (workstring[j] - '0');
} else {
increment = 0;
}
j++;
} while (workstring[j] != '\0');
}
if (noiterationnum) {
strcpy(outfilename, infilename);
} else if (increment == 0) {
strcpy(outfilename, infilename);
strcat(outfilename, ".1");
} else {
workstring[increment] = '%';
workstring[increment + 1] = 'd';
workstring[increment + 2] = '\0';
sprintf(outfilename, workstring, meshnumber + 1);
}
// Additional input file name has the end ".a".
strcpy(addinfilename, infilename);
strcat(addinfilename, ".a");
// Background filename has the form "*.b.ele", "*.b.node", ...
strcpy(bgmeshfilename, infilename);
strcat(bgmeshfilename, ".b");
return true;
}
#endif // ifndef behaviorCXX
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef mainCXX
#define mainCXX
#include "tetgen.h"
///////////////////////////////////////////////////////////////////////////////
// //
// test_tri_tri() Triangle-triangle intersection tests. //
// //
///////////////////////////////////////////////////////////////////////////////
void test_tri_tri(tetgenbehavior *b, tetgenio *in)
{
tetgenmesh m;
tetgenmesh::face s1, s2;
tetgenmesh::point U[3], V[3], T1[3], T2[3];
tetgenmesh::intersection dir;
int types[2], pos[4];
int i, j;
m.b = b;
m.in = in;
exactinit();
m.initializepools();
m.transfernodes();
m.meshsurface();
m.subfacepool->traversalinit();
s1.sh = m.shellfacetraverse(m.subfacepool);
s2.sh = m.shellfacetraverse(m.subfacepool);
V[0] = (tetgenmesh::point) s1.sh[3]; // P
V[1] = (tetgenmesh::point) s1.sh[4]; // Q
V[2] = (tetgenmesh::point) s1.sh[5]; // R
U[0] = (tetgenmesh::point) s2.sh[3]; // A
U[1] = (tetgenmesh::point) s2.sh[4]; // B
U[2] = (tetgenmesh::point) s2.sh[5]; // C
// The permuations of {0, 1, 2}
int perm[6][3] = {
{0, 1, 2},
{2, 0, 1},
{1, 2, 0},
{1, 0, 2},
{2, 1, 0},
{0, 2, 1}};
b->epsilon = 0;
b->verbose = 3;
for (j = 0; j < 36; j++) {
// Get the permuation of the vertices.
T1[0] = U[perm[j/6][0]];
T1[1] = U[perm[j/6][1]];
T1[2] = U[perm[j/6][2]];
T2[0] = V[perm[j%6][0]];
T2[1] = V[perm[j%6][1]];
T2[2] = V[perm[j%6][2]];
i = m.tri_tri_test(T1[0], T1[1], T1[2], T2[0], T2[1], T2[2], NULL, 1,
types, pos);
if (i == 0) {
printf(" [%d] DISJOINT.\n", j);
continue;
}
// Report the intersection types and positions.
for (i = 0; i < 2; i++) {
dir = (enum tetgenmesh::intersection) types[i];
switch (dir) {
case tetgenmesh::DISJOINT:
printf(" [%d] DISJOINT\n", j); break;
case tetgenmesh::SHAREVERT:
printf(" [%d] SHAREVERT %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::SHAREEDGE:
printf(" [%d] SHAREEDGE %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::SHAREFACE:
printf(" [%d] SHAREFACE\n", j); break;
case tetgenmesh::TOUCHEDGE:
printf(" [%d] TOUCHEDGE %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::TOUCHFACE:
printf(" [%d] TOUCHFACE %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::ACROSSVERT:
printf(" [%d] ACROSSVERT %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::ACROSSEDGE:
printf(" [%d] ACROSSEDGE %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::ACROSSFACE:
printf(" [%d] ACROSSFACE %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::ACROSSTET:
printf(" [%d] ACROSSTET\n", j); break;
case tetgenmesh::TRIEDGEINT:
printf(" [%d] TRIEDGEINT %d %d\n", j, pos[i*2], pos[i*2+1]); break;
case tetgenmesh::EDGETRIINT:
printf(" [%d] EDGETRIINT %d %d\n", j, pos[i*2], pos[i*2+1]); break;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// //
// tetrahedralize() The interface for users using TetGen library to //
// generate tetrahedral meshes with all features. //
// //
// The sequence is roughly as follows. Many of these steps can be skipped, //
// depending on the command line switches. //
// //
// - Initialize constants and parse the command line. //
// - Read the vertices from a file and either //
// - tetrahedralize them (no -r), or //
// - read an old mesh from files and reconstruct it (-r). //
// - Insert the PLC segments and facets (-p). //
// - Read the holes (-p), regional attributes (-pA), and regional volume //
// constraints (-pa). Carve the holes and concavities, and spread the //
// regional attributes and volume constraints. //
// - Enforce the constraints on minimum quality bound (-q) and maximum //
// volume (-a). Also enforce the conforming Delaunay property (-q and -a). //
// - Promote the mesh's linear tetrahedra to higher order elements (-o). //
// - Write the output files and print the statistics. //
// - Check the consistency and Delaunay property of the mesh (-C). //
// //
///////////////////////////////////////////////////////////////////////////////
void tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out,
tetgenio *addin, tetgenio *bgmin)
{
tetgenmesh m;
// Variables for timing the performance of TetGen (defined in time.h).
clock_t tv[17];
tv[0] = clock();
m.b = b;
m.in = in;
exactinit();
m.initializepools();
m.transfernodes();
tv[1] = clock();
if (b->refine) {
// m.reconstructmesh();
} else {
m.incrementaldelaunay();
}
tv[2] = clock();
if (!b->quiet) {
if (b->refine) {
printf("Mesh reconstruction seconds:");
} else {
printf("Delaunay seconds:");
}
printf(" %g\n", (tv[2] - tv[1]) / (REAL) CLOCKS_PER_SEC);
}
if (b->plc) { // if has -p option
m.meshsurface();
}
tv[3] = clock();
if (!b->quiet) {
if (b->plc) {
printf("Surface meshing seconds: %g\n",
(tv[3] - tv[2]) / (REAL) CLOCKS_PER_SEC);
}
}
if (b->plc) { // if has -p option
m.formskeleton();
}
tv[4] = clock();
if (!b->quiet) {
if (b->plc) {
if (b->diagnose != 1) {
printf("Boundary recovery ");
} else {
printf("Intersection ");
}
printf("seconds: %g\n", (tv[4] - tv[3]) / (REAL) CLOCKS_PER_SEC);
}
}
if (b->plc) {
if (b->convexity == 0) { // if has no -c option.
m.carveholes();
}
}
tv[5] = clock();
if (!b->quiet) {
if (b->plc) {
if (b->convexity == 0) { // if has no -c option.
printf("Holes and region seconds: %g\n",
(tv[5] - tv[4]) / (REAL) CLOCKS_PER_SEC);
}
}
}
printf("\n");
if (out != (tetgenio *) NULL) {
out->firstnumber = in->firstnumber;
out->mesh_dim = in->mesh_dim;
}
if (b->nonodewritten || b->noiterationnum) {
if (!b->quiet) {
printf("NOT writing a .node file.\n");
}
} else {
m.outnodes(out);
}
if (b->noelewritten == 1) {
if (!b->quiet) {
printf("NOT writing an .ele file.\n");
}
m.numberedges();
} else {
m.outelements(out);
}
if (b->nofacewritten) {
if (!b->quiet) {
printf("NOT writing an .face file.\n");
}
if (b->plc || b->refine) {
m.numbersubedges();
}
} else {
if (b->facesout) {
if (m.tetrahedronpool->items > 0l) {
m.outfaces(out); // Output all faces.
}
if (b->plc || b->refine) {
m.numberedges();
}
} else {
if (b->plc || b->refine) {
if (m.subfacepool->items > 0l) {
m.outsubfaces(out); // Output boundary faces.
}
} else {
if (m.tetrahedronpool->items > 0l) {
m.outhullfaces(out); // Output convex hull faces.
}
}
}
}
if (b->edgesout) {
if (b->edgesout > 1) {
m.outedges(out); // -ee, output all mesh edges.
} else {
m.outsubsegments(out); // -e, only output subsegments.
}
}
if (b->neighout) {
m.outneighbors(out);
}
if (b->voroout) {
// m.outvoronoi(out);
}
tv[6] = clock();
if (!b->quiet) {
printf("\nOutput seconds: %g\n",
(tv[6] - tv[5]) / (REAL) CLOCKS_PER_SEC);
printf("Total running seconds: %g\n\n",
(tv[6] - tv[0]) / (REAL) CLOCKS_PER_SEC);
}
if (b->docheck) {
if (b->plc) {
m.checkshells(1);
}
if (m.checkdelaunay(b->plc) > 0) assert(0);
}
if (!b->quiet) {
m.statistics();
}
}
#ifndef TETLIBRARY
///////////////////////////////////////////////////////////////////////////////
// //
// main() The entrance for running TetGen from command line. //
// //
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
#else // with TETLIBRARY
///////////////////////////////////////////////////////////////////////////////
// //
// tetrahedralize() The entrance for calling TetGen from another program. //
// //
///////////////////////////////////////////////////////////////////////////////
void tetrahedralize(char *switches, tetgenio *in, tetgenio *out,
tetgenio *addin, tetgenio *bgmin)
#endif // not TETLIBRARY
{
tetgenbehavior b;
#ifndef TETLIBRARY
tetgenio in, addin, bgmin;
if (!b.parse_commandline(argc, argv)) {
terminatetetgen(1);
}
if (b.refine) {
if (!in.load_tetmesh(b.infilename)) {
terminatetetgen(1);
}
} else {
if (!in.load_plc(b.infilename, (int) b.object)) {
terminatetetgen(1);
}
}
if (b.insertaddpoints) {
if (!addin.load_node(b.addinfilename)) {
addin.numberofpoints = 0l;
}
}
if (b.metric) {
if (!bgmin.load_tetmesh(b.bgmeshfilename)) {
bgmin.numberoftetrahedra = 0l;
}
}
// FOR DEBUG -S1 option.
if (b.steiner > 0) {
test_tri_tri(&b, &in);
terminatetetgen(0);
}
if (bgmin.numberoftetrahedra > 0l) {
tetrahedralize(&b, &in, NULL, &addin, &bgmin);
} else {
tetrahedralize(&b, &in, NULL, &addin, NULL);
}
return 0;
#else // with TETLIBRARY
if (!b.parse_commandline(switches)) {
terminatetetgen(1);
}
tetrahedralize(&b, in, out, addin, bgmin);
#endif // not TETLIBRARY
}
#endif // #ifndef mainCXX
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2150,6 +2150,16 @@ algorithm can be quite poor.
@c holes with surfaces in contact with the exterior shell, intersecting
@c primitives, etc.)
@c todo: add section explaining which algorithm to choose in which
@c situation: 2D (robustness: MeshAdapt>Delaunay>Frontal; performance:
@c Delaunay>Frontal>MeshAdapt; element quality:
@c Frontal>Delaunay/MeshAdapt). Tip: for large 2D/plane meshes use
@c Delaunay/or frontal. Most robust algo for complex curved surfaces:
@c meshadapt. 3D: most robust and fastest: Tetgen+Delaunay. But if you
@c need coupling to structured grid: Netgen. In most cases, you should
@c optimize the mesh.
@menu
* Elementary vs physical entities::
* Mesh commands::
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment