TGLMarchingCubes.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLMarchingCubes.cxx 33600 2010-05-21 09:24:32Z rdm $
00002 // Author:  Timur Pocheptsov  06/01/2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include <algorithm>
00013 #include <cmath>
00014 
00015 #include "TError.h"
00016 #include "TF3.h"
00017 
00018 #include "TGLMarchingCubes.h"
00019 
00020 /*
00021 Implementation of "marching cubes" algortihm for GL module. Used by 
00022 TF3GLPainter, TGLIsoPainter, TGL5DPainter. 
00023 Good and clear algorithm explanation can be found here: 
00024 http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
00025 */
00026 
00027 namespace Rgl {
00028 namespace Mc {
00029 
00030 /*
00031 Some routines, values and tables for marching cube method.
00032 */
00033 extern const UInt_t  eInt[256];
00034 extern const Float_t vOff[8][3];
00035 extern const UChar_t eConn[12][2];
00036 extern const Float_t eDir[12][3];
00037 extern const Int_t   conTbl[256][16];
00038 
00039 namespace {
00040 
00041 enum ECubeBitMasks {
00042    k0  = 0x1,
00043    k1  = 0x2,
00044    k2  = 0x4,
00045    k3  = 0x8,
00046    k4  = 0x10,
00047    k5  = 0x20,
00048    k6  = 0x40,
00049    k7  = 0x80,
00050    k8  = 0x100,
00051    k9  = 0x200,
00052    k10 = 0x400,
00053    k11 = 0x800,
00054    //
00055    k1_5            = k1 | k5,
00056    k2_6            = k2 | k6,
00057    k3_7            = k3 | k7,
00058    k4_5_6_7        = k4 | k5 | k6 | k7,
00059    k5_6            = k5 | k6,
00060    k0_1_2_3_7_8_11 = k0 | k1 | k2 | k3 | k7 | k8 | k11,
00061    k6_7            = k6 | k7
00062 };
00063 
00064 //______________________________________________________________________
00065 template<class E, class V>
00066 void ConnectTriangles(TCell<E> &cell, TIsoMesh<V> *mesh, V eps)
00067 {
00068    UInt_t t[3];
00069    for (UInt_t i = 0; i < 5; ++i) {
00070       if (conTbl[cell.fType][3 * i] < 0)
00071          break;
00072       for (Int_t j = 2; j >= 0; --j)
00073          t[j] = cell.fIds[conTbl[cell.fType][3 * i + j]];
00074 
00075       const V *v0 = &mesh->fVerts[t[0] * 3];
00076       const V *v1 = &mesh->fVerts[t[1] * 3];
00077       const V *v2 = &mesh->fVerts[t[2] * 3];
00078 
00079       if (std::abs(v0[0] - v1[0]) < eps && 
00080           std::abs(v0[1] - v1[1]) < eps &&
00081           std::abs(v0[2] - v1[2]) < eps)
00082          continue;
00083 
00084       if (std::abs(v2[0] - v1[0]) < eps && 
00085           std::abs(v2[1] - v1[1]) < eps &&
00086           std::abs(v2[2] - v1[2]) < eps)
00087          continue;
00088 
00089       if (std::abs(v0[0] - v2[0]) < eps && 
00090           std::abs(v0[1] - v2[1]) < eps &&
00091           std::abs(v0[2] - v2[2]) < eps)
00092          continue;
00093 
00094       mesh->AddTriangle(t);
00095    }
00096 }
00097 
00098 }//unnamed namespace.
00099 
00100 /*
00101 TF3Adapter.
00102 */
00103 //______________________________________________________________________
00104 void TF3Adapter::SetDataSource(const TF3 *f3)
00105 {
00106    fTF3 = f3;
00107    fW = f3->GetXaxis()->GetNbins();//f3->GetNpx();
00108    fH = f3->GetYaxis()->GetNbins();//f3->GetNpy();
00109    fD = f3->GetZaxis()->GetNbins();//f3->GetNpz();
00110 }
00111 
00112 //______________________________________________________________________
00113 Double_t TF3Adapter::GetData(UInt_t i, UInt_t j, UInt_t k)const
00114 {
00115    return fTF3->Eval(fMinX * fXScaleInverted + i * fStepX * fXScaleInverted, 
00116                      fMinY * fYScaleInverted + j * fStepY * fYScaleInverted, 
00117                      fMinZ * fZScaleInverted + k * fStepZ * fZScaleInverted);
00118 }
00119 
00120 /*
00121 TF3 split edge implementation.
00122 */
00123 //______________________________________________________________________
00124 void TF3EdgeSplitter::SplitEdge(TCell<Double_t> & cell, TIsoMesh<Double_t> * mesh, UInt_t i,
00125                                 Double_t x, Double_t y, Double_t z, Double_t iso)const
00126 {
00127    //Split the edge and find normal in a new vertex.
00128    Double_t v[3] = {};
00129    const Double_t ofst = GetOffset(cell.fVals[eConn[i][0]], cell.fVals[eConn[i][1]], iso);
00130    v[0] = x + (vOff[eConn[i][0]][0] + ofst * eDir[i][0]) * fStepX;
00131    v[1] = y + (vOff[eConn[i][0]][1] + ofst * eDir[i][1]) * fStepY;
00132    v[2] = z + (vOff[eConn[i][0]][2] + ofst * eDir[i][2]) * fStepZ;
00133    cell.fIds[i] = mesh->AddVertex(v);
00134 
00135    const Double_t stepXU = fStepX * fXScaleInverted;
00136    const Double_t xU     = x * fXScaleInverted;
00137    const Double_t stepYU = fStepY * fYScaleInverted;
00138    const Double_t yU     = y * fYScaleInverted;
00139    const Double_t stepZU = fStepZ * fZScaleInverted;
00140    const Double_t zU     = z * fZScaleInverted;
00141 
00142    Double_t vU[3] = {};//U - unscaled.
00143    vU[0] = xU + (vOff[eConn[i][0]][0] + ofst * eDir[i][0]) * stepXU;
00144    vU[1] = yU + (vOff[eConn[i][0]][1] + ofst * eDir[i][1]) * stepYU;
00145    vU[2] = zU + (vOff[eConn[i][0]][2] + ofst * eDir[i][2]) * stepZU;
00146    //Find normals.
00147    Double_t n[3];
00148    n[0] = fTF3->Eval(vU[0] - 0.1 * stepXU, vU[1], vU[2]) -
00149           fTF3->Eval(vU[0] + 0.1 * stepXU, vU[1], vU[2]);
00150    n[1] = fTF3->Eval(vU[0], vU[1] - 0.1 * stepYU, vU[2]) -
00151           fTF3->Eval(vU[0], vU[1] + 0.1 * stepYU, vU[2]);
00152    n[2] = fTF3->Eval(vU[0], vU[1], vU[2] - 0.1 * stepZU) -
00153           fTF3->Eval(vU[0], vU[1], vU[2] + 0.1 * stepZU);
00154 
00155    const Double_t len = std::sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
00156    if (len > 1e-7) {
00157       n[0] /= len;
00158       n[1] /= len;
00159       n[2] /= len;
00160    }
00161 
00162    mesh->AddNormal(n);
00163 }
00164 /*
00165 TMeshBuilder's implementation.
00166 "this->" is used with type-dependant names
00167 in templates.
00168 */
00169 //______________________________________________________________________
00170 template<class D, class V>
00171 void TMeshBuilder<D, V>::BuildMesh(const D *s, const TGridGeometry<V> &g,
00172                                    MeshType_t *m, V iso)
00173 {
00174    //Build iso-mesh using marching cubes.
00175    static_cast<TGridGeometry<V> &>(*this) = g;
00176 
00177    this->SetDataSource(s);
00178 
00179    if (GetW() < 2 || GetH() < 2 || GetD() < 2) {
00180       Error("TMeshBuilder::BuildMesh", 
00181             "Bad grid size, one of dimensions is less than 2");
00182       return;
00183    }
00184 
00185    fSlices[0].ResizeSlice(GetW() - 1, GetH() - 1);
00186    fSlices[1].ResizeSlice(GetW() - 1, GetH() - 1);
00187 
00188    this->SetNormalEvaluator(s);
00189 
00190    fMesh = m;
00191    fIso  = iso;
00192 
00193    SliceType_t *slice1 = fSlices;
00194    SliceType_t *slice2 = fSlices + 1;
00195 
00196    this->FetchDensities();
00197    NextStep(0, 0, slice1);
00198 
00199    for (UInt_t i = 1, e = GetD(); i < e - 1; ++i) {
00200       NextStep(i, slice1, slice2);
00201       std::swap(slice1, slice2);
00202    }
00203 
00204    if(fAvgNormals)
00205       BuildNormals();
00206 }
00207 
00208 //______________________________________________________________________
00209 template<class D, class V>
00210 void TMeshBuilder<D, V>::NextStep(UInt_t depth, const SliceType_t *prevSlice, 
00211                                   SliceType_t *curr)const
00212 {
00213    //Fill slice with vertices and triangles.
00214 
00215    if (!prevSlice) {
00216       //The first slice in mc grid.
00217       BuildFirstCube(curr);
00218       BuildRow(curr);
00219       BuildCol(curr);
00220       BuildSlice(curr);
00221    } else {
00222       BuildFirstCube(depth, prevSlice, curr);
00223       BuildRow(depth, prevSlice, curr);
00224       BuildCol(depth, prevSlice, curr);
00225       BuildSlice(depth, prevSlice, curr);
00226    }
00227 }
00228 
00229 //______________________________________________________________________
00230 template<class D, class V>
00231 void TMeshBuilder<D, V>::BuildFirstCube(SliceType_t *s)const
00232 {
00233    //The first cube in a grid. nx == 0, ny == 0, nz ==0.
00234    CellType_t & cell = s->fCells[0];
00235    cell.fVals[0] = GetData(0, 0, 0);
00236    cell.fVals[1] = GetData(1, 0, 0);
00237    cell.fVals[2] = GetData(1, 1, 0);
00238    cell.fVals[3] = GetData(0, 1, 0);
00239    cell.fVals[4] = GetData(0, 0, 1);
00240    cell.fVals[5] = GetData(1, 0, 1);
00241    cell.fVals[6] = GetData(1, 1, 1);
00242    cell.fVals[7] = GetData(0, 1, 1);
00243 
00244    cell.fType = 0;
00245    for (UInt_t i = 0; i < 8; ++i) {
00246       if (cell.fVals[i] <= fIso)
00247          cell.fType |= 1 << i;
00248    }
00249 
00250    for (UInt_t i = 0, edges = eInt[cell.fType]; i < 12; ++i) {
00251       if (edges & (1 << i))
00252          SplitEdge(cell, fMesh, i, this->fMinX, this->fMinY, this->fMinZ, fIso);
00253    }
00254 
00255    ConnectTriangles(cell, fMesh, fEpsilon);
00256 }
00257 
00258 //______________________________________________________________________
00259 template<class D, class V>
00260 void TMeshBuilder<D, V>::BuildRow(SliceType_t *s)const
00261 {
00262    //The first row (along x) in the first slice:
00263    //ny == 0, nz == 0, nx : [1, W - 1].
00264    //Each cube has previous cube.
00265    //Values 0, 3, 4, 7 are taken from the previous cube.
00266    //Edges 3, 7, 8, 11 are taken from the previous cube.
00267    for (UInt_t i = 1, e = GetW() - 1; i < e; ++i) {
00268       const CellType_t &prev = s->fCells[i - 1];
00269       CellType_t &cell = s->fCells[i];
00270       cell.fType = 0;
00271 
00272       cell.fVals[0] = prev.fVals[1], cell.fVals[4] = prev.fVals[5];
00273       cell.fVals[7] = prev.fVals[6], cell.fVals[3] = prev.fVals[2];
00274       cell.fType |= (prev.fType & k1_5) >> 1;
00275       cell.fType |= (prev.fType & k2_6) << 1;
00276 
00277       if ((cell.fVals[1] = GetData(i + 1, 0, 0)) <= fIso)
00278          cell.fType |= k1;
00279       if ((cell.fVals[2] = GetData(i + 1, 1, 0)) <= fIso)
00280          cell.fType |= k2;
00281       if ((cell.fVals[5] = GetData(i + 1, 0, 1)) <= fIso)
00282          cell.fType |= k5;
00283       if ((cell.fVals[6] = GetData(i + 1, 1, 1)) <= fIso)
00284          cell.fType |= k6;
00285 
00286       const UInt_t edges = eInt[cell.fType];
00287       if (!edges)
00288          continue;
00289       //1. Take edges 3, 7, 8, 11 from the previous cube.
00290       if (edges & k3)
00291          cell.fIds[3]  = prev.fIds[1];
00292       if (edges & k7)
00293          cell.fIds[7]  = prev.fIds[5];
00294       if (edges & k8)
00295          cell.fIds[8]  = prev.fIds[9];
00296       if (edges & k11)
00297          cell.fIds[11] = prev.fIds[10];
00298       //2. Intersect edges 0, 1, 2, 4, 5, 6, 9, 10.
00299       const V x = this->fMinX + i * this->fStepX;
00300       if (edges & k0)
00301          SplitEdge(cell, fMesh, 0, x, this->fMinY, this->fMinZ, fIso);
00302       if (edges & k1)
00303          SplitEdge(cell, fMesh, 1, x, this->fMinY, this->fMinZ, fIso);
00304       if (edges & k2)
00305          SplitEdge(cell, fMesh, 2, x, this->fMinY, this->fMinZ, fIso);
00306       if (edges & k4)
00307          SplitEdge(cell, fMesh, 4, x, this->fMinY, this->fMinZ, fIso);
00308       if (edges & k5)
00309          SplitEdge(cell, fMesh, 5, x, this->fMinY, this->fMinZ, fIso);
00310       if (edges & k6)
00311          SplitEdge(cell, fMesh, 6, x, this->fMinY, this->fMinZ, fIso);
00312       if (edges & k9)
00313          SplitEdge(cell, fMesh, 9, x, this->fMinY, this->fMinZ, fIso);
00314       if (edges & k10)
00315          SplitEdge(cell, fMesh, 10, x, this->fMinY, this->fMinZ, fIso);
00316       //3. Connect new triangles.
00317       ConnectTriangles(cell, fMesh, fEpsilon);
00318    }
00319 }
00320 
00321 //______________________________________________________________________
00322 template<class D, class V>
00323 void TMeshBuilder<D, V>::BuildCol(SliceType_t *s)const
00324 {
00325    //"Col" (column) consists of cubes along y axis
00326    //on the first slice (nx == 0, nz == 0).
00327    //Each cube has a previous cube and shares values:
00328    //0, 1, 4, 5 (in prev.: 3, 2, 7, 6); and edges:
00329    //0, 4, 8, 9 (in prev.: 2, 6, 10, 11).
00330    const UInt_t w = GetW();
00331    const UInt_t h = GetH();
00332 
00333    for (UInt_t i = 1; i < h - 1; ++i) {
00334       const CellType_t &prev = s->fCells[(i - 1) * (w - 1)];
00335       CellType_t &cell = s->fCells[i * (w - 1)];
00336       cell.fType = 0;
00337       //Take values 0, 1, 4, 5 from the prev. cube.
00338       cell.fVals[0] = prev.fVals[3], cell.fVals[1] = prev.fVals[2];
00339       cell.fVals[4] = prev.fVals[7], cell.fVals[5] = prev.fVals[6];
00340       cell.fType |= (prev.fType & k2_6) >> 1;
00341       cell.fType |= (prev.fType & k3_7) >> 3;
00342       //Calculate values 2, 3, 6, 7.
00343       if((cell.fVals[2] = GetData(1, i + 1, 0)) <= fIso)
00344          cell.fType |= k2;
00345       if((cell.fVals[3] = GetData(0, i + 1, 0)) <= fIso)
00346          cell.fType |= k3;
00347       if((cell.fVals[6] = GetData(1, i + 1, 1)) <= fIso)
00348          cell.fType |= k6;
00349       if((cell.fVals[7] = GetData(0, i + 1, 1)) <= fIso)
00350          cell.fType |= k7;
00351 
00352       const UInt_t edges = eInt[cell.fType];
00353       if(!edges)
00354          continue;
00355       //Take edges from the previous cube.
00356       if (edges & k0)
00357          cell.fIds[0] = prev.fIds[2];
00358       if (edges & k4)
00359          cell.fIds[4] = prev.fIds[6];
00360       if (edges & k9)
00361          cell.fIds[9] = prev.fIds[10];
00362       if (edges & k8)
00363          cell.fIds[8] = prev.fIds[11];
00364       //Find the remaining edges.
00365       const V y = this->fMinY + i * this->fStepY;
00366 
00367       if (edges & k1)
00368          SplitEdge(cell, fMesh, 1, this->fMinX, y, this->fMinZ, fIso);
00369       if (edges & k2)
00370          SplitEdge(cell, fMesh, 2, this->fMinX, y, this->fMinZ, fIso);
00371       if (edges & k3)
00372          SplitEdge(cell, fMesh, 3, this->fMinX, y, this->fMinZ, fIso);
00373       if (edges & k5)
00374          SplitEdge(cell, fMesh, 5, this->fMinX, y, this->fMinZ, fIso);
00375       if (edges & k6)
00376          SplitEdge(cell, fMesh, 6, this->fMinX, y, this->fMinZ, fIso);
00377       if (edges & k7)
00378          SplitEdge(cell, fMesh, 7, this->fMinX, y, this->fMinZ, fIso);
00379       if (edges & k10)
00380          SplitEdge(cell, fMesh, 10, this->fMinX, y, this->fMinZ, fIso);
00381       if (edges & k11)
00382          SplitEdge(cell, fMesh, 11, this->fMinX, y, this->fMinZ, fIso);
00383 
00384       ConnectTriangles(cell, fMesh, fEpsilon);
00385    }
00386 }
00387 
00388 //______________________________________________________________________
00389 template<class D, class V>
00390 void TMeshBuilder<D, V>::BuildSlice(SliceType_t *s)const
00391 {
00392    //Slice with nz == 0.
00393    //nx : [1, W - 1], ny : [1, H - 1].
00394    //nx increased inside inner loop, ny - enclosing loop.
00395    //Each cube has two neighbours: ny - 1 => "left",
00396    //nx - 1 => "right".
00397    const UInt_t w = GetW();
00398    const UInt_t h = GetH();
00399 
00400    for (UInt_t i = 1; i < h - 1; ++i) {
00401       const V y = this->fMinY + i * this->fStepY;
00402 
00403       for (UInt_t j = 1; j < w - 1; ++j) {
00404          const CellType_t &left  = s->fCells[(i - 1) * (w - 1) + j];
00405          const CellType_t &right = s->fCells[i * (w - 1) + j - 1];
00406          CellType_t &cell = s->fCells[i * (w - 1) + j];
00407          cell.fType = 0;
00408          //Take values 0, 1, 4, 5 from left cube.
00409          cell.fVals[1] = left.fVals[2];
00410          cell.fVals[0] = left.fVals[3];
00411          cell.fVals[5] = left.fVals[6];
00412          cell.fVals[4] = left.fVals[7];
00413          cell.fType |= (left.fType & k2_6) >> 1;
00414          cell.fType |= (left.fType & k3_7) >> 3;
00415          //3, 7 from right cube.
00416          cell.fVals[3] = right.fVals[2];
00417          cell.fVals[7] = right.fVals[6];
00418          cell.fType |= (right.fType & k2_6) << 1;
00419          //Calculate values 2, 6.
00420          if((cell.fVals[2] = GetData(j + 1, i + 1, 0)) <= fIso)
00421             cell.fType |= k2;
00422          if((cell.fVals[6] = GetData(j + 1, i + 1, 1)) <= fIso)
00423             cell.fType |= k6;
00424 
00425          const UInt_t edges = eInt[cell.fType];
00426          if(!edges)
00427             continue;
00428          //Take edges 0, 4, 8, 9 from the "left" cube.
00429          //In left cube their indices are 2, 6, 11, 10.
00430          if(edges & k0)
00431             cell.fIds[0] = left.fIds[2];
00432          if(edges & k4)
00433             cell.fIds[4] = left.fIds[6];
00434          if(edges & k8)
00435             cell.fIds[8] = left.fIds[11];
00436          if(edges & k9)
00437             cell.fIds[9] = left.fIds[10];
00438          //Take edges 3, 7, 11 from the "right" cube.
00439          //Their "right" indices are 1, 5, 10.
00440          if(edges & k3)
00441             cell.fIds[3]  = right.fIds[1];
00442          if(edges & k7)
00443             cell.fIds[7]  = right.fIds[5];
00444          if(edges & k11)
00445             cell.fIds[11] = right.fIds[10];
00446          //Calculate the remaining intersections: edges
00447          //1, 2, 5, 6, 10.
00448          const V x = this->fMinX + j * this->fStepX;
00449          if (edges & k1)
00450             SplitEdge(cell, fMesh, 1, x, y, this->fMinZ, fIso);
00451          if (edges & k2)
00452             SplitEdge(cell, fMesh, 2, x, y, this->fMinZ, fIso);
00453          if (edges & k5)
00454             SplitEdge(cell, fMesh, 5, x, y, this->fMinZ, fIso);
00455          if (edges & k6)
00456             SplitEdge(cell, fMesh, 6, x, y, this->fMinZ, fIso);
00457          if (edges & k10)
00458             SplitEdge(cell, fMesh, 10, x, y, this->fMinZ, fIso);
00459 
00460          ConnectTriangles(cell, fMesh, fEpsilon);
00461       }
00462    }
00463 }
00464 
00465 //______________________________________________________________________
00466 template<class D, class V>
00467 void TMeshBuilder<D, V>::BuildFirstCube(UInt_t depth, const SliceType_t *prevSlice,
00468                                         SliceType_t *slice)const
00469 {
00470    //The first cube in a slice with nz == depth.
00471    //Neighbour is the first cube in the previous slice.
00472    //Four values and four edges come from the previous cube.
00473    const CellType_t &prevCell = prevSlice->fCells[0];
00474    CellType_t &cell = slice->fCells[0];
00475    cell.fType = 0;
00476    //Values 0, 1, 2, 3 are 4, 5, 6, 7
00477    //in the previous cube.
00478    cell.fVals[0] = prevCell.fVals[4];
00479    cell.fVals[1] = prevCell.fVals[5];
00480    cell.fVals[2] = prevCell.fVals[6];
00481    cell.fVals[3] = prevCell.fVals[7];
00482    cell.fType |= (prevCell.fType & k4_5_6_7) >> 4;
00483    //Calculate 4, 5, 6, 7.
00484    if((cell.fVals[4] = GetData(0, 0, depth + 1)) <= fIso)
00485       cell.fType |= k4;
00486    if((cell.fVals[5] = GetData(1, 0, depth + 1)) <= fIso)
00487       cell.fType |= k5;
00488    if((cell.fVals[6] = GetData(1, 1, depth + 1)) <= fIso)
00489       cell.fType |= k6;
00490    if((cell.fVals[7] = GetData(0, 1, depth + 1)) <= fIso)
00491       cell.fType |= k7;
00492 
00493    const UInt_t edges = eInt[cell.fType];
00494    if(!edges)
00495       return;
00496 
00497    //Edges 0, 1, 2, 3 taken from the prev. cube -
00498    //they have indices 4, 5, 6, 7 there.
00499    if(edges & k0)
00500       cell.fIds[0] = prevCell.fIds[4];
00501    if(edges & k1)
00502       cell.fIds[1] = prevCell.fIds[5];
00503    if(edges & k2)
00504       cell.fIds[2] = prevCell.fIds[6];
00505    if(edges & k3)
00506       cell.fIds[3] = prevCell.fIds[7];
00507 
00508    const V z = this->fMinZ + depth * this->fStepZ;
00509 
00510    if(edges & k4)
00511       SplitEdge(cell, fMesh, 4,  this->fMinX, this->fMinY, z, fIso);
00512    if(edges & k5)
00513       SplitEdge(cell, fMesh, 5,  this->fMinX, this->fMinY, z, fIso);
00514    if(edges & k6)
00515       SplitEdge(cell, fMesh, 6,  this->fMinX, this->fMinY, z, fIso);
00516    if(edges & k7)
00517       SplitEdge(cell, fMesh, 7,  this->fMinX, this->fMinY, z, fIso);
00518    if(edges & k8)
00519       SplitEdge(cell, fMesh, 8,  this->fMinX, this->fMinY, z, fIso);
00520    if(edges & k9)
00521       SplitEdge(cell, fMesh, 9,  this->fMinX, this->fMinY, z, fIso);
00522    if(edges & k10)
00523       SplitEdge(cell, fMesh, 10, this->fMinX, this->fMinY, z, fIso);
00524    if(edges & k11)
00525       SplitEdge(cell, fMesh, 11, this->fMinX, this->fMinY, z, fIso);
00526 
00527    ConnectTriangles(cell, fMesh, fEpsilon);
00528 }
00529 
00530 //______________________________________________________________________
00531 template<class D, class V>
00532 void TMeshBuilder<D, V>::BuildRow(UInt_t depth, const SliceType_t *prevSlice,
00533                                   SliceType_t *slice)const
00534 {
00535    //Row with ny == 0 and nz == depth, nx : [1, W - 1].
00536    //Two neighbours: one from previous slice (called bottom cube here),
00537    //the second is the previous cube in a row.
00538    const V z = this->fMinZ + depth * this->fStepZ;
00539    const UInt_t w = GetW();
00540 
00541    for (UInt_t i = 1; i < w - 1; ++i) {
00542       const CellType_t &prevCell = slice->fCells[i - 1];
00543       const CellType_t &bottCell = prevSlice->fCells[i];
00544       CellType_t &cell = slice->fCells[i];
00545       cell.fType = 0;
00546       //Value 0 is not required,
00547       //only bit number 0 in fType is interesting.
00548       //3, 4, 7 come from the previous box (2, 5, 6)
00549       cell.fVals[3] = prevCell.fVals[2];
00550       cell.fVals[4] = prevCell.fVals[5];
00551       cell.fVals[7] = prevCell.fVals[6];
00552       cell.fType |= (prevCell.fType & k1_5) >> 1;
00553       cell.fType |= (prevCell.fType & k2_6) << 1;
00554       //1, 2 can be taken from the bottom cube (5, 6).
00555       cell.fVals[1] = bottCell.fVals[5];
00556       cell.fVals[2] = bottCell.fVals[6];
00557       cell.fType |= (bottCell.fType & k5_6) >> 4;
00558       //5, 6 must be calculated.
00559       if((cell.fVals[5] = GetData(i + 1, 0, depth + 1)) <= fIso)
00560          cell.fType |= k5;
00561       if((cell.fVals[6] = GetData(i + 1, 1, depth + 1)) <= fIso)
00562          cell.fType |= k6;
00563 
00564       UInt_t edges = eInt[cell.fType];
00565 
00566       if(!edges)
00567          continue;
00568       //Take edges 3, 7, 8, 11 from the previous cube (1, 5, 9, 10).
00569       if(edges & k3)
00570          cell.fIds[3] = prevCell.fIds[1];
00571       if(edges & k7)
00572          cell.fIds[7] = prevCell.fIds[5];
00573       if(edges & k8)
00574          cell.fIds[8] = prevCell.fIds[9];
00575       if(edges & k11)
00576          cell.fIds[11] = prevCell.fIds[10];
00577       //Take edges 0, 1, 2 from the bottom cube (4, 5, 6).
00578       if(edges & k0)
00579          cell.fIds[0] = bottCell.fIds[4];
00580       if(edges & k1)
00581          cell.fIds[1] = bottCell.fIds[5];
00582       if(edges & k2)
00583          cell.fIds[2] = bottCell.fIds[6];
00584 
00585       edges &= ~k0_1_2_3_7_8_11;
00586 
00587       if (edges) {
00588          const V x = this->fMinX + i * this->fStepX;
00589 
00590          if(edges & k4)
00591             SplitEdge(cell, fMesh, 4,  x, this->fMinY, z, fIso);
00592          if(edges & k5)
00593             SplitEdge(cell, fMesh, 5,  x, this->fMinY, z, fIso);
00594          if(edges & k6)
00595             SplitEdge(cell, fMesh, 6,  x, this->fMinY, z, fIso);
00596          if(edges & k9)
00597             SplitEdge(cell, fMesh, 9,  x, this->fMinY, z, fIso);
00598          if(edges & k10)
00599             SplitEdge(cell, fMesh, 10, x, this->fMinY, z, fIso);
00600       }
00601 
00602       ConnectTriangles(cell, fMesh, fEpsilon);
00603    }
00604 }
00605 
00606 //______________________________________________________________________
00607 template<class D, class V>
00608 void TMeshBuilder<D, V>::BuildCol(UInt_t depth, const SliceType_t *prevSlice,
00609                                   SliceType_t *slice)const
00610 {
00611    //nz == depth, nx == 0, ny : [1, H - 1].
00612    //Two neighbours - from previous slice ("bottom" cube)
00613    //and previous cube in a column.
00614    const V z = this->fMinZ + depth * this->fStepZ;
00615    const UInt_t w = GetW();
00616    const UInt_t h = GetH();
00617 
00618    for (UInt_t i = 1; i < h - 1; ++i) {
00619       const CellType_t &left = slice->fCells[(i - 1) * (w - 1)];
00620       const CellType_t &bott = prevSlice->fCells[i * (w - 1)];
00621       CellType_t &cell = slice->fCells[i * (w - 1)];
00622       cell.fType = 0;
00623       //Value 0 is not required, only bit.
00624       //Take 1, 4, 5 from left cube.
00625       cell.fVals[1] = left.fVals[2];
00626       cell.fVals[4] = left.fVals[7];
00627       cell.fVals[5] = left.fVals[6];
00628       cell.fType |= (left.fType & k2_6) >> 1;
00629       cell.fType |= (left.fType & k3_7) >> 3;
00630       //2, 3 from bottom.
00631       cell.fVals[2] = bott.fVals[6];
00632       cell.fVals[3] = bott.fVals[7];
00633       cell.fType |= (bott.fType & k6_7) >> 4;
00634       //Calculate 6, 7.
00635       if((cell.fVals[6] = GetData(1, i + 1, depth + 1)) <= fIso)
00636          cell.fType |= k6;
00637       if((cell.fVals[7] = GetData(0, i + 1, depth + 1)) <= fIso)
00638          cell.fType |= k7;
00639 
00640       const UInt_t edges = eInt[cell.fType];
00641       if(!edges)
00642          continue;
00643 
00644       if(edges & k0)
00645          cell.fIds[0] = left.fIds[2];
00646       if(edges & k4)
00647          cell.fIds[4] = left.fIds[6];
00648       if(edges & k8)
00649          cell.fIds[8] = left.fIds[11];
00650       if(edges & k9)
00651          cell.fIds[9] = left.fIds[10];
00652 
00653       if(edges & k1)
00654          cell.fIds[1] = bott.fIds[5];
00655       if(edges & k2)
00656          cell.fIds[2] = bott.fIds[6];
00657       if(edges & k3)
00658          cell.fIds[3] = bott.fIds[7];
00659 
00660       const V y = this->fMinY + i * this->fStepY;
00661       
00662       if(edges & k5)
00663          SplitEdge(cell, fMesh, 5,  this->fMinX, y, z, fIso);
00664       if(edges & k6)
00665          SplitEdge(cell, fMesh, 6,  this->fMinX, y, z, fIso);
00666       if(edges & k7)
00667          SplitEdge(cell, fMesh, 7,  this->fMinX, y, z, fIso);
00668       if(edges & k10)
00669          SplitEdge(cell, fMesh, 10, this->fMinX, y, z, fIso);
00670       if(edges & k11)
00671          SplitEdge(cell, fMesh, 11, this->fMinX, y, z, fIso);
00672 
00673       ConnectTriangles(cell, fMesh, fEpsilon);
00674    }
00675 }
00676 
00677 
00678 //______________________________________________________________________
00679 template<class D, class V>
00680 void TMeshBuilder<D, V>::BuildSlice(UInt_t depth, const SliceType_t *prevSlice,
00681                                     SliceType_t *slice)const
00682 {
00683    //nz == depth, nx : [1, W - 1], ny : [1, H - 1].
00684    //Each cube has 3 neighbours, "bottom" cube from
00685    //the previous slice, "left" and "right" from the
00686    //current slice.
00687    const V z = this->fMinZ + depth * this->fStepZ;
00688    const UInt_t h = GetH();
00689    const UInt_t w = GetW();
00690 
00691    for (UInt_t i = 1; i < h - 1; ++i) {
00692       const V y = this->fMinY + i * this->fStepY;
00693       for (UInt_t j = 1; j < w - 1; ++j) {
00694          const CellType_t &left = slice->fCells[(i - 1) * (w - 1) + j];
00695          const CellType_t &right = slice->fCells[i * (w - 1) + j - 1];
00696          const CellType_t &bott = prevSlice->fCells[i * (w - 1) + j];
00697          CellType_t &cell = slice->fCells[i * (w - 1) + j];
00698          cell.fType = 0;
00699 
00700          cell.fVals[1] = left.fVals[2];
00701          cell.fVals[4] = left.fVals[7];
00702          cell.fVals[5] = left.fVals[6];
00703          cell.fType |= (left.fType & k2_6) >> 1;
00704          cell.fType |= (left.fType & k3_7) >> 3;
00705 
00706          cell.fVals[2] = bott.fVals[6];
00707          cell.fVals[3] = bott.fVals[7];
00708          cell.fType |= (bott.fType & k6_7) >> 4;
00709 
00710          cell.fVals[7] = right.fVals[6];
00711          cell.fType |= (right.fType & k6) << 1;
00712 
00713          if ((cell.fVals[6] = GetData(j + 1, i + 1, depth + 1)) <= fIso)
00714             cell.fType |= k6;
00715 
00716          const UInt_t edges = eInt[cell.fType];
00717          if (!edges)
00718             continue;
00719 
00720          if(edges & k0)
00721             cell.fIds[0] = left.fIds[2];
00722          if(edges & k4)
00723             cell.fIds[4] = left.fIds[6];
00724          if(edges & k8)
00725             cell.fIds[8] = left.fIds[11];
00726          if(edges & k9)
00727             cell.fIds[9] = left.fIds[10];
00728 
00729          if(edges & k3)
00730             cell.fIds[3] = right.fIds[1];
00731          if(edges & k7)
00732             cell.fIds[7] = right.fIds[5];
00733          if(edges & k11)
00734             cell.fIds[11] = right.fIds[10];
00735 
00736          if(edges & k1)
00737             cell.fIds[1] = bott.fIds[5];
00738          if(edges & k2)
00739             cell.fIds[2] = bott.fIds[6];
00740 
00741          const V x = this->fMinX + j * this->fStepX;
00742          if(edges & k5)
00743             SplitEdge(cell, fMesh, 5,  x, y, z, fIso);
00744          if(edges & k6)
00745             SplitEdge(cell, fMesh, 6,  x, y, z, fIso);
00746          if(edges & k10)
00747             SplitEdge(cell, fMesh, 10, x, y, z, fIso);
00748 
00749          ConnectTriangles(cell, fMesh, fEpsilon);
00750       }
00751    }
00752 }
00753 
00754 //______________________________________________________________________
00755 template<class D, class V>
00756 void TMeshBuilder<D, V>::BuildNormals()const
00757 {
00758    //Build averaged normals using vertices and
00759    //trinagles.
00760    typedef std::vector<UInt_t>::size_type size_type;
00761    const UInt_t *t;
00762    V *p1, *p2, *p3;
00763    V v1[3], v2[3], n[3];
00764    
00765    fMesh->fNorms.assign(fMesh->fVerts.size(), V());
00766 
00767    for (size_type i = 0, e = fMesh->fTris.size() / 3; i < e; ++i) {
00768       t  = &fMesh->fTris[i * 3];
00769       p1 = &fMesh->fVerts[t[0] * 3];
00770       p2 = &fMesh->fVerts[t[1] * 3];
00771       p3 = &fMesh->fVerts[t[2] * 3];
00772       v1[0] = p2[0] - p1[0];
00773       v1[1] = p2[1] - p1[1];
00774       v1[2] = p2[2] - p1[2];
00775       v2[0] = p3[0] - p1[0];
00776       v2[1] = p3[1] - p1[1];
00777       v2[2] = p3[2] - p1[2];
00778       n[0] = v1[1] * v2[2] - v1[2] * v2[1];
00779       n[1] = v1[2] * v2[0] - v1[0] * v2[2];
00780       n[2] = v1[0] * v2[1] - v1[1] * v2[0];
00781 
00782       const V len = std::sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
00783 
00784       if (len < fEpsilon)//degenerated triangle
00785          continue;
00786 
00787       n[0] /= len;
00788       n[1] /= len;
00789       n[2] /= len;
00790       UInt_t ind = t[0] * 3;
00791       fMesh->fNorms[ind]     += n[0];
00792       fMesh->fNorms[ind + 1] += n[1];
00793       fMesh->fNorms[ind + 2] += n[2];
00794       ind = t[1] * 3;
00795       fMesh->fNorms[ind]     += n[0];
00796       fMesh->fNorms[ind + 1] += n[1];
00797       fMesh->fNorms[ind + 2] += n[2];
00798       ind = t[2] * 3;
00799       fMesh->fNorms[ind]     += n[0];
00800       fMesh->fNorms[ind + 1] += n[1];
00801       fMesh->fNorms[ind + 2] += n[2];
00802    }
00803 
00804    for (size_type i = 0, e = fMesh->fNorms.size() / 3; i < e; ++i) {
00805       V * nn = &fMesh->fNorms[i * 3];
00806       const V len = std::sqrt(nn[0] * nn[0] + nn[1] * nn[1] + nn[2] * nn[2]);
00807       if (len < fEpsilon)
00808          continue;
00809       fMesh->fNorms[i * 3]     /= len;
00810       fMesh->fNorms[i * 3 + 1] /= len;
00811       fMesh->fNorms[i * 3 + 2] /= len;
00812    }
00813 }
00814 
00815 /////////////////////////////////////////////////////////////////////////
00816 //****************************TABLES***********************************//
00817 /////////////////////////////////////////////////////////////////////////
00818 
00819 const UInt_t eInt[256] = 
00820 {
00821    0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 
00822    0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
00823    0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 
00824    0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
00825    0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 
00826    0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
00827    0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 
00828    0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
00829    0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c, 
00830    0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
00831    0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc, 
00832    0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
00833    0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c, 
00834    0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
00835    0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc, 
00836    0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
00837    0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 
00838    0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
00839    0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 
00840    0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
00841    0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 
00842    0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
00843    0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 
00844    0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
00845    0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 
00846    0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
00847    0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 
00848    0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
00849    0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 
00850    0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
00851    0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 
00852    0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
00853 };
00854 
00855 const Float_t vOff[8][3] =
00856 {
00857    {0.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {1.f, 1.f, 0.f},
00858    {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {1.f, 0.f, 1.f},
00859    {1.f, 1.f, 1.f}, {0.f, 1.f, 1.f}
00860 };
00861 
00862 const UChar_t eConn[12][2] =
00863 {
00864    {0, 1}, {1, 2}, {2, 3}, {3, 0},
00865    {4, 5}, {5, 6}, {6, 7}, {7, 4},
00866    {0, 4}, {1, 5}, {2, 6}, {3, 7}
00867 };
00868    
00869 const Float_t eDir[12][3] =
00870 {
00871    { 1.f,  0.f, 0.f}, {0.f,  1.f, 0.f}, {-1.f, 0.f, 0.f},
00872    { 0.f, -1.f, 0.f}, {1.f,  0.f, 0.f}, { 0.f, 1.f, 0.f},
00873    {-1.f,  0.f, 0.f}, {0.f, -1.f, 0.f}, { 0.f, 0.f, 1.f},
00874    { 0.f,  0.f, 1.f}, {0.f,  0.f, 1.f}, { 0.f, 0.f, 1.f}
00875 };
00876 
00877 
00878 const Int_t conTbl[256][16] = 
00879 {
00880    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00881    {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00882    {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00883    {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00884    {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00885    {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00886    {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00887    {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00888    {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00889    {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00890    {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00891    {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00892    {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00893    {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00894    {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
00895    {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00896    {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00897    {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00898    {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00899    {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
00900    {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00901    {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
00902    {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00903    {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00904    {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00905    {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
00906    {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00907    {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
00908    {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
00909    {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
00910    {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00911    {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
00912    {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00913    {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00914    {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00915    {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00916    {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00917    {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00918    {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00919    {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
00920    {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00921    {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
00922    {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
00923    {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
00924    {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
00925    {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
00926    {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
00927    {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
00928    {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00929    {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00930    {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00931    {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00932    {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
00933    {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
00934    {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
00935    {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
00936    {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
00937    {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00938    {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
00939    {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
00940    {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
00941    {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
00942    {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
00943    {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00944    {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00945    {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00946    {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00947    {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00948    {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00949    {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
00950    {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00951    {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
00952    {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00953    {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00954    {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
00955    {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
00956    {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
00957    {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00958    {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
00959    {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
00960    {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00961    {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
00962    {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
00963    {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
00964    {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
00965    {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
00966    {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
00967    {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
00968    {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
00969    {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
00970    {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
00971    {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
00972    {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
00973    {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
00974    {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
00975    {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
00976    {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00977    {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
00978    {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
00979    {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00980    {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00981    {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
00982    {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00983    {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
00984    {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
00985    {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
00986    {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
00987    {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
00988    {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
00989    {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
00990    {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
00991    {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
00992    {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
00993    {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
00994    {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
00995    {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
00996    {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
00997    {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
00998    {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
00999    {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01000    {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
01001    {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
01002    {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
01003    {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
01004    {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
01005    {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01006    {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
01007    {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01008    {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01009    {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01010    {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01011    {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
01012    {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01013    {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
01014    {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
01015    {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
01016    {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01017    {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
01018    {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
01019    {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
01020    {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
01021    {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
01022    {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
01023    {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
01024    {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01025    {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
01026    {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
01027    {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
01028    {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
01029    {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
01030    {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
01031    {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
01032    {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
01033    {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01034    {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
01035    {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
01036    {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
01037    {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
01038    {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
01039    {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01040    {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01041    {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
01042    {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
01043    {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
01044    {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
01045    {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
01046    {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
01047    {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
01048    {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
01049    {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
01050    {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
01051    {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
01052    {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
01053    {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
01054    {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
01055    {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
01056    {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
01057    {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
01058    {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
01059    {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
01060    {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
01061    {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
01062    {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
01063    {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
01064    {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
01065    {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
01066    {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
01067    {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01068    {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
01069    {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
01070    {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01071    {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01072    {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01073    {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
01074    {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
01075    {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
01076    {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
01077    {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
01078    {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
01079    {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
01080    {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
01081    {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
01082    {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
01083    {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
01084    {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01085    {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
01086    {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
01087    {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01088    {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
01089    {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
01090    {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
01091    {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
01092    {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
01093    {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
01094    {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
01095    {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01096    {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
01097    {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
01098    {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
01099    {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
01100    {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
01101    {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01102    {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
01103    {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01104    {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
01105    {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
01106    {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
01107    {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
01108    {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
01109    {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
01110    {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
01111    {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
01112    {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
01113    {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
01114    {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
01115    {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01116    {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
01117    {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
01118    {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01119    {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01120    {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01121    {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
01122    {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
01123    {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01124    {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
01125    {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
01126    {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01127    {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01128    {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
01129    {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01130    {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
01131    {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01132    {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01133    {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01134    {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
01135    {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
01136 };
01137 
01138 template class TMeshBuilder<TH3C, Float_t>;
01139 template class TMeshBuilder<TH3S, Float_t>;
01140 template class TMeshBuilder<TH3I, Float_t>;
01141 template class TMeshBuilder<TH3F, Float_t>;
01142 template class TMeshBuilder<TH3D, Float_t>;
01143 template class TMeshBuilder<TF3, Double_t>;
01144 //TMeshBuilder does not need any detail from TKDEFGT.
01145 //TKDEFGT only helps to select correct implementation.
01146 //Forward class declaration is enough for TKDEFGT.
01147 template class TMeshBuilder<TKDEFGT, Float_t>;
01148 
01149 }//namespace Mc
01150 }//namespace Rgl

Generated on Tue Jul 5 14:18:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1