00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ROOT_TGLMarchingCubes
00013 #define ROOT_TGLMarchingCubes
00014
00015 #include <vector>
00016
00017 #ifndef ROOT_TH3
00018 #include "TH3.h"
00019 #endif
00020
00021 #ifndef ROOT_TGLIsoMesh
00022 #include "TGLIsoMesh.h"
00023 #endif
00024 #ifndef ROOT_TKDEAdapter
00025 #include "TKDEAdapter.h"
00026 #endif
00027
00028
00029
00030
00031
00032
00033
00034
00035 class TF3;
00036 class TKDEFGT;
00037
00038 namespace Rgl {
00039 namespace Mc {
00040
00041
00042
00043
00044 extern const UInt_t eInt[256];
00045 extern const Float_t vOff[8][3];
00046 extern const UChar_t eConn[12][2];
00047 extern const Float_t eDir[12][3];
00048 extern const Int_t conTbl[256][16];
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 template<class V>
00116 class TCell {
00117 public:
00118 TCell() : fType(), fIds(), fVals()
00119 {
00120
00121
00122
00123
00124 }
00125
00126 UInt_t fType;
00127 UInt_t fIds[12];
00128 V fVals[8];
00129 };
00130
00131
00132
00133
00134
00135 template<class V>
00136 class TSlice {
00137 public:
00138 TSlice()
00139 {
00140 }
00141
00142 void ResizeSlice(UInt_t w, UInt_t h)
00143 {
00144 fCells.resize(w * h);
00145 }
00146
00147 std::vector<TCell<V> > fCells;
00148 private:
00149 TSlice(const TSlice &rhs);
00150 TSlice & operator = (const TSlice &rhs);
00151 };
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 template<class H, class E>
00173 class TH3Adapter {
00174 protected:
00175
00176 typedef E ElementType_t;
00177
00178 TH3Adapter()
00179 : fSrc(0), fW(0), fH(0), fD(0), fSliceSize(0)
00180 {
00181 }
00182
00183 UInt_t GetW()const
00184 {
00185 return fW - 2;
00186 }
00187
00188 UInt_t GetH()const
00189 {
00190 return fH - 2;
00191 }
00192
00193 UInt_t GetD()const
00194 {
00195 return fD - 2;
00196 }
00197
00198 void SetDataSource(const H *hist)
00199 {
00200 fSrc = hist->GetArray();
00201 fW = hist->GetNbinsX() + 2;
00202 fH = hist->GetNbinsY() + 2;
00203 fD = hist->GetNbinsZ() + 2;
00204 fSliceSize = fW * fH;
00205 }
00206
00207 void FetchDensities()const{}
00208
00209 ElementType_t GetData(UInt_t i, UInt_t j, UInt_t k)const
00210 {
00211 i += 1;
00212 j += 1;
00213 k += 1;
00214 return fSrc[k * fSliceSize + j * fW + i];
00215 }
00216
00217 const ElementType_t *fSrc;
00218 UInt_t fW;
00219 UInt_t fH;
00220 UInt_t fD;
00221 UInt_t fSliceSize;
00222 };
00223
00224
00225
00226
00227
00228
00229
00230 class TF3Adapter : protected virtual TGridGeometry<Double_t> {
00231 protected:
00232 typedef Double_t ElementType_t;
00233
00234 TF3Adapter() : fTF3(0), fW(0), fH(0), fD(0)
00235 {
00236 }
00237
00238 UInt_t GetW()const
00239 {
00240 return fW;
00241 }
00242
00243 UInt_t GetH()const
00244 {
00245 return fH;
00246 }
00247
00248 UInt_t GetD()const
00249 {
00250 return fD;
00251 }
00252
00253 void SetDataSource(const TF3 *f);
00254
00255 void FetchDensities()const{}
00256
00257 Double_t GetData(UInt_t i, UInt_t j, UInt_t k)const;
00258
00259 const TF3 *fTF3;
00260
00261 UInt_t fW;
00262 UInt_t fH;
00263 UInt_t fD;
00264 };
00265
00266
00267
00268
00269
00270 template<class> class TSourceAdapterSelector;
00271
00272 template<>
00273 class TSourceAdapterSelector<TH3C> {
00274 public:
00275 typedef TH3Adapter<TH3C, Char_t> Type_t;
00276 };
00277
00278 template<>
00279 class TSourceAdapterSelector<TH3S> {
00280 public:
00281 typedef TH3Adapter<TH3S, Short_t> Type_t;
00282 };
00283
00284 template<>
00285 class TSourceAdapterSelector<TH3I> {
00286 public:
00287 typedef TH3Adapter<TH3I, Int_t> Type_t;
00288 };
00289
00290 template<>
00291 class TSourceAdapterSelector<TH3F> {
00292 public:
00293 typedef TH3Adapter<TH3F, Float_t> Type_t;
00294 };
00295
00296 template<>
00297 class TSourceAdapterSelector<TH3D> {
00298 public:
00299 typedef TH3Adapter<TH3D, Double_t> Type_t;
00300 };
00301
00302 template<>
00303 class TSourceAdapterSelector<TF3> {
00304 public:
00305 typedef TF3Adapter Type_t;
00306 };
00307
00308 template<>
00309 class TSourceAdapterSelector<TKDEFGT> {
00310 public:
00311 typedef Fgt::TKDEAdapter Type_t;
00312 };
00313
00314
00315
00316
00317
00318
00319
00320
00321 template<class E, class V>
00322 V GetOffset(E val1, E val2, V iso)
00323 {
00324 const V delta = val2 - val1;
00325 if (!delta)
00326 return 0.5f;
00327 return (iso - val1) / delta;
00328 }
00329
00330 template<class H, class E, class V>
00331 class TDefaultSplitter : protected virtual TGridGeometry<V> {
00332 protected:
00333 void SetNormalEvaluator(const H * )
00334 {
00335 }
00336 void SplitEdge(TCell<E> & cell, TIsoMesh<V> * mesh, UInt_t i,
00337 V x, V y, V z, V iso)const
00338 {
00339 V v[3];
00340 const V offset = GetOffset(cell.fVals[eConn[i][0]],
00341 cell.fVals[eConn[i][1]],
00342 iso);
00343 v[0] = x + (vOff[eConn[i][0]][0] + offset * eDir[i][0]) * this->fStepX;
00344 v[1] = y + (vOff[eConn[i][0]][1] + offset * eDir[i][1]) * this->fStepY;
00345 v[2] = z + (vOff[eConn[i][0]][2] + offset * eDir[i][2]) * this->fStepZ;
00346 cell.fIds[i] = mesh->AddVertex(v);
00347 }
00348
00349
00350 };
00351
00352
00353
00354
00355
00356
00357 class TF3EdgeSplitter : protected virtual TGridGeometry<Double_t> {
00358 protected:
00359 TF3EdgeSplitter() : fTF3(0)
00360 {
00361 }
00362
00363 void SetNormalEvaluator(const TF3 *tf3)
00364 {
00365 fTF3 = tf3;
00366 }
00367
00368 void SplitEdge(TCell<Double_t> & cell, TIsoMesh<Double_t> * mesh, UInt_t i,
00369 Double_t x, Double_t y, Double_t z, Double_t iso)const;
00370
00371 const TF3 *fTF3;
00372 };
00373
00374
00375
00376
00377
00378
00379 template<class, class> class TSplitterSelector;
00380
00381 template<class V>
00382 class TSplitterSelector<TH3C, V> {
00383 public:
00384 typedef TDefaultSplitter<TH3C, Char_t, V> Type_t;
00385 };
00386
00387 template<class V>
00388 class TSplitterSelector<TH3S, V> {
00389 public:
00390 typedef TDefaultSplitter<TH3S, Short_t, V> Type_t;
00391 };
00392
00393 template<class V>
00394 class TSplitterSelector<TH3I, V> {
00395 public:
00396 typedef TDefaultSplitter<TH3I, Int_t, V> Type_t;
00397 };
00398
00399 template<class V>
00400 class TSplitterSelector<TH3F, V> {
00401 public:
00402 typedef TDefaultSplitter<TH3F, Float_t, V> Type_t;
00403 };
00404
00405 template<class V>
00406 class TSplitterSelector<TH3D, V> {
00407 public:
00408 typedef TDefaultSplitter<TH3D, Double_t, V> Type_t;
00409 };
00410
00411 template<class V>
00412 class TSplitterSelector<TKDEFGT, V> {
00413 public:
00414 typedef TDefaultSplitter<TKDEFGT, Float_t, Float_t> Type_t;
00415 };
00416
00417 template<class V>
00418 class TSplitterSelector<TF3, V> {
00419 public:
00420 typedef TF3EdgeSplitter Type_t;
00421 };
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 template<class DataSource, class ValueType>
00432 class TMeshBuilder : public TSourceAdapterSelector<DataSource>::Type_t,
00433 public TSplitterSelector<DataSource, ValueType>::Type_t
00434 {
00435 private:
00436
00437 typedef typename TSourceAdapterSelector<DataSource>::Type_t DataSourceBase_t;
00438 typedef typename TSplitterSelector<DataSource, ValueType>::Type_t SplitterBase_t;
00439
00440
00441 using DataSourceBase_t::GetW;
00442 using DataSourceBase_t::GetH;
00443 using DataSourceBase_t::GetD;
00444 using DataSourceBase_t::GetData;
00445 using SplitterBase_t::SplitEdge;
00446
00447 typedef typename DataSourceBase_t::ElementType_t ElementType_t;
00448
00449 typedef TCell<ElementType_t> CellType_t;
00450 typedef TSlice<ElementType_t> SliceType_t;
00451 typedef TIsoMesh<ValueType> MeshType_t;
00452
00453 public:
00454 TMeshBuilder(Bool_t averagedNormals, ValueType eps = 1e-7)
00455 : fAvgNormals(averagedNormals), fMesh(0), fIso(), fEpsilon(eps)
00456 {
00457 }
00458
00459 void BuildMesh(const DataSource *src, const TGridGeometry<ValueType> &geom,
00460 MeshType_t *mesh, ValueType iso);
00461
00462 private:
00463
00464 Bool_t fAvgNormals;
00465 SliceType_t fSlices[2];
00466 MeshType_t *fMesh;
00467 ValueType fIso;
00468 ValueType fEpsilon;
00469
00470 void NextStep(UInt_t depth, const SliceType_t *prevSlice,
00471 SliceType_t *curr)const;
00472
00473 void BuildFirstCube(SliceType_t *slice)const;
00474 void BuildRow(SliceType_t *slice)const;
00475 void BuildCol(SliceType_t *slice)const;
00476 void BuildSlice(SliceType_t *slice)const;
00477 void BuildFirstCube(UInt_t depth, const SliceType_t *prevSlice,
00478 SliceType_t *slice)const;
00479 void BuildRow(UInt_t depth, const SliceType_t *prevSlice,
00480 SliceType_t *slice)const;
00481 void BuildCol(UInt_t depth, const SliceType_t *prevSlice,
00482 SliceType_t *slice)const;
00483 void BuildSlice(UInt_t depth, const SliceType_t *prevSlice,
00484 SliceType_t *slice)const;
00485
00486 void BuildNormals()const;
00487
00488 TMeshBuilder(const TMeshBuilder &rhs);
00489 TMeshBuilder & operator = (const TMeshBuilder &rhs);
00490 };
00491
00492 }
00493 }
00494
00495 #endif