00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00022
00023
00024
00025
00026
00027 namespace Rgl {
00028 namespace Mc {
00029
00030
00031
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 }
00099
00100
00101
00102
00103
00104 void TF3Adapter::SetDataSource(const TF3 *f3)
00105 {
00106 fTF3 = f3;
00107 fW = f3->GetXaxis()->GetNbins();
00108 fH = f3->GetYaxis()->GetNbins();
00109 fD = f3->GetZaxis()->GetNbins();
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
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
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] = {};
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
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
00166
00167
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
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
00214
00215 if (!prevSlice) {
00216
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
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
00263
00264
00265
00266
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
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
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
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
00326
00327
00328
00329
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
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
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
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
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
00393
00394
00395
00396
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
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
00416 cell.fVals[3] = right.fVals[2];
00417 cell.fVals[7] = right.fVals[6];
00418 cell.fType |= (right.fType & k2_6) << 1;
00419
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
00429
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
00439
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
00447
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
00471
00472
00473 const CellType_t &prevCell = prevSlice->fCells[0];
00474 CellType_t &cell = slice->fCells[0];
00475 cell.fType = 0;
00476
00477
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
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
00498
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
00536
00537
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
00547
00548
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
00555 cell.fVals[1] = bottCell.fVals[5];
00556 cell.fVals[2] = bottCell.fVals[6];
00557 cell.fType |= (bottCell.fType & k5_6) >> 4;
00558
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
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
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
00612
00613
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
00624
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
00631 cell.fVals[2] = bott.fVals[6];
00632 cell.fVals[3] = bott.fVals[7];
00633 cell.fType |= (bott.fType & k6_7) >> 4;
00634
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
00684
00685
00686
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
00759
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)
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
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
01145
01146
01147 template class TMeshBuilder<TKDEFGT, Float_t>;
01148
01149 }
01150 }