From dc5baebc1aeaf5b07440f667d6a0c907e976c27a Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Thu, 1 Jul 2004 18:45:47 +0000 Subject: [PATCH] upgraded Triangle to version 1.5 --- Triangle/README | 17 ++-- Triangle/triangle.c | 230 +++++++++++++++++++++++++++++--------------- doc/gmsh.html | 5 +- 3 files changed, 167 insertions(+), 85 deletions(-) diff --git a/Triangle/README b/Triangle/README index 57a72db937..8570b1e278 100644 --- a/Triangle/README +++ b/Triangle/README @@ -13,9 +13,9 @@ Gmsh if no compensation is received. Triangle A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. -Version 1.4 +Version 1.5 -Copyright 1993, 1995, 1997, 1998, 2002 Jonathan Richard Shewchuk +Copyright 1993, 1995, 1997, 1998, 2002, 2004 Jonathan Richard Shewchuk 2360 Woolsey #H Berkeley, California 94705-1927 Please send bugs and comments to jrs@cs.berkeley.edu @@ -24,10 +24,13 @@ Created as part of the Archimedes project (tools for parallel FEM). Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship. There is no warranty whatsoever. Use at your own risk. -Triangle generates exact Delaunay triangulations, exact constrained -Delaunay triangulations, Voronoi diagrams, and quality conforming Delaunay -triangulations. The latter can be generated with no small angles or large, -and are thus suitable for finite element analysis. + +Triangle generates exact Delaunay triangulations, constrained Delaunay +triangulations, Voronoi diagrams, and quality conforming Delaunay +triangulations. The latter can be generated with no small angles, and are +thus suitable for finite element analysis. Show Me graphically displays +the contents of the geometric files used by Triangle. Show Me can also +write images in PostScript form. Information on the algorithms used by Triangle, including complete references, can be found in the comments at the beginning of the triangle.c @@ -68,4 +71,4 @@ publication, please include an acknowledgment as well. Jonathan Richard Shewchuk -November 2, 2002 +April 27, 2004 diff --git a/Triangle/triangle.c b/Triangle/triangle.c index ad45da7c26..203100baca 100644 --- a/Triangle/triangle.c +++ b/Triangle/triangle.c @@ -11,10 +11,10 @@ /* A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. */ /* (triangle.c) */ /* */ -/* Version 1.4 */ -/* November 1, 2002 */ +/* Version 1.5 */ +/* April 27, 2004 */ /* */ -/* Copyright 1993, 1995, 1997, 1998, 2002 */ +/* Copyright 1993, 1995, 1997, 1998, 2002, 2004 */ /* Jonathan Richard Shewchuk */ /* 2360 Woolsey #H */ /* Berkeley, California 94705-1927 */ @@ -149,6 +149,12 @@ /* lations," International Journal of Computational Geometry & Applica- */ /* tions 5(1-2):193-213, March-June 1995. */ /* */ +/* The method of inserting new vertices off-center (not precisely at the */ +/* circumcenter of every poor-quality triangle) is from Alper Ungor, */ +/* "Off-centers: A New Type of Steiner Points for Computing Size-Optimal */ +/* quality-guaranteed Delaunay triangulations," Proceedings of LATIN */ +/* 2004 (Buenos Aires, Argentina), April 2004. */ +/* */ /* For definitions of and results involving Delaunay triangulations, */ /* constrained and conforming versions thereof, and other aspects of */ /* triangular mesh generation, see the excellent survey by Marshall Bern */ @@ -623,10 +629,11 @@ struct splaynode { /* determines how new records should be aligned in memory. itembytes and */ /* itemwords are the length of a record in bytes (after rounding up) and */ /* words. itemsperblock is the number of items allocated at once in a */ -/* single block. items is the number of currently allocated items. */ -/* maxitems is the maximum number of items that have been allocated at */ -/* once; it is the current number of items plus the number of records kept */ -/* on deaditemstack. */ +/* single block. itemsfirstblock is the number of items in the first */ +/* block, which can vary from the others. items is the number of */ +/* currently allocated items. maxitems is the maximum number of items */ +/* that have been allocated at once; it is the current number of items */ +/* plus the number of records kept on deaditemstack. */ struct memorypool { VOID **firstblock, **nowblock; @@ -638,6 +645,7 @@ struct memorypool { int alignbytes; int itembytes, itemwords; int itemsperblock; + int itemsfirstblock; long items, maxitems; int unallocateditems; int pathitemsleft; @@ -755,6 +763,7 @@ struct behavior { /* quality: -q switch. */ /* minangle: minimum angle bound, specified after -q switch. */ /* goodangle: cosine squared of minangle. */ +/* offconstant: constant used to place off-center Steiner points. */ /* vararea: -a switch without number. */ /* fixedarea: -a switch with number. */ /* maxarea: maximum area bound, specified after -a switch. */ @@ -796,7 +805,7 @@ struct behavior { int order; int nobisect; int steiner; - REAL minangle, goodangle; + REAL minangle, goodangle, offconstant; REAL maxarea; /* Variables for file names. */ @@ -1348,25 +1357,15 @@ int minus1mod3[3] = {2, 0, 1}; #ifdef EXTERNAL_TEST -#ifdef ANSI_DECLARATORS -extern int triunsuitable(vertex triorg, vertex tridest, vertex triapex, - REAL area); -#else /* not ANSI_DECLARATORS */ -extern int triunsuitable(); -#endif /* not ANSI_DECLARATORS */ +int triunsuitable(); #else /* not EXTERNAL_TEST */ -#ifdef ANSI_DECLARATORS -int triunsuitable(vertex triorg, vertex tridest, vertex triapex, REAL area) -#else /* not ANSI_DECLARATORS */ int triunsuitable(triorg, tridest, triapex, area) vertex triorg; /* The triangle's origin vertex. */ vertex tridest; /* The triangle's destination vertex. */ vertex triapex; /* The triangle's apex vertex. */ REAL area; /* The area of the triangle. */ -#endif /* not ANSI_DECLARATORS */ - { REAL dxoa, dxda, dxod; REAL dyoa, dyda, dyod; @@ -1414,7 +1413,7 @@ int size; { VOID *memptr; - memptr = malloc(size); + memptr = malloc((unsigned int) size); if (memptr == (VOID *) NULL) { printf("Error: Out of memory.\n"); exit(1); @@ -1531,8 +1530,9 @@ void info() printf("Triangle\n"); printf( "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n"); - printf("Version 1.4\n\n"); - printf("Copyright 1993, 1995, 1997, 1998, 2002 Jonathan Richard Shewchuk\n"); + printf("Version 1.5\n\n"); + printf( +"Copyright 1993, 1995, 1997, 1998, 2002, 2004 Jonathan Richard Shewchuk\n"); printf("2360 Woolsey #H / Berkeley, California 94705-1927\n"); printf("Bugs/comments to jrs@cs.berkeley.edu\n"); printf( @@ -3111,15 +3111,17 @@ void info() printf( " Marshall Bern, L. Paul Chew, Boris Delaunay, Rex A. Dwyer, David\n"); printf( -" Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E. Knuth, C. L.\n"); +" Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E. Knuth, Charles L.\n" +); printf( " Lawson, Der-Tsai Lee, Ernst P. Mucke, Douglas M. Priest, Jim Ruppert,\n"); printf( " Isaac Saias, Bruce J. Schachter, Micha Sharir, Daniel D. Sleator, Jorge\n"); printf( -" Stolfi, Robert E. Tarjan, Christopher J. Van Wyk, and Binhai Zhu. See\n"); - printf( -" the comments at the beginning of the source code for references.\n"); +" Stolfi, Robert E. Tarjan, Alper Ungor, Christopher J. Van Wyk, and Binhai\n" +); + printf(" Zhu. See the comments at the beginning of the source code for\n"); + printf(" references.\n\n"); exit(0); } @@ -3386,6 +3388,11 @@ struct behavior *b; #endif /* not TRILIBRARY */ b->usesegments = b->poly || b->refine || b->quality || b->convex; b->goodangle = cos(b->minangle * PI / 180.0); + if (b->goodangle == 1.0) { + b->offconstant = 0.0; + } else { + b->offconstant = 0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle)); + } b->goodangle *= b->goodangle; if (b->refine && b->noiterationnum) { printf( @@ -3718,7 +3725,7 @@ struct memorypool *pool; (alignptr + (unsigned long) pool->alignbytes - (alignptr % (unsigned long) pool->alignbytes)); /* There are lots of unallocated items left in this block. */ - pool->unallocateditems = pool->itemsperblock; + pool->unallocateditems = pool->itemsfirstblock; /* The stack of deallocated items is empty. */ pool->deaditemstack = (VOID *) NULL; } @@ -3744,12 +3751,13 @@ struct memorypool *pool; #ifdef ANSI_DECLARATORS void poolinit(struct memorypool *pool, int bytecount, int itemcount, - enum wordtype wtype, int alignment) + int firstitemcount, enum wordtype wtype, int alignment) #else /* not ANSI_DECLARATORS */ -void poolinit(pool, bytecount, itemcount, wtype, alignment) +void poolinit(pool, bytecount, itemcount, firstitemcount, wtype, alignment) struct memorypool *pool; int bytecount; int itemcount; +int firstitemcount; enum wordtype wtype; int alignment; #endif /* not ANSI_DECLARATORS */ @@ -3777,12 +3785,18 @@ int alignment; * (pool->alignbytes / wordsize); pool->itembytes = pool->itemwords * wordsize; pool->itemsperblock = itemcount; + if (firstitemcount == 0) { + pool->itemsfirstblock = itemcount; + } else { + pool->itemsfirstblock = firstitemcount; + } - /* Allocate a block of items. Space for `itemsperblock' items and one */ + /* Allocate a block of items. Space for `itemsfirstblock' items and one */ /* pointer (to point to the next block) are allocated, as well as space */ /* to ensure alignment of the items. */ - pool->firstblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes - + sizeof(VOID *) + pool->alignbytes); + pool->firstblock = (VOID **) + trimalloc(pool->itemsfirstblock * pool->itembytes + (int) sizeof(VOID *) + + pool->alignbytes); /* Set the next block pointer to NULL. */ *(pool->firstblock) = (VOID *) NULL; poolrestart(pool); @@ -3839,11 +3853,13 @@ struct memorypool *pool; if (*(pool->nowblock) == (VOID *) NULL) { /* Allocate a new block of items, pointed to by the previous block. */ newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes + - sizeof(VOID *) + pool->alignbytes); + (int) sizeof(VOID *) + + pool->alignbytes); *(pool->nowblock) = (VOID *) newblock; /* The next block pointer is NULL. */ *newblock = (VOID *) NULL; } + /* Move to the new block. */ pool->nowblock = (VOID **) *(pool->nowblock); /* Find the first item in the block. */ @@ -3856,6 +3872,7 @@ struct memorypool *pool; /* There are lots of unallocated items left in this block. */ pool->unallocateditems = pool->itemsperblock; } + /* Allocate a new item. */ newitem = pool->nextitem; /* Advance `nextitem' pointer to next free item in block. */ @@ -3921,7 +3938,7 @@ struct memorypool *pool; (alignptr + (unsigned long) pool->alignbytes - (alignptr % (unsigned long) pool->alignbytes)); /* Set the number of items left in the current block. */ - pool->pathitemsleft = pool->itemsperblock; + pool->pathitemsleft = pool->itemsfirstblock; } /*****************************************************************************/ @@ -3953,6 +3970,7 @@ struct memorypool *pool; if (pool->pathitem == pool->nextitem) { return (VOID *) NULL; } + /* Check whether any untraversed items remain in the current block. */ if (pool->pathitemsleft == 0) { /* Find the next block. */ @@ -3966,6 +3984,7 @@ struct memorypool *pool; /* Set the number of items left in the current block. */ pool->pathitemsleft = pool->itemsperblock; } + newitem = pool->pathitem; /* Find the next item in the block. */ if (pool->itemwordtype == POINTER) { @@ -4020,8 +4039,9 @@ int subsegwords; unsigned long alignptr; /* Set up `dummytri', the `triangle' that occupies "outer space." */ - m->dummytribase = (triangle *) trimalloc(trianglewords * sizeof(triangle) + - m->triangles.alignbytes); + m->dummytribase = (triangle *) + trimalloc(trianglewords * (int) sizeof(triangle) + + m->triangles.alignbytes); /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */ alignptr = (unsigned long) m->dummytribase; m->dummytri = (triangle *) @@ -4043,7 +4063,7 @@ int subsegwords; /* Set up `dummysub', the omnipresent subsegment pointed to by any */ /* triangle side or subsegment end that isn't attached to a real */ /* subsegment. */ - m->dummysubbase = (subseg *) trimalloc(subsegwords * sizeof(subseg) + + m->dummysubbase = (subseg *) trimalloc(subsegwords * (int) sizeof(subseg) + m->subsegs.alignbytes); /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */ alignptr = (unsigned long) m->dummysubbase; @@ -4108,8 +4128,10 @@ struct behavior *b; sizeof(triangle); vertexsize = (m->vertex2triindex + 1) * sizeof(triangle); } + /* Initialize the pool of vertices. */ poolinit(&m->vertices, vertexsize, VERTEXPERBLOCK, + m->invertices > VERTEXPERBLOCK ? m->invertices : VERTEXPERBLOCK, (sizeof(REAL) >= sizeof(triangle)) ? FLOATINGPOINT : POINTER, 0); } @@ -4165,14 +4187,17 @@ struct behavior *b; (trisize < 6 * sizeof(triangle) + sizeof(int))) { trisize = 6 * sizeof(triangle) + sizeof(int); } + /* Having determined the memory size of a triangle, initialize the pool. */ - poolinit(&m->triangles, trisize, TRIPERBLOCK, POINTER, 4); + poolinit(&m->triangles, trisize, TRIPERBLOCK, + (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2) : + TRIPERBLOCK, POINTER, 4); if (b->usesegments) { /* Initialize the pool of subsegments. Take into account all six */ /* pointers and one boundary marker. */ poolinit(&m->subsegs, 6 * sizeof(triangle) + sizeof(int), SUBSEGPERBLOCK, - POINTER, 4); + SUBSEGPERBLOCK, POINTER, 4); /* Initialize the "outer space" triangle and omnipresent subsegment. */ dummyinit(m, b, m->triangles.itemwords, m->subsegs.itemwords); @@ -4404,11 +4429,17 @@ int number; getblock = m->vertices.firstblock; current = b->firstnumber; + /* Find the right block. */ - while (current + m->vertices.itemsperblock <= number) { + if (current + m->vertices.itemsfirstblock <= number) { getblock = (VOID **) *getblock; - current += m->vertices.itemsperblock; + current += m->vertices.itemsfirstblock; + while (current + m->vertices.itemsperblock <= number) { + getblock = (VOID **) *getblock; + current += m->vertices.itemsperblock; + } } + /* Now find the right vertex. */ alignptr = (unsigned long) (getblock + 1); foundvertex = (vertex) (alignptr + (unsigned long) m->vertices.alignbytes - @@ -6325,9 +6356,11 @@ vertex pd; #ifdef ANSI_DECLARATORS void findcircumcenter(struct mesh *m, struct behavior *b, vertex torg, vertex tdest, vertex tapex, - vertex circumcenter, REAL *xi, REAL *eta, REAL *minedge) + vertex circumcenter, REAL *xi, REAL *eta, REAL *minedge, + int offcenter) #else /* not ANSI_DECLARATORS */ -void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta, minedge) +void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta, minedge, + offcenter) struct mesh *m; struct behavior *b; vertex torg; @@ -6337,13 +6370,14 @@ vertex circumcenter; REAL *xi; REAL *eta; REAL *minedge; +int offcenter; #endif /* not ANSI_DECLARATORS */ { REAL xdo, ydo, xao, yao; REAL dodist, aodist, dadist; REAL denominator; - REAL dx, dy; + REAL dx, dy, dxoff, dyoff; m->circumcentercount++; @@ -6366,26 +6400,66 @@ REAL *minedge; /* Don't count the above as an orientation test. */ m->counterclockcount--; } - circumcenter[0] = torg[0] - (ydo * aodist - yao * dodist) * denominator; - circumcenter[1] = torg[1] + (xdo * aodist - xao * dodist) * denominator; + dx = (yao * dodist - ydo * aodist) * denominator; + dy = (xdo * aodist - xao * dodist) * denominator; + + /* Find the (squared) length of the triangle's shortest edge. This */ + /* serves as a conservative estimate of the insertion radius of the */ + /* circumcenter's parent. The estimate is used to ensure that */ + /* the algorithm terminates even if very small angles appear in */ + /* the input PSLG. */ + if ((dodist < aodist) && (dodist < dadist)) { + *minedge = dodist; + if (offcenter && (b->offconstant > 0.0)) { + /* Find the position of the off-center, as described by Alper Ungor. */ + dxoff = 0.5 * xdo - b->offconstant * ydo; + dyoff = 0.5 * ydo + b->offconstant * xdo; + /* If the off-center is closer to the origin than the */ + /* circumcenter, use the off-center instead. */ + if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) { + dx = dxoff; + dy = dyoff; + } + } + } else if (aodist < dadist) { + *minedge = aodist; + if (offcenter && (b->offconstant > 0.0)) { + dxoff = 0.5 * xao + b->offconstant * yao; + dyoff = 0.5 * yao - b->offconstant * xao; + /* If the off-center is closer to the origin than the */ + /* circumcenter, use the off-center instead. */ + if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) { + dx = dxoff; + dy = dyoff; + } + } + } else { + *minedge = dadist; + if (offcenter && (b->offconstant > 0.0)) { + dxoff = 0.5 * (tapex[0] - tdest[0]) - + b->offconstant * (tapex[1] - tdest[1]); + dyoff = 0.5 * (tapex[1] - tdest[1]) + + b->offconstant * (tapex[0] - tdest[0]); + /* If the off-center is closer to the destination than the */ + /* circumcenter, use the off-center instead. */ + if (dxoff * dxoff + dyoff * dyoff < + (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) { + dx = xdo + dxoff; + dy = ydo + dyoff; + } + } + } + + circumcenter[0] = torg[0] + dx; + circumcenter[1] = torg[1] + dy; /* To interpolate vertex attributes for the new vertex inserted at */ /* the circumcenter, define a coordinate system with a xi-axis, */ /* directed from the triangle's origin to its destination, and */ /* an eta-axis, directed from its origin to its apex. */ /* Calculate the xi and eta coordinates of the circumcenter. */ - dx = circumcenter[0] - torg[0]; - dy = circumcenter[1] - torg[1]; - *xi = (dx * yao - xao * dy) * (2.0 * denominator); - *eta = (xdo * dy - dx * ydo) * (2.0 * denominator); - - /* Find the length of the triangle's shortest edge. This serves as */ - /* a conservative estimate of the insertion radius of the */ - /* circumcenter's parent. The estimate is used to ensure that */ - /* the algorithm terminates even if very small angles appear in */ - /* the input PSLG. */ - *minedge = ((dodist < aodist) && (dodist < dadist)) ? dodist : - (aodist < dadist) ? aodist : dadist; + *xi = (yao * dx - xao * dy) * (2.0 * denominator); + *eta = (xdo * dy - ydo * dx) * (2.0 * denominator); } /** **/ @@ -7692,7 +7766,7 @@ struct otri *searchtri; - (alignptr % (unsigned long) m->triangles.alignbytes)); for (j = 0; j < samplesperblock; j++) { if (i == triblocks - 1) { - samplenum = randomnation((int) + samplenum = randomnation((unsigned int) (m->triangles.maxitems - (i * TRIPERBLOCK))); } else { samplenum = randomnation(TRIPERBLOCK); @@ -9184,7 +9258,7 @@ int arraysize; return; } /* Choose a random pivot to split the array. */ - pivot = (int) randomnation(arraysize); + pivot = (int) randomnation((unsigned int) arraysize); pivotx = sortarray[pivot][0]; pivoty = sortarray[pivot][1]; /* Split the array. */ @@ -9260,7 +9334,7 @@ int axis; return; } /* Choose a random pivot to split the array. */ - pivot = (int) randomnation(arraysize); + pivot = (int) randomnation((unsigned int) arraysize); pivot1 = sortarray[pivot][axis]; pivot2 = sortarray[pivot][1 - axis]; /* Split the array. */ @@ -9947,7 +10021,7 @@ struct behavior *b; } /* Allocate an array of pointers to vertices for sorting. */ - sortarray = (vertex *) trimalloc(m->invertices * sizeof(vertex)); + sortarray = (vertex *) trimalloc(m->invertices * (int) sizeof(vertex)); traversalinit(&m->vertices); for (i = 0; i < m->invertices; i++) { sortarray[i] = vertextraverse(m); @@ -10386,8 +10460,9 @@ struct event **freeevents; int i; maxevents = (3 * m->invertices) / 2; - *eventheap = (struct event **) trimalloc(maxevents * sizeof(struct event *)); - *events = (struct event *) trimalloc(maxevents * sizeof(struct event)); + *eventheap = (struct event **) + trimalloc(maxevents * (int) sizeof(struct event *)); + *events = (struct event *) trimalloc(maxevents * (int) sizeof(struct event)); traversalinit(&m->vertices); for (i = 0; i < m->invertices; i++) { thisvertex = vertextraverse(m); @@ -10773,7 +10848,7 @@ struct behavior *b; triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */ poolinit(&m->splaynodes, sizeof(struct splaynode), SPLAYNODEPERBLOCK, - POINTER, 0); + SPLAYNODEPERBLOCK, POINTER, 0); splayroot = (struct splaynode *) NULL; if (b->verbose) { @@ -11230,7 +11305,8 @@ FILE *polyfile; /* Allocate a temporary array that maps each vertex to some adjacent */ /* triangle. I took care to allocate all the permanent memory for */ /* triangles and subsegments first. */ - vertexarray = (triangle *) trimalloc(m->vertices.items * sizeof(triangle)); + vertexarray = (triangle *) + trimalloc(m->vertices.items * (int) sizeof(triangle)); /* Each vertex is initially unrepresented. */ for (i = 0; i < m->vertices.items; i++) { vertexarray[i] = (triangle) m->dummytri; @@ -12944,13 +13020,15 @@ int regions; if (regions > 0) { /* Allocate storage for the triangles in which region points fall. */ - regiontris = (struct otri *) trimalloc(regions * sizeof(struct otri)); + regiontris = (struct otri *) + trimalloc(regions * (int) sizeof(struct otri)); } if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) { /* Initialize a pool of viri to be used for holes, concavities, */ /* regional attributes, and/or regional area constraints. */ - poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, POINTER, 0); + poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, + POINTER, 0); } if (!b->convex) { @@ -13449,7 +13527,8 @@ struct badtriang *badtri; errorflag = 0; /* Create a new vertex at the triangle's circumcenter. */ newvertex = (vertex) poolalloc(&m->vertices); - findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, &minedge); + findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, &minedge, + 1); /* Check whether the new vertex lies on a triangle vertex. */ if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) || @@ -13558,7 +13637,7 @@ struct behavior *b; } /* Initialize the pool of encroached subsegments. */ poolinit(&m->badsubsegs, sizeof(struct badsubseg), BADSUBSEGPERBLOCK, - POINTER, 0); + BADSUBSEGPERBLOCK, POINTER, 0); if (b->verbose) { printf(" Looking for encroached subsegments.\n"); } @@ -13576,7 +13655,7 @@ struct behavior *b; if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) { /* Initialize the pool of bad triangles. */ poolinit(&m->badtriangles, sizeof(struct badtriang), BADTRIPERBLOCK, - POINTER, 0); + BADTRIPERBLOCK, POINTER, 0); /* Initialize the queues of bad triangles. */ for (i = 0; i < 64; i++) { m->queuefront[i] = (struct badtriang *) NULL; @@ -13586,7 +13665,7 @@ struct behavior *b; tallyfaces(m, b); /* Initialize the pool of recently flipped triangles. */ poolinit(&m->flipstackers, sizeof(struct flipstacker), FLIPSTACKERPERBLOCK, - POINTER, 0); + FLIPSTACKERPERBLOCK, POINTER, 0); m->checkquality = 1; if (b->verbose) { printf(" Splitting bad triangles.\n"); @@ -14124,7 +14203,7 @@ int *regions; stringptr = readline(inputline, polyfile, polyfilename); *holes = (int) strtol(stringptr, &stringptr, 0); if (*holes > 0) { - holelist = (REAL *) trimalloc(2 * *holes * sizeof(REAL)); + holelist = (REAL *) trimalloc(2 * *holes * (int) sizeof(REAL)); *hlist = holelist; for (i = 0; i < 2 * *holes; i += 2) { stringptr = readline(inputline, polyfile, polyfilename); @@ -14155,7 +14234,7 @@ int *regions; stringptr = readline(inputline, polyfile, polyfilename); *regions = (int) strtol(stringptr, &stringptr, 0); if (*regions > 0) { - regionlist = (REAL *) trimalloc(4 * *regions * sizeof(REAL)); + regionlist = (REAL *) trimalloc(4 * *regions * (int) sizeof(REAL)); *rlist = regionlist; index = 0; for (i = 0; i < *regions; i++) { @@ -14954,7 +15033,8 @@ char **argv; org(triangleloop, torg); dest(triangleloop, tdest); apex(triangleloop, tapex); - findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, &dum); + findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, &dum, + 0); #ifdef TRILIBRARY /* X and y coordinates. */ plist[coordindex++] = circumcenter[0]; diff --git a/doc/gmsh.html b/doc/gmsh.html index b013cb5ab2..f377061e73 100644 --- a/doc/gmsh.html +++ b/doc/gmsh.html @@ -257,9 +257,8 @@ the Algorithm Oriented Mesh Database</a>. <p> Gmsh can use Jonathan Shewchuk's <a -href="http://www-2.cs.cmu.edu/~quake/triangle.html">Triangle</a> (<a -href="http://www.cs.berkeley.edu/~jrs/triangle.shar.gz">download</a>) -as an alternative 2D mesh generator and Joachim Schöberl's +href="http://www-2.cs.cmu.edu/~quake/triangle.html">Triangle</a> as an +alternative 2D mesh generator and Joachim Schöberl's <a href="http://www.hpfem.jku.at/netgen">Netgen</a> as an alternative 3D mesh generator/optimizer. -- GitLab