00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00031
00032
00033
00035
00036 #include <cassert>
00037 #include <iostream>
00038
00039
00040 #include "isosurface.h"
00041 #include "vector3d.h"
00042
00046
00048 IsoSurface::IsoSurface()
00050 {
00051
00052 }
00053
00055 IsoSurface::~IsoSurface()
00057 {
00058 clearSurfaces();
00059 }
00060
00062 void IsoSurface::setParameters(const std::vector<double>* values, const Point3D<unsigned int>& pointDimension, const Point3D<float>& pointDelta, const Point3D<float>& pointOrigin)
00068 {
00069 clearParameters();
00070
00071
00072 densityValues.assign(values->begin(), values->end());
00073
00074 numPoints = pointDimension;
00075 delta = pointDelta;
00076 origin = pointOrigin;
00077 }
00078
00080 void IsoSurface::addSurface(const double isoDensity)
00083 {
00084 isoLevels.push_back(isoDensity);
00085 calculateSurface(isoDensity);
00086
00087
00088 vector<Point3D<float> >* singleVerticesList = new vector<Point3D<float> >;
00089 vector<unsigned int>* singleTriangleIndices = new vector<unsigned int>;
00090 renameVerticesAndTriangles(singleVerticesList, singleTriangleIndices);
00091 verticesList.push_back(singleVerticesList);
00092 triangleIndices.push_back(singleTriangleIndices);
00093
00094
00095 vector<float>* singleNormals = new vector<float>;
00096 calculateNormals(singleNormals, numSurfaces() - 1);
00097 normals.push_back(singleNormals);
00098 }
00099
00101 void IsoSurface::changeSurface(const unsigned int surface, const double isoDensity)
00103 {
00104 if(surface >= numSurfaces())
00105 return;
00106
00107 isoLevels[surface] = isoDensity;
00108 calculateSurface(isoDensity);
00109 renameVerticesAndTriangles(verticesList[surface], triangleIndices[surface]);
00110 calculateNormals(normals[surface], surface);
00111 }
00112
00114 bool IsoSurface::densityPresent() const
00116 {
00117 return densityValues.size() != 0;
00118 }
00119
00121 unsigned int IsoSurface::numSurfaces() const
00123 {
00124 return isoLevels.size();
00125 }
00126
00128 unsigned int IsoSurface::numTriangles(const unsigned int surface) const
00130 {
00131 if(surface >= numSurfaces())
00132 return 0;
00133
00134 return triangleIndices[surface]->size()/3;
00135 }
00136
00138 unsigned int IsoSurface::numVertices(const unsigned int surface) const
00140 {
00141 if(surface >= numSurfaces())
00142 return 0;
00143
00144 return verticesList[surface]->size();
00145 }
00146
00148 void IsoSurface::getTriangle(const unsigned int surface, const unsigned int index, Point3D<float>& point1, Point3D<float>& point2, Point3D<float>& point3, Point3D<float>& normal1, Point3D<float>& normal2, Point3D<float>& normal3) const
00154 {
00155 if(surface >= numSurfaces() || index >= triangleIndices[surface]->size()/3)
00156 {
00157 point1.setValues(0.0, 0.0, 0.0);
00158 point2.setValues(0.0, 0.0, 0.0);
00159 point3.setValues(0.0, 0.0, 0.0);
00160 normal1.setValues(0.0, 0.0, 0.0);
00161 normal2.setValues(0.0, 0.0, 0.0);
00162 normal3.setValues(0.0, 0.0, 0.0);
00163 return;
00164 }
00165
00166 unsigned int id1, id2, id3;
00167 if(isoLevels[surface] < 0.0)
00168 {
00169 id1 = triangleIndices[surface]->at(index*3);
00170 id2 = triangleIndices[surface]->at(index*3 + 1);
00171 id3 = triangleIndices[surface]->at(index*3 + 2);
00172 }
00173 else
00174 {
00175 id2 = triangleIndices[surface]->at(index*3);
00176 id1 = triangleIndices[surface]->at(index*3 + 1);
00177 id3 = triangleIndices[surface]->at(index*3 + 2);
00178 }
00179 point1 = verticesList[surface]->at(id1);
00180 point2 = verticesList[surface]->at(id2);
00181 point3 = verticesList[surface]->at(id3);
00182 point1.add(origin);
00183 point2.add(origin);
00184 point3.add(origin);
00185 if(isoLevels[surface] < 0.0)
00186 {
00187 normal1.setValues(-normals[surface]->at(id1*3), -normals[surface]->at(id1*3 + 1), -normals[surface]->at(id1*3 + 2));
00188 normal2.setValues(-normals[surface]->at(id2*3), -normals[surface]->at(id2*3 + 1), -normals[surface]->at(id2*3 + 2));
00189 normal3.setValues(-normals[surface]->at(id3*3), -normals[surface]->at(id3*3 + 1), -normals[surface]->at(id3*3 + 2));
00190 }
00191 else
00192 {
00193 normal1.setValues(normals[surface]->at(id1*3), normals[surface]->at(id1*3 + 1), normals[surface]->at(id1*3 + 2));
00194 normal2.setValues(normals[surface]->at(id2*3), normals[surface]->at(id2*3 + 1), normals[surface]->at(id2*3 + 2));
00195 normal3.setValues(normals[surface]->at(id3*3), normals[surface]->at(id3*3 + 1), normals[surface]->at(id3*3 + 2));
00196 }
00197 }
00198
00200 Point3D<float> IsoSurface::getPoint(const unsigned int surface, const unsigned int index) const
00202 {
00203 if(surface >= numSurfaces() || index >= verticesList[surface]->size())
00204 return Point3D<float>(0.0f, 0.0f, 0.0f);
00205
00206 Point3D<float> result = verticesList[surface]->at(index);
00207 result.add(origin);
00208 return result;
00209 }
00210
00212 void IsoSurface::clearParameters()
00214 {
00215 clearSurfaces();
00216 densityValues.clear();
00217 }
00218
00220 void IsoSurface::clearSurfaces()
00222 {
00223 for(unsigned int i = 0; i < numSurfaces(); i++)
00224 {
00225 delete verticesList[i];
00226 delete triangleIndices[i];
00227 delete normals[i];
00228 }
00229 isoLevels.clear();
00230 verticesList.clear();
00231 triangleIndices.clear();
00232 normals.clear();
00233 }
00234
00236 void IsoSurface::removeSurface(const unsigned int surface)
00238 {
00239 if(surface >= numSurfaces())
00240 return;
00241
00242 delete verticesList[surface];
00243 delete triangleIndices[surface];
00244 delete normals[surface];
00245 vector< vector<Point3D<float> >* >::iterator itv = verticesList.begin();
00246 itv += surface;
00247 verticesList.erase(itv);
00248 vector< vector<unsigned int>* >::iterator itt = triangleIndices.begin();
00249 itt += surface;
00250 triangleIndices.erase(itt);
00251 vector< vector<float>* >::iterator itn = normals.begin();
00252 itn += surface;
00253 normals.erase(itn);
00254 vector<double>::iterator iti = isoLevels.begin();
00255 iti += surface;
00256 isoLevels.erase(iti);
00257 }
00258
00260 Point3D<float> IsoSurface::getOrigin() const
00262 {
00263 return origin;
00264 }
00265
00267 Point3D<float> IsoSurface::getDelta() const
00269 {
00270 return delta;
00271 }
00272
00274 Point3D<unsigned int> IsoSurface::getNumPoints() const
00276 {
00277 return numPoints;
00278 }
00279
00283
00285 void IsoSurface::calculateSurface(const double isoDensity)
00287 {
00288 currentIsoLevel = isoDensity;
00289 vertices.clear();
00290 triangles.clear();
00291
00292 for(unsigned int z = 0; z < numPoints.z() - 1; z++)
00293 for(unsigned int y = 0; y < numPoints.y() -1; y++)
00294 for(unsigned int x = 0; x < numPoints.x() - 1; x++)
00295 {
00297 unsigned int tableIndex = 0;
00298 if(densityValues[getArrayIndex(x, y, z)] < currentIsoLevel)
00299 tableIndex |= 1;
00300 if(densityValues[getArrayIndex(x, y+1, z)] < currentIsoLevel)
00301 tableIndex |= 2;
00302 if(densityValues[getArrayIndex(x+1, y+1, z)] < currentIsoLevel)
00303 tableIndex |= 4;
00304 if(densityValues[getArrayIndex(x+1, y, z)] < currentIsoLevel)
00305 tableIndex |= 8;
00306 if(densityValues[getArrayIndex(x, y, z+1)] < currentIsoLevel)
00307 tableIndex |= 16;
00308 if(densityValues[getArrayIndex(x, y+1, z+1)] < currentIsoLevel)
00309 tableIndex |= 32;
00310 if(densityValues[getArrayIndex(x+1, y+1, z+1)] < currentIsoLevel)
00311 tableIndex |= 64;
00312 if(densityValues[getArrayIndex(x+1, y, z+1)] < currentIsoLevel)
00313 tableIndex |= 128;
00314
00316 if(edgeTable[tableIndex] != 0)
00317 {
00318 if(edgeTable[tableIndex] & 8)
00319 {
00320 Point3D<float> point = intersection(x, y, z, 3);
00321 unsigned int id = getEdgeID(x, y, z, 3);
00322 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00323 }
00324 if(edgeTable[tableIndex] & 1)
00325 {
00326 Point3D<float> point = intersection(x, y, z, 0);
00327 unsigned int id = getEdgeID(x, y, z, 0);
00328 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00329 }
00330 if(edgeTable[tableIndex] & 256)
00331 {
00332 Point3D<float> point = intersection(x, y, z, 8);
00333 unsigned int id = getEdgeID(x, y, z, 8);
00334 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00335 }
00336
00337 if(x == numPoints.x() - 2)
00338 {
00339 if(edgeTable[tableIndex] & 4)
00340 {
00341 Point3D<float> point = intersection(x, y, z, 2);
00342 unsigned int id = getEdgeID(x, y, z, 2);
00343 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00344 }
00345 if(edgeTable[tableIndex] & 2048)
00346 {
00347 Point3D<float> point = intersection(x, y, z, 11);
00348 unsigned int id = getEdgeID(x, y, z, 11);
00349 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00350 }
00351 }
00352 if(y == numPoints.y() - 2)
00353 {
00354 if(edgeTable[tableIndex] & 2)
00355 {
00356 Point3D<float> point = intersection(x, y, z, 1);
00357 unsigned int id = getEdgeID(x, y, z, 1);
00358 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00359 }
00360 if(edgeTable[tableIndex] & 512)
00361 {
00362 Point3D<float> point = intersection(x, y, z, 9);
00363 unsigned int id = getEdgeID(x, y, z, 9);
00364 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00365 }
00366 }
00367 if(z == numPoints.z() - 2)
00368 {
00369 if(edgeTable[tableIndex] & 16)
00370 {
00371 Point3D<float> point = intersection(x, y, z, 4);
00372 unsigned int id = getEdgeID(x, y, z, 4);
00373 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00374 }
00375 if(edgeTable[tableIndex] & 128)
00376 {
00377 Point3D<float> point = intersection(x, y, z, 7);
00378 unsigned int id = getEdgeID(x, y, z, 7);
00379 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00380 }
00381 }
00382 if((x == numPoints.x() - 2) && (y == numPoints.y() - 2))
00383 {
00384 if(edgeTable[tableIndex] & 1024)
00385 {
00386 Point3D<float> point = intersection(x, y, z, 10);
00387 unsigned int id = getEdgeID(x, y, z, 10);
00388 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00389 }
00390 }
00391 if((x == numPoints.x() - 2) && (z == numPoints.z() - 2))
00392 {
00393 if(edgeTable[tableIndex] & 64)
00394 {
00395 Point3D<float> point = intersection(x, y, z, 6);
00396 unsigned int id = getEdgeID(x, y, z, 6);
00397 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00398 }
00399 }
00400 if((y == numPoints.y() - 2) && (z == numPoints.z() - 2))
00401 {
00402 if(edgeTable[tableIndex] & 32)
00403 {
00404 Point3D<float> point = intersection(x, y, z, 5);
00405 unsigned int id = getEdgeID(x, y, z, 5);
00406 vertices.insert(std::map<unsigned int, Point3D<float> >::value_type(id, point));
00407 }
00408 }
00409
00410 for(unsigned int i = 0; triTable[tableIndex][i] != -1; i += 3)
00411 {
00412 Triangle triangle;
00413 triangle.pointID[0] = getEdgeID(x, y, z, triTable[tableIndex][i]);
00414 triangle.pointID[1] = getEdgeID(x, y, z, triTable[tableIndex][i+1]);
00415 triangle.pointID[2] = getEdgeID(x, y, z, triTable[tableIndex][i+2]);
00416 triangles.push_back(triangle);
00417 }
00418 }
00419 }
00420 }
00421
00423 Point3D<float> IsoSurface::intersection(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int edge)
00425 {
00426 unsigned int v1x = x, v1y = y, v1z = z;
00427 unsigned int v2x = x, v2y = y, v2z = z;
00428
00429 switch(edge)
00430 {
00431 case 0: v2y += 1;
00432 break;
00433 case 1: v1y += 1;
00434 v2x += 1;
00435 v2y += 1;
00436 break;
00437 case 2: v1x += 1;
00438 v1y += 1;
00439 v2x += 1;
00440 break;
00441 case 3: v1x += 1;
00442 break;
00443 case 4: v1z += 1;
00444 v2y += 1;
00445 v2z += 1;
00446 break;
00447 case 5: v1y += 1;
00448 v1z += 1;
00449 v2x += 1;
00450 v2y += 1;
00451 v2z += 1;
00452 break;
00453 case 6: v1x += 1;
00454 v1y += 1;
00455 v1z += 1;
00456 v2x += 1;
00457 v2z += 1;
00458 break;
00459 case 7: v1x += 1;
00460 v1z += 1;
00461 v2z += 1;
00462 break;
00463 case 8: v2z += 1;
00464 break;
00465 case 9: v1y += 1;
00466 v2y += 1;
00467 v2z += 1;
00468 break;
00469 case 10: v1x += 1;
00470 v1y += 1;
00471 v2x += 1;
00472 v2y += 1;
00473 v2z += 1;
00474 break;
00475 case 11: v1x += 1;
00476 v2x += 1;
00477 v2z += 1;
00478 break;
00479 }
00480 Point3D<float> point1(v1x * delta.x(), v1y * delta.y(), v1z * delta.z());
00481 Point3D<float> point2(v2x * delta.y(), v2y * delta.y(), v2z * delta.z());
00482
00483 double var1 = densityValues[getArrayIndex(v1x, v1y, v1z)];
00484 double var2 = densityValues[getArrayIndex(v2x, v2y, v2z)];
00485 return interpolate(point1, point2, var1, var2);
00486 }
00487
00489 Point3D<float> IsoSurface::interpolate(const Point3D<float> point1, const Point3D<float> point2, const double var1, const double var2)
00491 {
00492 const float mu = static_cast<float>((currentIsoLevel - var1)/(var2 - var1));
00493 const float x = point1.x() + mu*(point2.x() - point1.x());
00494 const float y = point1.y() + mu*(point2.y() - point1.y());
00495 const float z = point1.z() + mu*(point2.z() - point1.z());
00496
00497 return Point3D<float>(x, y, z);
00498 }
00499
00501 unsigned int IsoSurface::getEdgeID(const unsigned int x, const unsigned int y, const unsigned int z, const unsigned int edge)
00503 {
00504 switch(edge)
00505 {
00506 case 0: return getVertexID(x, y, z) + 1;
00507 case 1: return getVertexID(x, y+1, z);
00508 case 2: return getVertexID(x+1, y, z) + 1;
00509 case 3: return getVertexID(x, y, z);
00510 case 4: return getVertexID(x, y, z+1) + 1;
00511 case 5: return getVertexID(x, y+1, z+1);
00512 case 6: return getVertexID(x+1, y, z+1) + 1;
00513 case 7: return getVertexID(x, y, z+1);
00514 case 8: return getVertexID(x, y, z) + 2;
00515 case 9: return getVertexID(x, y+1, z) + 2;
00516 case 10: return getVertexID(x+1, y+1, z) + 2;
00517 case 11: return getVertexID(x+1, y, z) + 2;
00518 default: return static_cast<unsigned int>(-1);
00519 }
00520 }
00521
00523 unsigned int IsoSurface::getVertexID(const unsigned int x, const unsigned int y, const unsigned int z)
00525 {
00526 return 3*getArrayIndex(x, y, z);
00527 }
00528
00530 void IsoSurface::renameVerticesAndTriangles(vector<Point3D<float> >* singleVerticesList, vector<unsigned int>* singleTriangleIndices)
00532 {
00533 unsigned int nextID = 0;
00534 std::map<unsigned int, Point3D<float> >::iterator itVertices = vertices.begin();
00535 std::vector<Triangle>::iterator itTriangles = triangles.begin();
00536
00538 while(itVertices != vertices.end())
00539 {
00540 (*itVertices).second.setID(nextID++);
00541 itVertices++;
00542 }
00543
00545 while(itTriangles != triangles.end())
00546 {
00547 for(unsigned int i = 0; i < 3; i++)
00548 {
00549 unsigned int newID = vertices[(*itTriangles).pointID[i]].id();
00550 (*itTriangles).pointID[i] = newID;
00551 }
00552 itTriangles++;
00553 }
00554
00557 singleVerticesList->clear();
00558 singleVerticesList->reserve(vertices.size());
00559 singleTriangleIndices->clear();
00560 singleTriangleIndices->reserve(triangles.size()*3);
00561
00562
00563 itVertices = vertices.begin();
00564 for(unsigned int i = 0; i < vertices.size(); i++, itVertices++)
00565 singleVerticesList->push_back((*itVertices).second);
00566 vertices.clear();
00567
00568 itTriangles = triangles.begin();
00569 for(unsigned int i = 0; i < triangles.size(); i++, itTriangles++)
00570 {
00571 singleTriangleIndices->push_back((*itTriangles).pointID[0]);
00572 singleTriangleIndices->push_back((*itTriangles).pointID[1]);
00573 singleTriangleIndices->push_back((*itTriangles).pointID[2]);
00574 }
00575 triangles.clear();
00576 }
00577
00579 void IsoSurface::calculateNormals(vector<float>* singleNormals, const unsigned int surface)
00581 {
00582 singleNormals->clear();
00583 singleNormals->reserve(triangleIndices[surface]->size());
00584
00585 for(unsigned int i = 0; i < triangleIndices[surface]->size(); i++)
00586 singleNormals->push_back(0.0f);
00587
00588 for(unsigned int i = 0; i < triangleIndices[surface]->size()/3; i++)
00589 {
00590 unsigned int id1 = triangleIndices[surface]->at(i*3);
00591 unsigned int id2 = triangleIndices[surface]->at(i*3 + 1);
00592 unsigned int id3 = triangleIndices[surface]->at(i*3 + 2);
00593 Vector3D<float> vector1(verticesList[surface]->at(id1), verticesList[surface]->at(id2));
00594 Vector3D<float> vector2(verticesList[surface]->at(id1), verticesList[surface]->at(id3));
00595 Vector3D<float> normal = vector2.cross(vector1);
00596 normal.normalize();
00597 singleNormals->at(id1*3) += normal.x();
00598 singleNormals->at(id1*3 + 1) += normal.y();
00599 singleNormals->at(id1*3 + 2) += normal.z();
00600 singleNormals->at(id2*3) += normal.x();
00601 singleNormals->at(id2*3 + 1) += normal.y();
00602 singleNormals->at(id2*3 + 2) += normal.z();
00603 singleNormals->at(id3*3) += normal.x();
00604 singleNormals->at(id3*3 + 1) += normal.y();
00605 singleNormals->at(id3*3 + 2) += normal.z();
00606 }
00607 }
00608
00610 unsigned int IsoSurface::getArrayIndex(const unsigned int x, const unsigned int y, const unsigned int z) const
00612 {
00613 return x*numPoints.y()*numPoints.z() + y*numPoints.z() + z;
00614 }
00615
00619
00620 const unsigned int IsoSurface::edgeTable[256] =
00621 {
00622 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
00623 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
00624 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
00625 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
00626 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
00627 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
00628 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
00629 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
00630 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
00631 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
00632 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
00633 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
00634 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
00635 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
00636 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
00637 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
00638 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
00639 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
00640 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
00641 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
00642 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
00643 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
00644 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
00645 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
00646 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
00647 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
00648 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
00649 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
00650 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
00651 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
00652 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
00653 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
00654 };
00655
00656 const int IsoSurface::triTable[256][16] =
00657 {
00658 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00659 {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00660 {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00661 {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00662 {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00663 {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00664 {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00665 {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00666 {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00667 {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00668 {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00669 {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00670 {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00671 {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00672 {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00673 {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00674 {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00675 {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00676 {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00677 {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00678 {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00679 {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
00680 {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00681 {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00682 {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00683 {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00684 {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00685 {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
00686 {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
00687 {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
00688 {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00689 {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00690 {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00691 {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00692 {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00693 {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00694 {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00695 {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00696 {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00697 {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
00698 {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00699 {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00700 {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00701 {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
00702 {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
00703 {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
00704 {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00705 {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00706 {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00707 {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00708 {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00709 {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00710 {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
00711 {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
00712 {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
00713 {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00714 {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
00715 {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00716 {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
00717 {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00718 {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
00719 {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
00720 {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
00721 {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00722 {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00723 {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00724 {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00725 {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00726 {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00727 {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
00728 {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00729 {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
00730 {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00731 {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00732 {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00733 {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
00734 {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00735 {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00736 {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
00737 {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00738 {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00739 {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
00740 {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00741 {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00742 {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
00743 {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
00744 {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
00745 {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
00746 {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00747 {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00748 {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
00749 {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
00750 {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00751 {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
00752 {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
00753 {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
00754 {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00755 {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
00756 {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00757 {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00758 {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00759 {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
00760 {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00761 {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00762 {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
00763 {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
00764 {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00765 {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
00766 {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
00767 {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
00768 {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00769 {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00770 {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00771 {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
00772 {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
00773 {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00774 {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00775 {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
00776 {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00777 {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00778 {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00779 {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
00780 {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
00781 {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
00782 {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
00783 {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00784 {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
00785 {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00786 {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00787 {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00788 {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00789 {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00790 {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00791 {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00792 {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
00793 {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
00794 {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00795 {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00796 {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
00797 {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
00798 {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00799 {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
00800 {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
00801 {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00802 {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00803 {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00804 {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
00805 {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
00806 {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
00807 {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
00808 {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
00809 {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
00810 {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00811 {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00812 {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
00813 {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
00814 {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
00815 {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00816 {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
00817 {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00818 {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00819 {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
00820 {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00821 {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
00822 {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
00823 {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
00824 {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
00825 {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
00826 {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
00827 {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
00828 {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
00829 {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
00830 {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
00831 {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
00832 {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
00833 {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
00834 {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00835 {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
00836 {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
00837 {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00838 {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
00839 {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
00840 {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
00841 {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
00842 {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
00843 {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
00844 {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
00845 {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00846 {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
00847 {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
00848 {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00849 {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00850 {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00851 {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
00852 {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
00853 {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
00854 {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00855 {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
00856 {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
00857 {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
00858 {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00859 {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
00860 {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
00861 {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
00862 {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00863 {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
00864 {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
00865 {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00866 {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00867 {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
00868 {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
00869 {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
00870 {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
00871 {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
00872 {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
00873 {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00874 {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
00875 {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
00876 {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
00877 {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
00878 {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
00879 {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00880 {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
00881 {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00882 {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00883 {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
00884 {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
00885 {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
00886 {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
00887 {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
00888 {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00889 {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
00890 {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
00891 {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
00892 {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
00893 {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00894 {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00895 {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
00896 {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00897 {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00898 {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00899 {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00900 {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
00901 {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00902 {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
00903 {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
00904 {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00905 {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00906 {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
00907 {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00908 {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
00909 {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00910 {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00911 {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00912 {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00913 {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
00914 };
00915