@@ -425,15 +426,15 @@ void *qh_setdelnth(setT *set, int nth) {
setelemT *sizep;
setelemT *elemp, *lastp;
- elemp= (setelemT *)SETelemaddr_(set, nth, void);
sizep= SETsizeaddr_(set);
if ((sizep->i--)==0) /* if was a full set */
- sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
+ sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
if (nth < 0 || nth >= sizep->i) {
qh_fprintf(qhmem.ferr, 6174, "qhull internal error (qh_setdelnth): nth %d is out-of-bounds for set:\n", nth);
qh_setprint(qhmem.ferr, "", set);
qh_errexit(qhmem_ERRqhull, NULL, NULL);
}
+ elemp= (setelemT *)SETelemaddr_(set, nth, void); /* nth valid by QH6174 */
lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
elem= elemp->p;
elemp->p= lastp->p; /* may overwrite itself */
@@ -572,7 +573,7 @@ void **qh_setendpointer(setT *set) {
/*---------------------------------
- qh_setequal( )
+ qh_setequal( setA, setB )
returns 1 if two sorted sets are equal, otherwise returns 0
notes:
@@ -714,7 +715,7 @@ int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB) {
*/
void qh_setfree(setT **setp) {
int size;
- void **freelistp; /* used !qh_NOmem */
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
if (*setp) {
size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
@@ -740,7 +741,7 @@ void qh_setfree(setT **setp) {
free each element
free set
*/
-void qh_setfree2 (setT **setp, int elemsize) {
+void qh_setfree2(setT **setp, int elemsize) {
void *elem, **elemp;
FOREACHelem_(*setp)
@@ -882,7 +883,7 @@ void qh_setlarger(setT **oldsetp) {
/*---------------------------------
- qh_setlast( )
+ qh_setlast( set )
return last element of set or NULL (use type conversion)
notes:
@@ -922,9 +923,9 @@ void *qh_setlast(setT *set) {
*/
setT *qh_setnew(int setsize) {
setT *set;
- int sizereceived; /* used !qh_NOmem */
+ int sizereceived; /* used if !qh_NOmem */
int size;
- void **freelistp; /* used !qh_NOmem */
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
if (!setsize)
setsize++;
@@ -1244,10 +1245,10 @@ setT *qh_settemppop(void) {
append set to tempstack
*/
void qh_settemppush(setT *set) {
- if (!set) {
- fprintf (qhmem.ferr, "qhull error (qh_settemppush): can not push a NULL temp\n");
- qh_errexit (qhmem_ERRqhull, NULL, NULL);
- }
+ if (!set) {
+ qh_fprintf(qhmem.ferr, 6267, "qhull error (qh_settemppush): can not push a NULL temp\n");
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
qh_setappend(&qhmem.tempstack, set);
if (qhmem.IStracing >= 5)
qh_fprintf(qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n",
@@ -1335,3 +1336,5 @@ void qh_setzero(setT *set, int idx, int size) {
count= size - idx + 1; /* +1 for NULL terminator */
memset((char *)SETelemaddr_(set, idx, void), 0, (size_t)count * SETelemsize);
} /* setzero */
+
+
diff --git a/extern/qhull/qset.h b/extern/libqhull/qset.h
similarity index 98%
rename from extern/qhull/qset.h
rename to extern/libqhull/qset.h
index 759b501a8017..7e4e7d14f6b9 100644
--- a/extern/qhull/qset.h
+++ b/extern/libqhull/qset.h
@@ -16,9 +16,9 @@
- every set is NULL terminated
- sets may be sorted or unsorted, the caller must distinguish this
- Copyright (c) 1993-2012 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhull/qset.h#4 $$Change: 1464 $
- $DateTime: 2012/01/25 22:58:41 $$Author: bbarber $
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/qset.h#2 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
*/
#ifndef qhDEFset
@@ -33,6 +33,8 @@
typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
#endif
+/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
+
/*------------------------------------------
@@ -459,10 +461,10 @@ void *qh_setdelnth(setT *set, int nth);
void *qh_setdelnthsorted(setT *set, int nth);
void *qh_setdelsorted(setT *set, void *newelem);
setT *qh_setduplicate( setT *set, int elemsize);
+void **qh_setendpointer(setT *set);
int qh_setequal(setT *setA, setT *setB);
int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
-void **qh_setendpointer(setT *set);
void qh_setfree(setT **set);
void qh_setfree2( setT **setp, int elemsize);
void qh_setfreelong(setT **set);
diff --git a/extern/qhull/random.c b/extern/libqhull/random.c
similarity index 91%
rename from extern/qhull/random.c
rename to extern/libqhull/random.c
index 21b15025afd6..176d697aeb5a 100644
--- a/extern/qhull/random.c
+++ b/extern/libqhull/random.c
@@ -1,14 +1,16 @@
/* ---------------------------------
- random.c -- utilities
+ random.c and utilities
Park & Miller's minimimal standard random number generator
argc/argv conversion
- Used by rbox. Do not use 'qh'
+ Used by rbox. Do not use 'qh'
*/
#include "libqhull.h"
+#include "random.h"
+
#include
#include
#include
@@ -138,7 +140,7 @@ int qh_argv_to_command_size(int argc, char *argv[]) {
/* Global variables and constants */
-int qh_rand_seed= 1; /* define as global variable instead of using qh */
+int qh_last_random= 1; /* define as global variable instead of using qh */
#define qh_rand_a 16807
#define qh_rand_m 2147483647
@@ -147,7 +149,7 @@ int qh_rand_seed= 1; /* define as global variable instead of using qh */
int qh_rand( void) {
int lo, hi, test;
- int seed = qh_rand_seed;
+ int seed = qh_last_random;
hi = seed / qh_rand_q; /* seed div q */
lo = seed % qh_rand_q; /* seed mod q */
@@ -156,7 +158,7 @@ int qh_rand( void) {
seed= test;
else
seed= test + qh_rand_m;
- qh_rand_seed= seed;
+ qh_last_random= seed;
/* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
/* seed = qh_RANDOMmax; for testing */
return seed;
@@ -164,21 +166,21 @@ int qh_rand( void) {
void qh_srand( int seed) {
if (seed < 1)
- qh_rand_seed= 1;
+ qh_last_random= 1;
else if (seed >= qh_rand_m)
- qh_rand_seed= qh_rand_m - 1;
+ qh_last_random= qh_rand_m - 1;
else
- qh_rand_seed= seed;
+ qh_last_random= seed;
} /* qh_srand */
/*---------------------------------
qh_randomfactor( scale, offset )
-return a random factor r * scale + offset
+ return a random factor r * scale + offset
notes:
-qh.RANDOMa/b are defined in global.c
+ qh.RANDOMa/b are defined in global.c
*/
realT qh_randomfactor(realT scale, realT offset) {
realT randr;
@@ -191,13 +193,13 @@ realT qh_randomfactor(realT scale, realT offset) {
>--------------------------------
qh_randommatrix( buffer, dim, rows )
-generate a random dim X dim matrix in range [-1,1]
-assumes buffer is [dim+1, dim]
+ generate a random dim X dim matrix in range [-1,1]
+ assumes buffer is [dim+1, dim]
returns:
-sets buffer to random numbers
-sets rows to rows of buffer
-sets row[dim] as scratch row
+ sets buffer to random numbers
+ sets rows to rows of buffer
+ sets row[dim] as scratch row
*/
void qh_randommatrix(realT *buffer, int dim, realT **rows) {
int i, k;
diff --git a/extern/qhull/random.h b/extern/libqhull/random.h
similarity index 77%
rename from extern/qhull/random.h
rename to extern/libqhull/random.h
index e1e29270419a..0c6896b76549 100644
--- a/extern/qhull/random.h
+++ b/extern/libqhull/random.h
@@ -2,13 +2,13 @@
>--------------------------------
random.h
- header file for random routines
+ header file for random and utility routines
see qh-geom.htm and random.c
- Copyright (c) 1993-2012 The Geometry Center.
- $Id: //main/2011/qhull/src/libqhull/random.h#3 $$Change: 1464 $
- $DateTime: 2012/01/25 22:58:41 $$Author: bbarber $
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/random.h#2 $$Change: 2026 $
+ $DateTime: 2015/11/07 22:44:39 $$Author: bbarber $
*/
#ifndef qhDEFrandom
@@ -29,3 +29,6 @@ int qh_strtol(const char *s, char **endp);
double qh_strtod(const char *s, char **endp);
#endif /* qhDEFrandom */
+
+
+
diff --git a/extern/qhull/rboxlib.c b/extern/libqhull/rboxlib.c
similarity index 75%
rename from extern/qhull/rboxlib.c
rename to extern/libqhull/rboxlib.c
index 0122563f7062..f945133fa0b7 100644
--- a/extern/qhull/rboxlib.c
+++ b/extern/libqhull/rboxlib.c
@@ -12,8 +12,8 @@
incorrect range if qh_RANDOMmax is defined wrong (user.h)
*/
+#include "libqhull.h" /* First for user.h */
#include "random.h"
-#include "libqhull.h"
#include
#include
@@ -33,10 +33,12 @@
#define PI 3.1415926535897932384
/* ------------------------------ prototypes ----------------*/
-int roundi( double a);
-void out1( double a);
-void out2n( double a, double b);
-void out3n( double a, double b, double c);
+int qh_roundi( double a);
+void qh_out1( double a);
+void qh_out2n( double a, double b);
+void qh_out3n( double a, double b, double c);
+void qh_outcoord(int iscdd, double *coord, int dim);
+void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim);
void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
void qh_free(void *mem);
@@ -55,6 +57,7 @@ struct rboxT {
int isinteger;
double out_offset;
jmp_buf errexit; /* exit label for rboxpoints, defined by setjmp(), called by qh_errexit_rbox() */
+ char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
};
@@ -75,8 +78,7 @@ rboxT rbox;
5 (qh_ERRqhull) on internal error
notes:
- To avoid stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
- Rbox is not multithreaded.
+ To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
design:
Straight line code (consider defining a struct and functions):
@@ -88,18 +90,19 @@ rboxT rbox;
int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
int i,j,k;
int gendim;
+ int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
int cubesize, diamondsize, seed=0, count, apex;
- int dim=3 , numpoints= 0, totpoints, addpoints=0;
- int issphere=0, isaxis=0, iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
- int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0;
+ int dim=3, numpoints=0, totpoints, addpoints=0;
+ int issphere=0, isaxis=0, iscdd=0, islens=0, isregular=0, iswidth=0, addcube=0;
+ int isgap=0, isspiral=0, NOcommand=0, adddiamond=0;
int israndom=0, istime=0;
int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
- double width=0.0, gap=0.0, radius= 0.0;
+ double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
- double *simplex= NULL, *simplexp;
+ double *coordp, *simplex= NULL, *simplexp;
int nthroot, mult[MAXdim];
- double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
- double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
+ double norm, factor, randr, rangap, lensangle=0, lensbase=1;
+ double anglediff, angle, x, y, cube=0.0, diamond=0.0;
double box= qh_DEFAULTbox; /* scale all numbers before output */
double randmax= qh_RANDOMmax;
char command[200], seedbuf[200];
@@ -117,7 +120,7 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
exitcode= setjmp(rbox.errexit);
if (exitcode) {
- /* same code for error exit and normal return */
+ /* same code for error exit and normal return. qh.NOerrexit is set */
if (simplex)
qh_free(simplex);
rbox_inuse= False;
@@ -194,6 +197,30 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
box= qh_strtod(s, &s);
isbox= 1;
break;
+ case 'C':
+ if (*s)
+ coincidentpoints= qh_strtol(s, &s);
+ if (*s == ',') {
+ ++s;
+ coincidentradius= qh_strtod(s, &s);
+ }
+ if (*s == ',') {
+ ++s;
+ coincidenttotal= qh_strtol(s, &s);
+ }
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(rbox.ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidentpoints==0){
+ qh_fprintf_rbox(rbox.ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
+ qh_fprintf_rbox(rbox.ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ break;
case 'D':
dim= qh_strtol(s, &s);
if (dim < 1
@@ -313,6 +340,12 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
qh_fprintf_rbox(rbox.ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
qh_errexit_rbox(qh_ERRinput);
}
+ if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
+ qh_fprintf_rbox(rbox.ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidenttotal == 0)
+ coincidenttotal= numpoints;
/* ============= print header with total points =============== */
if (issimplex || ismesh)
@@ -335,6 +368,7 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
}else
totpoints= numpoints + isaxis;
totpoints += cubesize + diamondsize + addpoints;
+ totpoints += coincidentpoints*coincidenttotal;
/* ============= seed randoms =============== */
if (istime == 0) {
@@ -365,6 +399,7 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
else if (NOcommand)
qh_fprintf_rbox(rbox.fout, 9392, "%d\n%d\n", dim, totpoints);
else
+ /* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
qh_fprintf_rbox(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
/* ============= explicit points =============== */
@@ -372,9 +407,9 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
while (s && *s) { /* 'P' */
count= 0;
if (iscdd)
- out1( 1.0);
+ qh_out1( 1.0);
while (*++s) {
- out1( qh_strtod(s, &s));
+ qh_out1( qh_strtod(s, &s));
count++;
if (isspace(*s) || !*s)
break;
@@ -385,7 +420,7 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
}
if (count < dim) {
for (k=dim-count; k--; )
- out1( 0.0);
+ qh_out1( 0.0);
}else if (count > dim) {
qh_fprintf_rbox(rbox.ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
count, dim, s);
@@ -425,9 +460,9 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
simplexp= simplex;
for (i=0; i=0; k--) {
if (j & ( 1 << k))
- out1( cube);
+ qh_out1( cube);
else
- out1( -cube);
+ qh_out1( -cube);
}
qh_fprintf_rbox(rbox.fout, 9400, "\n");
}
@@ -722,14 +763,14 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
if (adddiamond) {
for (j=0; j=0; k--) {
if (j/2 != k)
- out1( 0.0);
+ qh_out1( 0.0);
else if (j & 0x1)
- out1( diamond);
+ qh_out1( diamond);
else
- out1( -diamond);
+ qh_out1( -diamond);
}
qh_fprintf_rbox(rbox.fout, 9401, "\n");
}
@@ -739,16 +780,15 @@ int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
qh_fprintf_rbox(rbox.fout, 9402, "end\nhull\n");
/* same code for error exit and normal return */
- if (simplex)
- qh_free(simplex);
+ qh_free(simplex);
rbox_inuse= False;
return qh_ERRnone;
} /* rboxpoints */
/*------------------------------------------------
-outxxx - output functions
+outxxx - output functions for qh_rboxpoints
*/
-int roundi( double a) {
+int qh_roundi( double a) {
if (a < 0.0) {
if (a - 0.5 < INT_MIN) {
qh_fprintf_rbox(rbox.ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
@@ -762,33 +802,69 @@ int roundi( double a) {
}
return (int)(a + 0.5);
}
-} /* roundi */
+} /* qh_roundi */
-void out1(double a) {
+void qh_out1(double a) {
if (rbox.isinteger)
- qh_fprintf_rbox(rbox.fout, 9403, "%d ", roundi( a+rbox.out_offset));
+ qh_fprintf_rbox(rbox.fout, 9403, "%d ", qh_roundi( a+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset);
-} /* out1 */
+} /* qh_out1 */
-void out2n( double a, double b) {
+void qh_out2n( double a, double b) {
if (rbox.isinteger)
- qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset));
+ qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset);
-} /* out2n */
+} /* qh_out2n */
-void out3n( double a, double b, double c) {
+void qh_out3n( double a, double b, double c) {
if (rbox.isinteger)
- qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", roundi(a+rbox.out_offset), roundi(b+rbox.out_offset), roundi(c+rbox.out_offset));
+ qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset), qh_roundi(c+rbox.out_offset));
else
qh_fprintf_rbox(rbox.fout, 9408, qh_REAL_3n, a+rbox.out_offset, b+rbox.out_offset, c+rbox.out_offset);
-} /* out3n */
+} /* qh_out3n */
+
+void qh_outcoord(int iscdd, double *coord, int dim) {
+ double *p= coord;
+ int k;
+
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=0; k < dim; k++)
+ qh_out1(*(p++));
+ qh_fprintf_rbox(rbox.fout, 9396, "\n");
+} /* qh_outcoord */
+
+void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
+ double *p;
+ double randr, delta;
+ int i,k;
+ double randmax= qh_RANDOMmax;
+
+ for (i= 0; i= ZEND, printed, or same as initial value
*/
-void qh_printstatlevel(FILE *fp, int id, int start) {
+void qh_printstatlevel(FILE *fp, int id) {
#define NULLfield " "
if (id >= ZEND || qhstat printed[id])
@@ -640,7 +644,6 @@ void qh_printstatlevel(FILE *fp, int id, int start) {
qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]);
return;
}
- start= 0; /* not used */
if (qh_nostatistic(id) || !qhstat doc[id])
return;
qhstat printed[id]= True;
@@ -674,7 +677,7 @@ void qh_printstats(FILE *fp, int idx, int *nextindex) {
if (qh_newstats(idx, &nexti)) {
qh_fprintf(fp, 9367, "\n");
for (j=idx; j
/*---------------------------------
+ >--------------------------------
- qh_call_qhull( void )
- template for calling qhull from inside your program
- remove #if 0, #endif to compile
+ Qhull-template
+ Template for calling qhull from inside your program
returns:
exit code(see qh_ERR... in libqhull.h)
@@ -57,10 +56,6 @@
notes:
This can be called any number of times.
-
- see:
- qh_call_qhull_once()
-
*/
#if 0
{
@@ -76,12 +71,14 @@
facetT *facet; /* set by FORALLfacets */
int curlong, totlong; /* memory remaining after qh_memfreeshort */
+ QHULL_LIB_CHECK /* Check for compatible library */
+
#if qh_QHpointer /* see user.h */
- if (qh_qh){
- printf ("QH6238: Qhull link error. The global variable qh_qh was not initialized\n\
+ if (qh_qh){ /* should be NULL */
+ qh_printf_stderr(6238, "Qhull link error. The global variable qh_qh was not initialized\n\
to NULL by global.c. Please compile this program with -Dqh_QHpointer_dllimport\n\
as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
- exit -1;
+ exit(1);
}
#endif
@@ -106,6 +103,7 @@
qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
build new qhull data structure and return exitcode (0 if no errors)
+ if numpoints=0 and points=NULL, initializes qhull
notes:
do not modify points until finished with results.
@@ -113,7 +111,7 @@
do not call qhull functions before qh_new_qhull().
The qhull data structure is not initialized until qh_new_qhull().
- outfile may be null
+ Default errfile is stderr, outfile may be null
qhull_cmd must start with "qhull "
projects points to a new point array for Delaunay triangulations ('d' and 'v')
transforms points into a new point array for halfspace intersection ('H')
@@ -125,7 +123,8 @@
- use qh_freeqhull(qh_ALL) to free intermediate convex hulls
see:
- user_eg.c for an example
+ Qhull-template at the beginning of this file.
+ An example of using qh_new_qhull is user_eg.c
*/
int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
char *qhull_cmd, FILE *outfile, FILE *errfile) {
@@ -134,15 +133,24 @@ int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
static boolT firstcall = True;
coordT *new_points;
+ if(!errfile){
+ errfile= stderr;
+ }
if (firstcall) {
qh_meminit(errfile);
firstcall= False;
+ } else {
+ qh_memcheck();
}
- if (strncmp(qhull_cmd,"qhull ", (size_t)6)) {
+ if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
qh_fprintf(errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
- qh_exit(qh_ERRinput);
+ return qh_ERRinput;
}
qh_initqhull_start(NULL, outfile, errfile);
+ if(numpoints==0 && points==NULL){
+ trace1((qh ferr, 1047, "qh_new_qhull: initialize Qhull\n"));
+ return 0;
+ }
trace1((qh ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
exitcode = setjmp(qh errexit);
if (!exitcode)
@@ -246,11 +254,12 @@ void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
else if (exitcode == qh_ERRprec && !qh PREmerge)
qh_printhelp_degenerate(qh ferr);
if (qh NOerrexit) {
- qh_fprintf(qh ferr, 6187, "qhull error while ending program. Exit program\n");
+ qh_fprintf(qh ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
qh_exit(qh_ERRqhull);
}
qh ERREXITcalled= False;
qh NOerrexit= True;
+ qh ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
longjmp(qh errexit, exitcode);
} /* errexit */
@@ -446,7 +455,7 @@ The center point is coplanar with a facet, or a vertex is coplanar\n\
with a neighboring facet. The maximum round off error for\n\
computing distances is %2.2g. The center point, facets and distances\n\
to the center point are as follows:\n\n", qh DISTround);
- qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, -1);
+ qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, qh_IDunknown);
qh_fprintf(fp, 9378, "\n");
FORALLfacets {
qh_fprintf(fp, 9379, "facet");
@@ -523,3 +532,5 @@ void qh_user_memsizes(void) {
/* qh_memsize(size); */
} /* user_memsizes */
+
+
diff --git a/extern/qhull/user.h b/extern/libqhull/user.h
similarity index 91%
rename from extern/qhull/user.h
rename to extern/libqhull/user.h
index 45b3202696a3..523aa7b4e842 100644
--- a/extern/qhull/user.h
+++ b/extern/libqhull/user.h
@@ -4,8 +4,11 @@
user.h
user redefinable constants
+ for each source file, user.h is included first
see qh-user.htm. see COPYING for copyright information.
+ See user.c for sample code.
+
before reading any code, review libqhull.h for data structure definitions and
the "qh" macro.
@@ -29,6 +32,12 @@ Code flags --
#ifndef qhDEFuser
#define qhDEFuser 1
+/* Derived from Qt's corelib/global/qglobal.h */
+#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
+# define QHULL_OS_WIN
+#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
+# define QHULL_OS_WIN
+#endif
/*============================================================*/
/*============= qhull library constants ======================*/
/*============================================================*/
@@ -47,10 +56,11 @@ Code flags --
msgcode -- Unique message codes for qh_fprintf
- If add new messages, assign these values and increment.
+ If add new messages, assign these values and increment in user.h and user_r.h
+ See QhullError.h for 10000 errors.
- def counters = [27, 1047, 2059, 3025, 4068, 5003,
- 6241, 7079, 8143, 9410, 10000, 11026]
+ def counters = [27, 1048, 2059, 3026, 4068, 5003,
+ 6273, 7081, 8147, 9411, 10000, 11029]
See: qh_ERR* [libqhull.h]
*/
@@ -65,7 +75,7 @@ Code flags --
#define MSG_WARNING 7000
#define MSG_STDERR 8000 /* log messages Written to qh.ferr */
#define MSG_OUTPUT 9000
-#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError [QhullError.h] */
+#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
#define MSG_FIXUP 11000 /* FIXUP QH11... */
#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
@@ -374,7 +384,7 @@ stop after qh_JOGGLEmaxretry attempts
total hash slots / used hash slots. Must be at least 1.1.
notes:
- =2 for at worst 50% occupancy for qh hash_table and normally 25% occupancy
+ =2 for at worst 50% occupancy for qh.hash_table and normally 25% occupancy
*/
#define qh_HASHfactor 2
@@ -429,7 +439,7 @@ stop after qh_JOGGLEmaxretry attempts
do not occur in data structures and pointers are the same size. Be careful
of machines (e.g., DEC Alpha) with large pointers.
- If using gcc, best alignment is
+ If using gcc, best alignment is [fmax_() is defined in geom_r.h]
#define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
*/
#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
@@ -489,9 +499,11 @@ stop after qh_JOGGLEmaxretry attempts
__MSC_VER
defined by Microsoft Visual C++
- __MWERKS__ && __POWERPC__
- defined by Metrowerks when compiling for the Power Macintosh
+ __MWERKS__ && __INTEL__
+ defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
+ __MWERKS__ && __POWERPC__
+ defined by Metrowerks when compiling for PowerPC-based Macintosh
__STDC__
defined for strict ANSI C
*/
@@ -585,14 +597,12 @@ stop after qh_JOGGLEmaxretry attempts
It is required for msvc-2005. It is not needed for gcc.
notes:
+ [jan'16] qh_QHpointer is deprecated for Qhull. Use libqhull_r instead.
all global variables for qhull are in qh, qhmem, and qhstat
qh is defined in libqhull.h
qhmem is defined in mem.h
qhstat is defined in stat.h
- C++ build defines qh_QHpointer [libqhullp.pro, libqhullcpp.pro]
- see:
- user_eg.c for an example
*/
#ifdef qh_QHpointer
#if qh_dllimport
@@ -805,6 +815,19 @@ stop after qh_JOGGLEmaxretry attempts
*/
#define qh_WIDEcoplanar 6
+/*----------------------------------
+
+ qh_WIDEduplicate
+ Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
+ Override with option Q12 no-wide-duplicate
+
+ Notes:
+ Merging a duplicate ridge can lead to very wide facets.
+ A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
+*/
+#define qh_WIDEduplicate 100
+
/*----------------------------------
@@ -852,4 +875,35 @@ stop after qh_JOGGLEmaxretry attempts
*/
#define qh_ZEROdelaunay 2
+/*============================================================*/
+/*============= Microsoft DevStudio ==========================*/
+/*============================================================*/
+
+/*
+ Finding Memory Leaks Using the CRT Library
+ https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
+
+ Reports enabled in qh_lib_check for Debug window and stderr
+
+ From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
+
+ Watch: {,,msvcr80d.dll}_crtBreakAlloc Value from {n} in the leak report
+ _CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
+
+ Examples
+ http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
+ https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
+*/
+#if 0 /* off (0) by default for QHULL_CRTDBG */
+#define QHULL_CRTDBG
+#endif
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
+#define _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
#endif /* qh_DEFuser */
+
+
+
diff --git a/extern/qhull/usermem.c b/extern/libqhull/usermem.c
similarity index 55%
rename from extern/qhull/usermem.c
rename to extern/libqhull/usermem.c
index 722c0b42f871..0e99e8f66c18 100644
--- a/extern/qhull/usermem.c
+++ b/extern/libqhull/usermem.c
@@ -13,13 +13,14 @@
See libqhull.h for data structures, macros, and user-callable functions.
See user.c for qhull-related, redefinable functions
see user.h for user-definable constants
- See userprintf.c for qh_fprintf and userprintf_rbox,c for qh_fprintf_rbox
+ See userprintf.c for qh_fprintf and userprintf_rbox.c for qh_fprintf_rbox
Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull.h"
+#include
#include
/*---------------------------------
+
+ qh_fprintf_stderr( msgcode, format, list of args )
+ fprintf to stderr with msgcode (non-zero)
+
+ notes:
+ qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
+
+ It is typically followed by qh_errexit().
+
+ Redefine this function to avoid using stderr
+
+ Use qh_fprintf [userprintf.c] for normal printing
+*/
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ va_start(args, fmt);
+ if(msgcode)
+ fprintf(stderr, "QH%.4d ", msgcode);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+} /* fprintf_stderr */
+
/*---------------------------------
-qh_free( mem )
-free memory
+ qh_free( mem )
+ free memory
-notes:
-same as free()
+ notes:
+ same as free()
+ No calls to qh_errexit()
*/
void qh_free(void *mem) {
free(mem);
@@ -60,3 +90,5 @@ void qh_free(void *mem) {
void *qh_malloc(size_t size) {
return malloc(size);
} /* malloc */
+
+
diff --git a/extern/qhull/userprintf.c b/extern/libqhull/userprintf.c
similarity index 86%
rename from extern/qhull/userprintf.c
rename to extern/libqhull/userprintf.c
index d6c245b217b4..190d7cd79b3b 100644
--- a/extern/qhull/userprintf.c
+++ b/extern/libqhull/userprintf.c
@@ -19,6 +19,7 @@
*/
#include "libqhull.h"
+#include "mem.h"
#include
#include
@@ -35,13 +36,15 @@
same as fprintf()
fgets() is not trapped like fprintf()
exit qh_fprintf via qh_errexit()
+ may be called for errors in qh_initstatistics and qh_meminit
*/
void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
- fprintf(stderr, "QH6232 Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf called.\n");
+ /* could use qhmem.ferr, but probably better to be cautious */
+ qh_fprintf_stderr(6232, "Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf called.\n");
qh_errexit(6232, NULL, NULL);
}
va_start(args, fmt);
@@ -60,3 +63,4 @@ void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
/* Place debugging traps here. Use with option 'Tn' */
} /* qh_fprintf */
+
diff --git a/extern/qhull/userprintf_rbox.c b/extern/libqhull/userprintf_rbox.c
similarity index 92%
rename from extern/qhull/userprintf_rbox.c
rename to extern/libqhull/userprintf_rbox.c
index 0e1a12ac3f34..8edd2001aa5c 100644
--- a/extern/qhull/userprintf_rbox.c
+++ b/extern/libqhull/userprintf_rbox.c
@@ -41,7 +41,7 @@ void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
- fprintf(stderr, "QH6231 Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
+ qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
qh_errexit_rbox(6231);
}
if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
@@ -50,3 +50,4 @@ void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
vfprintf(fp, fmt, args);
va_end(args);
} /* qh_fprintf_rbox */
+
diff --git a/setupext.py b/setupext.py
index 0a31d074af58..a53ce2edf101 100644
--- a/setupext.py
+++ b/setupext.py
@@ -1313,14 +1313,14 @@ def check(self):
self.__class__.found_external = True
try:
return self._check_for_pkg_config(
- 'qhull', 'qhull/qhull_a.h', min_version='2003.1')
+ 'libqhull', 'libqhull/qhull_a.h', min_version='2015.2')
except CheckFailed as e:
self.__class__.found_pkgconfig = False
# Qhull may not be in the pkg-config system but may still be
# present on this system, so check if the header files can be
# found.
include_dirs = [
- os.path.join(x, 'qhull') for x in get_include_dirs()]
+ os.path.join(x, 'libqhull') for x in get_include_dirs()]
if has_include_file(include_dirs, 'qhull_a.h'):
return 'Using system Qhull (version unknown, no pkg-config info)'
else:
@@ -1333,7 +1333,7 @@ def add_flags(self, ext):
default_libraries=['qhull'])
else:
ext.include_dirs.append('extern')
- ext.sources.extend(glob.glob('extern/qhull/*.c'))
+ ext.sources.extend(glob.glob('extern/libqhull/*.c'))
class TTConv(SetupPackage):
diff --git a/src/qhull_wrap.c b/src/qhull_wrap.c
index 06d278ebdd57..38779441b4fd 100644
--- a/src/qhull_wrap.c
+++ b/src/qhull_wrap.c
@@ -7,7 +7,7 @@
*/
#include "Python.h"
#include "numpy/noprefix.h"
-#include "qhull/qhull_a.h"
+#include "libqhull/qhull_a.h"
#include
@@ -109,6 +109,8 @@ delaunay_impl(int npoints, const double* x, const double* y,
int* triangles_ptr;
int* neighbors_ptr;
+ QHULL_LIB_CHECK
+
/* Allocate points. */
points = (coordT*)malloc(npoints*ndim*sizeof(coordT));
if (points == NULL) {