📄 qhull_global.cxx
字号:
/*<html><pre> -<a href="qh-c.htm#global"
>-------------------------------</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-1999, The Geometry Center
*/
#include <ivp_physics.hxx>
#include "qhull_a.hxx"
/*========= qh definition =======================*/
#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-c.htm#global"
>-------------------------------</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)
break;
if (!qh PRINTout[i]) {
qh PRINTout[i]= format;
break;
}
}
} /* appendprint */
/*-<a href="qh-c.htm#global"
>-------------------------------</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) {
ivp_message( "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) {
ivp_message( "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
ivp_message( "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-c.htm#global"
>-------------------------------</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 searchset);
if (qh line) /* allocated by qh_readinput, freed if no error */
P_FREE (qh line);
if (qh half_space)
P_FREE (qh half_space);
if (qh temp_malloc)
P_FREE (qh temp_malloc);
if (qh feasible_point) /* allocated by qh_readfeasible */
P_FREE (qh feasible_point);
if (qh feasible_string) /* allocated by qh_initflags */
P_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) {
P_FREE(qh first_point);
qh first_point= NULL;
}
if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
P_FREE (qh input_points);
qh input_points= NULL;
}
trace5((qh ferr, "qh_freebuffers: finished\n"));
} /* freebuffers */
/*-<a href="qh-c.htm#global"
>-------------------------------</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-c.htm#global"
>-------------------------------</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
P_FREE (qh_qh);
qh_qh= NULL;
#else
memset((char *)&qh_qh, 0, sizeof(qhT));
qh NOerrexit= True;
#endif
} /* freeqhull */
/*-<a href="qh-c.htm#global"
>-------------------------------</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-c.htm#global"
>-------------------------------</a><a name="init_B">-</a>
qh_init_B( points, numpoints, dim, ismalloc )
initialize globals for points array
points has numpoints dim-dimensional points
points[0] is the first coordinate of the first point
points[1] is the second coordinate of the first point
points[dim] is the first coordinate of the second point
ismalloc=True
Qhull will call free(points) on exit or input transformation
ismalloc=False
Qhull will allocate a new point array if needed for input transformation
qh.qhull_command
is the option string.
It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
returns:
if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
projects the input to a new point array
if qh.DELAUNAY,
qh.hull_dim is increased by one
if qh.ATinfinity,
qh_projectinput adds point-at-infinity for Delaunay tri.
if qh.SCALEinput
changes the upper and lower bounds of the input, see qh_scaleinput()
if qh.ROTATEinput
rotates the input by a random rotation, see qh_rotateinput()
if qh.DELAUNAY
rotates about the last coordinate
notes:
called after points are defined
qh_errexit() may be used
*/
void qh_init_B (coordT *points, int numpoints, int dim, boolT ismalloc) {
qh_initqhull_globals (points, numpoints, dim, ismalloc);
if (qhmem.LASTsize == 0)
qh_initqhull_mem();
/* mem.c and qset.c are initialized */
qh_initqhull_buffers();
qh_initthresholds (qh qhull_command);
if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay))
qh_projectinput();
if (qh SCALEinput)
qh_scaleinput();
if (qh ROTATErandom >= 0) {
qh_randommatrix (qh gm_matrix, qh hull_dim, qh gm_row);
if (qh DELAUNAY) {
int k, lastk= qh hull_dim-1;
for (k= 0; k < lastk; k++) {
qh gm_row[k][lastk]= 0.0;
qh gm_row[lastk][k]= 0.0;
}
qh gm_row[lastk][lastk]= 1.0;
}
qh_gram_schmidt (qh hull_dim, qh gm_row);
qh_rotateinput (qh gm_row);
}
} /* init_B */
/*-<a href="qh-c.htm#global"
>-------------------------------</a><a name="init_qhull_command">-</a>
qh_init_qhull_command( argc, argv )
build qh.qhull_command from argc/argv
returns:
a space-deliminated string of options (just as typed)
notes:
makes option string easy to input and output
argc/argv may be 0/NULL
*/
void qh_init_qhull_command(int argc, char *argv[]) {
int i;
char *s;
if (argc) {
if ((s= strrchr( argv[0], '\\'))) /* Borland gives full path */
strcpy (qh qhull_command, s+1);
else
strcpy (qh qhull_command, argv[0]);
if ((s= strstr (qh qhull_command, ".EXE"))
|| (s= strstr (qh qhull_command, ".exe")))
*s= '\0';
}
for (i=1; i < argc; i++) {
if (strlen (qh qhull_command) + strlen(argv[i]) + 1 < sizeof(qh qhull_command)) {
strcat (qh qhull_command, " ");
strcat (qh qhull_command, argv[i]);
}else {
ivp_message( "qhull input error: more than %d characters in command line\n",
(int)sizeof(qh qhull_command));
exit (1); /* can not use qh_errexit */
}
}
} /* init_qhull_command */
/*-<a href="qh-c.htm#global"
>-------------------------------</a><a name="initflags">-</a>
qh_initflags( commandStr )
set flags and initialized constants from commandStr
returns:
sets qh.qhull_command to command if needed
notes:
ignores first word (e.g., "qhull d")
use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
see:
qh_initthresholds() continues processing of 'Pdn' and 'PDn'
'prompt' in unix.c for documentation
design:
for each space-deliminated option group
if top-level option
check syntax
append approriate option to option string
set appropriate global variable or append printFormat to print options
else
for each sub-option
check syntax
append approriate option to option string
set appropriate global variable or append printFormat to print options
*/
void qh_initflags(char *command) {
int k, i, lastproject;
char *s= command, *t, *prev_s, *start, key;
boolT isgeom= False, wasproject;
realT r;
if (command != &qh qhull_command[0]) {
*qh qhull_command= '\0';
strncat( qh qhull_command, command, sizeof( qh qhull_command));
}
while (*s && !isspace(*s)) /* skip program name */
s++;
while (*s) {
while (*s && isspace(*s))
s++;
if (*s == '-')
s++;
if (!*s)
break;
prev_s= s;
switch (*s++) {
case 'd':
qh_option ("delaunay", NULL, NULL);
qh DELAUNAY= True;
break;
case 'f':
qh_option ("facets", NULL, NULL);
qh_appendprint (qh_PRINTfacets);
break;
case 'i':
qh_option ("incidence", NULL, NULL);
qh_appendprint (qh_PRINTincidences);
break;
case 'm':
qh_option ("mathematica", NULL, NULL);
qh_appendprint (qh_PRINTmathematica);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -