/*************************************************************************/
/*! Set's up the label info */
/*************************************************************************/


/*************************************************************************/
/*! Setup the various arrays for the splitted graph */
/*************************************************************************/


/*************************************************************************/
/*! This function creates and initializes a graph_t data structure */
/*************************************************************************/


/*************************************************************************/
/*! This function initializes a graph_t data structure */
/*************************************************************************/


/*************************************************************************/
/*! This function frees the refinement/partition memory stored in a graph */
/*************************************************************************/


/*************************************************************************/
/*! This function deallocates any memory stored in a graph */
/*************************************************************************/


/*************************************************************************
* This function is the entry point of the initial partition algorithm
* that does recursive bissection.
* This algorithm assembles the graph to all the processors and preceeds
* by parallelizing the recursive bisection step.
**************************************************************************/


/*************************************************************************
* This function keeps one parts
**************************************************************************/


/*************************************************************************
* This function finds a matching using the HEM heuristic
**************************************************************************/


/*************************************************************************
* This function is the entry point of the initial balancing algorithm.
* This algorithm assembles the graph to all the processors and preceeds
* with the balancing step.
**************************************************************************/


/***********************************************************************************
* This function is the entry point of the parallel multilevel local diffusion
* algorithm. It uses parallel undirected diffusion followed by adaptive k-way
* refinement. This function utilizes local coarsening.
************************************************************************************/


/*************************************************************************
* This function is used to transfer information from the moved graph
* back to the original graph. The information is transfered from array
* minfo to array info. The routine assumes that graph->where is left intact
* and it is used to get the inverse mapping information.
* The routine assumes that graph->where corresponds to a npes-way partition.
**************************************************************************/


/*************************************************************************
* This function is used to convert a partition vector to a permutation
* vector.
**************************************************************************/


/*************************************************************************
* This function quickly performs a check on the consistency of moved graph.
**************************************************************************/


/*************************************************************************
* This function computes the initial id/ed
**************************************************************************/


/*************************************************************************
* This function performs k-way refinement
**************************************************************************/


/*************************************************************************
* This function checks if the vertex weights of two vertices are below
* a given set of values
**************************************************************************/


/*************************************************************************
* This function computes the load imbalance over all the constrains
* For now assume that we just want balanced partitionings
**************************************************************************/


/**************************************************************
*  This subroutine remaps a partitioning on a single processor
**************************************************************/


/*************************************************************************
*  This is a comparison function for Serial Remap
**************************************************************************/


/*************************************************************************
* This function selects the partition number and the queue from which
* we will move vertices out
**************************************************************************/


/*************************************************************************
* This function checks if the balance achieved is better than the diff
* For now, it uses a 2-norm measure
**************************************************************************/


/*************************************************************************
* This function computes the load imbalance over all the constrains
**************************************************************************/


/*************************************************************************
* This function balances two partitions by moving the highest gain
* (including negative gain) vertices to the other domain.
* It is used only when tha unbalance is due to non contigous
* subdomains. That is, the are no boundary vertices.
* It moves vertices from the domain that is overweight to the one that
* is underweight.
**************************************************************************/


/*************************************************************************
*  This function computes the edge-cut of a serial graph.
**************************************************************************/


/*************************************************************************
*  This function computes the TotalV of a serial graph.
**************************************************************************/


/*************************************************************************
* This function performs the gather/scatter for the boundary vertices
**************************************************************************/


/*************************************************************************
* This function computes the max of a single element
**************************************************************************/


/*************************************************************************
* This function is the entry point of the initial partitioning algorithm.
* This algorithm assembles the graph to all the processors and preceed
* serially.
**************************************************************************/


/*************************************************************************
* This function extracts a subgraph from a graph given an indicator array.
**************************************************************************/


/*************************************************************************
* This function initializes the various timers
**************************************************************************/


/*************************************************************************
* This function prints timing information about KMETIS
**************************************************************************/


/*************************************************************************
* This function prints timer stat
**************************************************************************/


/*************************************************************************/
/*! This function assembles the graph into a single processor */
/*************************************************************************/


/*************************************************************************/
/*! Finds a HEM matching involving both local and remote vertices */
/*************************************************************************/


/*************************************************************************/
/*! Finds a HEM matching involving only local vertices */
/*************************************************************************/


/*************************************************************************/
/*! This function creates the coarser graph after a global matching */
/*************************************************************************/


/*************************************************************************/
/*! This function creates the coarser graph after a local matching */
/*************************************************************************/


/***********************************************************************************
* This function is the entry point of the parallel kmetis algorithm that uses
* coordinates to compute an initial graph distribution.
************************************************************************************/


/***********************************************************************************
* This function is the entry point of the parallel ordering algorithm.
* This function assumes that the graph is already nice partitioned among the
* processors and then proceeds to perform recursive bisection.
************************************************************************************/


/*************************************************************************
* This function prints a matrix
**************************************************************************/


/*************************************************************************
* This function computes movement statistics for adaptive refinement
* schemes
**************************************************************************/


/**************************************************************************/
/*! The driver of the multilvelel separator finding algorithm */
/**************************************************************************/


/*************************************************************************
* This function compacts a graph by removing the vertex separator
**************************************************************************/


/*************************************************************************
* This function performs a k-way directed diffusion
**************************************************************************/


/*************************************************************************
*  This function computes the load for each subdomain
**************************************************************************/


/*************************************************************************
* This function implements the CG solver used during the directed diffusion
**************************************************************************/


/*************************************************************************
* This function performs Matrix-Vector multiplication
**************************************************************************/


/*************************************************************************
* This function sets up the transfer vectors
**************************************************************************/


/***********************************************************************************
* This function is the entry point of the parallel k-way multilevel mesh partitionioner.
* This function assumes nothing about the mesh distribution.
* It is the general case.
************************************************************************************/


/*************************************************************************
* This function remaps that graph so that it will minimize the
* redistribution cost
**************************************************************************/


/*************************************************************************
* This function computes the assignment using the the objective the
* minimization of the total volume of data that needs to move
**************************************************************************/


/*************************************************************************
* This function changes the numbering from 1 to 0 or 0 to 1
**************************************************************************/


/***********************************************************************************
* This function is the entry point of the serial ordering algorithm.
************************************************************************************/


/*************************************************************************
* This function assembles the graph into a single processor
**************************************************************************/


/***********************************************************************************
* This function is the entry point of the parallel k-way multilevel partitionioner.
* This function assumes nothing about the graph distribution.
* It is the general case.
************************************************************************************/


/*************************************************************************/
/*! This function de-allocate various pools of memory */
/**************************************************************************/


/*************************************************************************
* This function setsup the ctrl_t structure
**************************************************************************/


/*************************************************************************
* This function creates a mesh_t data structure and initializes
* the various fields
**************************************************************************/


/*************************************************************************
* This function initializes the various fields of a mesh_t.
**************************************************************************/


/*************************************************************************
* This function prints an error message and exits
**************************************************************************/


/*************************************************************************
* This function does a binary search on an array for a key and returns
* the index
**************************************************************************/


/*************************************************************************
* This function returns true if the a is a power of 2
**************************************************************************/


/*************************************************************************
* These functions return the index of the maximum element in a vector
**************************************************************************/


/*************************************************************************
* These functions return the index of the almost maximum element in a vector
**************************************************************************/


/*************************************************************************
* This function returns the average value of an array
**************************************************************************/


/*************************************************************************
* This function checks if v+u2 provides a better balance in the weight
* vector that v+u1
**************************************************************************/


/*************************************************************************
* This function checks if the pairwise balance of the between the two
* partitions will improve by moving the vertex v from pfrom to pto,
* subject to the target partition weights of tfrom, and tto respectively
**************************************************************************/


/*************************************************************************
* This function checks if it will be better to move a vertex to pt2 than
* to pt1 subject to their target weights of tt1 and tt2, respectively
* This routine takes into account the weight of the vertex in question
**************************************************************************/


/*************************************************************************
* This function computes the top three values of a real_t array
**************************************************************************/


/*************************************************************************
* This function prints a vector stored in each processor
**************************************************************************/


/*************************************************************************
* This function prints the local portion of the graph stored at each
* processor
**************************************************************************/


/*************************************************************************
* This function prints the local portion of the graph stored at each
* processor along with degree information during refinement
**************************************************************************/


/*************************************************************************
* This function prints the information computed during setup
**************************************************************************/


/*************************************************************************
* This function prints information about the graphs that were sent/received
**************************************************************************/


/*************************************************************************
* This function writes a graph in the format used by serial METIS
**************************************************************************/


/*************************************************************************
* This function projects a partition.
**************************************************************************/


/*************************************************************************
* This function computes the initial id/ed
**************************************************************************/


/***********************************************************************************/
/*! This function tests the various graph partitioning and ordering routines */
/***********************************************************************************/


/******************************************************************************
* This function takes a partition vector that is distributed and reads in
* the original graph and computes the edgecut
*******************************************************************************/


/******************************************************************************
* This function takes a graph and its partition vector and creates a new
* graph corresponding to the one after the movement
*******************************************************************************/


/*****************************************************************************
*  This function sets up a graph data structure for partitioning
*****************************************************************************/


/*************************************************************************
* This function reads the CSR matrix
**************************************************************************/


/*************************************************************************
* This function writes a distributed graph to file
**************************************************************************/


/*************************************************************************/
/*! Reads the coordinates associated with the vertices of a graph */
/*************************************************************************/


/*************************************************************************
* This function reads the spd matrix
**************************************************************************/


/*************************************************************************
* This function writes out a partition vector
**************************************************************************/


/*************************************************************************
* This function writes out the ordering vector
**************************************************************************/


/*************************************************************************
* This function reads a mesh from a file
**************************************************************************/


/*************************************************************************
* This function implements a simple graph adaption strategy.
**************************************************************************/


/*************************************************************************
* This function changes the numbering to be from 1 instead of 0
**************************************************************************/


/*
 * draw the boundaries associated with a grid
 */


/*
 * open display and get defaults
 */


/*
 * callback for exit and help buttons
 */


/*
 * callback for springs selection
 */


/*
 * callback for springs inside a region selection
 */


/*
    write_mode_str("Press the left mouse button to display the depth of the background grid at the pointer");
    write_mode_str("Press the left mouse button to display the depth of the edit grid at the pointer");
    write_mode_str("Use the left mouse button to display the element nearest the pointer");
    write_mode_str("Use the left mouse button to display the node nearest the pointer");
    write_mode_str("Use the left mouse button to display the element containing the pointer");
*/


/*
 * bandwidth reduction callback
 */


/*
 * create the main menubar
 */


/*
 * informative message at the lower left of the canvas
 */


/*           postscript initialization routine  */


/*
 * strip special chars from a string
 */


/*
 * set scroll amount
 */


/*
 * set the reduction factor for drawing elements
 */


/*
 * set the reduction/expansion factor for shrink and expand
 */


/* returns 1 if p is to right of halfedge e */


/*
 * Create the wdata Frame and the wdata Panel
 */


/*
 * read a region
 */


/*
 * Read a region popup
 */


/*
 * Save a region
 */


/*
 * use Fortune's sweepline code
 */


/*
 * Make the nodes of the grid build points
 */


/*
 * Draw selected nodes with color
 */


/**********************************************************************
 * XtFlush - Flushes all Xt events.
 **********************************************************************/


/*
 * handle the close item on the WM menu
 */


/*
 * Manage and raise
 */


/*
 * Create the annot Frame and the annot Panel
 */


/*
 * Draw a grid with a reduction factor
 */


/*
 * Fill each element of a grid with color color
 */


/*
 * Fill a single element with color color
 */


/*
 * Draw the gradient of each element as a vector at the cell center.
 */


/*
 * Draw the slopes of a grid as isolines
 */


/*
 * draw either the node numbers n = 0 or mark the nodes n = 1
 */


/* sort sites on y, then x, coord */


/* return a single in-storage site */


/* read all sites, sort, and compute xmin, xmax, ymin, ymax */


/* read one site */


/*
 * Write the external and internal boundaries of a grid
 */


/*
 * Read the external and internal boundaries of a grid
 */


/*
 * Read a boundary in binary format
 */


/*
 * Write a boundary in binary format
 */


/* Create the netcdf file */


/* Write the grid to the netcdf file fname */


/* Read the grid from the netcdf file fname */


/*
 * find the nearest object to (x,y)
 */


/*
 * draw annotative text
 */


/*
 * draw annotative boxes
 */


/*
 * draw annotative lines
 */


/*
 * compute the mins and maxes of a vector x
 */


/*
 * free and check for NULL pointer
 */


/*
 * swap doubles and ints
 */


/*
 * convert a string from lower to upper case
 */


/*
 * remove all that fortran nastiness
 */


/*
 * log base 2
 */


/*
 * compute the area bounded by the polygon (xi,yi)
 */


/*
 * compute the perimeter bounded by the polygon (xi,yi)
 */


/*
 * nicenum: find a "nice" number approximately equal to x
 * round if round=1, ceil if round=0
 */


/*
 * expt(a,n)=a^n for integer n
 * roundoff errors in pow were causing problems, so I wrote my own
 */


/*
 * set the print options
 */


/*
 * popup to define boundary segments
 */


/*
 * select open boundary
 */


/*
 * select land boundary
 */


/*
 * delete open boundary
 */


/*
 * write open boundary
 */


/* read build points file with locations of start and end locations of open/land boundaries */


/*
 * define an open boundary from selections made on the drawing area
 */


/*
 * define a land boundary from selections made on the drawing area
 */


/*
 * draw the open boundaries
 */


/*
 * draw the land boundaries
 */


/*
 * draw the current state of adcirc selections TODO move out of here
 */


/*
 * write the open boundaries
 */


/*
 * Read a set of build points to build points struct bno
 */


/*
 * Read a grid in ASCII format, set defaults for isolines
 */


/*
 * Merge a grid to the edit grid
 */


/*
 * Write a grid in ASCII
 */


/*
 * Write a grid in binary format
 */


/*
 * Read a grid in binary format
 */


/*
 * read a finite difference grid
 */


/* check errors on netcdf file operations */


/*
 * routines to determine if a point lies in a polygon
*/


/*
 * determine if (x,y) is in the polygon xlist[], ylist[]
 */


/*
 * Update the boundary menu on the main panel
 */


/*
 * return TRUE if area is greater than 0.0
 * FALSE otherwise
 */


/*
 * reverse the order of the boundary
 */


/*
 * check the boundaries of grid gridno for proper
 * orientation
 */


/*
 * Compute the cumulative distance along a boundary
 */


/*
 * Walk the coastal boundary and place points in the edit grid boundary
 * such that the selected criteria is satisfied.
 *
 * p1 = maxcour
 * p2 = dt
 * p3 = tol
 *
 */


/*
 * Allocate memory for boundary bno of length npts,
 * btype == 0 => external boundary
 */


/*
 * Copy boundary bno and return a handle to the copy
 */


/*
 * Copy a collection of boundaries from one grid to another
 */


/*
 * Resize a boundary
 */


/*
 * Free a boundary
 */


/*
 * Free a collection of boundaries
 */


/*
 * Return the next available boundary
 */


/*
 * update the items in define world/view popup
 */


/*
 * Create the world Frame and the world Panel
 */


/*
 * Allocate a grid and initialize the boundary
 */


/*
 * Allocate a grid, but not the boundary
 */


/*
 * Add a triangle to the grid
 */


/*
 * Add a quadrangle to the grid
 */


/*
 * Pointer based versions of the above routines
 */


/*
 * delete elements as indicated by ellist != 0
 */


/*
 * draw rotated box
 */


/*
 * draw an xor'ed box
 */


/*
 * switch on the area calculator
 */


/*
 * switch on the perimeter calculator
 */


/*
 * evaluate an expression for the calculator
 */


/*
 * draw a cursor for text writing
 * TODO: fix the rotation problems (cursor doesn't track)
 */


/*
 * update string drawn on the canvas
 */


/*
 * canvas event proc
 */


/*
	select a font to use below
*/


/*
	write s at xpos, ypos in device coordinates
	of size scale, direction dir, color color, using vector
	TODO - fix underlining
*/


/*
	get the x extent of the string in hershey coordinates given size
*/


/*
	get the y extent of the string in hershey coordinates given size
*/


/* implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax,
   deltax, deltay (can all be estimates).
   Performance suffers if they are wrong; better to make nsites,
   deltax, and deltay too big than too small.  (?) */


/*
 * initialize_cms_data()
 *    Initialize the colormap segment data and setup the RGB values.
 */


/*
 * Create the help Panel
 */


/*
 * Create the region Frame and Panel
 */


/*
 * write elements inside (inout==1) a region, outside if inout==0
 * inside region means center of element is in the region.
 * TODO allow for varying definitions of inside.
 *       1. center
 *       2. all nodes
 *       3. one node
 */


/*
 * write nodes inside (inout==1) a region, outside if inout==0
 */


/* Get entry from hash table, pruning any deleted nodes */


/* This delete routine can't reclaim node, since pointers from hash
   table may be present.   */


/*
 * save_image_on_disk - this routine saves the region specified by the various
 *               parameters out to disk in the "defacto standard" (xwd) format.
 *               This has now been modified to take two window id's.  The
 *               first is to gather "window" information such as visual
 *               type, etc, and the second is where the image comes from.
 *               This is because in wscrawl 2.0, the image comes from a
 *               Pixmap, so pixmaps are VALID for the second win_id, but
 *               not for the first.  In the simple case of getting an
 *               image from a window, just pass the window id in twice.
 *
 *               "the_colormap" can be NULL if you wish to use the default
 *               colormap.  Most times this will be the case.
 */


/*
 * Image_Size - this routine takes an XImage and returns it's total byte count
 */


/*
 * _swapshort - this routine is stolen, and I don't know what it does
 */


/*
 * _swaplong - this routine is stolen, and I don't know what it does
 */


/*
 * read_image_from_disk - this routine reads the file indicated and allocates
 *               and loads up and then finally returns the XImage structure
 *               ready to blow out to the indicated display.  If at all
 *               possible, it attempts to return an image with the
 *               depth equalling the depth of the disp passed in.  Either
 *               way, it will return the depth it managed to get.
 */


/*
 * allocate_colors_and_assign_em - this function takes an XImage and it's
 *            colormap as it was at the time the image was created, and
 *            allocates cells in the system colormap matching those old colors
 *            and shuffles the pixels in the image to point to our new color
 *            cells instead of those old color cells.
 */


/*
   compute the isolines
 */


/*
 * Return the number of nodes for each element type
 */


/*
 * test the grid for composition of purely triangles
 */


/*
 * test the node for colocation
 */


/*
 * test a grid for existence of 1-d elements
 */


/*
 * test an element for type
 */


/*
 * Test a grid for being composed of quadrangles
 */


/*
 * delete the elements given in the array elar
 */


/*
 * Nodes have been renumbered, load them back to the grid
 */


/*
 * Delete nodes given in the array nodes
 */


/*
 * cut a grid along a given line
 */


/*
 * Loop through a grid and find elements that are not
 * oriented in a counter-clockwise fashion - mark them
 * on the drawing area and sawp nodes to fix them.
 */


/*
 * Split every element in a grid into 3 or 4 elements
 * depending on the value of it
 */


/*
 * initialize q for nodes
 */


/*
 * initialize q for elements
 */


/*
 * Add a single node to the q
 */


/*
 * Add a single element to the q
 */


/*
 * Split all elements into 4, using an edgelist for performance
 */


/*
 * determine if a node given by x, y is already in
 * the table of nodes, possible problems here with
 * the 0.00001 business.
 */


/*
 * split a single element into 4, being careful not
 * to include the added nodes more than once to the table of nodes.
 */


/*
 * split an element into 3 elements by adding a middle node
 */


/*
 * swap a shared line between 2 adjacent elements
 */


/*
 * convert a quadrangle to triangles
 */


/*
 * loop through a grid and convert triangles to
 * quadrangles by looking at neighboring elements
 */


/*
 * test for the sign of the area, test for orientation of
 * nodes
 */


/*
 * compute area for 2d elements
 */


/*
 * compute the area given the nodes
 */


/*
 * compute the area given the vertices
 */


/*
 * move the node nearsest to oldx, oldy to newx, newy
 */


/*
 * interpolate depths defined in grid 1 (g1) to grid 2 (g2)
 *
 */


/*
double get_depth_element(int gno, int ind, double x, double y)
{
    double x1, x2, x3, x4, y1, y2, y3, y4, xi, eta;
    double h, r, s, area2, a[4], b[4], g[4], shapef[4];
    int n0, n1, n2, n3;

    if (grid[gno].depthflag) {
	if (ind >= 0 && ind < grid[gno].nmel && grid[gno].edepth != NULL) {
	    return grid[gno].edepth[ind];
	} else {
	}
    }
    if (grid[gno].icon[ind].nn = 3) {

	n0 = grid[gno].icon[ind].nl[0];
	n1 = grid[gno].icon[ind].nl[1];
	n2 = grid[gno].icon[ind].nl[2];
	x1 = grid[gno].xord[n0];
	x2 = grid[gno].xord[n1];
	x3 = grid[gno].xord[n2];
	y1 = grid[gno].yord[n0];
	y2 = grid[gno].yord[n1];
	y3 = grid[gno].yord[n2];
	a[0] = x2 * y3 - x3 * y2;
	a[1] = x3 * y1 - x1 * y3;
	a[2] = x1 * y2 - x2 * y1;
	b[0] = x2 - y3;
	b[1] = y3 - y1;
	b[2] = y1 - y2;
	g[0] = x3 - x2;
	g[1] = x1 - x3;
	g[2] = x2 - x1;
	area2 = a[0] + a[1] + a[2];
	area2 = 1.0 / area2;
	s = (a[2] + b[2] * x + g[2] * y) * area2;
	r = (a[1] + b[1] * x + g[1] * y) * area2;
	h = 1.0 - r - s;
	return (grid[gno].depth[n0] * h + grid[gno].depth[n1] * r + grid[gno].depth[n2] * s);
    } else if (grid[gno].icon[ind].nn = 4) {

	n0 = grid[gno].icon[ind].nl[0];
	n1 = grid[gno].icon[ind].nl[1];
	n2 = grid[gno].icon[ind].nl[2];
	n3 = grid[gno].icon[ind].nl[3];
	x1 = grid[gno].xord[n0];
	x2 = grid[gno].xord[n1];
	x3 = grid[gno].xord[n2];
	x4 = grid[gno].xord[n3];
	y1 = grid[gno].yord[n0];
	y2 = grid[gno].yord[n1];
	y3 = grid[gno].yord[n2];
	y4 = grid[gno].yord[n3];
	ibilinear(x1, x2, x3, x4, y1, y2, y3, y4, x, y, &xi, &eta, shapef);
	return (grid[gno].depth[n0] * shapef[0] + grid[gno].depth[n1] * shapef[1] + grid[gno].depth[n2] * shapef[2] + grid[gno].depth[n3] * shapef[3]);
    } else {
	fprintf(stderr, "Error, unknown element type %d in get_depth_element() setting depth to -1.0\n", ind);
	return -1.0;
    }
}
*/


/*
 * routines to reduce bandwidth
 *
 */


/*
 * return the elements associated with a given node
 */


/*
 * mark nodes within a region
 */


/*
 * add middle nodes to a grid
 */


/*
 * compute the volume of a prism
 */


/*
 * compute the volume of a prism given the coordinates of the triangle on top.
 */


/*
 * compute the circumcenter of a triangle, used for median axis computation
 */


/*****************************************************************************/
/*                                                                           */
/*  internalerror()   Ask the user to send me the defective product.  Exit.  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  parsecommandline()   Read the command line, identify switches, and set   */
/*                       up options and file names.                          */
/*                                                                           */
/*  The effects of this routine are felt entirely through global variables.  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  printtriangle()   Print out the details of a triangle/edge handle.       */
/*                                                                           */
/*  I originally wrote this procedure to simplify debugging; it can be       */
/*  called directly from the debugger, and presents information about a      */
/*  triangle/edge handle in digestible form.  It's also used when the        */
/*  highest level of verbosity (`-VVV') is specified.                        */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  printshelle()   Print out the details of a shell edge handle.            */
/*                                                                           */
/*  I originally wrote this procedure to simplify debugging; it can be       */
/*  called directly from the debugger, and presents information about a      */
/*  shell edge handle in digestible form.  It's also used when the highest   */
/*  level of verbosity (`-VVV') is specified.                                */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  poolinit()   Initialize a pool of memory for allocation of items.        */
/*                                                                           */
/*  This routine initializes the machinery for allocating items.  A `pool'   */
/*  is created whose records have size at least `bytecount'.  Items will be  */
/*  allocated in `itemcount'-item blocks.  Each item is assumed to be a      */
/*  collection of words, and either pointers or floating-point values are    */
/*  assumed to be the "primary" word type.  (The "primary" word type is used */
/*  to determine alignment of items.)  If `alignment' isn't zero, all items  */
/*  will be `alignment'-byte aligned in memory.  `alignment' must be either  */
/*  a multiple or a factor of the primary word size; powers of two are safe. */
/*  `alignment' is normally used to create a few unused bits at the bottom   */
/*  of each item's pointer, in which information may be stored.              */
/*                                                                           */
/*  Don't change this routine unless you understand it.                      */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  poolrestart()   Deallocate all items in a pool.                          */
/*                                                                           */
/*  The pool is returned to its starting state, except that no memory is     */
/*  freed to the operating system.  Rather, the previously allocated blocks  */
/*  are ready to be reused.                                                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pooldeinit()   Free to the operating system all memory taken by a pool.  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pooldealloc()   Deallocate space for an item.                            */
/*                                                                           */
/*  The deallocated space is stored in a queue for later reuse.              */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  traversalinit()   Prepare to traverse the entire list of items.          */
/*                                                                           */
/*  This routine is used in conjunction with traverse().                     */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  dummyinit()   Initialize the triangle that fills "outer space" and the   */
/*                omnipresent shell edge.                                    */
/*                                                                           */
/*  The triangle that fills "outer space", called `dummytri', is pointed to  */
/*  by every triangle and shell edge on a boundary (be it outer or inner) of */
/*  the triangulation.  Also, `dummytri' points to one of the triangles on   */
/*  the convex hull (until the holes and concavities are carved), making it  */
/*  possible to find a starting triangle for point location.                 */
/*                                                                           */
/*  The omnipresent shell edge, `dummysh', is pointed to by every triangle   */
/*  or shell edge that doesn't have a full complement of real shell edges    */
/*  to point to.                                                             */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  initializepointpool()   Calculate the size of the point data structure   */
/*                          and initialize its memory pool.                  */
/*                                                                           */
/*  This routine also computes the `pointmarkindex' and `point2triindex'     */
/*  indices used to find values within each point.                           */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  initializetrisegpools()   Calculate the sizes of the triangle and shell  */
/*                            edge data structures and initialize their      */
/*                            memory pools.                                  */
/*                                                                           */
/*  This routine also computes the `highorderindex', `elemattribindex', and  */
/*  `areaboundindex' indices used to find values within each triangle.       */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  triangledealloc()   Deallocate space for a triangle, marking it dead.    */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  triangletraverse()   Traverse the triangles, skipping dead ones.         */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  shelledealloc()   Deallocate space for a shell edge, marking it dead.    */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  shelletraverse()   Traverse the shell edges, skipping dead ones.         */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pointdealloc()   Deallocate space for a point, marking it dead.          */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pointtraverse()   Traverse the points, skipping dead ones.               */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  triangledeinit()   Free all remaining allocated memory.                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  maketriangle()   Create a new triangle with orientation zero.            */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  makeshelle()   Create a new shell edge with orientation zero.            */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  exactinit()   Initialize the variables used for exact arithmetic.        */
/*                                                                           */
/*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
/*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
/*  error.  It is used for floating-point error analysis.                    */
/*                                                                           */
/*  `splitter' is used to split floating-point numbers into two half-        */
/*  length significands for exact multiplication.                            */
/*                                                                           */
/*  I imagine that a highly optimizing compiler might be too smart for its   */
/*  own good, and somehow cause this routine to fail, if it pretends that    */
/*  floating-point arithmetic is too much like real arithmetic.              */
/*                                                                           */
/*  Don't change this routine unless you fully understand it.                */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  triangleinit()   Initialize some variables.                              */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
/*                                                                           */
/*  This is a simple linear congruential random number generator.  Hence, it */
/*  is a bad random number generator, but good enough for most randomized    */
/*  geometric algorithms.                                                    */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  makepointmap()   Construct a mapping from points to triangles to improve  */
/*                  the speed of point location for segment insertion.       */
/*                                                                           */
/*  Traverses all the triangles, and provides each corner of each triangle   */
/*  with a pointer to that triangle.  Of course, pointers will be            */
/*  overwritten by other pointers because (almost) each point is a corner    */
/*  of several triangles, but in the end every point will point to some      */
/*  triangle that contains it.                                               */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  preciselocate()   Find a triangle or edge containing a given point.      */
/*                                                                           */
/*  Begins its search from `searchtri'.  It is important that `searchtri'    */
/*  be a handle with the property that `searchpoint' is strictly to the left */
/*  of the edge denoted by `searchtri', or is collinear with that edge and   */
/*  does not intersect that edge.  (In particular, `searchpoint' should not  */
/*  be the origin or destination of that edge.)                              */
/*                                                                           */
/*  These conditions are imposed because preciselocate() is normally used in */
/*  one of two situations:                                                   */
/*                                                                           */
/*  (1)  To try to find the location to insert a new point.  Normally, we    */
/*       know an edge that the point is strictly to the left of.  In the     */
/*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
/*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
/*       that edge is the shortest edge of the triangle whose circumcenter   */
/*       is being inserted.                                                  */
/*                                                                           */
/*  (2)  To try to find an existing point.  In this case, any edge on the    */
/*       convex hull is a good starting edge.  The possibility that the      */
/*       vertex one seeks is an endpoint of the starting edge must be        */
/*       screened out before preciselocate() is called.                      */
/*                                                                           */
/*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
/*                                                                           */
/*  This implementation differs from that given by Guibas and Stolfi.  It    */
/*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
/*  is on the other side of the line containing that edge.  After entering   */
/*  a triangle, there are two edges by which one can leave that triangle.    */
/*  If both edges are valid (`searchpoint' is on the other side of both      */
/*  edges), one of the two is chosen by drawing a line perpendicular to      */
/*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
/*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
/*  falls on, an exit edge is chosen.                                        */
/*                                                                           */
/*  This implementation is empirically faster than the Guibas and Stolfi     */
/*  point location routine (which I originally used), which tends to spiral  */
/*  in toward its target.                                                    */
/*                                                                           */
/*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
/*  is a handle whose origin is the existing vertex.                         */
/*                                                                           */
/*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
/*  handle whose primary edge is the edge on which the point lies.           */
/*                                                                           */
/*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
/*  `searchtri' is a handle on the triangle that contains the point.         */
/*                                                                           */
/*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
/*  handle whose primary edge the point is to the right of.  This might      */
/*  occur when the circumcenter of a triangle falls just slightly outside    */
/*  the mesh due to floating-point roundoff error.  It also occurs when      */
/*  seeking a hole or region point that a foolish user has placed outside    */
/*  the mesh.                                                                */
/*                                                                           */
/*  WARNING:  This routine is designed for convex triangulations, and will   */
/*  not generally work after the holes and concavities have been carved.     */
/*  However, it can still be used to find the circumcenter of a triangle, as */
/*  long as the search is begun from the triangle in question.               */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  locate()   Find a triangle or edge containing a given point.             */
/*                                                                           */
/*  Searching begins from one of:  the input `searchtri', a recently         */
/*  encountered triangle `recenttri', or from a triangle chosen from a       */
/*  random sample.  The choice is made by determining which triangle's       */
/*  origin is closest to the point we are searcing for.  Normally,           */
/*  `searchtri' should be a handle on the convex hull of the triangulation.  */
/*                                                                           */
/*  Details on the random sampling method can be found in the Mucke, Saias,  */
/*  and Zhu paper cited in the header of this code.                          */
/*                                                                           */
/*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
/*                                                                           */
/*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
/*  is a handle whose origin is the existing vertex.                         */
/*                                                                           */
/*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
/*  handle whose primary edge is the edge on which the point lies.           */
/*                                                                           */
/*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
/*  `searchtri' is a handle on the triangle that contains the point.         */
/*                                                                           */
/*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
/*  handle whose primary edge the point is to the right of.  This might      */
/*  occur when the circumcenter of a triangle falls just slightly outside    */
/*  the mesh due to floating-point roundoff error.  It also occurs when      */
/*  seeking a hole or region point that a foolish user has placed outside    */
/*  the mesh.                                                                */
/*                                                                           */
/*  WARNING:  This routine is designed for convex triangulations, and will   */
/*  not generally work after the holes and concavities have been carved.     */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  insertshelle()   Create a new shell edge and insert it between two       */
/*                   triangles.                                              */
/*                                                                           */
/*  The new shell edge is inserted at the edge described by the handle       */
/*  `tri'.  Its vertices are properly initialized.  The marker `shellemark'  */
/*  is applied to the shell edge and, if appropriate, its vertices.          */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  flip()   Transform two triangles to two different triangles by flipping  */
/*           an edge within a quadrilateral.                                 */
/*                                                                           */
/*  Imagine the original triangles, abc and bad, oriented so that the        */
/*  shared edge ab lies in a horizontal plane, with the point b on the left  */
/*  and the point a on the right.  The point c lies below the edge, and the  */
/*  point d lies above the edge.  The `flipedge' handle holds the edge ab    */
/*  of triangle abc, and is directed left, from vertex a to vertex b.        */
/*                                                                           */
/*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
/*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
/*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
/*  may have held the original triangles are still valid, although not       */
/*  directed as they were before.                                            */
/*                                                                           */
/*  Upon completion of this routine, the `flipedge' handle holds the edge    */
/*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
/*  (Hence, the two triangles have rotated counterclockwise.)                */
/*                                                                           */
/*  WARNING:  This transformation is geometrically valid only if the         */
/*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
/*  valid only if there is not a shell edge between the triangles abc and    */
/*  bad.  This routine does not check either of these preconditions, and     */
/*  it is the responsibility of the calling routine to ensure that they are  */
/*  met.  If they are not, the streets shall be filled with wailing and      */
/*  gnashing of teeth.                                                       */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  insertsite()   Insert a vertex into a Delaunay triangulation,            */
/*                 performing flips as necessary to maintain the Delaunay    */
/*                 property.                                                 */
/*                                                                           */
/*  The point `insertpoint' is located.  If `searchtri.tri' is not NULL,     */
/*  the search for the containing triangle begins from `searchtri'.  If      */
/*  `searchtri.tri' is NULL, a full point location procedure is called.      */
/*  If `insertpoint' is found inside a triangle, the triangle is split into  */
/*  three; if `insertpoint' lies on an edge, the edge is split in two,       */
/*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
/*  used to restore the Delaunay property.  If `insertpoint' lies on an      */
/*  existing vertex, no action is taken, and the value DUPLICATEPOINT is     */
/*  returned.  On return, `searchtri' is set to a handle whose origin is the */
/*  existing vertex.                                                         */
/*                                                                           */
/*  Normally, the parameter `splitedge' is set to NULL, implying that no     */
/*  segment should be split.  In this case, if `insertpoint' is found to     */
/*  lie on a segment, no action is taken, and the value VIOLATINGPOINT is    */
/*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
/*  is the violated segment.                                                 */
/*                                                                           */
/*  If the calling routine wishes to split a segment by inserting a point in */
/*  it, the parameter `splitedge' should be that segment.  In this case,     */
/*  `searchtri' MUST be the triangle handle reached by pivoting from that    */
/*  segment; no point location is done.                                      */
/*                                                                           */
/*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
/*  there should be checks for the creation of encroached segments or bad    */
/*  quality faces.  If a newly inserted point encroaches upon segments,      */
/*  these segments are added to the list of segments to be split if          */
/*  `segmentflaws' is set.  If bad triangles are created, these are added    */
/*  to the queue if `triflaws' is set.                                       */
/*                                                                           */
/*  If a duplicate point or violated segment does not prevent the point      */
/*  from being inserted, the return value will be ENCROACHINGPOINT if the    */
/*  point encroaches upon a segment (and checking is enabled), or            */
/*  SUCCESSFULPOINT otherwise.  In either case, `searchtri' is set to a      */
/*  handle whose origin is the newly inserted vertex.                        */
/*                                                                           */
/*  insertsite() does not use flip() for reasons of speed; some              */
/*  information can be reused from edge flip to edge flip, like the          */
/*  locations of shell edges.                                                */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
/*                         has a certain "nice" shape.  This includes the    */
/*                         polygons that result from deletion of a point or  */
/*                         insertion of a segment.                           */
/*                                                                           */
/*  This is a conceptually difficult routine.  The starting assumption is    */
/*  that we have a polygon with n sides.  n - 1 of these sides are currently */
/*  represented as edges in the mesh.  One side, called the "base", need not */
/*  be.                                                                      */
/*                                                                           */
/*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
/*  triangles that share a common origin.  For each of these triangles, the  */
/*  edge opposite the origin is one of the sides of the polygon.  The        */
/*  primary edge of each triangle is the edge directed from the origin to    */
/*  the destination; note that this is not the same edge that is a side of   */
/*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
/*  From there, the triangles follow in counterclockwise order about the     */
/*  polygon, until `lastedge', the primary edge of the last triangle.        */
/*  `firstedge' and `lastedge' are probably connected to other triangles     */
/*  beyond the extremes of the fan, but their identity is not important, as  */
/*  long as the fan remains connected to them.                               */
/*                                                                           */
/*  Imagine the polygon oriented so that its base is at the bottom.  This    */
/*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
/*  The right vertex of the base is the destination of `firstedge', and the  */
/*  left vertex of the base is the apex of `lastedge'.                       */
/*                                                                           */
/*  The challenge now is to find the right sequence of edge flips to         */
/*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
/*  edge flip effectively removes one triangle from the fan, committing it   */
/*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
/*  is set, the final flip will be performed, resulting in a fan of one      */
/*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
/*  performed, resulting in a fan of two triangles, and an unfinished        */
/*  triangular polygon that is not yet filled out with a single triangle.    */
/*  On completion of the routine, `lastedge' is the last remaining triangle, */
/*  or the leftmost of the last two.                                         */
/*                                                                           */
/*  Although the flips are performed in the order described above, the       */
/*  decisions about what flips to perform are made in precisely the reverse  */
/*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
/*  uses up to two recursive calls to triangulate the "subproblems"          */
/*  (polygons with fewer edges), and then performs an edge flip.             */
/*                                                                           */
/*  The "decision" it makes is which vertex of the polygon should be         */
/*  connected to the base.  This decision is made by testing every possible  */
/*  vertex.  Once the best vertex is found, the two edges that connect this  */
/*  vertex to the base become the bases for two smaller polygons.  These     */
/*  are triangulated recursively.  Unfortunately, this approach can take     */
/*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
/*  rarely a big deal for point deletion, where n is rarely larger than ten, */
/*  but it could be a big deal for segment insertion, especially if there's  */
/*  a lot of long segments that each cut many triangles.  I ought to code    */
/*  a faster algorithm some time.                                            */
/*                                                                           */
/*  The `edgecount' parameter is the number of sides of the polygon,         */
/*  including its base.  `triflaws' is a flag that determines whether the    */
/*  new triangles should be tested for quality, and enqueued if they are     */
/*  bad.                                                                     */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pointsort()   Sort an array of points by x-coordinate, using the         */
/*                y-coordinate as a secondary key.                           */
/*                                                                           */
/*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
/*  the usual quicksort mistakes.                                            */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  pointmedian()   An order statistic algorithm, almost.  Shuffles an array */
/*                  of points so that the first `median' points occur        */
/*                  lexicographically before the remaining points.           */
/*                                                                           */
/*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
/*  if axis == 1.  Very similar to the pointsort() procedure, but runs in    */
/*  randomized linear time.                                                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  alternateaxes()   Sorts the points as appropriate for the divide-and-    */
/*                    conquer algorithm with alternating cuts.               */
/*                                                                           */
/*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
/*  For the base case, subsets containing only two or three points are       */
/*  always sorted by x-coordinate.                                           */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
/*                 single Delaunay triangulation.                            */
/*                                                                           */
/*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
/*  a triangle-based, rather than edge-based, data structure.                */
/*                                                                           */
/*  The algorithm walks up the gap between the two triangulations, knitting  */
/*  them together.  As they are merged, some of their bounding triangles     */
/*  are converted into real triangles of the triangulation.  The procedure   */
/*  pulls each hull's bounding triangles apart, then knits them together     */
/*  like the teeth of two gears.  The Delaunay property determines, at each  */
/*  step, whether the next "tooth" is a bounding triangle of the left hull   */
/*  or the right.  When a bounding triangle becomes real, its apex is        */
/*  changed from NULL to a real point.                                       */
/*                                                                           */
/*  Only two new triangles need to be allocated.  These become new bounding  */
/*  triangles at the top and bottom of the seam.  They are used to connect   */
/*  the remaining bounding triangles (those that have not been converted     */
/*  into real triangles) into a single fan.                                  */
/*                                                                           */
/*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
/*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
/*  the destination of `innerleft' is the rightmost vertex of the            */
/*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
/*  triangles of the right triangulation.  The origin of `innerright' and    */
/*  destination of `farright' are the leftmost and rightmost vertices.       */
/*                                                                           */
/*  On completion, the origin of `farleft' is the leftmost vertex of the     */
/*  merged triangulation, and the destination of `farright' is the rightmost */
/*  vertex.                                                                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  divconqrecurse()   Recursively form a Delaunay triangulation by the      */
/*                     divide-and-conquer method.                            */
/*                                                                           */
/*  Recursively breaks down the problem into smaller pieces, which are       */
/*  knitted together by mergehulls().  The base cases (problems of two or    */
/*  three points) are handled specially here.                                */
/*                                                                           */
/*  On completion, `farleft' and `farright' are bounding triangles such that */
/*  the origin of `farleft' is the leftmost vertex (breaking ties by         */
/*  choosing the highest leftmost vertex), and the destination of            */
/*  `farright' is the rightmost vertex (breaking ties by choosing the        */
/*  lowest rightmost vertex).                                                */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  divconqdelaunay()   Form a Delaunay triangulation by the divide-and-     */
/*                      conquer method.                                      */
/*                                                                           */
/*  Sorts the points, calls a recursive procedure to triangulate them, and   */
/*  removes the bounding box, setting boundary markers as appropriate.       */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  delaunay()   Form a Delaunay triangulation.                              */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  finddirection()   Find the first triangle on the path from one point     */
/*                    to another.                                            */
/*                                                                           */
/*  Finds the triangle that intersects a line segment drawn from the         */
/*  origin of `searchtri' to the point `endpoint', and returns the result    */
/*  in `searchtri'.  The origin of `searchtri' does not change, even though  */
/*  the triangle returned may differ from the one passed in.  This routine   */
/*  is used to find the direction to move in to get from one point to        */
/*  another.                                                                 */
/*                                                                           */
/*  The return value notes whether the destination or apex of the found      */
/*  triangle is collinear with the two points in question.                   */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  segmentintersection()   Find the intersection of an existing segment     */
/*                          and a segment that is being inserted.  Insert    */
/*                          a point at the intersection, splitting an        */
/*                          existing shell edge.                             */
/*                                                                           */
/*  The segment being inserted connects the apex of splittri to endpoint2.   */
/*  splitshelle is the shell edge being split, and MUST be opposite          */
/*  splittri.  Hence, the edge being split connects the origin and           */
/*  destination of splittri.                                                 */
/*                                                                           */
/*  On completion, splittri is a handle having the newly inserted            */
/*  intersection point as its origin, and endpoint1 as its destination.      */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  scoutsegment()   Scout the first triangle on the path from one endpoint  */
/*                   to another, and check for completion (reaching the      */
/*                   second endpoint), a collinear point, and the            */
/*                   intersection of two segments.                           */
/*                                                                           */
/*  Returns one if the entire segment is successfully inserted, and zero if  */
/*  the job must be finished by conformingedge() or constrainededge().       */
/*                                                                           */
/*  If the first triangle on the path has the second endpoint as its         */
/*  destination or apex, a shell edge is inserted and the job is done.       */
/*                                                                           */
/*  If the first triangle on the path has a destination or apex that lies on */
/*  the segment, a shell edge is inserted connecting the first endpoint to   */
/*  the collinear point, and the search is continued from the collinear      */
/*  point.                                                                   */
/*                                                                           */
/*  If the first triangle on the path has a shell edge opposite its origin,  */
/*  then there is a segment that intersects the segment being inserted.      */
/*  Their intersection point is inserted, splitting the shell edge.          */
/*                                                                           */
/*  Otherwise, return zero.                                                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  delaunayfixup()   Enforce the Delaunay condition at an edge, fanning out */
/*                    recursively from an existing point.  Pay special       */
/*                    attention to stacking inverted triangles.              */
/*                                                                           */
/*  This is a support routine for inserting segments into a constrained      */
/*  Delaunay triangulation.                                                  */
/*                                                                           */
/*  The origin of fixuptri is treated as if it has just been inserted, and   */
/*  the local Delaunay condition needs to be enforced.  It is only enforced  */
/*  in one sector, however, that being the angular range defined by          */
/*  fixuptri.                                                                */
/*                                                                           */
/*  This routine also needs to make decisions regarding the "stacking" of    */
/*  triangles.  (Read the description of constrainededge() below before      */
/*  reading on here, so you understand the algorithm.)  If the position of   */
/*  the new point (the origin of fixuptri) indicates that the vertex before  */
/*  it on the polygon is a reflex vertex, then "stack" the triangle by       */
/*  doing nothing.  (fixuptri is an inverted triangle, which is how stacked  */
/*  triangles are identified.)                                               */
/*                                                                           */
/*  Otherwise, check whether the vertex before that was a reflex vertex.     */
/*  If so, perform an edge flip, thereby eliminating an inverted triangle    */
/*  (popping it off the stack).  The edge flip may result in the creation    */
/*  of a new inverted triangle, depending on whether or not the new vertex   */
/*  is visible to the vertex three edges behind on the polygon.              */
/*                                                                           */
/*  If neither of the two vertices behind the new vertex are reflex          */
/*  vertices, fixuptri and fartri, the triangle opposite it, are not         */
/*  inverted; hence, ensure that the edge between them is locally Delaunay.  */
/*                                                                           */
/*  `leftside' indicates whether or not fixuptri is to the left of the       */
/*  segment being inserted.  (Imagine that the segment is pointing up from   */
/*  endpoint1 to endpoint2.)                                                 */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  constrainededge()   Force a segment into a constrained Delaunay          */
/*                      triangulation by deleting the triangles it           */
/*                      intersects, and triangulating the polygons that      */
/*                      form on each side of it.                             */
/*                                                                           */
/*  Generates a single edge connecting `endpoint1' to `endpoint2'.  The      */
/*  triangle `starttri' has `endpoint1' as its origin.  `newmark' is the     */
/*  boundary marker of the segment.                                          */
/*                                                                           */
/*  To insert a segment, every triangle whose interior intersects the        */
/*  segment is deleted.  The union of these deleted triangles is a polygon   */
/*  (which is not necessarily monotone, but is close enough), which is       */
/*  divided into two polygons by the new segment.  This routine's task is    */
/*  to generate the Delaunay triangulation of these two polygons.            */
/*                                                                           */
/*  You might think of this routine's behavior as a two-step process.  The   */
/*  first step is to walk from endpoint1 to endpoint2, flipping each edge    */
/*  encountered.  This step creates a fan of edges connected to endpoint1,   */
/*  including the desired edge to endpoint2.  The second step enforces the   */
/*  Delaunay condition on each side of the segment in an incremental manner: */
/*  proceeding along the polygon from endpoint1 to endpoint2 (this is done   */
/*  independently on each side of the segment), each vertex is "enforced"    */
/*  as if it had just been inserted, but affecting only the previous         */
/*  vertices.  The result is the same as if the vertices had been inserted   */
/*  in the order they appear on the polygon, so the result is Delaunay.      */
/*                                                                           */
/*  In truth, constrainededge() interleaves these two steps.  The procedure  */
/*  walks from endpoint1 to endpoint2, and each time an edge is encountered  */
/*  and flipped, the newly exposed vertex (at the far end of the flipped     */
/*  edge) is "enforced" upon the previously flipped edges, usually affecting */
/*  only one side of the polygon (depending upon which side of the segment   */
/*  the vertex falls on).                                                    */
/*                                                                           */
/*  The algorithm is complicated by the need to handle polygons that are not */
/*  convex.  Although the polygon is not necessarily monotone, it can be     */
/*  triangulated in a manner similar to the stack-based algorithms for       */
/*  monotone polygons.  For each reflex vertex (local concavity) of the      */
/*  polygon, there will be an inverted triangle formed by one of the edge    */
/*  flips.  (An inverted triangle is one with negative area - that is, its   */
/*  vertices are arranged in clockwise order - and is best thought of as a   */
/*  wrinkle in the fabric of the mesh.)  Each inverted triangle can be       */
/*  thought of as a reflex vertex pushed on the stack, waiting to be fixed   */
/*  later.                                                                   */
/*                                                                           */
/*  A reflex vertex is popped from the stack when a vertex is inserted that  */
/*  is visible to the reflex vertex.  (However, if the vertex behind the     */
/*  reflex vertex is not visible to the reflex vertex, a new inverted        */
/*  triangle will take its place on the stack.)  These details are handled   */
/*  by the delaunayfixup() routine above.                                    */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  markhull()   Cover the convex hull of a triangulation with shell edges.  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  infecthull()   Virally infect all of the triangles of the convex hull    */
/*                 that are not protected by shell edges.  Where there are   */
/*                 shell edges, set boundary markers as appropriate.         */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  plague()   Spread the virus from all infected triangles to any neighbors */
/*             not protected by shell edges.  Delete all infected triangles. */
/*                                                                           */
/*  This is the procedure that actually creates holes and concavities.       */
/*                                                                           */
/*  This procedure operates in two phases.  The first phase identifies all   */
/*  the triangles that will die, and marks them as infected.  They are       */
/*  marked to ensure that each triangle is added to the virus pool only      */
/*  once, so the procedure will terminate.                                   */
/*                                                                           */
/*  The second phase actually eliminates the infected triangles.  It also    */
/*  eliminates orphaned points.                                              */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  regionplague()   Spread regional attributes and/or area constraints      */
/*                   (from a .poly file) throughout the mesh.                */
/*                                                                           */
/*  This procedure operates in two phases.  The first phase spreads an       */
/*  attribute and/or an area constraint through a (segment-bounded) region.  */
/*  The triangles are marked to ensure that each triangle is added to the    */
/*  virus pool only once, so the procedure will terminate.                   */
/*                                                                           */
/*  The second phase uninfects all infected triangles, returning them to     */
/*  normal.                                                                  */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  carveholes()   Find the holes and infect them.  Find the area            */
/*                 constraints and infect them.  Infect the convex hull.     */
/*                 Spread the infection and kill triangles.  Spread the      */
/*                 area constraints.                                         */
/*                                                                           */
/*  This routine mainly calls other routines to carry out all these          */
/*  functions.                                                               */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  findcircumcenter()   Find the circumcenter of a triangle.                */
/*                                                                           */
/*  The result is returned both in terms of x-y coordinates and xi-eta       */
/*  coordinates.  The xi-eta coordinate system is defined in terms of the    */
/*  triangle:  the origin of the triangle is the origin of the coordinate    */
/*  system; the destination of the triangle is one unit along the xi axis;   */
/*  and the apex of the triangle is one unit along the eta axis.             */
/*                                                                           */
/*  The return value indicates which edge of the triangle is shortest.       */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  highorder()   Create extra nodes for quadratic subparametric elements.   */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  numbernodes()   Number the points.                                       */
/*                                                                           */
/*  Each point is assigned a marker equal to its number.                     */
/*                                                                           */
/*  Used when writenodes() is not called because no .node file is written.   */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  quality_statistics()   Print statistics about the quality of the mesh.   */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/*  statistics()   Print all sorts of cool facts.                            */
/*                                                                           */
/*****************************************************************************/


/*
 * Create the mon Panel
 */


/*
 * Create the wparam Frame and the wparam Panel
 */


/*
 * Create the status Panel
 */


/*
 * Main properties popup
 */


/*
 * included for prop
 */


/*
 * Depths at elements
 */


/*
 * Draw build points
 */


/*
 * After triangulating build points load them to the grid, replacing
 * the grid's nodes and elements.
 */


/*
 * Load build points from grid gridno
 */


/*
 * Merge the grid's nodal points with the current set of build points.
 */


/* for communication between compare_build
				 * and elim_build_dupes */


/*
 * Allocate storage for build points struct bno of length npts
 */


/*
 * Resize a build bpoints structure
 */


/*
 * Add a single build point
 */


/*
 * Add an array of build points
 */


/*
 * Free a build points structure
 */


/*
 * Free all build points structures
 */


/*
 * Initialize all build points structures
 */


/*
 * Get the next available build points structure
 */


/*
 * set hardcopy flag and if writing to a file, check
 * to see if it exists
 */


/*
 * Create the locator Panel
 */


/*
 * device2world - given (x,y) in screen coordinates, return the world coordinates
 *             in (wx,wy) used for the display only
 */


/*
 * device2view - given (x,y) in screen coordinates, return the viewport coordinates
 */


/*
 * view2world - given (vx,vy) in viewport coordinates, return world coordinates
 *            in (x,y)
 */


/*
 * world2deviceabs - given world coordinates (wx,wy) return the device coordinates,
 *              for the display only
 */


/*
 * world2device - given world coordinates (wx,wy) return the device coordinates,
 *              for the display only
 */


/*
 * map world co-ordinates to viewport
 */


/*
 * defineworld - really should be called definewindow, defines the scaling
 *               of the plotting rectangle to be used for clipping
 */


/*
 * viewport - define the location of the clipping rectangle defined by
 *            defineworld on the display device
 */


/*
 * clip lines within rectangle defined in world coordinates
 */


/*
 * liang-barsky line clipping, the default as of v2.05
 */