44 #ifndef _INCLUDED_Field3D_SparseField_H_ 45 #define _INCLUDED_Field3D_SparseField_H_ 51 #include <boost/thread/mutex.hpp> 52 #include <boost/lexical_cast.hpp> 57 #define BLOCK_ORDER 4 // 2^BLOCK_ORDER is the block size along each axis 69 template <
class Field_T>
71 template <
class Field_T>
85 template <
typename Data_T>
93 typedef boost::intrusive_ptr<LinearSparseFieldInterp>
Ptr;
102 return "LinearSparseFieldInterp";
117 FIELD3D_VEC3_T<double> p(vsP - FIELD3D_VEC3_T<double>(0.5));
120 V3i c1(static_cast<int>(
floor(p.x)),
121 static_cast<int>(
floor(p.y)),
122 static_cast<int>(
floor(p.z)));
126 FIELD3D_VEC3_T<double> f1(
static_cast<FIELD3D_VEC3_T<double>
>(c2) - p);
128 FIELD3D_VEC3_T<double> f2(
static_cast<FIELD3D_VEC3_T<double>
>(1.0) - f1);
133 c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
134 c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
135 c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
136 c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
137 c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
138 c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
141 int i = c1.x, j = c1.y, k = c1.z, vi, vj, vk, bi, bj, bk;
148 if (vi < blockSize - 1 && vj < blockSize - 1 && vk < blockSize - 1) {
151 const int blockId = field.
blockId(bi, bj, bk);
158 const Data_T *
const p = field.
blockData(bi, bj, bk);
159 const Data_T *
const c111 =
160 p + vi + vj * blockSize + vk * blockSize * blockSize;
161 const Data_T *
const c121 = c111 + blockSize * (c2.y - c1.y);
163 c112 = c111 + blockSize * blockSize * (c2.z - c1.z);
164 const Data_T *
const c122 = c112 + blockSize * (c2.y - c1.y);
165 int xInc = c2.x - c1.x;
166 Data_T value =
static_cast<Data_T
> 167 (f1.x * (f1.y * (f1.z * *c111 +
169 f2.y * (f1.z * *c121 +
171 f2.x * (f1.y * (f1.z * *(c111 + xInc) +
172 f2.z * *(c112 + xInc)) +
173 f2.y * (f1.z * *(c121 + xInc) +
174 f2.z * *(c122 + xInc))));
185 return static_cast<Data_T
> 186 (f1.x * (f1.y * (f1.z * field.
fastValue(c1.x, c1.y, c1.z) +
187 f2.z * field.
fastValue(c1.x, c1.y, c2.z)) +
188 f2.y * (f1.z * field.
fastValue(c1.x, c2.y, c1.z) +
189 f2.z * field.
fastValue(c1.x, c2.y, c2.z))) +
190 f2.x * (f1.y * (f1.z * field.
fastValue(c2.x, c1.y, c1.z) +
191 f2.z * field.
fastValue(c2.x, c1.y, c2.z)) +
192 f2.y * (f1.z * field.
fastValue(c2.x, c2.y, c1.z) +
193 f2.z * field.
fastValue(c2.x, c2.y, c2.z))));
226 template <
typename Data_T>
233 : isAllocated(false),
234 emptyValue(static_cast<Data_T>(0)),
249 inline Data_T&
value(
int i,
int j,
int k,
int blockOrder)
251 {
return data[(k << blockOrder << blockOrder) + (j << blockOrder) + i]; }
255 inline const Data_T&
value(
int i,
int j,
int k,
int blockOrder)
const 256 {
return data[(k << blockOrder << blockOrder) + (j << blockOrder) + i]; }
262 boost::mutex::scoped_lock lock(ms_resizeMutex);
267 data =
new Data_T[n];
269 std::fill_n(data, n, emptyValue);
276 boost::mutex::scoped_lock lock(ms_resizeMutex);
291 Data_T *p = data, *end = data + n, *o = other.
data;
349 template <
class Data_T>
357 typedef boost::intrusive_ptr<SparseField>
Ptr;
358 typedef std::vector<Ptr>
Vec;
370 return "SparseField";
401 virtual void clear(
const Data_T &value);
405 void setBlockOrder(
int order);
408 int blockOrder()
const;
411 int blockSize()
const;
414 bool voxelIsInAllocatedBlock(
int i,
int j,
int k)
const;
417 bool blockIsAllocated(
int bi,
int bj,
int bk)
const;
421 const Data_T getBlockEmptyValue(
int bi,
int bj,
int bk)
const;
425 void setBlockEmptyValue(
int bi,
int bj,
int bk,
const Data_T &val);
428 bool blockIndexIsValid(
int bi,
int bj,
int bk)
const;
431 V3i blockRes()
const;
438 template <
typename Functor_T>
439 int releaseBlocks(Functor_T func);
442 int blockId(
int blockI,
int blockJ,
int blockK)
const;
447 void getBlockCoord(
int i,
int j,
int k,
int &bi,
int &bj,
int &bk)
const;
452 void getVoxelInBlock(
int i,
int j,
int k,
int &vi,
int &vj,
int &vk)
const;
457 i -= base::m_dataWindow.min.x;
458 j -= base::m_dataWindow.min.y;
459 k -= base::m_dataWindow.min.z;
464 {
return m_fileManager != NULL; }
467 void incBlockRef(
const int blockId)
const;
470 void activateBlock(
const int blockId)
const;
473 void decBlockRef(
const int blockId)
const;
478 size_t numGrains()
const;
481 bool getGrainBounds(
const size_t idx,
Box3i &vsBounds)
const;
487 virtual Data_T value(
int i,
int j,
int k)
const;
488 virtual long long int memSize()
const;
489 virtual size_t voxelCount()
const;
496 virtual Data_T& lvalue(
int i,
int j,
int k);
502 Data_T fastValue(
int i,
int j,
int k)
const;
504 Data_T& fastLValue(
int i,
int j,
int k);
508 Data_T* blockData(
int bi,
int bj,
int bk)
const;
570 void addReference(
const std::string &filename,
const std::string &layerPath,
571 int valuesPerBlock,
int occupiedBlocks);
574 void setupReferenceBlocks();
603 void deallocBlock(Block &block,
const Data_T &emptyValue);
655 template <
typename Data_T>
656 boost::mutex SparseBlock<Data_T>::ms_resizeMutex;
675 template <
typename Data_T>
680 f->
getBlockCoord(dvsBounds.min.x, dvsBounds.min.y, dvsBounds.min.z,
681 dbsBounds.min.x, dbsBounds.min.y, dbsBounds.min.z);
682 f->
getBlockCoord(dvsBounds.max.x, dvsBounds.max.y, dvsBounds.max.z,
683 dbsBounds.max.x, dbsBounds.max.y, dbsBounds.max.z);
696 template <
typename Data_T>
708 const V3i &validSize,
const V3i &blockSize)
711 Data_T first = block.
data[0];
714 size_t len = blockSize.x * blockSize.y * blockSize.z;
715 if (validSize == blockSize) {
717 for (
size_t i = 0; i < len; i++) {
718 if (block.
data[i] != first) {
726 for (
size_t i = 0; i < len; i++, x++) {
727 if (x >= blockSize.x) {
730 if (y >= blockSize.y) {
735 if (x >= validSize.x || y >= validSize.y || z >= validSize.z) {
738 if (block.
data[i] != first) {
746 retEmptyValue = first;
756 template <
typename Data_T>
757 inline bool isAnyLess(
const Data_T &left,
const Data_T &right)
759 return (std::abs(left) < right);
767 return (std::abs(left.x) < right.x ||
768 std::abs(left.y) < right.y ||
769 std::abs(left.z) < right.z );
777 return (std::abs(left.x) < right.x ||
778 std::abs(left.y) < right.y ||
779 std::abs(left.z) < right.z );
787 return (std::abs(left.x) < right.x ||
788 std::abs(left.y) < right.y ||
789 std::abs(left.z) < right.z );
797 template <
typename Data_T>
802 : m_maxValue(maxValue)
813 const V3i &validSize,
const V3i &blockSize)
816 Data_T first = block.
data[0];
818 bool allGreater =
true;
819 size_t len = blockSize.x * blockSize.y * blockSize.z;
821 if (validSize == blockSize) {
823 for (
size_t i = 0; i < len; i++) {
824 if (isAnyLess<Data_T>(block.
data[i], m_maxValue)) {
832 for (
size_t i = 0; i < len; i++, x++) {
833 if (x >= blockSize.x) {
836 if (y >= blockSize.y) {
841 if (x >= validSize.x || y >= validSize.y || z >= validSize.z) {
844 if (isAnyLess<Data_T>(block.
data[i], m_maxValue)) {
852 retEmptyValue = first;
871 template <
class Data_T>
875 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 876 typedef std::forward_iterator_tag iterator_category;
878 typedef ptrdiff_t difference_type;
879 typedef ptrdiff_t distance_type;
880 typedef Data_T *pointer;
881 typedef Data_T& reference;
887 const V3i ¤tPos,
int blockOrder)
888 : x(currentPos.x), y(currentPos.y), z(currentPos.z),
889 m_p(NULL), m_blockIsActivated(false),
890 m_blockStepsTicker(0), m_blockOrder(blockOrder),
891 m_blockId(-1), m_window(window), m_field(&field)
893 m_manager = m_field->m_fileManager;
894 setupNextBlock(x, y, z);
897 if (m_manager && m_blockId >= 0 &&
898 m_blockId < static_cast<int>(m_field->m_numBlocks)) {
899 if (m_field->m_blocks[m_blockId].isAllocated)
900 m_manager->decBlockRef<Data_T>(m_field->m_fileId, m_blockId);
905 bool resetPtr =
false;
907 if (x == m_window.max.x) {
908 if (y == m_window.max.y) {
922 ++m_blockStepsTicker;
924 if (!m_isEmptyBlock && (!m_manager || m_blockIsActivated))
927 if (m_blockStepsTicker == (1 << m_blockOrder))
931 m_blockStepsTicker = 0;
932 setupNextBlock(x, y, z);
936 template <
class Iter_T>
937 inline bool operator == (
const Iter_T &rhs)
const 939 return x == rhs.x && y == rhs.y && z == rhs.z;
941 template <
class Iter_T>
942 inline bool operator != (
const Iter_T &rhs)
const 944 return x != rhs.x || y != rhs.y || z != rhs.z;
948 if (!m_isEmptyBlock && m_manager && !m_blockIsActivated) {
949 m_manager->activateBlock<Data_T>(m_field->m_fileId, m_blockId);
950 m_blockIsActivated =
true;
951 const Block &block = m_field->m_blocks[m_blockId];
953 m_field->getVoxelInBlock(x, y, z, vi, vj, vk);
954 m_p = &block.
value(vi, vj, vk, m_blockOrder);
958 inline const Data_T* operator -> ()
const 960 if (!m_isEmptyBlock && m_manager && !m_blockIsActivated) {
962 manager->
activateBlock<Data_T>(m_field->m_fileId, m_blockId);
963 m_blockIsActivated =
true;
964 const Block &block = m_field->m_blocks[m_blockId];
966 m_field->getVoxelInBlock(x, y, z, vi, vj, vk);
967 m_p = &block.
value(vi, vj, vk, m_blockOrder);
987 m_field->applyDataWindowOffset(i, j, k);
988 m_field->getBlockCoord(i, j, k, m_blockI, m_blockJ, m_blockK);
989 int oldBlockId = m_blockId;
990 m_blockId = m_field->blockId(m_blockI, m_blockJ, m_blockK);
991 if (m_manager && oldBlockId != m_blockId &&
993 oldBlockId < static_cast<int>(m_field->m_numBlocks) &&
994 m_field->m_blocks[oldBlockId].isAllocated) {
995 m_manager->decBlockRef<Data_T>(m_field->m_fileId, oldBlockId);
997 if (m_blockId >= m_field->m_blockXYSize * m_field->m_blockRes.z) {
998 m_isEmptyBlock =
true;
1002 const Block &block = m_field->m_blocks[m_blockId];
1004 m_field->getVoxelInBlock(i, j, k, vi, vj, vk);
1005 m_blockStepsTicker = vi;
1007 if (m_manager && oldBlockId != m_blockId && m_blockId >= 0) {
1008 m_manager->incBlockRef<Data_T>(m_field->m_fileId, m_blockId);
1015 m_p = &block.
value(vi, vj, vk, m_blockOrder);
1017 m_isEmptyBlock =
false;
1020 m_isEmptyBlock =
true;
1022 if (m_field->m_fileManager) {
1023 m_blockIsActivated =
false;
1053 template <
class Data_T>
1057 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 1058 typedef std::forward_iterator_tag iterator_category;
1060 typedef ptrdiff_t difference_type;
1061 typedef ptrdiff_t distance_type;
1062 typedef Data_T *pointer;
1063 typedef Data_T& reference;
1068 const Box3i &window,
1069 const V3i ¤tPos,
int blockOrder)
1070 : x(currentPos.x), y(currentPos.y), z(currentPos.z),
1071 m_p(NULL), m_blockStepsTicker(0), m_blockOrder(blockOrder),
1072 m_blockId(-1), m_window(window), m_field(&field)
1074 setupNextBlock(x, y, z);
1078 bool resetPtr =
false;
1080 if (x == m_window.max.x) {
1081 if (y == m_window.max.y) {
1095 ++m_blockStepsTicker;
1097 if (!m_isEmptyBlock)
1100 if (m_blockStepsTicker == (1 << m_blockOrder))
1104 m_blockStepsTicker = 0;
1105 setupNextBlock(x, y, z);
1111 return x == rhs.
x && y == rhs.
y && z == rhs.
z;
1115 return x != rhs.
x || y != rhs.
y || z != rhs.
z;
1119 if (m_field->m_fileManager) {
1120 assert(
false &&
"Dereferencing iterator on a dynamic-read sparse field");
1126 if (m_isEmptyBlock) {
1128 m_field->lvalue(x, y, z);
1130 setupNextBlock(x, y, z);
1134 inline Data_T* operator -> ()
1136 if (m_field->m_fileManager) {
1137 assert(
false &&
"Dereferencing iterator on a dynamic-read sparse field");
1143 if (m_isEmptyBlock) {
1145 m_field->lvalue(x, y, z);
1147 setupNextBlock(x, y, z);
1158 m_field->applyDataWindowOffset(i, j, k);
1159 m_field->getBlockCoord(i, j, k, m_blockI, m_blockJ, m_blockK);
1160 m_blockId = m_field->blockId(m_blockI, m_blockJ, m_blockK);
1161 if (m_blockId >= m_field->m_blockXYSize * m_field->m_blockRes.z) {
1162 m_isEmptyBlock =
true;
1165 Block &block = m_field->m_blocks[m_blockId];
1167 m_field->getVoxelInBlock(i, j, k, vi, vj, vk);
1168 m_blockStepsTicker = vi;
1170 m_p = &block.
value(vi, vj, vk, m_blockOrder);
1171 m_isEmptyBlock =
false;
1174 m_isEmptyBlock =
true;
1199 template <
class Data_T>
1207 const V3i ¤tPos)
1208 : x(currentPos.x), y(currentPos.y), z(currentPos.z),
1209 m_window(window), m_field(field)
1211 recomputeBlockBoundingBox();
1216 if (x == m_window.max.x) {
1217 if (y == m_window.max.y) {
1228 recomputeBlockBoundingBox();
1234 return x == rhs.
x && y == rhs.
y && z == rhs.
z;
1239 return x != rhs.
x || y != rhs.
y || z != rhs.
z;
1244 return m_currentBlockWindow;
1252 int blockSize = m_field.blockSize();
1253 box.min =
V3i(x * blockSize, y * blockSize, z * blockSize);
1254 box.max = box.min +
V3i(blockSize - 1, blockSize - 1, blockSize - 1);
1259 m_currentBlockWindow = box;
1273 template <
class Data_T>
1285 template <
class Data_T>
1297 template <
class Data_T>
1313 template <
class Data_T>
1326 template <
class Data_T>
1364 template <
class Data_T>
1366 const std::string &layerPath,
1375 reference->valuesPerBlock = valuesPerBlock;
1376 reference->occupiedBlocks = occupiedBlocks;
1382 template <
class Data_T>
1396 template <
class Data_T>
1406 reference->
blocks.begin();
1407 int nextBlockIdx = 0;
1408 for (
size_t i = 0; i <
m_numBlocks; ++i, ++fb, ++bp) {
1421 template <
class Data_T>
1435 template <
class Data_T>
1444 template <
class Data_T>
1452 template <
class Data_T>
1460 template <
class Data_T>
1471 template <
class Data_T>
1480 template <
class Data_T>
1488 template <
class Data_T>
1502 template <
class Data_T>
1505 return bi >= 0 && bj >= 0 && bk >= 0 &&
1511 template <
class Data_T>
1519 template <
class Data_T>
1520 template <
typename Functor_T>
1524 int numDeallocs = 0;
1534 int bx = 0, by = 0, bz = 0;
1544 validSize = blockAllocSize;
1546 validSize.x = dataRes.x - bx * blockAllocSize.x;
1549 validSize.y = dataRes.y - by * blockAllocSize.y;
1552 validSize.z = dataRes.z - bz * blockAllocSize.z;
1556 if (func.check(
m_blocks[i], emptyValue, validSize, blockAllocSize)) {
1567 template <
class Data_T>
1575 template <
class Data_T>
1583 template <
class Data_T>
1622 template <
class Data_T>
1633 assert(
false &&
"Called fastLValue() on a dynamic-read sparse field");
1657 return block.
value(vi, vj, vk, m_blockOrder);
1663 template <
class Data_T>
1677 template <
class Data_T>
1681 long long int dataSize = 0;
1690 return sizeof(*this) + dataSize +
blockSize;
1695 template <
class Data_T>
1712 template <
class Data_T>
1724 template <
class Data_T>
1728 if (subset.isEmpty())
1729 return cend(subset);
1735 template <
class Data_T>
1748 template <
class Data_T>
1760 template <
class Data_T>
1771 template <
class Data_T>
1775 if (subset.isEmpty())
1782 template <
class Data_T>
1794 template <
class Data_T>
1799 V3i(subset.min.x, subset.min.y, subset.max.z + 1),
1805 template <
class Data_T>
1817 template <
class Data_T>
1827 template <
class Data_T>
1833 blockRes.x =
ceil(blockRes.x);
1834 blockRes.y =
ceil(blockRes.y);
1835 blockRes.z =
ceil(blockRes.z);
1836 V3i intBlockRes(static_cast<int>(blockRes.x),
1837 static_cast<int>(blockRes.y),
1838 static_cast<int>(blockRes.z));
1844 m_numBlocks = intBlockRes.x * intBlockRes.y * intBlockRes.z;
1850 template <
class Data_T>
1859 template <
class Data_T>
1861 int &bi,
int &bj,
int &bk)
const 1874 template <
class Data_T>
1876 int &vi,
int &vj,
int &vk)
const 1888 template <
class Data_T>
1896 template <
class Data_T>
1904 template <
class Data_T>
1912 template <
class Data_T>
1920 template <
class Data_T>
1931 const Box3i unclipped(start, end);
1934 return bounds == unclipped;
1939 template <
class Data_T>
1954 #endif // Include guard const class_type & m_field
Pointer to field we're traversing.
int m_blockOrder
Block size.
SparseField< double > SparseFieldd
void removeFieldFromCache(int refIdx)
#define FIELD3D_NAMESPACE_HEADER_CLOSE
V3i blockRes() const
Returns the resolution of the block array.
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
void addReference(const std::string &filename, const std::string &layerPath, int valuesPerBlock, int occupiedBlocks)
Internal function to create a Reference for the current field, for use in dynamic reading...
Box3i blockCoords(const Box3i &dvsBounds, const SparseField< Data_T > *f)
RefBase base
Convenience typedef for referring to base class.
V3i m_blockRes
Block array resolution.
size_t numGrains() const
Number of 'grains' to use with threaded access.
bool check(const SparseBlock< Data_T > &block, Data_T &retEmptyValue, const V3i &validSize, const V3i &blockSize)
Checks whether a given block can be released. It's safe to assume that the block is allocated if this...
int releaseBlocks(Functor_T func)
Releases any blocks that are deemed empty. This can be used to clean up after algorithms that write "...
Data_T & value(int i, int j, int k, int blockOrder)
Gets the value of a given voxel.
iterator begin()
Iterator to first element.
const Data_T getBlockEmptyValue(int bi, int bj, int bk) const
Returns the constant value of an block, whether it's allocated already or not..
bool voxelIsInAllocatedBlock(int i, int j, int k) const
Checks if a voxel is in an allocated block.
int m_fileId
File id. Used with m_fileManager if active. Otherwise -1.
SparseField< float > SparseFieldf
void activateBlock(int fileId, int blockIdx)
Called by SparseField when it's about to read from a block. This should not be called by the user...
static const char * staticClassType()
Box3i m_window
Window to traverse.
Data_T fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
RefBase & operator=(const RefBase &)
Assignment operator.
void applyDataWindowOffset(int &i, int &j, int &k) const
Applies data window offset.
const Data_T & value(int i, int j, int k, int blockOrder) const
Gets the const value of a given voxel.
void incBlockRef(int fileId, int blockIdx)
Increments the usage reference count on the specified block, to prevent it from getting unloaded whil...
int m_blockXYSize
Block array res.x * res.y.
int blockId(int blockI, int blockJ, int blockK) const
Calculates the block number based on a block i,j,k index.
Data_T * m_p
Current pointed-to element.
bool isDynamicLoad() const
Whether the field is dynamically loaded.
block_iterator(const class_type &field, const Box3i &window, const V3i ¤tPos)
Constructor.
void setBlockEmptyValue(int bi, int bj, int bk, const Data_T &val)
Sets the constant value of an block. If the block is already allocated, it gets deallocated.
Contains functions controlling the loading of sparse fields.
void setupReferenceBlocks()
Internal function to setup the Reference's block pointers, for use with dynamic reading.
boost::intrusive_ptr< FieldBase > Ptr
value_type sample(const SparseField< Data_T > &field, const V3d &vsP) const
int x
Current x/y/z coord.
Data_T * data
Pointer to data. Null if block is unallocated.
~SparseField()
Destructor.
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
int m_blockOrder
Block order (size = 2^blockOrder)
std::vector< int > fileBlockIndices
Index in file for each block.
boost::intrusive_ptr< SparseField > Ptr
int m_blockStepsTicker
Ticker for how many more steps to take before resetting the pointer.
static TemplatedFieldType< LinearSparseFieldInterp< Data_T > > ms_classType
void activateBlock(const int blockId) const
Activates a given block.
bool check(const SparseBlock< Data_T > &block, Data_T &retEmptyValue, const V3i &validSize, const V3i &blockSize)
Checks whether a given block can be released. It's safe to assume that the block is allocated if this...
void setupNextBlock(int i, int j, int k)
Convenience.
virtual Data_T & lvalue(int i, int j, int k)
Write access to a voxel. The coordinates are global coordinates.
SparseField()
Constructs an empty buffer.
SparseField< V3f > SparseField3f
SparseField< Data_T > class_type
Box3i m_dataWindow
Defines the area where data is allocated. This should be treated as a closed (i.e. inclusive) interval.
Data_T emptyValue
The value to use if the block isn't allocated. We allow setting this per block so that we for example...
SparseField< half > SparseFieldh
boost::intrusive_ptr< LinearSparseFieldInterp > Ptr
Sparse::SparseBlock< Data_T > Block
iterator end()
Iterator pointing one element past the last valid one.
static TemplatedFieldType< SparseField< Data_T > > ms_classType
FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(LinearSparseFieldInterp)
SparseField< Data_T > class_type
BlockPtrs blocks
Pointers to each block. This is so we can go in and manipulate them as we please. ...
Namespace for sparse field specifics.
void decBlockRef(const int blockId) const
Decrements the block ref count for the given block.
FIELD3D_VEC3_T< T > floor(const FIELD3D_VEC3_T< T > &v)
Floor function for Vec3.
void copySparseField(const SparseField &o)
Copies internal data, including blocks, from another SparseField, used by copy constructor and operat...
Checks if all the absolute values in the SparseBlock are greater than some number. Useful for making narrow band levelsets Used by SparseField::releaseBlocks().
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
void resize(int n)
Alloc data.
static const char * staticClassName()
const Data_T * m_p
Current pointed-to element.
bool blockIsAllocated(int bi, int bj, int bk) const
Checks if a block is allocated.
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
CheckMaxAbs(Data_T maxValue)
Constructor. Takes max value.
Box3i m_currentBlockWindow
Bounding box in voxel coordinates for the current block.
static const char * staticClassType()
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
Data_T m_dummy
Dummy value used when needing to return but indicating a failed call.
LinearSparseFieldInterp class_type
void recomputeBlockBoundingBox()
Box3i m_window
Bounding box for block indices.
void setBlockOrder(int order)
Sets the block order (i.e. the power-of-2 to use as block size.
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given 'grain'.
iterator(class_type &field, const Box3i &window, const V3i ¤tPos, int blockOrder)
void copy(const SparseBlock &other, size_t n)
Copy data from another block.
block_iterator blockBegin() const
int m_blockOrder
Block size.
virtual size_t voxelCount() const
Counts the number of voxels. For most fields, this is just the volume of the data window...
void setupBlocks()
Initializes the block structure. Will clear any existing data.
bool isAllocated
Whether the block is allocated or not.
int getNextId(const std::string filename, const std::string layerPath)
Returns the id of the next cache item. This is stored in the SparseField in order to reference its fi...
Used to return a string for the name of a templated field.
V3i const dataResolution() const
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
virtual long long int memSize() const
Returns the memory usage (in bytes)
int x
Current block index.
void decBlockRef(int fileId, int blockIdx)
Decrements the usage reference count on the specified block, after its value is no longer being used ...
Storage for one individual block of a SparseField.
SparseField< Data_T > class_type
Convenience typedef.
bool blockIndexIsValid(int bi, int bj, int bk) const
Returns whether a block index is valid.
void incBlockRef(const int blockId) const
Increments the block ref count for the given block.
Box3i m_window
Window to traverse.
LinearSparseFieldInterp< Data_T > LinearInterp
static const char * staticClassName()
Contains Field, WritableField and ResizableField classes.
bool match(const std::string &name, const std::string &attribute, const std::vector< std::string > &patterns, const MatchFlags flags=MatchEmptyPattern)
Matches a <name>:<attribute> string against a set of patterns.
static boost::mutex ms_resizeMutex
Prevents concurrent allocation of blocks. There should be little contention, and this prevents multip...
block_iterator blockEnd() const
Const iterator pointing to element one past the last valid block.
void getVoxelInBlock(int i, int j, int k, int &vi, int &vj, int &vk) const
Calculates the coordinates in a block for the given voxel index.
const_iterator cend() const
Const iterator pointing one element past the last valid one.
SparseField< V3d > SparseField3d
void getBlockCoord(int i, int j, int k, int &bi, int &bj, int &bk) const
Calculates the block coordinates that a given set of voxel coords are in.
void copyBlockStates(const SparseField< Data_T > &o)
Internal function to copy empty values and allocated flags, without copying data, used when copying a...
DEFINE_FIELD_RTTI_CONCRETE_CLASS
const class_type * m_field
Reference to field we're traversing.
Sparse::SparseBlock< Data_T > Block
const_iterator(const class_type &field, const Box3i &window, const V3i ¤tPos, int blockOrder)
V3i indexToCoord(const size_t idx, const V3i &res)
size_t m_numBlocks
Number of blocks in field.
CubicGenericFieldInterp< SparseField< Data_T > > CubicInterp
ResizableField< Data_T > base
SparseField & operator=(const SparseField &o)
Assignment operator. For cache-managed fields, it creates a new file reference, and for non-managed f...
bool m_isEmptyBlock
Whether we're at an empty block and we don't increment m_p.
bool m_isEmptyBlock
Whether we're at an empty block and we don't increment m_p.
int blockOrder() const
Returns the block order.
bool m_blockIsActivated
Used with delayed-load fields. Check if we've already activated the current blocks.
Sparse::SparseBlock< Data_T > Block
void deallocBlock(Block &block, const Data_T &emptyValue)
Deallocated the data of the given block and sets its empty value.
This Field subclass stores voxel data in block-allocated arrays.
SparseFile::Reference< Data_T > * reference(int index)
Returns a reference to the Reference object with the given index.
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
static SparseFileManager & singleton()
Returns a reference to the singleton instance.
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
virtual void sizeChanged()
Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.
Checks if all the values in the SparseBlock are equal. Used by SparseField::releaseBlocks().
const Box3i & blockBoundingBox()
Returns a reference to the bounding box representing the current block.
Data_T * blockData(int bi, int bj, int bk) const
Returns a pointer to the data in a block, or null if the given block is unallocated.
SparseField< V3h > SparseField3h
DEFINE_FIELD_RTTI_CONCRETE_CLASS
SparseField< Data_T > class_type
SparseFileManager * m_manager
Pointer to the singleton file manager.
SparseFileManager * m_fileManager
Pointer to SparseFileManager. Used when doing dynamic reading. NULL if not in use.
int m_blockStepsTicker
Ticker for how many more steps to take before resetting the pointer.
bool isAnyLess(const V3d &left, const V3d &right)
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
int blockSize() const
Returns the block size.
void setupNextBlock(int i, int j, int k)
Block * m_blocks
Array of blocks. Not using std::vector since SparseBlock is noncopyable.
class_type * m_field
Reference to field we're traversing.
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
std::string name
Optional name of the field.