📄 global.c
字号:
/*<html><pre> -<a href="qh-globa.htm"
>-------------------------------</a><a name="TOP">-</a>
global.c
initializes all the globals of the qhull application
see README
see qhull.h for qh.globals and function prototypes
see qhull_a.h for internal functions
copyright (c) 1993-2003, The Geometry Center
*/
#include "qhull_a.h"
/*========= qh definition (see qhull.h) =======================*/
#if qh_QHpointer
qhT *qh_qh= NULL; /* pointer to all global variables */
#else
qhT qh_qh; /* all global variables.
Add "= {0}" if this causes a compiler error.
Also qh_qhstat in stat.c and qhmem in mem.c. */
#endif
/*-<a href ="qh-globa.htm#TOC"
>--------------------------------</a><a name="qh_version">-</a>
qh_version
version string by year and date
the revision increases on code changes only
notes:
change date: Changes.txt, Announce.txt, README.txt,
qhull.man, qhull.txt, qhull-news.html, Eudora signatures,
change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt
change year: Copying.txt
check download size
recompile user_eg.c, rbox.c, qhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c
*/
char *qh_version = "2003.1 2003/12/30";
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="appendprint">-</a>
qh_appendprint( printFormat )
append printFormat to qh.PRINTout unless already defined
*/
void qh_appendprint (qh_PRINT format) {
int i;
for (i=0; i < qh_PRINTEND; i++) {
if (qh PRINTout[i] == format && format != qh_PRINTqhull)
break;
if (!qh PRINTout[i]) {
qh PRINTout[i]= format;
break;
}
}
} /* appendprint */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="checkflags">-</a>
qh_checkflags( commandStr, hiddenFlags )
errors if commandStr contains hiddenFlags
hiddenFlags starts and ends with a space and is space deliminated (checked)
notes:
ignores first word (e.g., "qconvex i")
use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
see:
qh_initflags() initializes Qhull according to commandStr
*/
void qh_checkflags(char *command, char *hiddenflags) {
char *s= command, *t, *chkerr, key, opt, prevopt;
char chkkey[]= " ";
char chkopt[]= " ";
char chkopt2[]= " ";
if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
qh_errexit(qh_ERRinput, NULL, NULL);
}
if (strpbrk(hiddenflags, ",\n\r\t")) {
fprintf(qh ferr, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
qh_errexit(qh_ERRinput, NULL, NULL);
}
while (*s && !isspace(*s)) /* skip program name */
s++;
while (*s) {
while (*s && isspace(*s))
s++;
if (*s == '-')
s++;
if (!*s)
break;
key = *s++;
chkerr = NULL;
if (key == '\'') { /* TO 'file name' */
t= strchr(s, '\'');
if (!t) {
fprintf(qh ferr, "qhull error (qh_checkflags): missing the 2nd single-quote for:\n%s\n", s-1);
qh_errexit(qh_ERRinput, NULL, NULL);
}
s= t+1;
continue;
}
chkkey[1]= key;
if (strstr(hiddenflags, chkkey)) {
chkerr= chkkey;
}else if (isupper(key)) {
opt= ' ';
prevopt= ' ';
chkopt[1]= key;
chkopt2[1]= key;
while (!chkerr && *s && !isspace(*s)) {
opt= *s++;
if (isalpha(opt)) {
chkopt[2]= opt;
if (strstr(hiddenflags, chkopt))
chkerr= chkopt;
if (prevopt != ' ') {
chkopt2[2]= prevopt;
chkopt2[3]= opt;
if (strstr(hiddenflags, chkopt2))
chkerr= chkopt2;
}
}else if (key == 'Q' && isdigit(opt) && prevopt != 'b'
&& (prevopt == ' ' || islower(prevopt))) {
chkopt[2]= opt;
if (strstr(hiddenflags, chkopt))
chkerr= chkopt;
}else {
qh_strtod (s-1, &t);
if (s < t)
s= t;
}
prevopt= opt;
}
}
if (chkerr) {
*chkerr= '\'';
chkerr[strlen(chkerr)-1]= '\'';
fprintf(qh ferr, "qhull error: option %s is not used with this program.\n It may be used with qhull.\n", chkerr);
qh_errexit(qh_ERRinput, NULL, NULL);
}
}
} /* checkflags */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="clock">-</a>
qh_clock()
return user CPU time in 100ths (qh_SECtick)
only defined for qh_CLOCKtype == 2
notes:
use first value to determine time 0
from Stevens '92 8.15
*/
unsigned long qh_clock (void) {
#if (qh_CLOCKtype == 2)
struct tms time;
static long clktck; /* initialized first call */
double ratio, cpu;
unsigned long ticks;
if (!clktck) {
if ((clktck= sysconf (_SC_CLK_TCK)) < 0) {
fprintf (qh ferr, "qhull internal error (qh_clock): sysconf() failed. Use qh_CLOCKtype 1 in user.h\n");
qh_errexit (qh_ERRqhull, NULL, NULL);
}
}
if (times (&time) == -1) {
fprintf (qh ferr, "qhull internal error (qh_clock): times() failed. Use qh_CLOCKtype 1 in user.h\n");
qh_errexit (qh_ERRqhull, NULL, NULL);
}
ratio= qh_SECticks / (double)clktck;
ticks= time.tms_utime * ratio;
return ticks;
#else
fprintf (qh ferr, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
qh_errexit (qh_ERRqhull, NULL, NULL); /* never returns */
return 0;
#endif
} /* clock */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuffers">-</a>
qh_freebuffers()
free up global memory buffers
notes:
must match qh_initbuffers()
*/
void qh_freebuffers (void) {
trace5((qh ferr, "qh_freebuffers: freeing up global memory buffers\n"));
/* allocated by qh_initqhull_buffers */
qh_memfree (qh NEARzero, qh hull_dim * sizeof(realT));
qh_memfree (qh lower_threshold, (qh input_dim+1) * sizeof(realT));
qh_memfree (qh upper_threshold, (qh input_dim+1) * sizeof(realT));
qh_memfree (qh lower_bound, (qh input_dim+1) * sizeof(realT));
qh_memfree (qh upper_bound, (qh input_dim+1) * sizeof(realT));
qh_memfree (qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT));
qh_memfree (qh gm_row, (qh hull_dim+1) * sizeof(coordT *));
qh NEARzero= qh lower_threshold= qh upper_threshold= NULL;
qh lower_bound= qh upper_bound= NULL;
qh gm_matrix= NULL;
qh gm_row= NULL;
qh_setfree (&qh other_points);
qh_setfree (&qh del_vertices);
qh_setfree (&qh coplanarset);
if (qh line) /* allocated by qh_readinput, freed if no error */
free (qh line);
if (qh half_space)
free (qh half_space);
if (qh temp_malloc)
free (qh temp_malloc);
if (qh feasible_point) /* allocated by qh_readfeasible */
free (qh feasible_point);
if (qh feasible_string) /* allocated by qh_initflags */
free (qh feasible_string);
qh line= qh feasible_string= NULL;
qh half_space= qh feasible_point= qh temp_malloc= NULL;
/* usually allocated by qh_readinput */
if (qh first_point && qh POINTSmalloc) {
free(qh first_point);
qh first_point= NULL;
}
if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
free (qh input_points);
qh input_points= NULL;
}
trace5((qh ferr, "qh_freebuffers: finished\n"));
} /* freebuffers */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freebuild">-</a>
qh_freebuild( allmem )
free global memory used by qh_initbuild and qh_buildhull
if !allmem,
does not free short memory (freed by qh_memfreeshort)
design:
free centrums
free each vertex
mark unattached ridges
for each facet
free ridges
free outside set, coplanar set, neighbor set, ridge set, vertex set
free facet
free hash table
free interior point
free merge set
free temporary sets
*/
void qh_freebuild (boolT allmem) {
facetT *facet;
vertexT *vertex;
ridgeT *ridge, **ridgep;
mergeT *merge, **mergep;
trace1((qh ferr, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
if (qh del_vertices)
qh_settruncate (qh del_vertices, 0);
if (allmem) {
qh_clearcenters (qh_ASnone);
while ((vertex= qh vertex_list)) {
if (vertex->next)
qh_delvertex (vertex);
else {
qh_memfree (vertex, sizeof(vertexT));
qh newvertex_list= qh vertex_list= NULL;
}
}
}else if (qh VERTEXneighbors) {
FORALLvertices
qh_setfreelong (&(vertex->neighbors));
}
qh VERTEXneighbors= False;
qh GOODclosest= NULL;
if (allmem) {
FORALLfacets {
FOREACHridge_(facet->ridges)
ridge->seen= False;
}
FORALLfacets {
if (facet->visible) {
FOREACHridge_(facet->ridges) {
if (!otherfacet_(ridge, facet)->visible)
ridge->seen= True; /* an unattached ridge */
}
}
}
while ((facet= qh facet_list)) {
FOREACHridge_(facet->ridges) {
if (ridge->seen) {
qh_setfree(&(ridge->vertices));
qh_memfree(ridge, sizeof(ridgeT));
}else
ridge->seen= True;
}
qh_setfree (&(facet->outsideset));
qh_setfree (&(facet->coplanarset));
qh_setfree (&(facet->neighbors));
qh_setfree (&(facet->ridges));
qh_setfree (&(facet->vertices));
if (facet->next)
qh_delfacet (facet);
else {
qh_memfree (facet, sizeof(facetT));
qh visible_list= qh newfacet_list= qh facet_list= NULL;
}
}
}else {
FORALLfacets {
qh_setfreelong (&(facet->outsideset));
qh_setfreelong (&(facet->coplanarset));
if (!facet->simplicial) {
qh_setfreelong (&(facet->neighbors));
qh_setfreelong (&(facet->ridges));
qh_setfreelong (&(facet->vertices));
}
}
}
qh_setfree (&(qh hash_table));
qh_memfree (qh interior_point, qh normal_size);
qh interior_point= NULL;
FOREACHmerge_(qh facet_mergeset) /* usually empty */
qh_memfree (merge, sizeof(mergeT));
qh facet_mergeset= NULL; /* temp set */
qh degen_mergeset= NULL; /* temp set */
qh_settempfree_all();
} /* freebuild */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="freeqhull">-</a>
qh_freeqhull( allmem )
free global memory
if !allmem,
does not free short memory (freed by qh_memfreeshort)
notes:
sets qh.NOerrexit in case caller forgets to
design:
free global and temporary memory from qh_initbuild and qh_buildhull
free buffers
free statistics
*/
void qh_freeqhull (boolT allmem) {
trace1((qh ferr, "qh_freeqhull: free global memory\n"));
qh NOerrexit= True; /* no more setjmp since called at exit */
qh_freebuild (allmem);
qh_freebuffers();
qh_freestatistics();
#if qh_QHpointer
free (qh_qh);
qh_qh= NULL;
#else
memset((char *)&qh_qh, 0, sizeof(qhT));
qh NOerrexit= True;
#endif
} /* freeqhull */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_A">-</a>
qh_init_A( infile, outfile, errfile, argc, argv )
initialize memory and stdio files
convert input options to option string (qh.qhull_command)
notes:
infile may be NULL if qh_readpoints() is not called
errfile should always be defined. It is used for reporting
errors. outfile is used for output and format options.
argc/argv may be 0/NULL
called before error handling initialized
qh_errexit() may not be used
*/
void qh_init_A (FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
qh_meminit (errfile);
qh_initqhull_start (infile, outfile, errfile);
qh_init_qhull_command (argc, argv);
} /* init_A */
/*-<a href="qh-globa.htm#TOC"
>-------------------------------</a><a name="init_B">-</a>
qh_init_B( points, numpoints, dim, ismalloc )
initialize globals for points array
points has numpoints dim-dimensional points
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -