]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - contrib/gtkgensurf/dec.cpp
more eol-style
[xonotic/netradiant.git] / contrib / gtkgensurf / dec.cpp
index 4dbedf8cf518784704214d1c258638085365ec81..c8569a6e1ca54b75e17403e9a5db8ad8091186a0 100644 (file)
-/*\r
-GenSurf plugin for GtkRadiant\r
-Copyright (C) 2001 David Hyde, Loki software and qeradiant.com\r
-\r
-This library is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU Lesser General Public\r
-License as published by the Free Software Foundation; either\r
-version 2.1 of the License, or (at your option) any later version.\r
-\r
-This library is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-Lesser General Public License for more details.\r
-\r
-You should have received a copy of the GNU Lesser General Public\r
-License along with this library; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
-*/\r
-\r
-#define SINGLE\r
-#ifdef SINGLE\r
-#define REAL float\r
-#else /* not SINGLE */\r
-#define REAL double\r
-#endif /* not SINGLE */\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <math.h>\r
-#include "gensurf.h"\r
-#include "triangle.h"\r
-\r
-typedef struct\r
-{\r
-       float error;\r
-       int   node;\r
-} TRITABLE;\r
-\r
-double dh, dv;\r
-int    NVP1;\r
-\r
-#define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))\r
-\r
-void MakeDecimatedMap(int *NumNodes, int *NumTris, NODE **pNode, TRI **pTri)\r
-{\r
-       int  compare(TRITABLE *, TRITABLE *);\r
-       int Bisect(NODE *, int, int, int);\r
-       void CalcAngles(NODE *, int *, float *);\r
-       void EdgeOnSide(int *, int *, int *);\r
-       int tricall(int, NODE *, int *, TRI **, TRI **, char *);\r
-       int CheckBorders(int *,int,NODE *,int *,TRI **);\r
-\r
-       float       biggesterror;\r
-       int         i, j, N;\r
-       int         j0, j1, j2;\r
-       int         NumNodesToSave;\r
-       int         NumNodesUsed;\r
-       NODE        *Node;\r
-       TRI         *Tri;\r
-       TRITABLE    *TriTable;\r
-\r
-       if(Decimate <= 0) return;\r
-        /*\r
-       ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);\r
-       SetCursor(ghCursorCurrent);\r
-        */\r
-       dh = (Hur-Hll)/NH;\r
-       dv = (Vur-Vll)/NV;\r
-       NVP1 = NV+1;\r
-\r
-       NumNodes[0] = (NH+1)*(NVP1);\r
-       *pNode = (NODE *) malloc(NumNodes[0] * sizeof(NODE));\r
-       Node = *pNode;\r
-       memset(Node,0,NumNodes[0]*sizeof(NODE));\r
-\r
-       // Copy [NH][NV] vertex array to our working node array\r
-       for(i=0,N=0; i<=NH; i++)\r
-       {\r
-               for(j=0; j<=NV; j++, N++)\r
-               {\r
-                       Node[N].p[0]  = (float)xyz[i][j].p[0];\r
-                       Node[N].p[1]  = (float)xyz[i][j].p[1];\r
-                       Node[N].p[2]  = (float)xyz[i][j].p[2];\r
-                       Node[N].fixed = xyz[i][j].fixed;\r
-               }\r
-       }\r
-       // Start things off with the corner values\r
-       Node[ 0].used           = 1;\r
-       Node[NV].used           = 1;\r
-       Node[NH*NVP1].used    = 1;\r
-       Node[NH*NVP1+NV].used = 1;\r
-       NumNodesUsed = 4;\r
-       tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");\r
-       Tri = *pTri;\r
-\r
-       // Which coordinates are we triangulating on?\r
-       switch(Plane)\r
-       {\r
-       case PLANE_XZ0:\r
-       case PLANE_XZ1:\r
-               j0 = 1;\r
-               j1 = 0;\r
-               j2 = 2;\r
-               break;\r
-       case PLANE_YZ0:\r
-       case PLANE_YZ1:\r
-               j0 = 0;\r
-               j1 = 1;\r
-               j2 = 2;\r
-               break;\r
-       default:\r
-               j0 = 2;\r
-               j1 = 0;\r
-               j2 = 1;\r
-       }\r
-\r
-       // TriTable stores the largest error in a triangle and the node where that\r
-       // error occurs\r
-       TriTable = (TRITABLE *) malloc(NH*NV*2 * sizeof(TRITABLE));\r
-       NumNodesToSave = min(NumNodes[0], (int)(0.01*(100-Decimate)*(NumNodes[0]-NumNodesUsed)+NumNodesUsed));\r
-\r
-       while(NumNodesUsed < NumNodesToSave)\r
-       {\r
-               for(i=0; i<NumTris[0]; i++)\r
-                       Tri[i].flag = 0;\r
-\r
-               // For every node that's not currently used, find what triangle it\r
-               // lies on, and the error at this node\r
-               for(i=0, biggesterror=0; i<NumNodes[0]; i++)\r
-               {\r
-                       if(Node[i].used) continue;\r
-                       for(j=0, Node[i].tri=-1; (j<NumTris[0]) && (Node[i].tri==-1); j++)\r
-                       {\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                            Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],\r
-                                            Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                            Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],\r
-                                            Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                            Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],\r
-                                            Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;\r
-                               Node[i].tri = j;\r
-                       }\r
-                       if(Node[i].tri < 0)\r
-                       {\r
-                          /*\r
-                               ghCursorCurrent = ghCursorDefault;\r
-                               SetCursor(ghCursorCurrent);\r
-                          */\r
-                               g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,\r
-                                       "Error: Couldn't find the triangle bounding a point.",\r
-                                       "Decimation Error",MB_ICONEXCLAMATION);\r
-                               return;\r
-                       }\r
-                       if(!Tri[Node[i].tri].flag)\r
-                       {\r
-                               PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,\r
-                                               Node[Tri[Node[i].tri].v[1]].p,\r
-                                               Node[Tri[Node[i].tri].v[2]].p,\r
-                                                               &Tri[Node[i].tri].plane);\r
-                               Tri[Node[i].tri].flag = 1;\r
-                       }\r
-                       Node[i].error =\r
-                               Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -\r
-                                                            Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -\r
-                                                                Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/\r
-                                                                Tri[Node[i].tri].plane.normal[j0];\r
-                       biggesterror = max(biggesterror,Absolute(Node[i].error));\r
-               }\r
-               if(biggesterror == 0)\r
-                       NumNodesToSave = NumNodesUsed;\r
-               else\r
-               {\r
-                       // For all current triangles, build a list of worst-case nodes\r
-                       memset(TriTable,0,NH*NV*2*sizeof(TRITABLE));\r
-                       for(i=0; i<NumNodes[0]; i++)\r
-                       {\r
-                               if(Node[i].used) continue;\r
-                               if(Absolute(Node[i].error) > TriTable[Node[i].tri].error)\r
-                               {\r
-                                       TriTable[Node[i].tri].error = (float)(Absolute(Node[i].error));\r
-                                       TriTable[Node[i].tri].node  = i;\r
-                               }\r
-                       }\r
-                       qsort( (void *)TriTable, (size_t)(NumTris[0]), sizeof(TRITABLE), (int (*)(const void *, const void *))compare );\r
-                       for(i=0; i<NumTris[0] && NumNodesUsed < NumNodesToSave && TriTable[i].error > 0.5*biggesterror; i++)\r
-                       {\r
-                               if(Node[TriTable[i].node].used) continue;  // shouldn't happen\r
-                               NumNodesUsed++;\r
-                               Node[TriTable[i].node].used++;\r
-                       }\r
-                       free(Tri);\r
-                       tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");\r
-                       Tri = *pTri;\r
-                       // Sliver-check along borders. Since borders are often linear, the errors\r
-                       // along borders will often be zero, so no new points will be added. This\r
-                       // tends to produce long, thin brushes. For all border triangles, check \r
-                       // that minimum angle isn't less than SLIVER_ANGLE. If it is, add another\r
-                       // vertex.\r
-                       while(CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri) > 0)\r
-                       {\r
-                       }\r
-                       Tri = *pTri;\r
-               }\r
-       }\r
-       free(TriTable);\r
-       // One last time (because we're pessimistic), check border triangles\r
-//     CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri);\r
-//     Tri = *pTri;\r
-\r
-       // Check that all fixed points are exact. If not, add them to the mix.\r
-       // First check to see if we have any fixed points that aren't already used.\r
-       for(i=0, N=0; i<NumNodes[0] && !N; i++)\r
-       {\r
-               if(Node[i].used) continue;\r
-               if(Node[i].fixed) N++;\r
-       }\r
-       if(N)\r
-       {\r
-               // Zero out the flag member of all triangles, indicating that\r
-               // the plane equation has not been found.\r
-               for(i=0; i<NumTris[0]; i++)\r
-                       Tri[i].flag = 0;\r
-\r
-               for(i=0; i<NumNodes[0]; i++)\r
-               {\r
-                       if(Node[i].used) continue;\r
-                       if(!Node[i].fixed) continue;\r
-                       Node[i].tri = -1;\r
-                       for(j=0; j<NumTris[0] && Node[i].tri==-1; j++)\r
-                       {\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                       Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],\r
-                                       Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                       Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],\r
-                                       Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;\r
-                               if( side(Node[i].p[j1],          Node[i].p[j2],\r
-                                       Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],\r
-                                       Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;\r
-                               Node[i].tri = j;\r
-                       }\r
-                       if(Node[i].tri < 0)\r
-                       {\r
-                          /*\r
-                               ghCursorCurrent = ghCursorDefault;\r
-                               SetCursor(ghCursorCurrent);\r
-                          */\r
-                               g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,\r
-                                       "Error: Couldn't find the triangle bounding a point.",\r
-                                       "Decimation Error",MB_ICONEXCLAMATION);\r
-                               return;\r
-                       }\r
-                       if(!Tri[Node[i].tri].flag)\r
-                       {\r
-                               PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,\r
-                                                   Node[Tri[Node[i].tri].v[1]].p,\r
-                                               Node[Tri[Node[i].tri].v[2]].p,\r
-                                               &Tri[Node[i].tri].plane);\r
-                               Tri[Node[i].tri].flag = 1;\r
-                       }\r
-                       Node[i].error =\r
-                               Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -\r
-                               Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -\r
-                               Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/\r
-                               Tri[Node[i].tri].plane.normal[j0];\r
-                       if(Absolute(Node[i].error) > 0.5)\r
-                       {\r
-                               NumNodesUsed++;\r
-                               Node[i].used++;\r
-                               free(Tri);\r
-                               tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");\r
-                               Tri = *pTri;\r
-                       }\r
-               }\r
-       }\r
-\r
-       // Swap node orders for surfaces facing down, north or west so that\r
-       // they are counterclockwise when facing the surface\r
-\r
-       if((Plane == PLANE_XY1) || (Plane == PLANE_XZ0) || (Plane == PLANE_YZ1) )\r
-       {\r
-               for(i=0; i<NumTris[0]; i++)\r
-               {\r
-                       j = Tri[i].v[1];\r
-                       Tri[i].v[1] = Tri[i].v[2];\r
-                       Tri[i].v[2] = j;\r
-               }\r
-       }\r
-\r
-       // Store bounding box coords\r
-       for(i=0; i<NumTris[0]; i++)\r
-       {\r
-               Tri[i].min[0] =                   Node[Tri[i].v[0]].p[0];\r
-               Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[1]].p[0]);\r
-               Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[2]].p[0]);\r
-               Tri[i].min[1] =                   Node[Tri[i].v[0]].p[1];\r
-               Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[1]].p[1]);\r
-               Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[2]].p[1]);\r
-               Tri[i].min[2] =                   Node[Tri[i].v[0]].p[2];\r
-               Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[1]].p[2]);\r
-               Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[2]].p[2]);\r
-               Tri[i].max[0] =                   Node[Tri[i].v[0]].p[0];\r
-               Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[1]].p[0]);\r
-               Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[2]].p[0]);\r
-               Tri[i].max[1] =                   Node[Tri[i].v[0]].p[1];\r
-               Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[1]].p[1]);\r
-               Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[2]].p[1]);\r
-               Tri[i].max[2] =                   Node[Tri[i].v[0]].p[2];\r
-               Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[1]].p[2]);\r
-               Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[2]].p[2]);\r
-       }\r
-        /*\r
-       ghCursorCurrent = ghCursorDefault;\r
-       SetCursor(ghCursorCurrent);\r
-        */\r
-}\r
-/* end MakeDecimatedMap */\r
-\r
-/*****************************************************************************/\r
-/*                                                                           */\r
-/*  tricall Takes an array of nodes, spits out an array of triangles         */\r
-/*                                                                           */\r
-/*****************************************************************************/\r
-int tricall(int NumNodes, NODE *Node, int *NumTris, TRI **inTri, TRI **Tri, LPSTR Options)\r
-{\r
-\r
-       struct triangulateio in, out;\r
-       int    i, N;\r
-       int    NumUsedNodes;\r
-       int    *NodeTable;\r
-       TRI    *ptri;\r
-\r
-       /* Define input points. */\r
-\r
-       for(i=0,NumUsedNodes=0; i<NumNodes; i++)\r
-               if(Node[i].used) NumUsedNodes++;\r
-\r
-       memset(&in, 0,sizeof(in));\r
-       memset(&out,0,sizeof(out));\r
-\r
-       NodeTable = (int *) malloc(NumUsedNodes * sizeof(int));\r
-\r
-       in.numberofpoints = NumUsedNodes;\r
-       in.numberofpointattributes = 0;\r
-       in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));\r
-       for(i=0,N=0; i<NumNodes; i++)\r
-       {\r
-               if(Node[i].used)\r
-               {\r
-                       switch(Plane)\r
-                       {\r
-                       case PLANE_XZ0:\r
-                       case PLANE_XZ1:\r
-                               in.pointlist[N*2  ] = Node[i].p[0];\r
-                               in.pointlist[N*2+1] = Node[i].p[2];\r
-                               break;\r
-                       case PLANE_YZ0:\r
-                       case PLANE_YZ1:\r
-                               in.pointlist[N*2  ] = Node[i].p[1];\r
-                               in.pointlist[N*2+1] = Node[i].p[2];\r
-                               break;\r
-                       default:\r
-                               in.pointlist[N*2  ] = Node[i].p[0];\r
-                               in.pointlist[N*2+1] = Node[i].p[1];\r
-                       }\r
-                       NodeTable[N] = i;\r
-                       N++;\r
-               }\r
-       }\r
-       in.pointattributelist = (REAL *) NULL;\r
-       in.pointmarkerlist    = (int *) NULL;\r
-\r
-       if(strstr(Options,"r"))\r
-       {\r
-               int    *TriTable;\r
-               TriTable = (int *) malloc(NumNodes * sizeof(int));\r
-               for(i=0,N=0; i<NumNodes; i++)\r
-               {\r
-                       if(Node[i].used)\r
-                       {\r
-                               TriTable[i] = N;\r
-                               N++;\r
-                       }\r
-               }\r
-               in.numberoftriangles          = NumTris[0];\r
-               in.numberofcorners            = 3;\r
-               in.numberoftriangleattributes = 0;\r
-               in.trianglelist               = (int *) malloc(in.numberofcorners * in.numberoftriangles * sizeof(int));\r
-               in.triangleattributelist      = (REAL *) NULL;\r
-               in.trianglearealist           = (REAL *) NULL;\r
-               ptri = *inTri;\r
-               for(i=0; i<in.numberoftriangles; i++)\r
-               {\r
-                       in.trianglelist[i*in.numberofcorners  ] = TriTable[ptri[i].v[0]];\r
-                       in.trianglelist[i*in.numberofcorners+1] = TriTable[ptri[i].v[1]];\r
-                       in.trianglelist[i*in.numberofcorners+2] = TriTable[ptri[i].v[2]];\r
-               }\r
-               free(TriTable);\r
-       }\r
-       else\r
-       {\r
-               in.numberoftriangles          = 0;\r
-               in.numberofcorners            = 3;\r
-               in.numberoftriangleattributes = 0;\r
-               in.trianglelist               = (int *) NULL;\r
-               in.triangleattributelist      = (REAL *) NULL;\r
-               in.trianglearealist           = (REAL *) NULL;\r
-       }\r
-\r
-       in.numberofsegments   = 0;\r
-       in.segmentlist        = (int *) NULL;\r
-       in.segmentmarkerlist  = (int *) NULL;\r
-\r
-       in.numberofholes      = 0;\r
-       in.holelist           = (REAL *) NULL;\r
-\r
-       in.numberofregions    = 0;\r
-       in.regionlist         = (REAL *) NULL;\r
-\r
-       in.numberofedges      = 0;\r
-       in.edgelist           = (int *) NULL;\r
-       in.edgemarkerlist     = (int *) NULL;\r
-       in.normlist           = (REAL *) NULL;\r
-\r
-       /* Make necessary initializations */\r
-       out.pointlist          = (REAL *) NULL;  /* Not needed if -N switch used. */\r
-       out.pointattributelist = (REAL *) NULL;  /* Not needed if -N switch used or \r
-                                                   number of point attributes is zero: */\r
-       out.pointmarkerlist    = (int *) NULL;   /* Not needed if -N or -B switch used. */\r
-       out.trianglelist       = (int *) NULL;   /* Not needed if -E switch used. */\r
-       out.triangleattributelist = (REAL *) NULL;   /* Not needed if -E switch used or \r
-                                                       number of triangle attributes is \r
-                                                    zero: */\r
-       out.trianglearealist   = (REAL *) NULL;\r
-       out.neighborlist       = (int *) NULL;   /* Needed only if -n switch used. */\r
-       out.segmentlist        = (int *) NULL;   /* Needed only if segments are output \r
-                                                   (-p or -c) and -P not used: */\r
-       out.segmentmarkerlist  = (int *) NULL;   /* Needed only if segments are output \r
-                                                   (-p or -c) and -P and -B not used: */\r
-       out.edgelist           = (int *) NULL;   /* Needed only if -e switch used. */\r
-       out.edgemarkerlist     = (int *) NULL;   /* Needed if -e used and -B not used. */\r
-\r
-       triangulate(Options, &in, &out, NULL);\r
-\r
-       NumTris[0] = out.numberoftriangles;\r
-       *Tri = (TRI *) malloc(NumTris[0] * sizeof(TRI));\r
-       ptri = *Tri;\r
-\r
-       for(i=0; i<NumTris[0]; i++)\r
-       {\r
-               ptri[i].v[0] = NodeTable[out.trianglelist[i*out.numberofcorners  ]];\r
-               ptri[i].v[1] = NodeTable[out.trianglelist[i*out.numberofcorners+1]];\r
-               ptri[i].v[2] = NodeTable[out.trianglelist[i*out.numberofcorners+2]];\r
-               ptri[i].n[0] = out.neighborlist[i*3  ];\r
-               ptri[i].n[1] = out.neighborlist[i*3+1];\r
-               ptri[i].n[2] = out.neighborlist[i*3+2];\r
-       }\r
-\r
-       /* Free all allocated arrays, including those allocated by Triangle. */\r
-       if(in.pointlist)              free(in.pointlist);\r
-       if(in.pointattributelist)     free(in.pointattributelist);\r
-       if(in.pointmarkerlist)        free(in.pointmarkerlist);\r
-       if(in.trianglelist)           free(in.trianglelist);\r
-       if(in.triangleattributelist)  free(in.triangleattributelist);\r
-       if(in.trianglearealist)       free(in.trianglearealist);\r
-       if(in.neighborlist)           free(in.neighborlist);\r
-       if(in.segmentlist)            free(in.segmentlist);\r
-       if(in.segmentmarkerlist)      free(in.segmentmarkerlist);\r
-       if(in.holelist)               free(in.holelist);\r
-       if(in.regionlist)             free(in.regionlist);\r
-       if(in.edgelist)               free(in.edgelist);\r
-       if(in.edgemarkerlist)         free(in.edgemarkerlist);\r
-       if(in.normlist)               free(in.normlist);\r
-       if(out.pointlist)             free(out.pointlist);\r
-       if(out.pointattributelist)    free(out.pointattributelist);\r
-       if(out.pointmarkerlist)       free(out.pointmarkerlist);\r
-       if(out.trianglelist)          free(out.trianglelist);\r
-       if(out.triangleattributelist) free(out.triangleattributelist);\r
-       if(out.trianglearealist)      free(out.trianglearealist);\r
-       if(out.neighborlist)          free(out.neighborlist);\r
-       if(out.segmentlist)           free(out.segmentlist);\r
-       if(out.segmentmarkerlist)     free(out.segmentmarkerlist);\r
-       if(out.holelist)              free(out.holelist);\r
-       if(out.regionlist)            free(out.regionlist);\r
-       if(out.edgelist)              free(out.edgelist);\r
-       if(out.edgemarkerlist)        free(out.edgemarkerlist);\r
-       if(out.normlist)              free(out.normlist);\r
-\r
-       free(NodeTable);\r
-       return 0;\r
-}\r
-\r
-void EdgeOnSide(int *v, int *edge, int *border)\r
-{\r
-       int R;\r
-       int k0, k1, N;\r
-       float Ndv;\r
-\r
-       border[0] = -1;\r
-\r
-       if( (v[0] <= NV) && (v[1] <= NV) )\r
-       {\r
-               edge[0]   = 0;\r
-               border[0] = 0;\r
-       }\r
-       if( (v[1] <= NV) && (v[2] <= NV) )\r
-       {\r
-               edge[0]   = 1;\r
-               border[0] = 0;\r
-       }\r
-       if( (v[2] <= NV) && (v[0] <= NV) )\r
-       {\r
-               edge[0]   = 2;\r
-               border[0] = 0;\r
-       }\r
-\r
-       R = NH*NVP1;\r
-\r
-       if( (v[0] >= R) && (v[1] >= R) )\r
-       {\r
-               edge[0]   = 0;\r
-               border[0] = 1;\r
-       }\r
-       if( (v[1] >= R) && (v[2] >= R) )\r
-       {\r
-               edge[0]   = 1;\r
-               border[0] = 1;\r
-       }\r
-       if( (v[2] >= R) && (v[0] >= R) )\r
-       {\r
-               edge[0]   = 2;\r
-               border[0] = 1;\r
-       }\r
-\r
-       if(border[0] >= 0)\r
-       {\r
-               k0  = edge[0];\r
-               k1  = (k0+1) % 3;\r
-               N   = Absolute(v[k0] - v[k1]);\r
-               Ndv = (float)(N*dv);\r
-       }\r
-       if( ((v[0] % NVP1) == 0)  && ((v[1] % NVP1) == 0) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[0] - v[1])*dh)) return;\r
-               edge[0]   = 0;\r
-               border[0] = 2;\r
-               return;\r
-       }\r
-       if( ((v[1] % NVP1) == 0)  && ((v[2] % NVP1) == 0) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[1] - v[2])*dh)) return;\r
-               edge[0]   = 1;\r
-               border[0] = 2;\r
-               return;\r
-       }\r
-       if( ((v[2] % NVP1) == 0)  && ((v[0] % NVP1) == 0) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[2] - v[0])*dh)) return;\r
-               edge[0]   = 2;\r
-               border[0] = 2;\r
-               return;\r
-       }\r
-\r
-       if( ((v[0] % NVP1) == NV) && ((v[1] % NVP1) == NV) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[0] - v[1])*dh)) return;\r
-               edge[0]   = 0;\r
-               border[0] = 3;\r
-               return;\r
-       }\r
-       if( ((v[1] % NVP1) == NV) && ((v[2] % NVP1) == NV) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[1] - v[2])*dh)) return;\r
-               edge[0]   = 1;\r
-               border[0] = 3;\r
-               return;\r
-       }\r
-       if( ((v[2] % NVP1) == NV) && ((v[0] % NVP1) == NV) )\r
-       {\r
-               if(border[0] >= 0)\r
-                       if( Ndv > (Absolute(v[2] - v[0])*dh)) return;\r
-               edge[0]   = 2;\r
-               border[0] = 3;\r
-               return;\r
-       }\r
-       return;\r
-}\r
-\r
-void CalcAngles(NODE *node, int *v, float *angle)\r
-{\r
-       int i, j, k;\r
-       vec l;\r
-       vec x0, x1, x2, y0, y1, y2;\r
-       vec2 vv[3];\r
-       vec dot;\r
-\r
-       switch(Plane)\r
-       {\r
-       case PLANE_XZ0:\r
-       case PLANE_XZ1:\r
-               i = 0;\r
-               j = 2;\r
-               break;\r
-       case PLANE_YZ0:\r
-       case PLANE_YZ1:\r
-               i = 1;\r
-               j = 2;\r
-               break;\r
-       default:\r
-               i = 0;\r
-               j = 1;\r
-       }\r
-       x0 = node[v[0]].p[i];\r
-       x1 = node[v[1]].p[i];\r
-       x2 = node[v[2]].p[i];\r
-       y0 = node[v[0]].p[j];\r
-       y1 = node[v[1]].p[j];\r
-       y2 = node[v[2]].p[j];\r
-\r
-       vv[0][0] = x1-x0;\r
-       vv[0][1] = y1-y0;\r
-       vv[1][0] = x2-x1;\r
-       vv[1][1] = y2-y1;\r
-       vv[2][0] = x0-x2;\r
-       vv[2][1] = y0-y2;\r
-\r
-       for(k=0; k<3; k++)\r
-       {\r
-               l = (vec)(sqrt( vv[k][0]*vv[k][0] + vv[k][1]*vv[k][1] ));\r
-               if(l > 0.)\r
-               {\r
-                       vv[k][0] /= l;\r
-                       vv[k][1] /= l;\r
-               }\r
-       }\r
-\r
-       dot = -(vv[0][0]*vv[2][0] + vv[0][1]*vv[2][1]);\r
-       angle[0] = (float)(acos(dot));\r
-       dot = -(vv[1][0]*vv[0][0] + vv[1][1]*vv[0][1]);\r
-       angle[1] = (float)(acos(dot));\r
-       dot = -(vv[2][0]*vv[1][0] + vv[2][1]*vv[1][1]);\r
-       angle[2] = (float)(acos(dot));\r
-}\r
-//=================================================================\r
-int Bisect(NODE *node, int border, int j0, int j1)\r
-{\r
-       int k;\r
-\r
-       switch(border)\r
-       {\r
-       case 0:\r
-               k = (j0+j1)/2;\r
-               break;\r
-       case 1:\r
-               k = (j0+j1)/2;\r
-               break;\r
-       case 2:\r
-               k = (int)((j0+j1)/(2*NVP1)) * NVP1;\r
-               break;\r
-       case 3:\r
-               k = (int)((j0+j1+2)/(2*NVP1)) * NVP1 - 1;\r
-               break;\r
-       }\r
-       return( ((k != j0) && (k != j1)) ? k : 0 );\r
-}\r
-//=================================================================\r
-int compare(TRITABLE *t1, TRITABLE *t2)\r
-{\r
-       if(t1->error > t2->error) return -1;\r
-       if(t1->error < t2->error) return  1;\r
-       return 0;\r
-}\r
-\r
-void MakeBrushes(int NumTris, NODE *Node, TRI *Tri,bool surf,\r
-                                int offset,char *texture0, char *texture1, char *texture2)\r
-{\r
-       extern double backface;\r
-       BRUSH   brush;\r
-       int             contents;\r
-       int             i, j;\r
-       float   Steep;\r
-       vec3_t  PlaneNormal,SurfNormal;\r
-       bool    CheckAngle;\r
-       vec3_t  t[2];\r
-\r
-       // if texture2 is identical to texture0, there's no need to\r
-       // check surface angle\r
-       if(!g_strcasecmp(texture0,texture2) || !strlen(texture2))\r
-               CheckAngle = FALSE;\r
-       else\r
-       {\r
-               CheckAngle = TRUE;\r
-               Steep = (float)cos((double)SlantAngle/57.2957795);\r
-               switch(Plane)\r
-               {\r
-               case PLANE_XY0: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;\r
-               case PLANE_XY1: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]=-1.;break;\r
-               case PLANE_XZ0: PlaneNormal[0]= 0.;PlaneNormal[1]= 1.;PlaneNormal[2]= 1.;break;\r
-               case PLANE_XZ1: PlaneNormal[0]= 0.;PlaneNormal[1]=-1.;PlaneNormal[2]= 1.;break;\r
-               case PLANE_YZ0: PlaneNormal[0]= 1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;\r
-               case PLANE_YZ1: PlaneNormal[0]=-1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;\r
-               }\r
-       }\r
-\r
-       contents = 0;\r
-       if(surf)\r
-       {\r
-               if(UseDetail) contents += CONTENTS_DETAIL;\r
-               if(UseLadder) contents += CONTENTS_LADDER;\r
-       }\r
-       \r
-       OpenFuncGroup();\r
-       for(i=0; i<NumTris; i++)\r
-       {\r
-               brush.Number   = i;\r
-               brush.NumFaces = 5;\r
-               // front\r
-               brush.face[0].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-               brush.face[0].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-               brush.face[0].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-               \r
-               brush.face[0].v[1][0] = Node[Tri[i].v[2]].p[0];\r
-               brush.face[0].v[1][1] = Node[Tri[i].v[2]].p[1];\r
-               brush.face[0].v[1][2] = Node[Tri[i].v[2]].p[2];\r
-               \r
-               brush.face[0].v[2][0] = Node[Tri[i].v[1]].p[0];\r
-               brush.face[0].v[2][1] = Node[Tri[i].v[1]].p[1];\r
-               brush.face[0].v[2][2] = Node[Tri[i].v[1]].p[2];\r
-\r
-               if(offset != 0)\r
-               {\r
-                       switch(Plane)\r
-                       {\r
-                       case PLANE_XY0:\r
-                               brush.face[0].v[0][2] += offset;\r
-                               brush.face[0].v[1][2] += offset;\r
-                               brush.face[0].v[1][2] += offset;\r
-                               break;\r
-                       case PLANE_XY1:\r
-                               brush.face[0].v[0][2] -= offset;\r
-                               brush.face[0].v[1][2] -= offset;\r
-                               brush.face[0].v[1][2] -= offset;\r
-                               break;\r
-                       case PLANE_XZ0:\r
-                               brush.face[0].v[0][1] += offset;\r
-                               brush.face[0].v[1][1] += offset;\r
-                               brush.face[0].v[1][1] += offset;\r
-                               break;\r
-                       case PLANE_XZ1:\r
-                               brush.face[0].v[0][1] -= offset;\r
-                               brush.face[0].v[1][1] -= offset;\r
-                               brush.face[0].v[1][1] -= offset;\r
-                               break;\r
-                       case PLANE_YZ0:\r
-                               brush.face[0].v[0][0] += offset;\r
-                               brush.face[0].v[1][0] += offset;\r
-                               brush.face[0].v[1][0] += offset;\r
-                               break;\r
-                       case PLANE_YZ1:\r
-                               brush.face[0].v[0][0] -= offset;\r
-                               brush.face[0].v[1][0] -= offset;\r
-                               brush.face[0].v[1][0] -= offset;\r
-                               break;\r
-                       }\r
-               }\r
-               switch(Plane)\r
-               {\r
-               case PLANE_XZ0:\r
-               case PLANE_XZ1:\r
-                       // back\r
-                       brush.face[1].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[1].v[0][1] = (float)backface;\r
-                       brush.face[1].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[1].v[1][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[1].v[1][1] = (float)backface;\r
-                       brush.face[1].v[1][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[1].v[2][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[1].v[2][1] = (float)backface;\r
-                       brush.face[1].v[2][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       // 0-1 side\r
-                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[2].v[2][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[2].v[2][1] = (float)backface;\r
-                       brush.face[2].v[2][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       // 1-2 side\r
-                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[3].v[2][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[3].v[2][1] = (float)backface;\r
-                       brush.face[3].v[2][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       // 2-0 side\r
-                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[4].v[2][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[4].v[2][1] = (float)backface;\r
-                       brush.face[4].v[2][2] = Node[Tri[i].v[0]].p[2];\r
-                       break;\r
-               case PLANE_YZ0:\r
-               case PLANE_YZ1:\r
-                       // back\r
-                       brush.face[1].v[0][0] = (float)backface;\r
-                       brush.face[1].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[1].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[1].v[1][0] = (float)backface;\r
-                       brush.face[1].v[1][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[1].v[1][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[1].v[2][0] = (float)backface;\r
-                       brush.face[1].v[2][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[1].v[2][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       // 0-1 side\r
-                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[2].v[2][0] = (float)backface;\r
-                       brush.face[2].v[2][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[2].v[2][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       // 1-2 side\r
-                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[3].v[2][0] = (float)backface;\r
-                       brush.face[3].v[2][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[3].v[2][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       // 2-0 side\r
-                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[4].v[2][0] = (float)backface;\r
-                       brush.face[4].v[2][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[4].v[2][2] = Node[Tri[i].v[0]].p[2];\r
-                       break;\r
-               default:\r
-                       // back\r
-                       brush.face[1].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[1].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[1].v[0][2] = (float)backface;\r
-                       \r
-                       brush.face[1].v[1][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[1].v[1][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[1].v[1][2] = (float)backface;\r
-                       \r
-                       brush.face[1].v[2][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[1].v[2][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[1].v[2][2] = (float)backface;\r
-                       \r
-                       // 0-1 side\r
-                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[2].v[2][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[2].v[2][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[2].v[2][2] = (float)backface;\r
-                       \r
-                       // 1-2 side\r
-                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];\r
-                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];\r
-                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];\r
-                       \r
-                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[3].v[2][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[3].v[2][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[3].v[2][2] = (float)backface;\r
-                       \r
-                       // 2-0 side\r
-                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];\r
-                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];\r
-                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];\r
-                       \r
-                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];\r
-                       \r
-                       brush.face[4].v[2][0] = Node[Tri[i].v[0]].p[0];\r
-                       brush.face[4].v[2][1] = Node[Tri[i].v[0]].p[1];\r
-                       brush.face[4].v[2][2] = (float)backface;\r
-               }\r
-               \r
-               for(j=0; j<5; j++)\r
-               {\r
-                       strcpy(brush.face[j].texture,\r
-                               (strlen(texture1) ? texture1 : texture0));\r
-                       brush.face[j].Shift[0] = (float)TexOffset[0];\r
-                       brush.face[j].Shift[1] = (float)TexOffset[1];\r
-                       brush.face[j].Rotate   = 0.;\r
-                       brush.face[j].Scale[0] = (float)TexScale[0];\r
-                       brush.face[j].Scale[1] = (float)TexScale[1];\r
-                       brush.face[j].Contents = contents;\r
-                       if(surf)\r
-                               brush.face[j].Surface = 0;\r
-                       else\r
-                               brush.face[j].Surface = SURF_HINT;\r
-                       brush.face[j].Value    = 0;\r
-               }\r
-\r
-               if(CheckAngle)\r
-               {\r
-                       XYZVectorSubtract(brush.face[0].v[2],brush.face[0].v[0],t[0]);\r
-                       XYZVectorSubtract(brush.face[0].v[1],brush.face[0].v[2],t[1]);\r
-                       CrossProduct(t[0],t[1],SurfNormal);\r
-                       VectorNormalize(SurfNormal,SurfNormal);\r
-                       if(DotProduct(SurfNormal,PlaneNormal) < Steep)\r
-                               strcpy(brush.face[0].texture,texture2);\r
-                       else\r
-                               strcpy(brush.face[0].texture,texture0);\r
-               }\r
-               else\r
-                       strcpy(brush.face[0].texture,texture0);\r
-\r
-               if(surf) brush.face[0].Value    = ArghRad2;\r
-               MakeBrush(&brush);\r
-       }\r
-       CloseFuncGroup();\r
-\r
-} // end MakeBrushes\r
-//=================================================================\r
-void MapOut(int NumNodes,int NumTris, NODE *Node, TRI *Tri)\r
-{\r
-       extern  double backface;\r
-       extern  double xmin, xmax, ymin, ymax, zmin, zmax;\r
-       BRUSH   brush;\r
-       char    hint[32], skip[32];\r
-       int             i, j;\r
-       int             face;\r
-        /*\r
-       ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);\r
-       SetCursor(ghCursorCurrent);\r
-        */\r
-       UseDetail = 1; // this is temporary\r
-       MakeBrushes(NumTris,Node,Tri,TRUE,0,Texture[Game][0],Texture[Game][1],Texture[Game][2]);\r
-\r
-       if(AddHints || GimpHints)\r
-       {\r
-               switch(Game)\r
-               {\r
-               case SIN:\r
-                       strcpy(hint,"generic/misc/hint");\r
-                       strcpy(skip,"generic/misc/skip");\r
-                       break;\r
-               case HALFLIFE:\r
-                       strcpy(hint,"HINT");\r
-                       strcpy(skip,"HINT");\r
-                       break;\r
-               case HERETIC2:\r
-                       strcpy(hint,"general/hint");\r
-                       strcpy(skip,"general/skip");\r
-                       break;\r
-               case KINGPIN:\r
-                       strcpy(hint,"common/0_hint");\r
-                       strcpy(skip,"common/0_skip");\r
-                       break;\r
-               case QUAKE3:\r
-                       strcpy(hint,"common/hint");\r
-                       strcpy(skip,"common/skip");\r
-                       break;\r
-               default:\r
-                       strcpy(hint,"e1u1/hint");\r
-                       strcpy(skip,"e1u1/skip");\r
-               }\r
-       }\r
-\r
-       if( GimpHints )\r
-               MakeBrushes(NumTris,Node,Tri,FALSE,HINT_OFFSET,hint,hint,hint);\r
-\r
-       if( AddHints==1 )\r
-       {\r
-               int   j0, j1, j2, k, k0, k1;\r
-               int   q[4];\r
-               int   w,h,h0,h1,t,OK;\r
-               float s[3];\r
-               double front;\r
-               int   MaxHints; // We don't want a whole slew of hint brushes, which we'd get\r
-                               // with low decimation values and our current placement scheme.\r
-                               // Limit number of hint brushes to number of undecimated grid\r
-                               // squares.\r
-\r
-               switch(Plane)\r
-               {\r
-               case PLANE_XY1:\r
-                       front  = LessThan(zmin,32.);\r
-                       break;\r
-               case PLANE_XZ0:\r
-                       front  = MoreThan(ymax,32.);\r
-                       break;\r
-               case PLANE_XZ1:\r
-                       front  = LessThan(ymin,32.);\r
-                       break;\r
-               case PLANE_YZ0:\r
-                       front  = MoreThan(xmax,32.);\r
-                       break;\r
-               case PLANE_YZ1:\r
-                       front  = LessThan(xmin,32.);\r
-                       break;\r
-               default:\r
-                       front  = MoreThan(zmax,32.);\r
-               }\r
-               \r
-               for(i=0; i<NumTris; i++)\r
-                       Tri[i].flag = 0;\r
-               \r
-               switch(Plane)\r
-               {\r
-               case PLANE_XZ0:\r
-               case PLANE_XZ1:\r
-                       j0 = 1;\r
-                       j1 = 0;\r
-                       j2 = 2;\r
-                       break;\r
-               case PLANE_YZ0:\r
-               case PLANE_YZ1:\r
-                       j0 = 0;\r
-                       j1 = 1;\r
-                       j2 = 2;\r
-                       break;\r
-               default:\r
-                       j0 = 2;\r
-                       j1 = 0;\r
-                       j2 = 1;\r
-               }\r
-               \r
-               brush.Number = 0;\r
-               brush.NumFaces = 6;\r
-               MaxHints = NH*NV-1;\r
-               for(w=1; w<min(16,NH) && brush.Number < MaxHints; w++)\r
-               {\r
-                       for(h=max(1,w/2); h<min(16,NV) && brush.Number < MaxHints; h++)\r
-                       {\r
-                               for(i=0; i<=NH-w && brush.Number < MaxHints; i++)\r
-                               {\r
-                                       for(j=0; j<=NV-h && brush.Number < MaxHints; j++)\r
-                                       {\r
-                                               q[0] = i*NVP1+j;\r
-                                               q[2] = q[0] + w*NVP1 + h;\r
-                                               switch(Plane)\r
-                                               {\r
-                                               case PLANE_XY1:\r
-                                               case PLANE_XZ0:\r
-                                               case PLANE_YZ1:\r
-                                                       q[1] = q[0] + h;\r
-                                                       q[3] = q[2] - h;\r
-                                                       break;\r
-                                               default:\r
-                                                       q[1] = q[2] - h;\r
-                                                       q[3] = q[0] + h;\r
-                                               }\r
-                                               for(k=0, OK=1; k<NumTris && OK; k++)\r
-                                               {\r
-                                                       if(Tri[k].min[j1] >= max(Node[q[0]].p[j1],Node[q[2]].p[j1])) continue;\r
-                                                       if(Tri[k].min[j2] >= max(Node[q[0]].p[j2],Node[q[2]].p[j2])) continue;\r
-                                                       if(Tri[k].max[j1] <= min(Node[q[0]].p[j1],Node[q[2]].p[j1])) continue;\r
-                                                       if(Tri[k].max[j2] <= min(Node[q[0]].p[j2],Node[q[2]].p[j2])) continue;\r
-\r
-                                                       for(h0=0; h0<4 && OK; h0++)\r
-                                                       {\r
-                                                               h1 = (h0+1)%4;\r
-                                                               for(t=0; t<3 && OK; t++)\r
-                                                               {\r
-                                                                       s[t] = side(Node[q[h0]].p[j1],Node[q[h0]].p[j2],\r
-                                                                               Node[q[h1]].p[j1],Node[q[h1]].p[j2],\r
-                                                                               Node[Tri[k].v[t]].p[j1],Node[Tri[k].v[t]].p[j2]);\r
-                                                               }\r
-                                                               if((s[1] > 0 || s[2] > 0) && s[0] < 0) OK=0;\r
-                                                               if((s[2] > 0 || s[0] > 0) && s[1] < 0) OK=0;\r
-                                                               if((s[0] > 0 || s[1] > 0) && s[2] < 0) OK=0;\r
-                                                       }\r
-                                               }\r
-                                               if(!OK) continue;\r
-                                               switch(Plane)\r
-                                               {\r
-                                               case PLANE_XZ0:\r
-                                               case PLANE_XZ1:\r
-                                                       // front\r
-                                                       brush.face[0].v[0][0] = Node[q[2]].p[0];\r
-                                                       brush.face[0].v[0][1] = (float)front;\r
-                                                       brush.face[0].v[0][2] = Node[q[2]].p[2];\r
-                                                       \r
-                                                       brush.face[0].v[1][0] = Node[q[1]].p[0];\r
-                                                       brush.face[0].v[1][1] = (float)front;\r
-                                                       brush.face[0].v[1][2] = Node[q[1]].p[2];\r
-                                                       \r
-                                                       brush.face[0].v[2][0] = Node[q[0]].p[0];\r
-                                                       brush.face[0].v[2][1] = (float)front;\r
-                                                       brush.face[0].v[2][2] = Node[q[0]].p[2];\r
-                                                       \r
-                                                       // back\r
-                                                       brush.face[1].v[0][0] = Node[q[0]].p[0];\r
-                                                       brush.face[1].v[0][1] = (float)backface;\r
-                                                       brush.face[1].v[0][2] = Node[q[0]].p[2];\r
-                                                       \r
-                                                       brush.face[1].v[1][0] = Node[q[1]].p[0];\r
-                                                       brush.face[1].v[1][1] = (float)backface;\r
-                                                       brush.face[1].v[1][2] = Node[q[1]].p[2];\r
-                                                       \r
-                                                       brush.face[1].v[2][0] = Node[q[2]].p[0];\r
-                                                       brush.face[1].v[2][1] = (float)backface;\r
-                                                       brush.face[1].v[2][2] = Node[q[2]].p[2];\r
-                                                       \r
-                                                       for(k0=0; k0<brush.NumFaces-2; k0++)\r
-                                                       {\r
-                                                               k =k0+2;\r
-                                                               k1=(k0+1) % (brush.NumFaces-2);\r
-                                                               \r
-                                                               brush.face[k].v[0][0] = Node[q[k0]].p[0];\r
-                                                               brush.face[k].v[0][1] = (float)front;\r
-                                                               brush.face[k].v[0][2] = Node[q[k0]].p[2];\r
-                                                               \r
-                                                               brush.face[k].v[1][0] = Node[q[k1]].p[0];\r
-                                                               brush.face[k].v[1][1] = (float)front;\r
-                                                               brush.face[k].v[1][2] = Node[q[k1]].p[2];\r
-                                                               \r
-                                                               brush.face[k].v[2][0] = Node[q[k1]].p[0];\r
-                                                               brush.face[k].v[2][1] = (float)backface;\r
-                                                               brush.face[k].v[2][2] = Node[q[k1]].p[2];\r
-                                                       }\r
-                                                       break;\r
-                                               case PLANE_YZ0:\r
-                                               case PLANE_YZ1:\r
-                                                       // front\r
-                                                       brush.face[0].v[0][0] = (float)front;\r
-                                                       brush.face[0].v[0][1] = Node[q[2]].p[1];\r
-                                                       brush.face[0].v[0][2] = Node[q[2]].p[2];\r
-                                                       \r
-                                                       brush.face[0].v[1][0] = (float)front;\r
-                                                       brush.face[0].v[1][1] = Node[q[1]].p[1];\r
-                                                       brush.face[0].v[1][2] = Node[q[1]].p[2];\r
-                                                       \r
-                                                       brush.face[0].v[2][0] = (float)front;\r
-                                                       brush.face[0].v[2][1] = Node[q[0]].p[1];\r
-                                                       brush.face[0].v[2][2] = Node[q[0]].p[2];\r
-                                                       \r
-                                                       // back\r
-                                                       brush.face[1].v[0][0] = (float)backface;\r
-                                                       brush.face[1].v[0][1] = Node[q[0]].p[1];\r
-                                                       brush.face[1].v[0][2] = Node[q[0]].p[2];\r
-                                                       \r
-                                                       brush.face[1].v[1][0] = (float)backface;\r
-                                                       brush.face[1].v[1][1] = Node[q[1]].p[1];\r
-                                                       brush.face[1].v[1][2] = Node[q[1]].p[2];\r
-                                                       \r
-                                                       brush.face[1].v[2][0] = (float)backface;\r
-                                                       brush.face[1].v[2][1] = Node[q[2]].p[1];\r
-                                                       brush.face[1].v[2][2] = Node[q[2]].p[2];\r
-                                                       \r
-                                                       for(k0=0; k0<brush.NumFaces-2; k0++)\r
-                                                       {\r
-                                                               k =k0+2;\r
-                                                               k1=(k0+1) % (brush.NumFaces-2);\r
-                                                               \r
-                                                               brush.face[k].v[0][0] = (float)front;\r
-                                                               brush.face[k].v[0][1] = Node[q[k0]].p[1];\r
-                                                               brush.face[k].v[0][2] = Node[q[k0]].p[2];\r
-                                                               \r
-                                                               brush.face[k].v[1][0] = (float)front;\r
-                                                               brush.face[k].v[1][1] = Node[q[k1]].p[1];\r
-                                                               brush.face[k].v[1][2] = Node[q[k1]].p[2];\r
-                                                               \r
-                                                               brush.face[k].v[2][0] = (float)backface;\r
-                                                               brush.face[k].v[2][1] = Node[q[k1]].p[1];\r
-                                                               brush.face[k].v[2][2] = Node[q[k1]].p[2];\r
-                                                       }\r
-                                                       break;\r
-                                               default:\r
-                                                       // front\r
-                                                       brush.face[0].v[0][0] = Node[q[2]].p[0];\r
-                                                       brush.face[0].v[0][1] = Node[q[2]].p[1];\r
-                                                       brush.face[0].v[0][2] = (float)front;\r
-                                                       \r
-                                                       brush.face[0].v[1][0] = Node[q[1]].p[0];\r
-                                                       brush.face[0].v[1][1] = Node[q[1]].p[1];\r
-                                                       brush.face[0].v[1][2] = (float)front;\r
-                                                       \r
-                                                       brush.face[0].v[2][0] = Node[q[0]].p[0];\r
-                                                       brush.face[0].v[2][1] = Node[q[0]].p[1];\r
-                                                       brush.face[0].v[2][2] = (float)front;\r
-                                                       \r
-                                                       // back\r
-                                                       brush.face[1].v[0][0] = Node[q[0]].p[0];\r
-                                                       brush.face[1].v[0][1] = Node[q[0]].p[1];\r
-                                                       brush.face[1].v[0][2] = (float)backface;\r
-                                                       \r
-                                                       brush.face[1].v[1][0] = Node[q[1]].p[0];\r
-                                                       brush.face[1].v[1][1] = Node[q[1]].p[1];\r
-                                                       brush.face[1].v[1][2] = (float)backface;\r
-                                                       \r
-                                                       brush.face[1].v[2][0] = Node[q[2]].p[0];\r
-                                                       brush.face[1].v[2][1] = Node[q[2]].p[1];\r
-                                                       brush.face[1].v[2][2] = (float)backface;\r
-                                                       \r
-                                                       for(k0=0; k0<brush.NumFaces-2; k0++)\r
-                                                       {\r
-                                                               k =k0+2;\r
-                                                               k1=(k0+1) % (brush.NumFaces-2);\r
-                                                               \r
-                                                               brush.face[k].v[0][0] = Node[q[k0]].p[0];\r
-                                                               brush.face[k].v[0][1] = Node[q[k0]].p[1];\r
-                                                               brush.face[k].v[0][2] = (float)front;\r
-                                                               \r
-                                                               brush.face[k].v[1][0] = Node[q[k1]].p[0];\r
-                                                               brush.face[k].v[1][1] = Node[q[k1]].p[1];\r
-                                                               brush.face[k].v[1][2] = (float)front;\r
-                                                               \r
-                                                               brush.face[k].v[2][0] = Node[q[k1]].p[0];\r
-                                                               brush.face[k].v[2][1] = Node[q[k1]].p[1];\r
-                                                               brush.face[k].v[2][2] = (float)backface;\r
-                                                       }\r
-                                                       break;\r
-                                               } // switch (Plane)\r
-                                               for(face=0; face<6; face++)\r
-                                               {\r
-                                                       strcpy(brush.face[face].texture,(face<=1 ? skip : hint));\r
-                                                       brush.face[face].Shift[0] = 0;\r
-                                                       brush.face[face].Shift[1] = 0;\r
-                                                       brush.face[face].Rotate   = 0.;\r
-                                                       brush.face[face].Scale[0] = 1;\r
-                                                       brush.face[face].Scale[1] = 1;\r
-                                                       brush.face[face].Contents = CONTENTS_DETAIL;\r
-                                                       brush.face[face].Surface  = (face<=1 ? SURF_SKIP : SURF_HINT);\r
-                                                       brush.face[face].Value    = 0;\r
-                                               }\r
-                                               if(!brush.Number) OpenFuncGroup();\r
-                                               MakeBrush(&brush);\r
-                                               brush.Number++;\r
-                                       } // for(j=\r
-                               }     // for(i=\r
-                       }         // for(h=\r
-               }             // for(w=\r
-               if(brush.Number) CloseFuncGroup();\r
-       }\r
-        /*\r
-       ghCursorCurrent = ghCursorDefault;\r
-       SetCursor(ghCursorCurrent);\r
-        */\r
-}\r
-//===========================================================================\r
-int CheckBorders(int *NumNodesUsed, int NumNodes, NODE *Node, int *NumTris, TRI **pTri)\r
-{\r
-       int border;\r
-       int i, j, k0, k1, N;\r
-       float angle[3];\r
-       TRI *Tri;\r
-\r
-       N = NumNodesUsed[0];\r
-       Tri = *pTri;\r
-       for(i=0; i<NumTris[0]; i++)\r
-       {\r
-               EdgeOnSide(Tri[i].v,&k0,&border);\r
-               if(border < 0) continue;\r
-               CalcAngles(Node, Tri[i].v, angle);\r
-               k1 = (k0+1) % 3;\r
-               if((angle[k0] < SLIVER_ANGLE) || (angle[k1] < SLIVER_ANGLE))\r
-               {\r
-                       j = Bisect(Node, border, Tri[i].v[k0], Tri[i].v[k1]);\r
-                       if(j >= 0)\r
-                       {\r
-                               if(!Node[j].used)    // Shouldn't be used, but...\r
-                               {\r
-                                       NumNodesUsed[0]++;\r
-                                       Node[j].used++;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       if(NumNodesUsed[0] > N)\r
-       {\r
-               free(*pTri);\r
-               tricall(NumNodes, Node, NumTris, NULL, pTri, "cnzBNPY");\r
-               Tri = *pTri;\r
-       }\r
-       return (NumNodesUsed[0] - N);\r
-}\r
+/*
+GenSurf plugin for GtkRadiant
+Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#define SINGLE
+#ifdef SINGLE
+#define REAL float
+#else /* not SINGLE */
+#define REAL double
+#endif /* not SINGLE */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "gensurf.h"
+#include "triangle.h"
+
+typedef struct
+{
+       float error;
+       int   node;
+} TRITABLE;
+
+double dh, dv;
+int    NVP1;
+
+#define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))
+
+void MakeDecimatedMap(int *NumNodes, int *NumTris, NODE **pNode, TRI **pTri)
+{
+       int  compare(TRITABLE *, TRITABLE *);
+       int Bisect(NODE *, int, int, int);
+       void CalcAngles(NODE *, int *, float *);
+       void EdgeOnSide(int *, int *, int *);
+       int tricall(int, NODE *, int *, TRI **, TRI **, char *);
+       int CheckBorders(int *,int,NODE *,int *,TRI **);
+
+       float       biggesterror;
+       int         i, j, N;
+       int         j0, j1, j2;
+       int         NumNodesToSave;
+       int         NumNodesUsed;
+       NODE        *Node;
+       TRI         *Tri;
+       TRITABLE    *TriTable;
+
+       if(Decimate <= 0) return;
+        /*
+       ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
+       SetCursor(ghCursorCurrent);
+        */
+       dh = (Hur-Hll)/NH;
+       dv = (Vur-Vll)/NV;
+       NVP1 = NV+1;
+
+       NumNodes[0] = (NH+1)*(NVP1);
+       *pNode = (NODE *) malloc(NumNodes[0] * sizeof(NODE));
+       Node = *pNode;
+       memset(Node,0,NumNodes[0]*sizeof(NODE));
+
+       // Copy [NH][NV] vertex array to our working node array
+       for(i=0,N=0; i<=NH; i++)
+       {
+               for(j=0; j<=NV; j++, N++)
+               {
+                       Node[N].p[0]  = (float)xyz[i][j].p[0];
+                       Node[N].p[1]  = (float)xyz[i][j].p[1];
+                       Node[N].p[2]  = (float)xyz[i][j].p[2];
+                       Node[N].fixed = xyz[i][j].fixed;
+               }
+       }
+       // Start things off with the corner values
+       Node[ 0].used           = 1;
+       Node[NV].used           = 1;
+       Node[NH*NVP1].used    = 1;
+       Node[NH*NVP1+NV].used = 1;
+       NumNodesUsed = 4;
+       tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
+       Tri = *pTri;
+
+       // Which coordinates are we triangulating on?
+       switch(Plane)
+       {
+       case PLANE_XZ0:
+       case PLANE_XZ1:
+               j0 = 1;
+               j1 = 0;
+               j2 = 2;
+               break;
+       case PLANE_YZ0:
+       case PLANE_YZ1:
+               j0 = 0;
+               j1 = 1;
+               j2 = 2;
+               break;
+       default:
+               j0 = 2;
+               j1 = 0;
+               j2 = 1;
+       }
+
+       // TriTable stores the largest error in a triangle and the node where that
+       // error occurs
+       TriTable = (TRITABLE *) malloc(NH*NV*2 * sizeof(TRITABLE));
+       NumNodesToSave = min(NumNodes[0], (int)(0.01*(100-Decimate)*(NumNodes[0]-NumNodesUsed)+NumNodesUsed));
+
+       while(NumNodesUsed < NumNodesToSave)
+       {
+               for(i=0; i<NumTris[0]; i++)
+                       Tri[i].flag = 0;
+
+               // For every node that's not currently used, find what triangle it
+               // lies on, and the error at this node
+               for(i=0, biggesterror=0; i<NumNodes[0]; i++)
+               {
+                       if(Node[i].used) continue;
+                       for(j=0, Node[i].tri=-1; (j<NumTris[0]) && (Node[i].tri==-1); j++)
+                       {
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                            Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],
+                                            Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                            Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],
+                                            Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                            Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],
+                                            Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;
+                               Node[i].tri = j;
+                       }
+                       if(Node[i].tri < 0)
+                       {
+                          /*
+                               ghCursorCurrent = ghCursorDefault;
+                               SetCursor(ghCursorCurrent);
+                          */
+                               g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,
+                                       "Error: Couldn't find the triangle bounding a point.",
+                                       "Decimation Error",MB_ICONEXCLAMATION);
+                               return;
+                       }
+                       if(!Tri[Node[i].tri].flag)
+                       {
+                               PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,
+                                               Node[Tri[Node[i].tri].v[1]].p,
+                                               Node[Tri[Node[i].tri].v[2]].p,
+                                                               &Tri[Node[i].tri].plane);
+                               Tri[Node[i].tri].flag = 1;
+                       }
+                       Node[i].error =
+                               Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -
+                                                            Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -
+                                                                Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/
+                                                                Tri[Node[i].tri].plane.normal[j0];
+                       biggesterror = max(biggesterror,Absolute(Node[i].error));
+               }
+               if(biggesterror == 0)
+                       NumNodesToSave = NumNodesUsed;
+               else
+               {
+                       // For all current triangles, build a list of worst-case nodes
+                       memset(TriTable,0,NH*NV*2*sizeof(TRITABLE));
+                       for(i=0; i<NumNodes[0]; i++)
+                       {
+                               if(Node[i].used) continue;
+                               if(Absolute(Node[i].error) > TriTable[Node[i].tri].error)
+                               {
+                                       TriTable[Node[i].tri].error = (float)(Absolute(Node[i].error));
+                                       TriTable[Node[i].tri].node  = i;
+                               }
+                       }
+                       qsort( (void *)TriTable, (size_t)(NumTris[0]), sizeof(TRITABLE), (int (*)(const void *, const void *))compare );
+                       for(i=0; i<NumTris[0] && NumNodesUsed < NumNodesToSave && TriTable[i].error > 0.5*biggesterror; i++)
+                       {
+                               if(Node[TriTable[i].node].used) continue;  // shouldn't happen
+                               NumNodesUsed++;
+                               Node[TriTable[i].node].used++;
+                       }
+                       free(Tri);
+                       tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
+                       Tri = *pTri;
+                       // Sliver-check along borders. Since borders are often linear, the errors
+                       // along borders will often be zero, so no new points will be added. This
+                       // tends to produce long, thin brushes. For all border triangles, check 
+                       // that minimum angle isn't less than SLIVER_ANGLE. If it is, add another
+                       // vertex.
+                       while(CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri) > 0)
+                       {
+                       }
+                       Tri = *pTri;
+               }
+       }
+       free(TriTable);
+       // One last time (because we're pessimistic), check border triangles
+//     CheckBorders(&NumNodesUsed,NumNodes[0],Node,NumTris,pTri);
+//     Tri = *pTri;
+
+       // Check that all fixed points are exact. If not, add them to the mix.
+       // First check to see if we have any fixed points that aren't already used.
+       for(i=0, N=0; i<NumNodes[0] && !N; i++)
+       {
+               if(Node[i].used) continue;
+               if(Node[i].fixed) N++;
+       }
+       if(N)
+       {
+               // Zero out the flag member of all triangles, indicating that
+               // the plane equation has not been found.
+               for(i=0; i<NumTris[0]; i++)
+                       Tri[i].flag = 0;
+
+               for(i=0; i<NumNodes[0]; i++)
+               {
+                       if(Node[i].used) continue;
+                       if(!Node[i].fixed) continue;
+                       Node[i].tri = -1;
+                       for(j=0; j<NumTris[0] && Node[i].tri==-1; j++)
+                       {
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                       Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2],
+                                       Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2]) < 0. ) continue;
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                       Node[Tri[j].v[1]].p[j1],Node[Tri[j].v[1]].p[j2],
+                                       Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2]) < 0. ) continue;
+                               if( side(Node[i].p[j1],          Node[i].p[j2],
+                                       Node[Tri[j].v[2]].p[j1],Node[Tri[j].v[2]].p[j2],
+                                       Node[Tri[j].v[0]].p[j1],Node[Tri[j].v[0]].p[j2]) < 0. ) continue;
+                               Node[i].tri = j;
+                       }
+                       if(Node[i].tri < 0)
+                       {
+                          /*
+                               ghCursorCurrent = ghCursorDefault;
+                               SetCursor(ghCursorCurrent);
+                          */
+                               g_FuncTable.m_pfnMessageBox(g_pRadiantWnd,
+                                       "Error: Couldn't find the triangle bounding a point.",
+                                       "Decimation Error",MB_ICONEXCLAMATION);
+                               return;
+                       }
+                       if(!Tri[Node[i].tri].flag)
+                       {
+                               PlaneFromPoints(Node[Tri[Node[i].tri].v[0]].p,
+                                                   Node[Tri[Node[i].tri].v[1]].p,
+                                               Node[Tri[Node[i].tri].v[2]].p,
+                                               &Tri[Node[i].tri].plane);
+                               Tri[Node[i].tri].flag = 1;
+                       }
+                       Node[i].error =
+                               Node[i].p[j0] - (Tri[Node[i].tri].plane.dist -
+                               Tri[Node[i].tri].plane.normal[j1]*Node[i].p[j1] -
+                               Tri[Node[i].tri].plane.normal[j2]*Node[i].p[j2]  )/
+                               Tri[Node[i].tri].plane.normal[j0];
+                       if(Absolute(Node[i].error) > 0.5)
+                       {
+                               NumNodesUsed++;
+                               Node[i].used++;
+                               free(Tri);
+                               tricall(NumNodes[0], Node, NumTris, NULL, pTri, "cnzBNPY");
+                               Tri = *pTri;
+                       }
+               }
+       }
+
+       // Swap node orders for surfaces facing down, north or west so that
+       // they are counterclockwise when facing the surface
+
+       if((Plane == PLANE_XY1) || (Plane == PLANE_XZ0) || (Plane == PLANE_YZ1) )
+       {
+               for(i=0; i<NumTris[0]; i++)
+               {
+                       j = Tri[i].v[1];
+                       Tri[i].v[1] = Tri[i].v[2];
+                       Tri[i].v[2] = j;
+               }
+       }
+
+       // Store bounding box coords
+       for(i=0; i<NumTris[0]; i++)
+       {
+               Tri[i].min[0] =                   Node[Tri[i].v[0]].p[0];
+               Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[1]].p[0]);
+               Tri[i].min[0] = min(Tri[i].min[0],Node[Tri[i].v[2]].p[0]);
+               Tri[i].min[1] =                   Node[Tri[i].v[0]].p[1];
+               Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[1]].p[1]);
+               Tri[i].min[1] = min(Tri[i].min[1],Node[Tri[i].v[2]].p[1]);
+               Tri[i].min[2] =                   Node[Tri[i].v[0]].p[2];
+               Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[1]].p[2]);
+               Tri[i].min[2] = min(Tri[i].min[2],Node[Tri[i].v[2]].p[2]);
+               Tri[i].max[0] =                   Node[Tri[i].v[0]].p[0];
+               Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[1]].p[0]);
+               Tri[i].max[0] = max(Tri[i].max[0],Node[Tri[i].v[2]].p[0]);
+               Tri[i].max[1] =                   Node[Tri[i].v[0]].p[1];
+               Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[1]].p[1]);
+               Tri[i].max[1] = max(Tri[i].max[1],Node[Tri[i].v[2]].p[1]);
+               Tri[i].max[2] =                   Node[Tri[i].v[0]].p[2];
+               Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[1]].p[2]);
+               Tri[i].max[2] = max(Tri[i].max[2],Node[Tri[i].v[2]].p[2]);
+       }
+        /*
+       ghCursorCurrent = ghCursorDefault;
+       SetCursor(ghCursorCurrent);
+        */
+}
+/* end MakeDecimatedMap */
+
+/*****************************************************************************/
+/*                                                                           */
+/*  tricall Takes an array of nodes, spits out an array of triangles         */
+/*                                                                           */
+/*****************************************************************************/
+int tricall(int NumNodes, NODE *Node, int *NumTris, TRI **inTri, TRI **Tri, LPSTR Options)
+{
+
+       struct triangulateio in, out;
+       int    i, N;
+       int    NumUsedNodes;
+       int    *NodeTable;
+       TRI    *ptri;
+
+       /* Define input points. */
+
+       for(i=0,NumUsedNodes=0; i<NumNodes; i++)
+               if(Node[i].used) NumUsedNodes++;
+
+       memset(&in, 0,sizeof(in));
+       memset(&out,0,sizeof(out));
+
+       NodeTable = (int *) malloc(NumUsedNodes * sizeof(int));
+
+       in.numberofpoints = NumUsedNodes;
+       in.numberofpointattributes = 0;
+       in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
+       for(i=0,N=0; i<NumNodes; i++)
+       {
+               if(Node[i].used)
+               {
+                       switch(Plane)
+                       {
+                       case PLANE_XZ0:
+                       case PLANE_XZ1:
+                               in.pointlist[N*2  ] = Node[i].p[0];
+                               in.pointlist[N*2+1] = Node[i].p[2];
+                               break;
+                       case PLANE_YZ0:
+                       case PLANE_YZ1:
+                               in.pointlist[N*2  ] = Node[i].p[1];
+                               in.pointlist[N*2+1] = Node[i].p[2];
+                               break;
+                       default:
+                               in.pointlist[N*2  ] = Node[i].p[0];
+                               in.pointlist[N*2+1] = Node[i].p[1];
+                       }
+                       NodeTable[N] = i;
+                       N++;
+               }
+       }
+       in.pointattributelist = (REAL *) NULL;
+       in.pointmarkerlist    = (int *) NULL;
+
+       if(strstr(Options,"r"))
+       {
+               int    *TriTable;
+               TriTable = (int *) malloc(NumNodes * sizeof(int));
+               for(i=0,N=0; i<NumNodes; i++)
+               {
+                       if(Node[i].used)
+                       {
+                               TriTable[i] = N;
+                               N++;
+                       }
+               }
+               in.numberoftriangles          = NumTris[0];
+               in.numberofcorners            = 3;
+               in.numberoftriangleattributes = 0;
+               in.trianglelist               = (int *) malloc(in.numberofcorners * in.numberoftriangles * sizeof(int));
+               in.triangleattributelist      = (REAL *) NULL;
+               in.trianglearealist           = (REAL *) NULL;
+               ptri = *inTri;
+               for(i=0; i<in.numberoftriangles; i++)
+               {
+                       in.trianglelist[i*in.numberofcorners  ] = TriTable[ptri[i].v[0]];
+                       in.trianglelist[i*in.numberofcorners+1] = TriTable[ptri[i].v[1]];
+                       in.trianglelist[i*in.numberofcorners+2] = TriTable[ptri[i].v[2]];
+               }
+               free(TriTable);
+       }
+       else
+       {
+               in.numberoftriangles          = 0;
+               in.numberofcorners            = 3;
+               in.numberoftriangleattributes = 0;
+               in.trianglelist               = (int *) NULL;
+               in.triangleattributelist      = (REAL *) NULL;
+               in.trianglearealist           = (REAL *) NULL;
+       }
+
+       in.numberofsegments   = 0;
+       in.segmentlist        = (int *) NULL;
+       in.segmentmarkerlist  = (int *) NULL;
+
+       in.numberofholes      = 0;
+       in.holelist           = (REAL *) NULL;
+
+       in.numberofregions    = 0;
+       in.regionlist         = (REAL *) NULL;
+
+       in.numberofedges      = 0;
+       in.edgelist           = (int *) NULL;
+       in.edgemarkerlist     = (int *) NULL;
+       in.normlist           = (REAL *) NULL;
+
+       /* Make necessary initializations */
+       out.pointlist          = (REAL *) NULL;  /* Not needed if -N switch used. */
+       out.pointattributelist = (REAL *) NULL;  /* Not needed if -N switch used or 
+                                                   number of point attributes is zero: */
+       out.pointmarkerlist    = (int *) NULL;   /* Not needed if -N or -B switch used. */
+       out.trianglelist       = (int *) NULL;   /* Not needed if -E switch used. */
+       out.triangleattributelist = (REAL *) NULL;   /* Not needed if -E switch used or 
+                                                       number of triangle attributes is 
+                                                    zero: */
+       out.trianglearealist   = (REAL *) NULL;
+       out.neighborlist       = (int *) NULL;   /* Needed only if -n switch used. */
+       out.segmentlist        = (int *) NULL;   /* Needed only if segments are output 
+                                                   (-p or -c) and -P not used: */
+       out.segmentmarkerlist  = (int *) NULL;   /* Needed only if segments are output 
+                                                   (-p or -c) and -P and -B not used: */
+       out.edgelist           = (int *) NULL;   /* Needed only if -e switch used. */
+       out.edgemarkerlist     = (int *) NULL;   /* Needed if -e used and -B not used. */
+
+       triangulate(Options, &in, &out, NULL);
+
+       NumTris[0] = out.numberoftriangles;
+       *Tri = (TRI *) malloc(NumTris[0] * sizeof(TRI));
+       ptri = *Tri;
+
+       for(i=0; i<NumTris[0]; i++)
+       {
+               ptri[i].v[0] = NodeTable[out.trianglelist[i*out.numberofcorners  ]];
+               ptri[i].v[1] = NodeTable[out.trianglelist[i*out.numberofcorners+1]];
+               ptri[i].v[2] = NodeTable[out.trianglelist[i*out.numberofcorners+2]];
+               ptri[i].n[0] = out.neighborlist[i*3  ];
+               ptri[i].n[1] = out.neighborlist[i*3+1];
+               ptri[i].n[2] = out.neighborlist[i*3+2];
+       }
+
+       /* Free all allocated arrays, including those allocated by Triangle. */
+       if(in.pointlist)              free(in.pointlist);
+       if(in.pointattributelist)     free(in.pointattributelist);
+       if(in.pointmarkerlist)        free(in.pointmarkerlist);
+       if(in.trianglelist)           free(in.trianglelist);
+       if(in.triangleattributelist)  free(in.triangleattributelist);
+       if(in.trianglearealist)       free(in.trianglearealist);
+       if(in.neighborlist)           free(in.neighborlist);
+       if(in.segmentlist)            free(in.segmentlist);
+       if(in.segmentmarkerlist)      free(in.segmentmarkerlist);
+       if(in.holelist)               free(in.holelist);
+       if(in.regionlist)             free(in.regionlist);
+       if(in.edgelist)               free(in.edgelist);
+       if(in.edgemarkerlist)         free(in.edgemarkerlist);
+       if(in.normlist)               free(in.normlist);
+       if(out.pointlist)             free(out.pointlist);
+       if(out.pointattributelist)    free(out.pointattributelist);
+       if(out.pointmarkerlist)       free(out.pointmarkerlist);
+       if(out.trianglelist)          free(out.trianglelist);
+       if(out.triangleattributelist) free(out.triangleattributelist);
+       if(out.trianglearealist)      free(out.trianglearealist);
+       if(out.neighborlist)          free(out.neighborlist);
+       if(out.segmentlist)           free(out.segmentlist);
+       if(out.segmentmarkerlist)     free(out.segmentmarkerlist);
+       if(out.holelist)              free(out.holelist);
+       if(out.regionlist)            free(out.regionlist);
+       if(out.edgelist)              free(out.edgelist);
+       if(out.edgemarkerlist)        free(out.edgemarkerlist);
+       if(out.normlist)              free(out.normlist);
+
+       free(NodeTable);
+       return 0;
+}
+
+void EdgeOnSide(int *v, int *edge, int *border)
+{
+       int R;
+       int k0, k1, N;
+       float Ndv;
+
+       border[0] = -1;
+
+       if( (v[0] <= NV) && (v[1] <= NV) )
+       {
+               edge[0]   = 0;
+               border[0] = 0;
+       }
+       if( (v[1] <= NV) && (v[2] <= NV) )
+       {
+               edge[0]   = 1;
+               border[0] = 0;
+       }
+       if( (v[2] <= NV) && (v[0] <= NV) )
+       {
+               edge[0]   = 2;
+               border[0] = 0;
+       }
+
+       R = NH*NVP1;
+
+       if( (v[0] >= R) && (v[1] >= R) )
+       {
+               edge[0]   = 0;
+               border[0] = 1;
+       }
+       if( (v[1] >= R) && (v[2] >= R) )
+       {
+               edge[0]   = 1;
+               border[0] = 1;
+       }
+       if( (v[2] >= R) && (v[0] >= R) )
+       {
+               edge[0]   = 2;
+               border[0] = 1;
+       }
+
+       if(border[0] >= 0)
+       {
+               k0  = edge[0];
+               k1  = (k0+1) % 3;
+               N   = Absolute(v[k0] - v[k1]);
+               Ndv = (float)(N*dv);
+       }
+       if( ((v[0] % NVP1) == 0)  && ((v[1] % NVP1) == 0) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[0] - v[1])*dh)) return;
+               edge[0]   = 0;
+               border[0] = 2;
+               return;
+       }
+       if( ((v[1] % NVP1) == 0)  && ((v[2] % NVP1) == 0) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[1] - v[2])*dh)) return;
+               edge[0]   = 1;
+               border[0] = 2;
+               return;
+       }
+       if( ((v[2] % NVP1) == 0)  && ((v[0] % NVP1) == 0) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[2] - v[0])*dh)) return;
+               edge[0]   = 2;
+               border[0] = 2;
+               return;
+       }
+
+       if( ((v[0] % NVP1) == NV) && ((v[1] % NVP1) == NV) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[0] - v[1])*dh)) return;
+               edge[0]   = 0;
+               border[0] = 3;
+               return;
+       }
+       if( ((v[1] % NVP1) == NV) && ((v[2] % NVP1) == NV) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[1] - v[2])*dh)) return;
+               edge[0]   = 1;
+               border[0] = 3;
+               return;
+       }
+       if( ((v[2] % NVP1) == NV) && ((v[0] % NVP1) == NV) )
+       {
+               if(border[0] >= 0)
+                       if( Ndv > (Absolute(v[2] - v[0])*dh)) return;
+               edge[0]   = 2;
+               border[0] = 3;
+               return;
+       }
+       return;
+}
+
+void CalcAngles(NODE *node, int *v, float *angle)
+{
+       int i, j, k;
+       vec l;
+       vec x0, x1, x2, y0, y1, y2;
+       vec2 vv[3];
+       vec dot;
+
+       switch(Plane)
+       {
+       case PLANE_XZ0:
+       case PLANE_XZ1:
+               i = 0;
+               j = 2;
+               break;
+       case PLANE_YZ0:
+       case PLANE_YZ1:
+               i = 1;
+               j = 2;
+               break;
+       default:
+               i = 0;
+               j = 1;
+       }
+       x0 = node[v[0]].p[i];
+       x1 = node[v[1]].p[i];
+       x2 = node[v[2]].p[i];
+       y0 = node[v[0]].p[j];
+       y1 = node[v[1]].p[j];
+       y2 = node[v[2]].p[j];
+
+       vv[0][0] = x1-x0;
+       vv[0][1] = y1-y0;
+       vv[1][0] = x2-x1;
+       vv[1][1] = y2-y1;
+       vv[2][0] = x0-x2;
+       vv[2][1] = y0-y2;
+
+       for(k=0; k<3; k++)
+       {
+               l = (vec)(sqrt( vv[k][0]*vv[k][0] + vv[k][1]*vv[k][1] ));
+               if(l > 0.)
+               {
+                       vv[k][0] /= l;
+                       vv[k][1] /= l;
+               }
+       }
+
+       dot = -(vv[0][0]*vv[2][0] + vv[0][1]*vv[2][1]);
+       angle[0] = (float)(acos(dot));
+       dot = -(vv[1][0]*vv[0][0] + vv[1][1]*vv[0][1]);
+       angle[1] = (float)(acos(dot));
+       dot = -(vv[2][0]*vv[1][0] + vv[2][1]*vv[1][1]);
+       angle[2] = (float)(acos(dot));
+}
+//=================================================================
+int Bisect(NODE *node, int border, int j0, int j1)
+{
+       int k;
+
+       switch(border)
+       {
+       case 0:
+               k = (j0+j1)/2;
+               break;
+       case 1:
+               k = (j0+j1)/2;
+               break;
+       case 2:
+               k = (int)((j0+j1)/(2*NVP1)) * NVP1;
+               break;
+       case 3:
+               k = (int)((j0+j1+2)/(2*NVP1)) * NVP1 - 1;
+               break;
+       }
+       return( ((k != j0) && (k != j1)) ? k : 0 );
+}
+//=================================================================
+int compare(TRITABLE *t1, TRITABLE *t2)
+{
+       if(t1->error > t2->error) return -1;
+       if(t1->error < t2->error) return  1;
+       return 0;
+}
+
+void MakeBrushes(int NumTris, NODE *Node, TRI *Tri,bool surf,
+                                int offset,char *texture0, char *texture1, char *texture2)
+{
+       extern double backface;
+       BRUSH   brush;
+       int             contents;
+       int             i, j;
+       float   Steep;
+       vec3_t  PlaneNormal,SurfNormal;
+       bool    CheckAngle;
+       vec3_t  t[2];
+
+       // if texture2 is identical to texture0, there's no need to
+       // check surface angle
+       if(!g_strcasecmp(texture0,texture2) || !strlen(texture2))
+               CheckAngle = FALSE;
+       else
+       {
+               CheckAngle = TRUE;
+               Steep = (float)cos((double)SlantAngle/57.2957795);
+               switch(Plane)
+               {
+               case PLANE_XY0: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
+               case PLANE_XY1: PlaneNormal[0]= 0.;PlaneNormal[1]= 0.;PlaneNormal[2]=-1.;break;
+               case PLANE_XZ0: PlaneNormal[0]= 0.;PlaneNormal[1]= 1.;PlaneNormal[2]= 1.;break;
+               case PLANE_XZ1: PlaneNormal[0]= 0.;PlaneNormal[1]=-1.;PlaneNormal[2]= 1.;break;
+               case PLANE_YZ0: PlaneNormal[0]= 1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
+               case PLANE_YZ1: PlaneNormal[0]=-1.;PlaneNormal[1]= 0.;PlaneNormal[2]= 1.;break;
+               }
+       }
+
+       contents = 0;
+       if(surf)
+       {
+               if(UseDetail) contents += CONTENTS_DETAIL;
+               if(UseLadder) contents += CONTENTS_LADDER;
+       }
+       
+       OpenFuncGroup();
+       for(i=0; i<NumTris; i++)
+       {
+               brush.Number   = i;
+               brush.NumFaces = 5;
+               // front
+               brush.face[0].v[0][0] = Node[Tri[i].v[0]].p[0];
+               brush.face[0].v[0][1] = Node[Tri[i].v[0]].p[1];
+               brush.face[0].v[0][2] = Node[Tri[i].v[0]].p[2];
+               
+               brush.face[0].v[1][0] = Node[Tri[i].v[2]].p[0];
+               brush.face[0].v[1][1] = Node[Tri[i].v[2]].p[1];
+               brush.face[0].v[1][2] = Node[Tri[i].v[2]].p[2];
+               
+               brush.face[0].v[2][0] = Node[Tri[i].v[1]].p[0];
+               brush.face[0].v[2][1] = Node[Tri[i].v[1]].p[1];
+               brush.face[0].v[2][2] = Node[Tri[i].v[1]].p[2];
+
+               if(offset != 0)
+               {
+                       switch(Plane)
+                       {
+                       case PLANE_XY0:
+                               brush.face[0].v[0][2] += offset;
+                               brush.face[0].v[1][2] += offset;
+                               brush.face[0].v[1][2] += offset;
+                               break;
+                       case PLANE_XY1:
+                               brush.face[0].v[0][2] -= offset;
+                               brush.face[0].v[1][2] -= offset;
+                               brush.face[0].v[1][2] -= offset;
+                               break;
+                       case PLANE_XZ0:
+                               brush.face[0].v[0][1] += offset;
+                               brush.face[0].v[1][1] += offset;
+                               brush.face[0].v[1][1] += offset;
+                               break;
+                       case PLANE_XZ1:
+                               brush.face[0].v[0][1] -= offset;
+                               brush.face[0].v[1][1] -= offset;
+                               brush.face[0].v[1][1] -= offset;
+                               break;
+                       case PLANE_YZ0:
+                               brush.face[0].v[0][0] += offset;
+                               brush.face[0].v[1][0] += offset;
+                               brush.face[0].v[1][0] += offset;
+                               break;
+                       case PLANE_YZ1:
+                               brush.face[0].v[0][0] -= offset;
+                               brush.face[0].v[1][0] -= offset;
+                               brush.face[0].v[1][0] -= offset;
+                               break;
+                       }
+               }
+               switch(Plane)
+               {
+               case PLANE_XZ0:
+               case PLANE_XZ1:
+                       // back
+                       brush.face[1].v[0][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[1].v[0][1] = (float)backface;
+                       brush.face[1].v[0][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[1].v[1][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[1].v[1][1] = (float)backface;
+                       brush.face[1].v[1][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[1].v[2][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[1].v[2][1] = (float)backface;
+                       brush.face[1].v[2][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       // 0-1 side
+                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[2].v[2][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[2].v[2][1] = (float)backface;
+                       brush.face[2].v[2][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       // 1-2 side
+                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[3].v[2][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[3].v[2][1] = (float)backface;
+                       brush.face[3].v[2][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       // 2-0 side
+                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[4].v[2][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[4].v[2][1] = (float)backface;
+                       brush.face[4].v[2][2] = Node[Tri[i].v[0]].p[2];
+                       break;
+               case PLANE_YZ0:
+               case PLANE_YZ1:
+                       // back
+                       brush.face[1].v[0][0] = (float)backface;
+                       brush.face[1].v[0][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[1].v[0][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[1].v[1][0] = (float)backface;
+                       brush.face[1].v[1][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[1].v[1][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[1].v[2][0] = (float)backface;
+                       brush.face[1].v[2][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[1].v[2][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       // 0-1 side
+                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[2].v[2][0] = (float)backface;
+                       brush.face[2].v[2][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[2].v[2][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       // 1-2 side
+                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[3].v[2][0] = (float)backface;
+                       brush.face[3].v[2][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[3].v[2][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       // 2-0 side
+                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[4].v[2][0] = (float)backface;
+                       brush.face[4].v[2][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[4].v[2][2] = Node[Tri[i].v[0]].p[2];
+                       break;
+               default:
+                       // back
+                       brush.face[1].v[0][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[1].v[0][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[1].v[0][2] = (float)backface;
+                       
+                       brush.face[1].v[1][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[1].v[1][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[1].v[1][2] = (float)backface;
+                       
+                       brush.face[1].v[2][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[1].v[2][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[1].v[2][2] = (float)backface;
+                       
+                       // 0-1 side
+                       brush.face[2].v[0][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[2].v[0][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[2].v[0][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[2].v[1][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[2].v[1][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[2].v[1][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[2].v[2][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[2].v[2][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[2].v[2][2] = (float)backface;
+                       
+                       // 1-2 side
+                       brush.face[3].v[0][0] = Node[Tri[i].v[1]].p[0];
+                       brush.face[3].v[0][1] = Node[Tri[i].v[1]].p[1];
+                       brush.face[3].v[0][2] = Node[Tri[i].v[1]].p[2];
+                       
+                       brush.face[3].v[1][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[3].v[1][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[3].v[1][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[3].v[2][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[3].v[2][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[3].v[2][2] = (float)backface;
+                       
+                       // 2-0 side
+                       brush.face[4].v[0][0] = Node[Tri[i].v[2]].p[0];
+                       brush.face[4].v[0][1] = Node[Tri[i].v[2]].p[1];
+                       brush.face[4].v[0][2] = Node[Tri[i].v[2]].p[2];
+                       
+                       brush.face[4].v[1][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[4].v[1][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[4].v[1][2] = Node[Tri[i].v[0]].p[2];
+                       
+                       brush.face[4].v[2][0] = Node[Tri[i].v[0]].p[0];
+                       brush.face[4].v[2][1] = Node[Tri[i].v[0]].p[1];
+                       brush.face[4].v[2][2] = (float)backface;
+               }
+               
+               for(j=0; j<5; j++)
+               {
+                       strcpy(brush.face[j].texture,
+                               (strlen(texture1) ? texture1 : texture0));
+                       brush.face[j].Shift[0] = (float)TexOffset[0];
+                       brush.face[j].Shift[1] = (float)TexOffset[1];
+                       brush.face[j].Rotate   = 0.;
+                       brush.face[j].Scale[0] = (float)TexScale[0];
+                       brush.face[j].Scale[1] = (float)TexScale[1];
+                       brush.face[j].Contents = contents;
+                       if(surf)
+                               brush.face[j].Surface = 0;
+                       else
+                               brush.face[j].Surface = SURF_HINT;
+                       brush.face[j].Value    = 0;
+               }
+
+               if(CheckAngle)
+               {
+                       XYZVectorSubtract(brush.face[0].v[2],brush.face[0].v[0],t[0]);
+                       XYZVectorSubtract(brush.face[0].v[1],brush.face[0].v[2],t[1]);
+                       CrossProduct(t[0],t[1],SurfNormal);
+                       VectorNormalize(SurfNormal,SurfNormal);
+                       if(DotProduct(SurfNormal,PlaneNormal) < Steep)
+                               strcpy(brush.face[0].texture,texture2);
+                       else
+                               strcpy(brush.face[0].texture,texture0);
+               }
+               else
+                       strcpy(brush.face[0].texture,texture0);
+
+               if(surf) brush.face[0].Value    = ArghRad2;
+               MakeBrush(&brush);
+       }
+       CloseFuncGroup();
+
+} // end MakeBrushes
+//=================================================================
+void MapOut(int NumNodes,int NumTris, NODE *Node, TRI *Tri)
+{
+       extern  double backface;
+       extern  double xmin, xmax, ymin, ymax, zmin, zmax;
+       BRUSH   brush;
+       char    hint[32], skip[32];
+       int             i, j;
+       int             face;
+        /*
+       ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
+       SetCursor(ghCursorCurrent);
+        */
+       UseDetail = 1; // this is temporary
+       MakeBrushes(NumTris,Node,Tri,TRUE,0,Texture[Game][0],Texture[Game][1],Texture[Game][2]);
+
+       if(AddHints || GimpHints)
+       {
+               switch(Game)
+               {
+               case SIN:
+                       strcpy(hint,"generic/misc/hint");
+                       strcpy(skip,"generic/misc/skip");
+                       break;
+               case HALFLIFE:
+                       strcpy(hint,"HINT");
+                       strcpy(skip,"HINT");
+                       break;
+               case HERETIC2:
+                       strcpy(hint,"general/hint");
+                       strcpy(skip,"general/skip");
+                       break;
+               case KINGPIN:
+                       strcpy(hint,"common/0_hint");
+                       strcpy(skip,"common/0_skip");
+                       break;
+               case QUAKE3:
+                       strcpy(hint,"common/hint");
+                       strcpy(skip,"common/skip");
+                       break;
+               default:
+                       strcpy(hint,"e1u1/hint");
+                       strcpy(skip,"e1u1/skip");
+               }
+       }
+
+       if( GimpHints )
+               MakeBrushes(NumTris,Node,Tri,FALSE,HINT_OFFSET,hint,hint,hint);
+
+       if( AddHints==1 )
+       {
+               int   j0, j1, j2, k, k0, k1;
+               int   q[4];
+               int   w,h,h0,h1,t,OK;
+               float s[3];
+               double front;
+               int   MaxHints; // We don't want a whole slew of hint brushes, which we'd get
+                               // with low decimation values and our current placement scheme.
+                               // Limit number of hint brushes to number of undecimated grid
+                               // squares.
+
+               switch(Plane)
+               {
+               case PLANE_XY1:
+                       front  = LessThan(zmin,32.);
+                       break;
+               case PLANE_XZ0:
+                       front  = MoreThan(ymax,32.);
+                       break;
+               case PLANE_XZ1:
+                       front  = LessThan(ymin,32.);
+                       break;
+               case PLANE_YZ0:
+                       front  = MoreThan(xmax,32.);
+                       break;
+               case PLANE_YZ1:
+                       front  = LessThan(xmin,32.);
+                       break;
+               default:
+                       front  = MoreThan(zmax,32.);
+               }
+               
+               for(i=0; i<NumTris; i++)
+                       Tri[i].flag = 0;
+               
+               switch(Plane)
+               {
+               case PLANE_XZ0:
+               case PLANE_XZ1:
+                       j0 = 1;
+                       j1 = 0;
+                       j2 = 2;
+                       break;
+               case PLANE_YZ0:
+               case PLANE_YZ1:
+                       j0 = 0;
+                       j1 = 1;
+                       j2 = 2;
+                       break;
+               default:
+                       j0 = 2;
+                       j1 = 0;
+                       j2 = 1;
+               }
+               
+               brush.Number = 0;
+               brush.NumFaces = 6;
+               MaxHints = NH*NV-1;
+               for(w=1; w<min(16,NH) && brush.Number < MaxHints; w++)
+               {
+                       for(h=max(1,w/2); h<min(16,NV) && brush.Number < MaxHints; h++)
+                       {
+                               for(i=0; i<=NH-w && brush.Number < MaxHints; i++)
+                               {
+                                       for(j=0; j<=NV-h && brush.Number < MaxHints; j++)
+                                       {
+                                               q[0] = i*NVP1+j;
+                                               q[2] = q[0] + w*NVP1 + h;
+                                               switch(Plane)
+                                               {
+                                               case PLANE_XY1:
+                                               case PLANE_XZ0:
+                                               case PLANE_YZ1:
+                                                       q[1] = q[0] + h;
+                                                       q[3] = q[2] - h;
+                                                       break;
+                                               default:
+                                                       q[1] = q[2] - h;
+                                                       q[3] = q[0] + h;
+                                               }
+                                               for(k=0, OK=1; k<NumTris && OK; k++)
+                                               {
+                                                       if(Tri[k].min[j1] >= max(Node[q[0]].p[j1],Node[q[2]].p[j1])) continue;
+                                                       if(Tri[k].min[j2] >= max(Node[q[0]].p[j2],Node[q[2]].p[j2])) continue;
+                                                       if(Tri[k].max[j1] <= min(Node[q[0]].p[j1],Node[q[2]].p[j1])) continue;
+                                                       if(Tri[k].max[j2] <= min(Node[q[0]].p[j2],Node[q[2]].p[j2])) continue;
+
+                                                       for(h0=0; h0<4 && OK; h0++)
+                                                       {
+                                                               h1 = (h0+1)%4;
+                                                               for(t=0; t<3 && OK; t++)
+                                                               {
+                                                                       s[t] = side(Node[q[h0]].p[j1],Node[q[h0]].p[j2],
+                                                                               Node[q[h1]].p[j1],Node[q[h1]].p[j2],
+                                                                               Node[Tri[k].v[t]].p[j1],Node[Tri[k].v[t]].p[j2]);
+                                                               }
+                                                               if((s[1] > 0 || s[2] > 0) && s[0] < 0) OK=0;
+                                                               if((s[2] > 0 || s[0] > 0) && s[1] < 0) OK=0;
+                                                               if((s[0] > 0 || s[1] > 0) && s[2] < 0) OK=0;
+                                                       }
+                                               }
+                                               if(!OK) continue;
+                                               switch(Plane)
+                                               {
+                                               case PLANE_XZ0:
+                                               case PLANE_XZ1:
+                                                       // front
+                                                       brush.face[0].v[0][0] = Node[q[2]].p[0];
+                                                       brush.face[0].v[0][1] = (float)front;
+                                                       brush.face[0].v[0][2] = Node[q[2]].p[2];
+                                                       
+                                                       brush.face[0].v[1][0] = Node[q[1]].p[0];
+                                                       brush.face[0].v[1][1] = (float)front;
+                                                       brush.face[0].v[1][2] = Node[q[1]].p[2];
+                                                       
+                                                       brush.face[0].v[2][0] = Node[q[0]].p[0];
+                                                       brush.face[0].v[2][1] = (float)front;
+                                                       brush.face[0].v[2][2] = Node[q[0]].p[2];
+                                                       
+                                                       // back
+                                                       brush.face[1].v[0][0] = Node[q[0]].p[0];
+                                                       brush.face[1].v[0][1] = (float)backface;
+                                                       brush.face[1].v[0][2] = Node[q[0]].p[2];
+                                                       
+                                                       brush.face[1].v[1][0] = Node[q[1]].p[0];
+                                                       brush.face[1].v[1][1] = (float)backface;
+                                                       brush.face[1].v[1][2] = Node[q[1]].p[2];
+                                                       
+                                                       brush.face[1].v[2][0] = Node[q[2]].p[0];
+                                                       brush.face[1].v[2][1] = (float)backface;
+                                                       brush.face[1].v[2][2] = Node[q[2]].p[2];
+                                                       
+                                                       for(k0=0; k0<brush.NumFaces-2; k0++)
+                                                       {
+                                                               k =k0+2;
+                                                               k1=(k0+1) % (brush.NumFaces-2);
+                                                               
+                                                               brush.face[k].v[0][0] = Node[q[k0]].p[0];
+                                                               brush.face[k].v[0][1] = (float)front;
+                                                               brush.face[k].v[0][2] = Node[q[k0]].p[2];
+                                                               
+                                                               brush.face[k].v[1][0] = Node[q[k1]].p[0];
+                                                               brush.face[k].v[1][1] = (float)front;
+                                                               brush.face[k].v[1][2] = Node[q[k1]].p[2];
+                                                               
+                                                               brush.face[k].v[2][0] = Node[q[k1]].p[0];
+                                                               brush.face[k].v[2][1] = (float)backface;
+                                                               brush.face[k].v[2][2] = Node[q[k1]].p[2];
+                                                       }
+                                                       break;
+                                               case PLANE_YZ0:
+                                               case PLANE_YZ1:
+                                                       // front
+                                                       brush.face[0].v[0][0] = (float)front;
+                                                       brush.face[0].v[0][1] = Node[q[2]].p[1];
+                                                       brush.face[0].v[0][2] = Node[q[2]].p[2];
+                                                       
+                                                       brush.face[0].v[1][0] = (float)front;
+                                                       brush.face[0].v[1][1] = Node[q[1]].p[1];
+                                                       brush.face[0].v[1][2] = Node[q[1]].p[2];
+                                                       
+                                                       brush.face[0].v[2][0] = (float)front;
+                                                       brush.face[0].v[2][1] = Node[q[0]].p[1];
+                                                       brush.face[0].v[2][2] = Node[q[0]].p[2];
+                                                       
+                                                       // back
+                                                       brush.face[1].v[0][0] = (float)backface;
+                                                       brush.face[1].v[0][1] = Node[q[0]].p[1];
+                                                       brush.face[1].v[0][2] = Node[q[0]].p[2];
+                                                       
+                                                       brush.face[1].v[1][0] = (float)backface;
+                                                       brush.face[1].v[1][1] = Node[q[1]].p[1];
+                                                       brush.face[1].v[1][2] = Node[q[1]].p[2];
+                                                       
+                                                       brush.face[1].v[2][0] = (float)backface;
+                                                       brush.face[1].v[2][1] = Node[q[2]].p[1];
+                                                       brush.face[1].v[2][2] = Node[q[2]].p[2];
+                                                       
+                                                       for(k0=0; k0<brush.NumFaces-2; k0++)
+                                                       {
+                                                               k =k0+2;
+                                                               k1=(k0+1) % (brush.NumFaces-2);
+                                                               
+                                                               brush.face[k].v[0][0] = (float)front;
+                                                               brush.face[k].v[0][1] = Node[q[k0]].p[1];
+                                                               brush.face[k].v[0][2] = Node[q[k0]].p[2];
+                                                               
+                                                               brush.face[k].v[1][0] = (float)front;
+                                                               brush.face[k].v[1][1] = Node[q[k1]].p[1];
+                                                               brush.face[k].v[1][2] = Node[q[k1]].p[2];
+                                                               
+                                                               brush.face[k].v[2][0] = (float)backface;
+                                                               brush.face[k].v[2][1] = Node[q[k1]].p[1];
+                                                               brush.face[k].v[2][2] = Node[q[k1]].p[2];
+                                                       }
+                                                       break;
+                                               default:
+                                                       // front
+                                                       brush.face[0].v[0][0] = Node[q[2]].p[0];
+                                                       brush.face[0].v[0][1] = Node[q[2]].p[1];
+                                                       brush.face[0].v[0][2] = (float)front;
+                                                       
+                                                       brush.face[0].v[1][0] = Node[q[1]].p[0];
+                                                       brush.face[0].v[1][1] = Node[q[1]].p[1];
+                                                       brush.face[0].v[1][2] = (float)front;
+                                                       
+                                                       brush.face[0].v[2][0] = Node[q[0]].p[0];
+                                                       brush.face[0].v[2][1] = Node[q[0]].p[1];
+                                                       brush.face[0].v[2][2] = (float)front;
+                                                       
+                                                       // back
+                                                       brush.face[1].v[0][0] = Node[q[0]].p[0];
+                                                       brush.face[1].v[0][1] = Node[q[0]].p[1];
+                                                       brush.face[1].v[0][2] = (float)backface;
+                                                       
+                                                       brush.face[1].v[1][0] = Node[q[1]].p[0];
+                                                       brush.face[1].v[1][1] = Node[q[1]].p[1];
+                                                       brush.face[1].v[1][2] = (float)backface;
+                                                       
+                                                       brush.face[1].v[2][0] = Node[q[2]].p[0];
+                                                       brush.face[1].v[2][1] = Node[q[2]].p[1];
+                                                       brush.face[1].v[2][2] = (float)backface;
+                                                       
+                                                       for(k0=0; k0<brush.NumFaces-2; k0++)
+                                                       {
+                                                               k =k0+2;
+                                                               k1=(k0+1) % (brush.NumFaces-2);
+                                                               
+                                                               brush.face[k].v[0][0] = Node[q[k0]].p[0];
+                                                               brush.face[k].v[0][1] = Node[q[k0]].p[1];
+                                                               brush.face[k].v[0][2] = (float)front;
+                                                               
+                                                               brush.face[k].v[1][0] = Node[q[k1]].p[0];
+                                                               brush.face[k].v[1][1] = Node[q[k1]].p[1];
+                                                               brush.face[k].v[1][2] = (float)front;
+                                                               
+                                                               brush.face[k].v[2][0] = Node[q[k1]].p[0];
+                                                               brush.face[k].v[2][1] = Node[q[k1]].p[1];
+                                                               brush.face[k].v[2][2] = (float)backface;
+                                                       }
+                                                       break;
+                                               } // switch (Plane)
+                                               for(face=0; face<6; face++)
+                                               {
+                                                       strcpy(brush.face[face].texture,(face<=1 ? skip : hint));
+                                                       brush.face[face].Shift[0] = 0;
+                                                       brush.face[face].Shift[1] = 0;
+                                                       brush.face[face].Rotate   = 0.;
+                                                       brush.face[face].Scale[0] = 1;
+                                                       brush.face[face].Scale[1] = 1;
+                                                       brush.face[face].Contents = CONTENTS_DETAIL;
+                                                       brush.face[face].Surface  = (face<=1 ? SURF_SKIP : SURF_HINT);
+                                                       brush.face[face].Value    = 0;
+                                               }
+                                               if(!brush.Number) OpenFuncGroup();
+                                               MakeBrush(&brush);
+                                               brush.Number++;
+                                       } // for(j=
+                               }     // for(i=
+                       }         // for(h=
+               }             // for(w=
+               if(brush.Number) CloseFuncGroup();
+       }
+        /*
+       ghCursorCurrent = ghCursorDefault;
+       SetCursor(ghCursorCurrent);
+        */
+}
+//===========================================================================
+int CheckBorders(int *NumNodesUsed, int NumNodes, NODE *Node, int *NumTris, TRI **pTri)
+{
+       int border;
+       int i, j, k0, k1, N;
+       float angle[3];
+       TRI *Tri;
+
+       N = NumNodesUsed[0];
+       Tri = *pTri;
+       for(i=0; i<NumTris[0]; i++)
+       {
+               EdgeOnSide(Tri[i].v,&k0,&border);
+               if(border < 0) continue;
+               CalcAngles(Node, Tri[i].v, angle);
+               k1 = (k0+1) % 3;
+               if((angle[k0] < SLIVER_ANGLE) || (angle[k1] < SLIVER_ANGLE))
+               {
+                       j = Bisect(Node, border, Tri[i].v[k0], Tri[i].v[k1]);
+                       if(j >= 0)
+                       {
+                               if(!Node[j].used)    // Shouldn't be used, but...
+                               {
+                                       NumNodesUsed[0]++;
+                                       Node[j].used++;
+                               }
+                       }
+               }
+       }
+       if(NumNodesUsed[0] > N)
+       {
+               free(*pTri);
+               tricall(NumNodes, Node, NumTris, NULL, pTri, "cnzBNPY");
+               Tri = *pTri;
+       }
+       return (NumNodesUsed[0] - N);
+}