00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __UT_VoxelArray__
00024 #define __UT_VoxelArray__
00025
00026 #include "UT_API.h"
00027 #include <SYS/SYS_Types.h>
00028 #include "UT_Vector2.h"
00029 #include "UT_Vector3.h"
00030 #include "UT_Vector4.h"
00031 #include "UT_PtrArray.h"
00032 #include "UT_RefArray.h"
00033 #include "UT_FilterType.h"
00034 #include "UT_COW.h"
00035 #include "UT_ThreadedAlgorithm.h"
00036 #include <VM/VM_SIMD.h>
00037
00038 #include <boost/shared_ptr.hpp>
00039
00040 class UT_BoundingBox;
00041 class UT_Filter;
00042
00043
00044 static const int TILEBITS = 4;
00045 static const int TILESIZE = 1 << TILEBITS;
00046 static const int TILEMASK = TILESIZE-1;
00047
00048
00049
00050
00051 enum UT_VoxelBorderType
00052 {
00053 UT_VOXELBORDER_CONSTANT,
00054 UT_VOXELBORDER_REPEAT,
00055 UT_VOXELBORDER_STREAK
00056 };
00057
00058 template <typename T> class UT_VoxelTile;
00059 template <typename T, bool DoRead, bool DoWrite, bool TestForWrite> class UT_VoxelProbe;
00060 template <typename T> class UT_VoxelProbeCube;
00061 template <typename T> class UT_VoxelProbeFace;
00062
00063
00064
00065
00066
00067
00068
00069 template <typename T>
00070 class UT_VoxelTileCompress
00071 {
00072 public:
00073 UT_VoxelTileCompress() {}
00074 virtual ~UT_VoxelTileCompress() {}
00075
00076
00077
00078 virtual bool writeThrough(UT_VoxelTile<T> &tile,
00079 int x, int y, int z, T t) const = 0;
00080
00081
00082
00083 virtual T getValue(const UT_VoxelTile<T> &tile,
00084 int x, int y, int z) const = 0;
00085
00086
00087
00088 virtual bool tryCompress(UT_VoxelTile<T> &tile,
00089 fpreal tol, T min, T max) const = 0;
00090
00091
00092
00093 virtual int getDataLength(const UT_VoxelTile<T> &tile) const = 0;
00094
00095
00096
00097 virtual void findMinMax(const UT_VoxelTile<T> &tile, T &min, T &max) const;
00098
00099
00100 virtual bool canSave() const { return false; }
00101 virtual void save(ostream &os, const UT_VoxelTile<T> &tile) const {}
00102 virtual void load(UT_IStream &is, UT_VoxelTile<T> &tile) const {}
00103
00104
00105
00106
00107 virtual const char *getName() = 0;
00108 };
00109
00110 UT_API UT_PtrArray<UT_VoxelTileCompress<fpreal16> *> &UTvoxelTileGetCompressionEngines(fpreal16 *dummy);
00111 UT_API UT_PtrArray<UT_VoxelTileCompress<fpreal32> *> &UTvoxelTileGetCompressionEngines(fpreal32 *dummy);
00112 UT_API UT_PtrArray<UT_VoxelTileCompress<fpreal64> *> &UTvoxelTileGetCompressionEngines(fpreal64 *dummy);
00113 UT_API UT_PtrArray<UT_VoxelTileCompress<uint8> *> &UTvoxelTileGetCompressionEngines(uint8 *dummy);
00114 UT_API UT_PtrArray<UT_VoxelTileCompress<int8> *> &UTvoxelTileGetCompressionEngines(int8 *dummy);
00115 UT_API UT_PtrArray<UT_VoxelTileCompress<int16> *> &UTvoxelTileGetCompressionEngines(int16 *dummy);
00116 UT_API UT_PtrArray<UT_VoxelTileCompress<int32> *> &UTvoxelTileGetCompressionEngines(int32 *dummy);
00117 UT_API UT_PtrArray<UT_VoxelTileCompress<int64> *> &UTvoxelTileGetCompressionEngines(int64 *dummy);
00118 UT_API UT_PtrArray<UT_VoxelTileCompress<UT_Vector2> *> &UTvoxelTileGetCompressionEngines(UT_Vector2 *dummy);
00119 UT_API UT_PtrArray<UT_VoxelTileCompress<UT_Vector3> *> &UTvoxelTileGetCompressionEngines(UT_Vector3 *dummy);
00120 UT_API UT_PtrArray<UT_VoxelTileCompress<UT_Vector4> *> &UTvoxelTileGetCompressionEngines(UT_Vector4 *dummy);
00121
00122 #define DEFINE_STD_FUNC(TYPE) \
00123 inline void \
00124 UTvoxelTileExpandMinMax(TYPE v, TYPE &min, TYPE &max) \
00125 { \
00126 if (v < min) \
00127 min = v; \
00128 else if (v > max) \
00129 max = v; \
00130 } \
00131 \
00132 inline fpreal \
00133 UTvoxelTileDist(TYPE a, TYPE b) \
00134 { \
00135 return (fpreal) SYSabs(a - b); \
00136 }
00137
00138 DEFINE_STD_FUNC(fpreal16)
00139 DEFINE_STD_FUNC(fpreal32)
00140 DEFINE_STD_FUNC(fpreal64)
00141 DEFINE_STD_FUNC(uint8)
00142 DEFINE_STD_FUNC(int8)
00143 DEFINE_STD_FUNC(int16)
00144 DEFINE_STD_FUNC(int32)
00145 DEFINE_STD_FUNC(int64)
00146
00147 #undef DEFINE_STD_FUNC
00148
00149 inline void
00150 UTvoxelTileExpandMinMax(UT_Vector2 v, UT_Vector2 &min, UT_Vector2 &max)
00151 {
00152 min.x() = SYSmin(v.x(), min.x());
00153 max.x() = SYSmax(v.x(), max.x());
00154
00155 min.y() = SYSmin(v.y(), min.y());
00156 max.y() = SYSmax(v.y(), max.y());
00157 }
00158
00159 inline void
00160 UTvoxelTileExpandMinMax(UT_Vector3 v, UT_Vector3 &min, UT_Vector3 &max)
00161 {
00162 min.x() = SYSmin(v.x(), min.x());
00163 max.x() = SYSmax(v.x(), max.x());
00164
00165 min.y() = SYSmin(v.y(), min.y());
00166 max.y() = SYSmax(v.y(), max.y());
00167
00168 min.z() = SYSmin(v.z(), min.z());
00169 max.z() = SYSmax(v.z(), max.z());
00170 }
00171
00172 inline void
00173 UTvoxelTileExpandMinMax(UT_Vector4 v, UT_Vector4 &min, UT_Vector4 &max)
00174 {
00175 min.x() = SYSmin(v.x(), min.x());
00176 max.x() = SYSmax(v.x(), max.x());
00177
00178 min.y() = SYSmin(v.y(), min.y());
00179 max.y() = SYSmax(v.y(), max.y());
00180
00181 min.z() = SYSmin(v.z(), min.z());
00182 max.z() = SYSmax(v.z(), max.z());
00183
00184 min.w() = SYSmin(v.w(), min.w());
00185 max.w() = SYSmax(v.w(), max.w());
00186 }
00187
00188 inline fpreal
00189 UTvoxelTileDist(const UT_Vector2 &a, const UT_Vector2 &b)
00190 {
00191 return SYSabs(a.x() - b.x()) + SYSabs(a.y() - b.y());
00192 }
00193
00194 inline fpreal
00195 UTvoxelTileDist(const UT_Vector3 &a, const UT_Vector3 &b)
00196 {
00197 return SYSabs(a.x() - b.x()) + SYSabs(a.y() - b.y())
00198 + SYSabs(a.z() - b.z());
00199 }
00200
00201 inline fpreal
00202 UTvoxelTileDist(const UT_Vector4 &a, const UT_Vector4 &b)
00203 {
00204 return SYSabs(a.x() - b.x()) + SYSabs(a.y() - b.y())
00205 + SYSabs(a.z() - b.z()) + SYSabs(a.w() - b.w());
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template <typename T>
00223 class UT_VoxelTile
00224 {
00225 public:
00226 UT_VoxelTile(int xres, int yres, int zres);
00227 virtual ~UT_VoxelTile();
00228
00229
00230 UT_VoxelTile(const UT_VoxelTile<T> &src);
00231
00232
00233 const UT_VoxelTile<T> &operator=(const UT_VoxelTile<T> &src);
00234
00235 enum CompressionType
00236 {
00237 COMPRESS_RAW,
00238 COMPRESS_RAWFULL,
00239 COMPRESS_CONSTANT,
00240 COMPRESS_ENGINE
00241 };
00242
00243
00244
00245 T operator()(int x, int y, int z) const
00246 {
00247 UT_ASSERT_P(x >= 0 && y >= 0 && z >= 0);
00248 UT_ASSERT_P(x < myRes[0] && y < myRes[1] && z < myRes[2]);
00249
00250 switch (myCompressionType)
00251 {
00252 case COMPRESS_RAW:
00253 return ((T *)myData)[
00254 ((z * myRes[1]) + y) * myRes[0] + x ];
00255
00256 case COMPRESS_CONSTANT:
00257 return *(T *)myData;
00258
00259 case COMPRESS_RAWFULL:
00260 return ((T *)myData)[
00261 ((z * TILESIZE) + y) * TILESIZE + x ];
00262 }
00263
00264
00265 UT_VoxelTileCompress<T> *engine;
00266
00267 engine = getCompressionEngine(myCompressionType);
00268 return engine->getValue(*this, x, y, z);
00269 }
00270
00271
00272 inline static T lerpValues(T v1, T v2, fpreal32 bias)
00273 {
00274 return v1 + (v2 - v1) * bias;
00275 }
00276
00277
00278
00279 T lerp(int x, int y, int z, float fx, float fy, float fz) const;
00280 #if 0
00281
00282
00283 T lerp(v4uf frac, int x, int y, int z) const;
00284 #endif
00285
00286
00287
00288
00289
00290
00291
00292
00293 T *fillCacheLine(T *cacheline, int &stride, int x, int y, int z, bool forcecopy, bool strideofone) const;
00294
00295
00296 void writeCacheLine(T *cacheline, int y, int z);
00297
00298
00299
00300 void setValue(int x, int y, int z, T t);
00301
00302
00303 void findMinMax(T &min, T &max) const;
00304
00305
00306 bool isConstant() const
00307 { return myCompressionType == COMPRESS_CONSTANT; }
00308
00309
00310 bool isRaw() const
00311 { return myCompressionType == COMPRESS_RAW; }
00312
00313
00314 bool isRawFull() const
00315 { return myCompressionType == COMPRESS_RAWFULL; }
00316
00317
00318
00319 bool tryCompress(fpreal tolerance);
00320
00321
00322 void makeConstant(T t);
00323
00324
00325 void uncompress();
00326
00327
00328 void uncompressFull();
00329
00330
00331 T *rawFullData()
00332 {
00333 uncompressFull();
00334 return (T *)myData;
00335 }
00336
00337
00338 int xres() const { return myRes[0]; }
00339 int yres() const { return myRes[1]; }
00340 int zres() const { return myRes[2]; }
00341
00342 int getRes(int dim) const { return myRes[dim]; }
00343
00344
00345 int64 getMemoryUsage() const;
00346
00347
00348 int64 getDataLength() const;
00349
00350
00351
00352
00353
00354
00355 void weightedSum(int pstart[3], int pend[3],
00356 float *weights[3], int start[3],
00357 T &result);
00358
00359
00360
00361
00362 static void expandMinMax(T v, T &min, T &max)
00363 {
00364 UTvoxelTileExpandMinMax(v, min, max);
00365 }
00366
00367
00368
00369 static fpreal dist(T a, T b)
00370 {
00371 return UTvoxelTileDist(a, b);
00372 }
00373
00374 static void registerCompressionEngine(UT_VoxelTileCompress<T> *engine);
00375
00376
00377 static int lookupCompressionEngine(const char *name);
00378
00379 static UT_VoxelTileCompress<T> *getCompressionEngine(int index);
00380
00381
00382
00383 void save(ostream &os);
00384
00385
00386
00387 void load(UT_IStream &is, const UT_IntArray &compression);
00388
00389
00390 static void saveCompressionTypes(ostream &os);
00391
00392
00393
00394 static void loadCompressionTypes(UT_IStream &is, UT_IntArray &compressions);
00395
00396 protected:
00397
00398
00399
00400
00401
00402 bool writeThrough(int x, int y, int z, T t);
00403
00404 public:
00405
00406
00407 void *myData;
00408 private:
00409
00410
00411 int8 myRes[3];
00412
00413
00414 int8 myCompressionType;
00415
00416 static UT_PtrArray<UT_VoxelTileCompress<T> *> &getCompressionEngines()
00417 {
00418 return UTvoxelTileGetCompressionEngines((T *) 0);
00419 }
00420
00421 friend class UT_VoxelTileCompress<T>;
00422 template <typename S, bool DoWrite, bool DoRead, bool TestForWrites>
00423 friend class UT_VoxelProbe;
00424 };
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 template <typename T>
00436 class UT_VoxelArray
00437 {
00438 public:
00439 UT_VoxelArray();
00440 virtual ~UT_VoxelArray();
00441
00442
00443 UT_VoxelArray(const UT_VoxelArray<T> &src);
00444
00445
00446 const UT_VoxelArray<T> &operator=(const UT_VoxelArray<T> &src);
00447
00448
00449
00450 void size(int xres, int yres, int zres);
00451
00452
00453
00454
00455 void match(const UT_VoxelArray<T> &src);
00456
00457 int getXRes() const { return myRes[0]; }
00458 int getYRes() const { return myRes[1]; }
00459 int getZRes() const { return myRes[2]; }
00460 int getRes(int axis) const { return myRes[axis]; }
00461
00462
00463 int64 getMemoryUsage() const;
00464
00465
00466
00467 void constant(T t);
00468
00469
00470
00471
00472
00473
00474 bool isConstant(T *cval = 0) const;
00475
00476
00477
00478
00479
00480
00481 T operator()(UT_Vector3 pos) const;
00482 #if 0
00483 T operator()(v4uf pos) const;
00484 #endif
00485
00486
00487
00488
00489
00490 T evaluate(const UT_Vector3 &pos, const UT_Filter &filter,
00491 fpreal radius) const;
00492
00493
00494
00495 void resample(const UT_VoxelArray<T> &src,
00496 UT_FilterType filtertype = UT_FILTER_POINT);
00497
00498
00499
00500
00501
00502 bool posToIndex(UT_Vector3 pos, int &x, int &y, int &z) const;
00503
00504
00505 bool posToIndex(UT_Vector3 pos, UT_Vector3 &ipos) const;
00506
00507
00508
00509 bool indexToPos(int x, int y, int z, UT_Vector3 &pos) const;
00510
00511
00512
00513 void clampIndex(int &x, int &y, int &z) const
00514 {
00515 x = SYSclamp(x, 0, myRes[0]-1);
00516 y = SYSclamp(y, 0, myRes[1]-1);
00517 z = SYSclamp(z, 0, myRes[2]-1);
00518 }
00519
00520
00521 bool isValidIndex(int x, int y, int z) const
00522 {
00523 return x >= 0 && x < myRes[0] &&
00524 y >= 0 && y < myRes[1] &&
00525 z >= 0 && z < myRes[2];
00526 }
00527
00528
00529
00530 T operator()(int x, int y, int z) const
00531 {
00532 UT_ASSERT_P(isValidIndex(x, y, z));
00533 return (*getTile(x >> TILEBITS,
00534 y >> TILEBITS,
00535 z >> TILEBITS))
00536 (x & TILEMASK, y & TILEMASK, z & TILEMASK);
00537 }
00538 void setValue(int x, int y, int z, T t)
00539 {
00540 UT_ASSERT_P(isValidIndex(x, y, z));
00541 getTile(x >> TILEBITS,
00542 y >> TILEBITS,
00543 z >> TILEBITS)->setValue(
00544 x & TILEMASK, y & TILEMASK, z & TILEMASK, t);
00545 }
00546
00547
00548
00549 T getValue(int x, int y, int z) const
00550 {
00551
00552 if (!myRes[0] && !myRes[1] && !myRes[2])
00553 {
00554 UT_ASSERT(!"getValue on empty voxel array!");
00555 return myBorderValue;
00556 }
00557
00558
00559
00560 switch (myBorderType)
00561 {
00562 case UT_VOXELBORDER_CONSTANT:
00563 if (!isValidIndex(x, y, z))
00564 return myBorderValue;
00565 break;
00566
00567 case UT_VOXELBORDER_REPEAT:
00568 if (x < 0 || x >= myRes[0])
00569 {
00570 x %= myRes[0];
00571 if (x < 0)
00572 x += myRes[0];
00573 }
00574 if (y < 0 || y >= myRes[1])
00575 {
00576 y %= myRes[1];
00577 if (y < 0)
00578 y += myRes[1];
00579 }
00580 if (z < 0 || z >= myRes[2])
00581 {
00582 z %= myRes[2];
00583 if (z < 0)
00584 z += myRes[2];
00585 }
00586 break;
00587
00588 case UT_VOXELBORDER_STREAK:
00589 clampIndex(x, y, z);
00590 break;
00591 }
00592
00593
00594 return (*this)(x, y, z);
00595 }
00596
00597 void setBorder(UT_VoxelBorderType type, T t);
00598 UT_VoxelBorderType getBorder() const { return myBorderType; }
00599 T getBorderValue() const { return myBorderValue; }
00600
00601
00602
00603
00604 void collapseAllTiles();
00605
00606
00607
00608
00609
00610
00611
00612 void expandAllTiles();
00613
00614
00615
00616 UT_VoxelTile<T> *getTile(int tx, int ty, int tz) const
00617 { return myTiles[xyzTileToLinear(tx, ty, tz)]; }
00618 UT_VoxelTile<T> *getLinearTile(int idx) const
00619 { return myTiles[idx]; }
00620 void linearTileToXYZ(int idx, int &x, int &y, int &z) const
00621 {
00622 x = idx % myTileRes[0];
00623 idx -= x;
00624 idx /= myTileRes[0];
00625 y = idx % myTileRes[1];
00626 idx -= y;
00627 idx /= myTileRes[1];
00628 z = idx;
00629 }
00630 int xyzTileToLinear(int x, int y, int z) const
00631 { return (z * myTileRes[1] + y) * myTileRes[0] + x; }
00632
00633
00634
00635 int getTileRes(int dim) const { return myTileRes[dim]; }
00636 int numTiles() const
00637 { return myTileRes[0] * myTileRes[1] * myTileRes[2]; }
00638 int numVoxels() const
00639 { return myRes[0] * myRes[1] * myRes[2]; }
00640
00641 fpreal getCompressionTolerance() const
00642 { return myCompressionTolerance; }
00643 void setCompressionTolerance(fpreal tol)
00644 { myCompressionTolerance = tol; }
00645
00646
00647
00648
00649
00650 void saveData(ostream &os);
00651
00652
00653 void loadData(UT_IStream &is);
00654
00655 private:
00656 THREADED_METHOD3(UT_VoxelArray<T>, numTiles() > 1,
00657 resamplethread,
00658 const UT_VoxelArray<T> &, src,
00659 const UT_Filter *, filter,
00660 float, radius)
00661 void resamplethreadPartial(const UT_VoxelArray<T> &src,
00662 const UT_Filter *filter,
00663 float radius,
00664 const UT_JobInfo &info);
00665
00666 void deleteVoxels();
00667
00668
00669 int myRes[3];
00670
00671
00672 int myTileRes[3];
00673
00674
00675 fpreal myCompressionTolerance;
00676
00677
00678 UT_VoxelTile<T> **myTiles;
00679
00680
00681 T myBorderValue;
00682 UT_VoxelBorderType myBorderType;
00683 };
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 template <typename T>
00697 class UT_VoxelMipMap
00698 {
00699 public:
00700
00701
00702 enum mipmaptype { MIPMAP_MAXIMUM=0, MIPMAP_AVERAGE=1, MIPMAP_MINIMUM=2 };
00703
00704 UT_VoxelMipMap();
00705 virtual ~UT_VoxelMipMap();
00706
00707
00708 UT_VoxelMipMap(const UT_VoxelMipMap<T> &src);
00709
00710
00711 const UT_VoxelMipMap<T> &operator=(const UT_VoxelMipMap<T> &src);
00712
00713
00714
00715
00716 void build(UT_VoxelArray<T> *baselevel,
00717 mipmaptype function);
00718
00719
00720
00721
00722 void build(UT_VoxelArray<T> *baselevel,
00723 const UT_RefArray<mipmaptype> &functions);
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 void traverseTopDown(bool (*function)(
00735 const UT_RefArray<T> &,
00736 const UT_BoundingBox &,
00737 bool,
00738 void *),
00739 void *data) const;
00740
00741
00742 int64 getMemoryUsage() const;
00743
00744 private:
00745 void doTraverse(int x, int y, int z, int level,
00746 bool (*function)(const UT_RefArray<T> &,
00747 const UT_BoundingBox &,
00748 bool,
00749 void *),
00750 void *data) const;
00751
00752 void initializePrivate();
00753 void destroyPrivate();
00754
00755 protected:
00756 T mixValues(T t1, T t2, mipmaptype function) const;
00757
00758
00759
00760 UT_VoxelArray<T> *myBaseLevel;
00761
00762 bool myOwnBase;
00763
00764
00765
00766 int myNumLevels;
00767
00768
00769
00770
00771
00772 UT_PtrArray<UT_VoxelArray<T> **> myLevels;
00773 };
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 template <typename T>
00798 class UT_VoxelArrayIterator
00799 {
00800 public:
00801 UT_VoxelArrayIterator();
00802 UT_VoxelArrayIterator(UT_VoxelArray<T> *vox);
00803 UT_VoxelArrayIterator(UT_COWReadHandle<UT_VoxelArray<T> > handle);
00804 virtual ~UT_VoxelArrayIterator();
00805
00806 void setArray(UT_VoxelArray<T> *vox)
00807 {
00808 myCurTile = -1;
00809 myHandle.resetHandle();
00810 myArray = vox;
00811
00812 setPartialRange(0, 1);
00813 }
00814
00815
00816
00817
00818 void setHandle(UT_COWReadHandle<UT_VoxelArray<T> > handle)
00819 {
00820 myHandle = handle;
00821
00822
00823
00824 myArray = const_cast<UT_VoxelArray<T> *>(&*myHandle);
00825
00826
00827 myCurTile = -1;
00828 setPartialRange(0, 1);
00829 }
00830
00831
00832
00833
00834
00835
00836 void setPartialRange(int idx, int numranges);
00837
00838
00839
00840
00841
00842
00843
00844 void restrictToBBox(const UT_BoundingBox &bbox);
00845
00846 void restrictToBBox(int xmin, int xmax,
00847 int ymin, int ymax,
00848 int zmin, int zmax);
00849
00850
00851 void rewind();
00852
00853
00854 bool atEnd() const
00855 { return myCurTile < 0; }
00856
00857
00858 void advance()
00859 {
00860
00861
00862 myPos[0]++;
00863 myTileLocalPos[0]++;
00864 if (myTileLocalPos[0] >= myTileSize[0])
00865 {
00866
00867 myPos[0] -= myTileLocalPos[0];
00868 myTileLocalPos[0] = 0;
00869
00870 myPos[1]++;
00871 myTileLocalPos[1]++;
00872 if (myTileLocalPos[1] >= myTileSize[1])
00873 {
00874
00875 myPos[1] -= myTileLocalPos[1];
00876 myTileLocalPos[1] = 0;
00877
00878 myPos[2]++;
00879 myTileLocalPos[2]++;
00880 if (myTileLocalPos[2] >= myTileSize[2])
00881 {
00882
00883 advanceTile();
00884 }
00885 }
00886 }
00887 }
00888
00889
00890 int x() const { return myPos[0]; }
00891 int y() const { return myPos[1]; }
00892 int z() const { return myPos[2]; }
00893 int idx(int idx) const { return myPos[idx]; }
00894
00895
00896
00897
00898 T getValue() const
00899 {
00900 UT_ASSERT_P(myCurTile >= 0);
00901
00902 UT_VoxelTile<T> *tile;
00903
00904 tile = myArray->getLinearTile(myCurTile);
00905 return (*tile)(myTileLocalPos[0],
00906 myTileLocalPos[1],
00907 myTileLocalPos[2]);
00908 }
00909
00910
00911 void setValue(T t) const
00912 {
00913 UT_ASSERT_P(myCurTile >= 0);
00914
00915 UT_VoxelTile<T> *tile;
00916
00917 tile = myArray->getLinearTile(myCurTile);
00918
00919 tile->setValue(myTileLocalPos[0],
00920 myTileLocalPos[1],
00921 myTileLocalPos[2], t);
00922 }
00923
00924
00925 bool isTileConstant() const
00926 {
00927 UT_ASSERT_P(myCurTile >= 0);
00928
00929 UT_VoxelTile<T> *tile;
00930
00931 tile = myArray->getLinearTile(myCurTile);
00932 return tile->isConstant();
00933 }
00934
00935
00936 bool isStartOfTile() const
00937 { return !(myTileLocalPos[0] ||
00938 myTileLocalPos[1] ||
00939 myTileLocalPos[2]); }
00940
00941
00942 UT_VoxelTile<T> *getTile() const
00943 {
00944 UT_ASSERT_P(myCurTile >= 0);
00945 return myArray->getLinearTile(myCurTile);
00946 }
00947
00948
00949
00950 void advanceTile();
00951
00952
00953
00954 bool getCompressOnExit() const { return myShouldCompressOnExit; }
00955 void setCompressOnExit(bool shouldcompress)
00956 { myShouldCompressOnExit = shouldcompress; }
00957
00958 protected:
00959
00960 UT_VoxelArray<T> *myArray;
00961
00962
00963 UT_COWReadHandle<UT_VoxelArray<T> > myHandle;
00964
00965
00966 int myPos[3];
00967
00968
00969
00970 bool myShouldCompressOnExit;
00971
00972 bool myUseTileList;
00973 UT_IntArray myTileList;
00974
00975 public:
00976
00977 int myCurTile;
00978
00979
00980 int myCurTileListIdx;
00981
00982
00983
00984 int myTileStart, myTileEnd;
00985
00986
00987 int myTilePos[3];
00988
00989
00990 int myTileLocalPos[3];
00991
00992
00993 int myTileSize[3];
00994 };
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 template <typename T, bool DoRead, bool DoWrite, bool TestForWrites>
01013 class UT_VoxelProbe
01014 {
01015 public:
01016 UT_VoxelProbe();
01017 UT_VoxelProbe(UT_VoxelArray<T> *vox, int prex = 0, int postx = 0);
01018 virtual ~UT_VoxelProbe();
01019
01020 void setArray(UT_VoxelArray<T> *vox, int prex = 0, int postx = 0);
01021
01022 inline T getValue() const
01023 {
01024 return *myCurLine;
01025 }
01026 inline T getValue(int offset) const
01027 {
01028 return myCurLine[myStride*offset];
01029 }
01030
01031 inline void setValue(T value)
01032 {
01033 UT_ASSERT_P(DoWrite);
01034 *myCurLine = value;
01035 if (TestForWrites)
01036 myDirty = true;
01037 }
01038
01039
01040
01041
01042
01043
01044 template <typename S>
01045 bool setIndex(UT_VoxelArrayIterator<S> &vit)
01046 { return setIndex(vit.x(), vit.y(), vit.z()); }
01047
01048 bool setIndex(int x, int y, int z);
01049
01050
01051 inline void advanceX()
01052 {
01053 myCurLine += myStride;
01054 myX++;
01055 UT_ASSERT_P(myX < myMaxValidX);
01056 }
01057
01058
01059
01060 inline void resetX(int x)
01061 {
01062 myCurLine += myStride * (x - myX);
01063 myX = x;
01064 UT_ASSERT_P(myX < myMaxValidX && myX >= myMinValidX);
01065 }
01066
01067 protected:
01068 void reloadCache(int x, int y, int z);
01069
01070 void writeCacheLine();
01071
01072 void buildConstantCache(T value);
01073
01074 T *myCurLine;
01075
01076
01077 T *myCacheLine;
01078
01079
01080 T *myAllocCacheLine;
01081
01082 int myX, myY, myZ;
01083 int myPreX, myPostX;
01084 int myStride;
01085 bool myForceCopy;
01086
01087 int myMinValidX, myMaxValidX;
01088
01089
01090
01091 bool myDirty;
01092
01093 UT_VoxelArray<T> *myArray;
01094
01095 friend class UT_VoxelProbeCube<T>;
01096 friend class UT_VoxelProbeFace<T>;
01097 };
01098
01099
01100
01101
01102
01103
01104 template <typename T, bool DoRead, bool DoWrite, bool TestForWrites>
01105 class UT_VoxelVectorProbe
01106 {
01107 public:
01108 UT_VoxelVectorProbe()
01109 { }
01110 UT_VoxelVectorProbe(UT_VoxelArray<T> *vx, UT_VoxelArray<T> *vy, UT_VoxelArray<T> *vz)
01111 { setArray(vx, vy, vz); }
01112 virtual ~UT_VoxelVectorProbe()
01113 {}
01114
01115 void setArray(UT_VoxelArray<T> *vx, UT_VoxelArray<T> *vy, UT_VoxelArray<T> *vz)
01116 {
01117 myLines[0].setArray(vx);
01118 myLines[1].setArray(vy);
01119 myLines[2].setArray(vz);
01120 }
01121
01122 inline UT_Vector3 getValue() const
01123 {
01124 return UT_Vector3(myLines[0].getValue(), myLines[1].getValue(), myLines[2].getValue());
01125 }
01126 inline T getValue(int axis) const
01127 {
01128 return myLines[axis].getValue();
01129 }
01130
01131 inline void setValue(const UT_Vector3 &v)
01132 {
01133 myLines[0].setValue(v.x());
01134 myLines[1].setValue(v.y());
01135 myLines[2].setValue(v.z());
01136 }
01137
01138 inline void setComponent(int axis, T val)
01139 {
01140 myLines[axis].setValue(val);
01141 }
01142
01143
01144
01145
01146
01147 template <typename S>
01148 bool setIndex(UT_VoxelArrayIterator<S> &vit)
01149 { return setIndex(vit.x(), vit.y(), vit.z()); }
01150
01151 bool setIndex(int x, int y, int z)
01152 {
01153 if (myLines[0].setIndex(x, y, z))
01154 {
01155 myLines[1].setIndex(x, y, z);
01156 myLines[2].setIndex(x, y, z);
01157 return true;
01158 }
01159 myLines[1].advanceX();
01160 myLines[2].advanceX();
01161 return false;
01162 }
01163
01164 void advanceX()
01165 { myLines[0].advanceX(); myLines[1].advanceX(); myLines[2].advanceX(); }
01166
01167 protected:
01168 UT_VoxelProbe<T, DoRead, DoWrite, TestForWrites> myLines[3];
01169 };
01170
01171 template <typename T>
01172 class
01173 UT_VoxelProbeCube
01174 {
01175 public:
01176 UT_VoxelProbeCube();
01177 virtual ~UT_VoxelProbeCube();
01178
01179 void setCubeArray(UT_VoxelArray<T> *vox);
01180 void setPlusArray(UT_VoxelArray<T> *vox);
01181
01182
01183
01184
01185 inline T getValue(int x, int y, int z) const
01186 { return myLines[y+1][z+1].getValue(x); }
01187
01188 template <typename S>
01189 bool setIndexCube(UT_VoxelArrayIterator<S> &vit)
01190 { return setIndexCube(vit.x(), vit.y(), vit.z()); }
01191 bool setIndexCube(int x, int y, int z);
01192
01193 template <typename S>
01194 bool setIndexPlus(UT_VoxelArrayIterator<S> &vit)
01195 { return setIndexPlus(vit.x(), vit.y(), vit.z()); }
01196 bool setIndexPlus(int x, int y, int z);
01197
01198
01199
01200 UT_Vector3 gradient() const
01201 { return UT_Vector3(getValue(1,0,0) - getValue(-1,0,0),
01202 getValue(0,1,0) - getValue(0,-1,0),
01203 getValue(0,0,1) - getValue(0,0,-1)); }
01204
01205 protected:
01206
01207
01208 static void rotateLines(UT_VoxelProbe<T, true, false, false> &ym, UT_VoxelProbe<T, true, false, false> &y0, UT_VoxelProbe<T, true, false, false> &yp);
01209
01210 UT_VoxelProbe<T, true, false, false> myLines[3][3];
01211
01212
01213 bool myValid;
01214 int myX, myY, myZ;
01215
01216 int myMinValidX, myMaxValidX;
01217 };
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 template <typename T, int XStep, int YStep, int ZStep>
01229 class
01230 UT_VoxelProbeAverage
01231 {
01232 public:
01233 UT_VoxelProbeAverage() {}
01234 virtual ~UT_VoxelProbeAverage() {}
01235
01236 void setArray(UT_VoxelArray<T> *vox);
01237
01238 template <typename S>
01239 bool setIndex(UT_VoxelArrayIterator<S> &vit)
01240 { return setIndex(vit.x(), vit.y(), vit.z()); }
01241 bool setIndex(int x, int y, int z);
01242
01243
01244
01245 inline T getValue() const
01246 {
01247 if (ZStep)
01248 return (valueZ(1) + valueZ(0)) * 0.5;
01249 return valueZ(0);
01250 }
01251
01252 protected:
01253 inline T valueZ(int z) const
01254 {
01255 if (YStep)
01256 return (valueYZ(1, z) + valueYZ(0, z)) * 0.5;
01257 return valueYZ(0, z);
01258 }
01259
01260 inline T valueYZ(int y, int z) const
01261 {
01262 if (XStep > 0)
01263 return (myLines[y][z].getValue(1) + myLines[y][z].getValue(0)) * 0.5;
01264 if (XStep < 0)
01265 return (myLines[y][z].getValue(-1) + myLines[y][z].getValue(0)) * 0.5;
01266 return myLines[y][z].getValue();
01267 }
01268
01269
01270 UT_VoxelProbe<T, true, false, false> myLines[2][2];
01271 };
01272
01273
01274
01275
01276
01277
01278
01279 template <typename T>
01280 class
01281 UT_VoxelProbeFace
01282 {
01283 public:
01284 UT_VoxelProbeFace();
01285 virtual ~UT_VoxelProbeFace();
01286
01287 void setArray(UT_VoxelArray<T> *vx, UT_VoxelArray<T> *vy, UT_VoxelArray<T> *vz);
01288 void setVoxelSize(const UT_Vector3 &voxelsize);
01289
01290 template <typename S>
01291 bool setIndex(UT_VoxelArrayIterator<S> &vit)
01292 { return setIndex(vit.x(), vit.y(), vit.z()); }
01293 bool setIndex(int x, int y, int z);
01294
01295
01296
01297
01298 inline T face(int axis, int side) const
01299 {
01300 if (axis == 0)
01301 return myLines[0][0].getValue(side);
01302 else
01303 return myLines[axis][side].getValue();
01304 }
01305
01306
01307
01308 inline UT_Vector3 value() const
01309 {
01310 return UT_Vector3(0.5f * (face(0, 0) + face(0, 1)),
01311 0.5f * (face(1, 0) + face(1, 1)),
01312 0.5f * (face(2, 0) + face(2, 1)));
01313 }
01314
01315
01316 inline T divergence() const
01317 {
01318 return (face(0,1)-face(0,0)) * myVoxelSize.x()
01319 + (face(1,1)-face(1,0)) * myVoxelSize.y()
01320 + (face(2,1)-face(2,0)) * myVoxelSize.z();
01321
01322 }
01323
01324 protected:
01325
01326 static void swapLines(UT_VoxelProbe<T, true, false, false> &ym,
01327 UT_VoxelProbe<T, true, false, false> &yp);
01328
01329
01330 UT_VoxelProbe<T, true, false, false> myLines[3][2];
01331
01332
01333
01334 bool myValid;
01335 int myX, myY, myZ;
01336
01337 int myMinValidX, myMaxValidX;
01338
01339 UT_Vector3 myVoxelSize, myInvVoxelSize;
01340 };
01341
01342
01343 #if defined( WIN32 ) || defined( LINUX ) || defined( MBSD ) || defined(GAMEOS)
01344 #include "UT_VoxelArray.C"
01345 #endif
01346
01347
01348
01349 typedef UT_VoxelArray<fpreal32> UT_VoxelArrayF;
01350 typedef UT_VoxelMipMap<fpreal32> UT_VoxelMipMapF;
01351 typedef UT_VoxelArrayIterator<fpreal32> UT_VoxelArrayIteratorF;
01352
01353 typedef UT_VoxelProbe<fpreal32, true, false, false> UT_VoxelProbeF;
01354 typedef UT_VoxelVectorProbe<fpreal32, true, false, false> UT_VoxelVectorProbeF;
01355
01356 typedef UT_VoxelProbe<fpreal32, false, true, false> UT_VoxelWOProbeF;
01357 typedef UT_VoxelVectorProbe<fpreal32, false, true, false> UT_VoxelVectorWOProbeF;
01358
01359 typedef UT_VoxelProbe<fpreal32, true, true, false> UT_VoxelRWProbeF;
01360 typedef UT_VoxelVectorProbe<fpreal32, true, true, false> UT_VoxelVectorRWProbeF;
01361
01362 typedef UT_VoxelProbe<fpreal32, true, true, true> UT_VoxelRWTProbeF;
01363 typedef UT_VoxelVectorProbe<fpreal32, true, true, true> UT_VoxelVectorRWTProbeF;
01364
01365
01366 typedef UT_VoxelProbeCube<fpreal32> UT_VoxelProbeCubeF;
01367
01368 #if 0
01369 typedef UT_VoxelArrayHandle<fpreal32> UT_VoxelArrayHandleF;
01370 typedef UT_VoxelArrayHandleAutoReadLock<fpreal32> UT_VoxelArrayHandleAutoReadLockF;
01371 typedef UT_VoxelArrayHandleAutoWriteLock<fpreal32> UT_VoxelArrayHandleAutoWriteLockF;
01372 #endif
01373
01374 typedef UT_COWHandle<UT_VoxelArray<fpreal32> > UT_VoxelArrayHandleF;
01375 typedef UT_COWReadHandle<UT_VoxelArray<fpreal32> > UT_VoxelArrayReadHandleF;
01376 typedef UT_COWWriteHandle<UT_VoxelArray<fpreal32> > UT_VoxelArrayWriteHandleF;
01377
01378 #endif
01379