Allink  v0.1
VarDataMarchCubes.cpp
00001 #include "VarData.h"
00002 
00003 //
00004 // Marching Cubes Example Program 
00005 // by Cory Bloyd (corysama@yahoo.com)
00006 //
00007 // A simple, portable and complete implementation of the Marching Cubes
00008 // and Marching Tetrahedrons algorithms in a single source file.
00009 // There are many ways that this code could be made faster, but the 
00010 // intent is for the code to be easy to understand.
00011 //
00012 // For a description of the algorithm go to
00013 // http://astronomy.swin.edu.au/pbourke/modelling/polygonise/
00014 //
00015 // This code is public domain.
00016 //
00017 XYZ VertexInterp(double isolevel,XYZ p1,XYZ p2,double valp1,double valp2);
00018 int PolygoniseCube(GRIDCELL g,double iso,VAR_TRIANGLE *tri);
00019 int PolygoniseSquare(GRIDCELL g,double iso,VAR_LINE *tri);
00020 XYZ TriangNorm(XYZ p1,XYZ p2,XYZ p3);
00021 VAR_TRIANGLE *VarData::MarchingCubes(double *Plot,int NSample,double IsoLevel,int *NTriang){
00022   int NTri = 0;
00023   double InvNSample = 1./(double)NSample;
00024   int NVertex = 2*NSample-1;
00025   GRIDCELL Grid;
00026   VAR_TRIANGLE triangles[10];
00027   VAR_TRIANGLE *Triang = NULL;
00028   for(int sx = 0;sx<NSample-1;sx++){
00029     for(int sy = 0;sy<NSample-1;sy++){
00030       for(int sz = 0;sz<NSample-1;sz++){
00031    Grid.p[0].x[0] = (sx)*InvNSample*pEdge(0);
00032    Grid.p[0].x[1] = (sy)*InvNSample*pEdge(1);
00033    Grid.p[0].x[2] = (sz)*InvNSample*pEdge(2);
00034    Grid.val[0] = Plot[((sx)*NSample+(sy))*NSample+sz];
00035    Grid.p[1].x[0] = (sx+1)*InvNSample*pEdge(0);
00036    Grid.p[1].x[1] = (sy)*InvNSample*pEdge(1);
00037    Grid.p[1].x[2] = (sz)*InvNSample*pEdge(2);
00038    Grid.val[1] = Plot[((sx+1)*NSample+(sy))*NSample+sz];
00039    Grid.p[2].x[0] = (sx+1)*InvNSample*pEdge(0);
00040    Grid.p[2].x[1] = (sy+1)*InvNSample*pEdge(1);
00041    Grid.p[2].x[2] = (sz)*InvNSample*pEdge(2);
00042    Grid.val[2] = Plot[((sx+1)*NSample+(sy+1))*NSample+sz];
00043    Grid.p[3].x[0] = (sx)*InvNSample*pEdge(0);
00044    Grid.p[3].x[1] = (sy+1)*InvNSample*pEdge(1);
00045    Grid.p[3].x[2] = (sz)*InvNSample*pEdge(2);
00046    Grid.val[3] = Plot[((sx)*NSample+(sy+1))*NSample+sz];
00047    Grid.p[4].x[0] = (sx)*InvNSample*pEdge(0);
00048    Grid.p[4].x[1] = (sy)*InvNSample*pEdge(1);
00049    Grid.p[4].x[2] = (sz+1)*InvNSample*pEdge(2);
00050    Grid.val[4] = Plot[((sx)*NSample+(sy))*NSample+sz+1];
00051    Grid.p[5].x[0] = (sx+1)*InvNSample*pEdge(0);
00052    Grid.p[5].x[1] = (sy)*InvNSample*pEdge(1);
00053    Grid.p[5].x[2] = (sz+1)*InvNSample*pEdge(2);
00054    Grid.val[5] = Plot[((sx+1)*NSample+(sy))*NSample+sz+1];
00055    Grid.p[6].x[0] = (sx+1)*InvNSample*pEdge(0);
00056    Grid.p[6].x[1] = (sy+1)*InvNSample*pEdge(1);
00057    Grid.p[6].x[2] = (sz+1)*InvNSample*pEdge(2);
00058    Grid.val[6] = Plot[((sx+1)*NSample+(sy+1))*NSample+sz+1];
00059    Grid.p[7].x[0] = (sx)*InvNSample*pEdge(0);
00060    Grid.p[7].x[1] = (sy+1)*InvNSample*pEdge(1);
00061    Grid.p[7].x[2] = (sz+1)*InvNSample*pEdge(2);
00062    Grid.val[7] = Plot[((sx)*NSample+(sy+1))*NSample+sz+1];
00063    int n = PolygoniseCube(Grid,IsoLevel,triangles);
00064    Triang = (VAR_TRIANGLE *)realloc(Triang,(NTri+n)*sizeof(VAR_TRIANGLE));
00065    int s[3];
00066    for(int l=0;l<n;l++){
00067      for(int v=0;v<3;v++){
00068        for(int d=0;d<3;d++){
00069          s[d] = (int)(triangles[l].p[v].x[d]*pInvEdge(d)*NVertex);
00070          if(s[d] < 0 || s[d] >= NVertex){
00071       printf("Marching: 0 <= sx %d < NVertex %d  0. < %lf < %lf\n",sx,NVertex,triangles[l].p[v].x[d],pEdge(d));
00072       continue;
00073          }
00074        }
00075        triangles[l].v[v] = (s[0]*NVertex+s[1])*NVertex+s[2];
00076      }
00077      Triang[NTri+l] = triangles[l];
00078    }
00079    NTri += n;
00080       }
00081     }
00082   }
00083   *NTriang = NTri;
00084   return Triang;
00085 }
00094 int PolygoniseCube(GRIDCELL g,double iso,VAR_TRIANGLE *tri){
00095   extern int edgeTable[256];
00096   extern int triTable[256][16];
00097   int i,ntri = 0;
00098   int cubeindex;
00099   XYZ vertlist[12];
00100   double OneThird = 1./3.;
00101   /*
00102     Determine the index into the edge table which
00103     tells us which vertices are inside of the surface
00104   */
00105   cubeindex = 0;
00106   if (g.val[0] < iso) cubeindex |= 1;
00107   if (g.val[1] < iso) cubeindex |= 2;
00108   if (g.val[2] < iso) cubeindex |= 4;
00109   if (g.val[3] < iso) cubeindex |= 8;
00110   if (g.val[4] < iso) cubeindex |= 16;
00111   if (g.val[5] < iso) cubeindex |= 32;
00112   if (g.val[6] < iso) cubeindex |= 64;
00113   if (g.val[7] < iso) cubeindex |= 128;
00114 
00115   /* Cube is entirely in/out of the surface */
00116   if (edgeTable[cubeindex] == 0)
00117     return(0);
00118 
00119   /* Find the vertices where the surface intersects the cube */
00120   if (edgeTable[cubeindex] & 1) {
00121     vertlist[0] = VertexInterp(iso,g.p[0],g.p[1],g.val[0],g.val[1]);
00122   }
00123   if (edgeTable[cubeindex] & 2) {
00124     vertlist[1] = VertexInterp(iso,g.p[1],g.p[2],g.val[1],g.val[2]);
00125   }
00126   if (edgeTable[cubeindex] & 4) {
00127     vertlist[2] = VertexInterp(iso,g.p[2],g.p[3],g.val[2],g.val[3]);
00128   }
00129   if (edgeTable[cubeindex] & 8) {
00130     vertlist[3] = VertexInterp(iso,g.p[3],g.p[0],g.val[3],g.val[0]);
00131   }
00132   if (edgeTable[cubeindex] & 16) {
00133     vertlist[4] = VertexInterp(iso,g.p[4],g.p[5],g.val[4],g.val[5]);
00134   }
00135   if (edgeTable[cubeindex] & 32) {
00136     vertlist[5] = VertexInterp(iso,g.p[5],g.p[6],g.val[5],g.val[6]);
00137   }
00138   if (edgeTable[cubeindex] & 64) {
00139     vertlist[6] = VertexInterp(iso,g.p[6],g.p[7],g.val[6],g.val[7]);
00140   }
00141   if (edgeTable[cubeindex] & 128) {
00142     vertlist[7] = VertexInterp(iso,g.p[7],g.p[4],g.val[7],g.val[4]);
00143   }
00144   if (edgeTable[cubeindex] & 256) {
00145     vertlist[8] = VertexInterp(iso,g.p[0],g.p[4],g.val[0],g.val[4]);
00146   }
00147   if (edgeTable[cubeindex] & 512) {
00148     vertlist[9] = VertexInterp(iso,g.p[1],g.p[5],g.val[1],g.val[5]);
00149   }
00150   if (edgeTable[cubeindex] & 1024) {
00151     vertlist[10] = VertexInterp(iso,g.p[2],g.p[6],g.val[2],g.val[6]);
00152   }
00153   if (edgeTable[cubeindex] & 2048) {
00154     vertlist[11] = VertexInterp(iso,g.p[3],g.p[7],g.val[3],g.val[7]);
00155   }
00156   /* Create the triangles */
00157   for (i=0;triTable[cubeindex][i]!=-1;i+=3) {
00158     tri[ntri].p[0] = vertlist[triTable[cubeindex][i  ]];
00159     tri[ntri].p[1] = vertlist[triTable[cubeindex][i+1]];
00160     tri[ntri].p[2] = vertlist[triTable[cubeindex][i+2]];
00161     for(int d=0;d<3;d++){
00162       tri[ntri].c.x[d] = (tri[ntri].p[0].x[d]+tri[ntri].p[1].x[d]+tri[ntri].p[2].x[d])*OneThird;
00163     }
00164     //TODO: Find the normal to the vertices, 
00165     // i.e. how the triangles are connected
00166     tri[ntri].n[0] = TriangNorm(tri[ntri].p[0],tri[ntri].p[1],tri[ntri].p[2]);
00167     tri[ntri].n[1] = TriangNorm(tri[ntri].p[0],tri[ntri].p[1],tri[ntri].p[2]);
00168     tri[ntri].n[2] = TriangNorm(tri[ntri].p[0],tri[ntri].p[1],tri[ntri].p[2]);
00169     //if(fabs(tri[ntri].n[0].x+tri[ntri].n[0].y+tri[ntri].n[0].z) <= 0.) continue;
00170     ntri++;
00171   }
00172   return(ntri);
00173 }
00174 VAR_LINE *VarData::MarchingSquares(double *Plot,int NSample,double IsoLevel,int *NTriang){
00175   int NTri = 0;
00176   double InvNSample = 1./(double)NSample;
00177   int NVertex = 2*NSample-1;
00178   GRIDCELL Grid;
00179   VAR_LINE triangles[4];
00180   VAR_LINE *Triang = NULL;
00181   for(int sx = 0;sx<NSample-1;sx++){
00182     for(int sy = 0;sy<NSample-1;sy++){
00183       Grid.p[0].x[0] = (sx)*InvNSample*pEdge(0);
00184       Grid.p[0].x[1] = (sy)*InvNSample*pEdge(1);
00185       Grid.p[0].x[2] = IsoLevel;
00186       Grid.val[0] = Plot[(sx)*NSample+(sy)];
00187       Grid.p[1].x[0] = (sx+1)*InvNSample*pEdge(0);
00188       Grid.p[1].x[1] = (sy)*InvNSample*pEdge(1);
00189       Grid.p[1].x[2] = IsoLevel;
00190       Grid.val[1] = Plot[(sx+1)*NSample+(sy)];
00191       Grid.p[2].x[0] = (sx+1)*InvNSample*pEdge(0);
00192       Grid.p[2].x[1] = (sy+1)*InvNSample*pEdge(1);
00193       Grid.p[2].x[2] = IsoLevel;
00194       Grid.val[2] = Plot[(sx+1)*NSample+(sy+1)];
00195       Grid.p[3].x[0] = (sx)*InvNSample*pEdge(0);
00196       Grid.p[3].x[1] = (sy+1)*InvNSample*pEdge(1);
00197       Grid.p[3].x[2] = IsoLevel;
00198       Grid.val[3] = Plot[(sx)*NSample+(sy+1)];
00199       int n = PolygoniseSquare(Grid,IsoLevel,triangles);
00200       Triang = (VAR_LINE *)realloc(Triang,(NTri+n)*sizeof(VAR_LINE));
00201       int s[3];
00202       for(int l=0;l<n;l++){
00203    for(int v=0;v<2;v++){
00204      for(int d=0;d<2;d++){
00205        s[d] = (int)(triangles[l].p[v].x[d]*pInvEdge(d)*NVertex);
00206        if(s[d] < 0 || s[d] >= NVertex){
00207          printf("Marching squares: 0 <= sx %d < NVertex %d  0. < %lf < %lf\n",s[d],NVertex,triangles[l].p[v].x[d],pEdge(d));
00208          continue;
00209        }
00210      }
00211      triangles[l].v[v] = s[0]*NVertex+s[1];
00212    }
00213    Triang[NTri+l] = triangles[l];
00214       }
00215       NTri += n;
00216     }
00217   }
00218   *NTriang = NTri;
00219   return Triang;
00220 }
00229 int PolygoniseSquare(GRIDCELL g,double iso,VAR_LINE *tri){
00230   extern int edgeTable2d[16];
00231   extern int triTable2d[16][4];
00232   int i,ntri = 0;
00233   int cubeindex;
00234   XYZ vertlist[4];
00235   XYZ Normal;
00236   Normal.x[0] = 0.;
00237   Normal.x[1] = 0.;
00238   Normal.x[2] = 1.;
00239   /*
00240     Determine the index into the edge table which
00241     tells us which vertices are inside of the surface
00242   */
00243   cubeindex = 0;
00244   if (g.val[0] < iso) cubeindex |= 1;
00245   if (g.val[1] < iso) cubeindex |= 2;
00246   if (g.val[2] < iso) cubeindex |= 4;
00247   if (g.val[3] < iso) cubeindex |= 8;
00248   /* Square is entirely in/out of the surface */
00249   if (edgeTable2d[cubeindex] == 0)
00250     return(0);
00251   /* Find the vertices where the surface intersects the cube */
00252   if (edgeTable2d[cubeindex] & 1) {
00253     vertlist[0] = VertexInterp(iso,g.p[0],g.p[1],g.val[0],g.val[1]);
00254   }
00255   if (edgeTable2d[cubeindex] & 2) {
00256     vertlist[1] = VertexInterp(iso,g.p[1],g.p[2],g.val[1],g.val[2]);
00257   }
00258   if (edgeTable2d[cubeindex] & 4) {
00259     vertlist[2] = VertexInterp(iso,g.p[2],g.p[3],g.val[2],g.val[3]);
00260   }
00261   if (edgeTable2d[cubeindex] & 8) {
00262     vertlist[3] = VertexInterp(iso,g.p[3],g.p[0],g.val[3],g.val[0]);
00263   }
00264   /* Create the triangles */
00265   for(i=0;triTable2d[cubeindex][i]!=-1;i+=2){
00266     tri[ntri].p[0] = vertlist[triTable2d[cubeindex][i  ]];
00267     tri[ntri].p[1] = vertlist[triTable2d[cubeindex][i+1]];
00268     for(int d=0;d<2;d++){
00269       tri[ntri].c.x[d] = (tri[ntri].p[0].x[d]+tri[ntri].p[1].x[d])*.5;
00270     }
00271     //TODO: Find the normal to the vertices, 
00272     // i.e. how the triangles are connected
00273     tri[ntri].n[0] = Normal;
00274     tri[ntri].n[1] = Normal;
00275     //if(fabs(tri[ntri].n[0].x+tri[ntri].n[0].y+tri[ntri].n[0].z) <= 0.) continue;
00276     ntri++;
00277   }
00278   return(ntri);
00279 }
00280 XYZ TriangNorm(XYZ p1,XYZ p2,XYZ p3){
00281   XYZ n;
00282   double Norm = 0.;
00283   n.x[0] = (p2.x[1]-p1.x[1])*(p2.x[2]-p3.x[2]) 
00284     - (p2.x[1]-p3.x[1])*(p2.x[2]-p1.x[2]);
00285   n.x[1] = (p2.x[2]-p1.x[2])*(p2.x[0]-p3.x[0]) 
00286     - (p2.x[2]-p3.x[2])*(p2.x[0]-p1.x[0]);
00287   n.x[2] = (p2.x[0]-p1.x[0])*(p2.x[1]-p3.x[1]) 
00288     - (p2.x[0]-p3.x[0])*(p2.x[1]-p1.x[1]);
00289   Norm = sqrt(SQR(n.x[0])+SQR(n.x[1])+SQR(n.x[2]));
00290   if(Norm > 0.){
00291     Norm = 1./Norm;
00292     n.x[0] *= Norm;
00293     n.x[1] *= Norm;
00294     n.x[2] *= Norm;
00295   }
00296   return n;
00297 }
00302 XYZ VertexInterp(double isolevel,XYZ p1,XYZ p2,double valp1,double valp2){
00303   double mu;
00304   XYZ p;
00305   if (ABS(isolevel-valp1) < 0.00001)
00306     return(p1);
00307   if (ABS(isolevel-valp2) < 0.00001)
00308     return(p2);
00309   if (ABS(valp1-valp2) < 0.00001)
00310     return(p1);
00311   mu = (isolevel - valp1) / (valp2 - valp1);
00312   p.x[0] = p1.x[0] + mu * (p2.x[0] - p1.x[0]);
00313   p.x[1] = p1.x[1] + mu * (p2.x[1] - p1.x[1]);
00314   p.x[2] = p1.x[2] + mu * (p2.x[2] - p1.x[2]);
00315   return(p);
00316 }
00350 int edgeTable[256]={
00351   0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
00352   0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
00353   0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
00354   0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
00355   0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
00356   0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
00357   0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
00358   0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
00359   0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
00360   0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
00361   0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
00362   0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
00363   0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
00364   0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
00365   0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
00366   0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
00367   0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
00368   0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
00369   0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
00370   0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
00371   0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
00372   0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
00373   0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
00374   0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
00375   0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
00376   0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
00377   0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
00378   0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
00379   0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
00380   0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
00381   0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
00382   0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0   
00383 };
00407 int triTable[256][16] =
00408   {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00409    {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00410    {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00411    {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00412    {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00413    {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00414    {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00415    {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00416    {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00417    {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00418    {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00419    {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00420    {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00421    {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00422    {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00423    {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00424    {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00425    {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00426    {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00427    {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00428    {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00429    {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
00430    {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00431    {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00432    {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00433    {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00434    {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00435    {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
00436    {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
00437    {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
00438    {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00439    {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00440    {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00441    {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00442    {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00443    {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00444    {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00445    {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00446    {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00447    {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
00448    {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00449    {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00450    {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00451    {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
00452    {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
00453    {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
00454    {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00455    {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00456    {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00457    {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00458    {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00459    {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00460    {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
00461    {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
00462    {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
00463    {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00464    {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
00465    {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00466    {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
00467    {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00468    {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
00469    {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
00470    {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
00471    {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00472    {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00473    {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00474    {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00475    {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00476    {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00477    {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
00478    {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00479    {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
00480    {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00481    {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00482    {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00483    {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
00484    {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00485    {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00486    {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
00487    {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00488    {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00489    {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
00490    {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00491    {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00492    {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
00493    {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
00494    {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
00495    {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
00496    {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00497    {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00498    {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
00499    {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
00500    {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00501    {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
00502    {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
00503    {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
00504    {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00505    {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
00506    {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00507    {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00508    {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00509    {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
00510    {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00511    {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00512    {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
00513    {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
00514    {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00515    {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
00516    {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
00517    {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
00518    {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00519    {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00520    {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00521    {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
00522    {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
00523    {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00524    {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00525    {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
00526    {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00527    {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00528    {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00529    {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
00530    {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
00531    {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
00532    {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
00533    {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00534    {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
00535    {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00536    {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00537    {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00538    {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00539    {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00540    {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00541    {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00542    {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00543    {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
00544    {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00545    {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00546    {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
00547    {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
00548    {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00549    {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
00550    {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
00551    {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00552    {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00553    {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00554    {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
00555    {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
00556    {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
00557    {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
00558    {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
00559    {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
00560    {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00561    {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00562    {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
00563    {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00564    {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
00565    {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00566    {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
00567    {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00568    {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00569    {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00570    {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00571    {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
00572    {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00573    {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
00574    {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
00575    {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
00576    {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
00577    {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
00578    {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
00579    {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
00580    {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
00581    {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
00582    {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
00583    {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
00584    {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00585    {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
00586    {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
00587    {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00588    {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
00589    {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
00590    {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
00591    {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
00592    {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
00593    {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00594    {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
00595    {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00596    {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
00597    {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
00598    {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00599    {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00600    {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00601    {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
00602    {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
00603    {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
00604    {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00605    {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
00606    {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
00607    {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
00608    {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00609    {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
00610    {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
00611    {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
00612    {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00613    {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00614    {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00615    {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00616    {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00617    {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
00618    {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
00619    {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
00620    {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
00621    {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
00622    {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
00623    {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00624    {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
00625    {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00626    {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
00627    {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
00628    {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00629    {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00630    {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
00631    {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00632    {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00633    {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
00634    {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
00635    {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
00636    {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
00637    {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
00638    {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00639    {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
00640    {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
00641    {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
00642    {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
00643    {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00644    {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00645    {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
00646    {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00647    {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00648    {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00649    {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00650    {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00651    {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00652    {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00653    {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
00654    {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00655    {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00656    {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00657    {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00658    {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
00659    {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00660    {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00661    {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00662    {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00663    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
00664 };
00693 int edgeTable2d[16]={
00694   0x0 , 0x09, 0x03, 0x0a, 0x06, 0x0f, 0x05, 0x0c, 
00695   0x0c, 0x05, 0x0f, 0x06, 0x0a, 0x03, 0x09, 0x0
00696 };
00697 int triTable2d[16][4] = {
00698   {-1,-1,-1,-1},
00699   {0,3,-1,-1},
00700   {0,1,-1,-1},
00701   {3,1,-1,-1},
00702   {1,2,-1,-1},
00703   {0,1,2,3},
00704   {0,2,-1,-1},
00705   {2,3,-1,-1},
00706   {2,3,-1,-1},
00707   {2,0,-1,-1},
00708   {3,0,1,2},
00709   {1,2,-1,-1},
00710   {1,3,-1,-1},
00711   {0,1,-1,-1},
00712   {3,0,-1,-1},
00713   {-1,-1,-1,-1}
00714 };
00715