Warning, file /include/root/TGLMarchingCubes.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_TGLMarchingCubes
0013 #define ROOT_TGLMarchingCubes
0014
0015 #include <vector>
0016
0017 #include "TH3.h"
0018
0019 #include "TGLIsoMesh.h"
0020 #include "TKDEAdapter.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029 class TF3;
0030 class TKDEFGT;
0031
0032 namespace Rgl {
0033 namespace Mc {
0034
0035
0036
0037
0038 extern const UInt_t eInt[256];
0039 extern const Float_t vOff[8][3];
0040 extern const UChar_t eConn[12][2];
0041 extern const Float_t eDir[12][3];
0042 extern const Int_t conTbl[256][16];
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 template<class V>
0110 class TCell {
0111 public:
0112 TCell() : fType(), fIds(), fVals()
0113 {
0114
0115
0116
0117
0118 }
0119
0120 UInt_t fType;
0121 UInt_t fIds[12];
0122 V fVals[8];
0123 };
0124
0125
0126
0127
0128
0129 template<class V>
0130 class TSlice {
0131 public:
0132 TSlice()
0133 {
0134 }
0135
0136 void ResizeSlice(UInt_t w, UInt_t h)
0137 {
0138 fCells.resize(w * h);
0139 }
0140
0141 std::vector<TCell<V> > fCells;
0142 private:
0143 TSlice(const TSlice &rhs) = delete;
0144 TSlice & operator = (const TSlice &rhs) = delete;
0145 };
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 template<class H, class E>
0167 class TH3Adapter {
0168 protected:
0169
0170 typedef E ElementType_t;
0171
0172 TH3Adapter()
0173 : fSrc(nullptr), fW(0), fH(0), fD(0), fSliceSize(0)
0174 {
0175 }
0176
0177 UInt_t GetW()const
0178 {
0179 return fW - 2;
0180 }
0181
0182 UInt_t GetH()const
0183 {
0184 return fH - 2;
0185 }
0186
0187 UInt_t GetD()const
0188 {
0189 return fD - 2;
0190 }
0191
0192 void SetDataSource(const H *hist)
0193 {
0194 fSrc = hist->GetArray();
0195 fW = hist->GetNbinsX() + 2;
0196 fH = hist->GetNbinsY() + 2;
0197 fD = hist->GetNbinsZ() + 2;
0198 fSliceSize = fW * fH;
0199 }
0200
0201 void FetchDensities()const{}
0202
0203 ElementType_t GetData(UInt_t i, UInt_t j, UInt_t k)const
0204 {
0205 i += 1;
0206 j += 1;
0207 k += 1;
0208 return fSrc[k * fSliceSize + j * fW + i];
0209 }
0210
0211 const ElementType_t *fSrc;
0212 UInt_t fW;
0213 UInt_t fH;
0214 UInt_t fD;
0215 UInt_t fSliceSize;
0216 };
0217
0218
0219
0220
0221
0222
0223
0224 class TF3Adapter : protected virtual TGridGeometry<Double_t> {
0225 protected:
0226 typedef Double_t ElementType_t;
0227
0228 TF3Adapter() : fTF3(nullptr), fW(0), fH(0), fD(0)
0229 {
0230 }
0231
0232 UInt_t GetW()const
0233 {
0234 return fW;
0235 }
0236
0237 UInt_t GetH()const
0238 {
0239 return fH;
0240 }
0241
0242 UInt_t GetD()const
0243 {
0244 return fD;
0245 }
0246
0247 void SetDataSource(const TF3 *f);
0248
0249 void FetchDensities()const{}
0250
0251 Double_t GetData(UInt_t i, UInt_t j, UInt_t k)const;
0252
0253 const TF3 *fTF3;
0254
0255 UInt_t fW;
0256 UInt_t fH;
0257 UInt_t fD;
0258 };
0259
0260
0261
0262
0263
0264 template<class> class TSourceAdapterSelector;
0265
0266 template<>
0267 class TSourceAdapterSelector<TH3C> {
0268 public:
0269 typedef TH3Adapter<TH3C, Char_t> Type_t;
0270 };
0271
0272 template<>
0273 class TSourceAdapterSelector<TH3S> {
0274 public:
0275 typedef TH3Adapter<TH3S, Short_t> Type_t;
0276 };
0277
0278 template<>
0279 class TSourceAdapterSelector<TH3I> {
0280 public:
0281 typedef TH3Adapter<TH3I, Int_t> Type_t;
0282 };
0283
0284 template<>
0285 class TSourceAdapterSelector<TH3F> {
0286 public:
0287 typedef TH3Adapter<TH3F, Float_t> Type_t;
0288 };
0289
0290 template<>
0291 class TSourceAdapterSelector<TH3D> {
0292 public:
0293 typedef TH3Adapter<TH3D, Double_t> Type_t;
0294 };
0295
0296 template<>
0297 class TSourceAdapterSelector<TF3> {
0298 public:
0299 typedef TF3Adapter Type_t;
0300 };
0301
0302 template<>
0303 class TSourceAdapterSelector<TKDEFGT> {
0304 public:
0305 typedef Fgt::TKDEAdapter Type_t;
0306 };
0307
0308
0309
0310
0311
0312
0313
0314
0315 template<class E, class V>
0316 V GetOffset(E val1, E val2, V iso)
0317 {
0318 const V delta = val2 - val1;
0319 if (!delta)
0320 return 0.5f;
0321 return (iso - val1) / delta;
0322 }
0323
0324 template<class H, class E, class V>
0325 class TDefaultSplitter : protected virtual TGridGeometry<V> {
0326 protected:
0327 void SetNormalEvaluator(const H * )
0328 {
0329 }
0330 void SplitEdge(TCell<E> & cell, TIsoMesh<V> * mesh, UInt_t i,
0331 V x, V y, V z, V iso)const
0332 {
0333 V v[3];
0334 const V offset = GetOffset(cell.fVals[eConn[i][0]],
0335 cell.fVals[eConn[i][1]],
0336 iso);
0337 v[0] = x + (vOff[eConn[i][0]][0] + offset * eDir[i][0]) * this->fStepX;
0338 v[1] = y + (vOff[eConn[i][0]][1] + offset * eDir[i][1]) * this->fStepY;
0339 v[2] = z + (vOff[eConn[i][0]][2] + offset * eDir[i][2]) * this->fStepZ;
0340 cell.fIds[i] = mesh->AddVertex(v);
0341 }
0342
0343
0344 };
0345
0346
0347
0348
0349
0350
0351 class TF3EdgeSplitter : protected virtual TGridGeometry<Double_t> {
0352 protected:
0353 TF3EdgeSplitter() : fTF3(nullptr)
0354 {
0355 }
0356
0357 void SetNormalEvaluator(const TF3 *tf3)
0358 {
0359 fTF3 = tf3;
0360 }
0361
0362 void SplitEdge(TCell<Double_t> & cell, TIsoMesh<Double_t> * mesh, UInt_t i,
0363 Double_t x, Double_t y, Double_t z, Double_t iso)const;
0364
0365 const TF3 *fTF3;
0366 };
0367
0368
0369
0370
0371
0372
0373 template<class, class> class TSplitterSelector;
0374
0375 template<class V>
0376 class TSplitterSelector<TH3C, V> {
0377 public:
0378 typedef TDefaultSplitter<TH3C, Char_t, V> Type_t;
0379 };
0380
0381 template<class V>
0382 class TSplitterSelector<TH3S, V> {
0383 public:
0384 typedef TDefaultSplitter<TH3S, Short_t, V> Type_t;
0385 };
0386
0387 template<class V>
0388 class TSplitterSelector<TH3I, V> {
0389 public:
0390 typedef TDefaultSplitter<TH3I, Int_t, V> Type_t;
0391 };
0392
0393 template<class V>
0394 class TSplitterSelector<TH3F, V> {
0395 public:
0396 typedef TDefaultSplitter<TH3F, Float_t, V> Type_t;
0397 };
0398
0399 template<class V>
0400 class TSplitterSelector<TH3D, V> {
0401 public:
0402 typedef TDefaultSplitter<TH3D, Double_t, V> Type_t;
0403 };
0404
0405 template<class V>
0406 class TSplitterSelector<TKDEFGT, V> {
0407 public:
0408 typedef TDefaultSplitter<TKDEFGT, Float_t, Float_t> Type_t;
0409 };
0410
0411 template<class V>
0412 class TSplitterSelector<TF3, V> {
0413 public:
0414 typedef TF3EdgeSplitter Type_t;
0415 };
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 template<class DataSource, class ValueType>
0426 class TMeshBuilder : public TSourceAdapterSelector<DataSource>::Type_t,
0427 public TSplitterSelector<DataSource, ValueType>::Type_t
0428 {
0429 private:
0430
0431 typedef typename TSourceAdapterSelector<DataSource>::Type_t DataSourceBase_t;
0432 typedef typename TSplitterSelector<DataSource, ValueType>::Type_t SplitterBase_t;
0433
0434
0435 using DataSourceBase_t::GetW;
0436 using DataSourceBase_t::GetH;
0437 using DataSourceBase_t::GetD;
0438 using DataSourceBase_t::GetData;
0439 using SplitterBase_t::SplitEdge;
0440
0441 typedef typename DataSourceBase_t::ElementType_t ElementType_t;
0442
0443 typedef TCell<ElementType_t> CellType_t;
0444 typedef TSlice<ElementType_t> SliceType_t;
0445 typedef TIsoMesh<ValueType> MeshType_t;
0446
0447 public:
0448 TMeshBuilder(Bool_t averagedNormals, ValueType eps = 1e-7)
0449 : fAvgNormals(averagedNormals), fMesh(nullptr), fIso(), fEpsilon(eps)
0450 {
0451 }
0452
0453 void BuildMesh(const DataSource *src, const TGridGeometry<ValueType> &geom,
0454 MeshType_t *mesh, ValueType iso);
0455
0456 private:
0457
0458 Bool_t fAvgNormals;
0459 SliceType_t fSlices[2];
0460 MeshType_t *fMesh;
0461 ValueType fIso;
0462 ValueType fEpsilon;
0463
0464 void NextStep(UInt_t depth, const SliceType_t *prevSlice,
0465 SliceType_t *curr)const;
0466
0467 void BuildFirstCube(SliceType_t *slice)const;
0468 void BuildRow(SliceType_t *slice)const;
0469 void BuildCol(SliceType_t *slice)const;
0470 void BuildSlice(SliceType_t *slice)const;
0471 void BuildFirstCube(UInt_t depth, const SliceType_t *prevSlice,
0472 SliceType_t *slice)const;
0473 void BuildRow(UInt_t depth, const SliceType_t *prevSlice,
0474 SliceType_t *slice)const;
0475 void BuildCol(UInt_t depth, const SliceType_t *prevSlice,
0476 SliceType_t *slice)const;
0477 void BuildSlice(UInt_t depth, const SliceType_t *prevSlice,
0478 SliceType_t *slice)const;
0479
0480 void BuildNormals()const;
0481
0482 TMeshBuilder(const TMeshBuilder &rhs);
0483 TMeshBuilder & operator = (const TMeshBuilder &rhs);
0484 };
0485
0486 }
0487 }
0488
0489 #endif