44 #ifndef _INCLUDED_MIPField_H_
45 #define _INCLUDED_MIPField_H_
49 #include <boost/lexical_cast.hpp>
50 #include <boost/thread/mutex.hpp>
108 template <
class Field_T>
115 typedef typename Field_T::value_type
Data_T;
118 typedef boost::intrusive_ptr<MIPField>
Ptr;
119 typedef std::vector<Ptr>
Vec;
156 virtual long long int memSize()
const;
167 virtual Data_T
value(
int i,
int j,
int k)
const;
188 virtual Data_T
mipValue(
size_t level,
int i,
int j,
int k)
const;
190 virtual bool levelLoaded(
const size_t level)
const;
198 Data_T
fastMipValue(
size_t level,
int i,
int j,
int k)
const;
223 void setup(
const FieldVec &fields);
230 FieldPtr
mipLevel(
const size_t level)
const;
233 const Field_T*
rawMipLevel(
const size_t level)
const;
286 template <
typename T>
295 template <
typename Data_T>
303 template <
typename Data_T>
313 template <
class Field_T>
316 m_ioMutex(new
boost::mutex)
323 template <
class Field_T>
332 template <
class Field_T>
336 base::operator=(rhs);
342 template <
class Field_T>
354 m_fields.resize(rhs.
m_fields.size());
356 for (
size_t i = 0, end = m_fields.size(); i < end; ++i) {
364 std::cerr <<
"MIPField::op=(): Failed to clone." << std::endl;
368 m_rawFields[i] = m_fields[i].get();
371 m_ioMutex.reset(
new boost::mutex);
378 template <
class Field_T>
383 base::m_numLevels = 0;
384 base::m_lowestLevel = 0;
389 template <
class Field_T>
395 sanityChecks(fields);
398 base::m_numLevels = fields.size();
399 base::m_lowestLevel = 0;
400 updateMapping(fields[0]);
403 m_mipRes.resize(base::m_numLevels);
404 m_relativeResolution.resize(base::m_numLevels);
406 for (
size_t i = 0; i < fields.size(); i++) {
408 m_mipRes[i] = m_fields[i]->extents().size() +
V3i(1);
410 m_relativeResolution[i] =
V3f(m_mipRes[i]) / m_mipRes[0];
416 template <
class Field_T>
426 if (proxies.size() != actions.size()) {
427 throw MIPFieldException(
"Incorrect number of lazy load actions");
430 sanityChecks(proxies);
432 m_loadActions = actions;
434 base::m_numLevels = proxies.size();
435 base::m_lowestLevel = 0;
436 m_fields.resize(base::m_numLevels);
437 updateMapping(proxies[0]);
440 m_mipRes.resize(base::m_numLevels);
441 m_relativeResolution.resize(base::m_numLevels);
442 for (
size_t i = 0; i < proxies.size(); i++) {
444 m_mipRes[i] = proxies[i]->extents().size() +
V3i(1);
446 m_relativeResolution[i] =
V3f(m_mipRes[i]) / m_mipRes[0];
454 template <
class Field_T>
458 assert(level < base::m_numLevels);
460 if (!m_rawFields[level]) {
461 loadLevelFromDisk(level);
463 return m_fields[level];
469 template <
class Field_T>
473 assert(level < base::m_numLevels);
475 if (!m_rawFields[level]) {
476 loadLevelFromDisk(level);
478 return m_rawFields[level];
483 template <
class Field_T>
484 typename Field_T::Ptr
487 assert(level < base::m_numLevels);
489 if (!m_rawFields[level]) {
490 loadLevelFromDisk(level);
492 return m_fields[level];
497 template <
class Field_T>
501 return fastMipValue(0, i, j, k);
506 template <
class Field_T>
511 for (
size_t i = 0; i < m_fields.size(); i++) {
513 count += m_fields[i]->voxelCount();
521 template <
class Field_T>
524 long long int mem = 0;
525 for (
size_t i = 0; i < m_fields.size(); i++) {
527 mem += m_fields[i]->memSize();
530 return mem +
sizeof(*this);
535 template <
class Field_T>
538 V3i baseRes = base::dataWindow().size() +
V3i(1);
540 m_fields[0]->setMapping(base::mapping());
542 for (
size_t i = 1; i < m_fields.size(); i++) {
546 m_fields[i]->extents(), i);
547 m_fields[i]->setMapping(mapping);
554 template <
class Field_T>
558 return fastMipValue(level, i, j, k);
563 template <
class Field_T>
566 assert(level < base::m_numLevels);
567 return m_mipRes[level];
572 template <
class Field_T>
575 assert(level < base::m_numLevels);
576 return m_rawFields[level] != NULL;
581 template <
typename Field_T>
585 outVsP = vsP * m_relativeResolution[level];
590 template <
typename Field_T>
594 assert(level < base::m_numLevels);
596 if (!m_rawFields[level]) {
597 loadLevelFromDisk(level);
599 return m_fields[level];
604 template <
class Field_T>
608 assert(level < base::m_numLevels);
610 if (!m_rawFields[level]) {
611 loadLevelFromDisk(level);
614 return m_rawFields[level]->fastValue(i, j, k);
619 template <
class Field_T>
622 m_rawFields.resize(m_fields.size());
623 for (
size_t i = 0; i < m_fields.size(); i++) {
624 m_rawFields[i] = m_fields[i].get();
630 template <
class Field_T>
633 base::m_extents = field->extents();
634 base::m_dataWindow = field->dataWindow();
635 base::setMapping(field->mapping());
640 template <
class Field_T>
644 if (!m_rawFields[level]) {
645 boost::mutex::scoped_lock lock(*m_ioMutex);
646 if (!m_rawFields[level]) {
648 m_fields[level] = m_loadActions[level]->load();
650 m_loadActions[level].reset();
654 V3i baseRes = base::dataWindow().size() +
V3i(1);
657 m_fields[level]->extents(), level);
658 m_fields[level]->setMapping(mapping);
665 template <
class Field_T>
670 using boost::lexical_cast;
672 using Exc::MIPFieldException;
675 if (fields.size() == 0) {
676 throw MIPFieldException(
"Zero fields in input");
679 for (
size_t i = 0; i < fields.size(); i++) {
681 throw MIPFieldException(
"Found null pointer in input");
685 V3i prevSize = fields[0]->extents().size();
686 for (
size_t i = 1; i < fields.size(); i++) {
687 V3i size = fields[i]->extents().size();
688 if (size.x > prevSize.x ||
689 size.y > prevSize.y ||
690 size.z > prevSize.z) {
691 throw MIPFieldException(
"Field " +
692 lexical_cast<string>(i) +
693 " had greater resolution than previous"
696 if (size.x >= prevSize.x &&
697 size.y >= prevSize.y &&
698 size.z >= prevSize.z) {
699 throw MIPFieldException(
"Field " +
700 lexical_cast<string>(i) +
701 " did not decrease in resolution from "
713 template <
typename Field_T>
723 #endif // Include guard
#define FIELD3D_NAMESPACE_HEADER_CLOSE
const Field_T * rawMipLevel(const size_t level) const
Returns a raw pointer to a MIP level.
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
virtual void getVsMIPCoord(const V3f &vsP, const size_t level, V3f &outVsP) const
Given a voxel space coordinate in the 0-level field, computes the coordinate in another level...
virtual Data_T mipValue(size_t level, int i, int j, int k) const
Read access to a voxel in a given MIP level.
static NestedFieldType< MIPField< Field_T > > ms_classType
Contains the DenseField class.
Namespace for Exception objects.
EmptyField< Data_T > ProxyField
virtual void mappingChanged()
We need to know if the mapping changed so that we may update the MIP levels' mappings.
boost::intrusive_ptr< FieldBase > Ptr
virtual size_t voxelCount() const
Counts the number of voxels. For most fields, this is just the volume of the data window...
LazyLoadAction< Field_T >::Vec m_loadActions
Lazy load actions. Only used if setupLazyLoad() has been called.
void setupLazyLoad(const ProxyVec &proxies, const typename LazyLoadAction< Field_T >::Vec &actions)
Sets up the MIP field in lazy-load mode.
Contains the EmptyField class.
FieldMapping::Ptr adjustedMIPFieldMapping(const FieldMapping::Ptr baseMapping, const V3i &baseRes, const Box3i &extents, const size_t level)
boost::intrusive_ptr< FieldRes > Ptr
CubicMIPFieldInterp< Data_T > CubicInterp
void setup(const FieldVec &fields)
Sets up the MIP field given a set of non-MIP fields This call performs sanity checking to ensure that...
This subclass stores a MIP representation of a Field_T field.
boost::intrusive_ptr< MIPField > Ptr
std::vector< Field_T * > m_rawFields
Raw pointers to MIP levels.
void clear()
Clears all the levels of the MIP field.
const MIPField & operator=(const MIPField &rhs)
Assignment operator.
Contains MIPInterp class.
MIPField()
Constructs an empty MIP field.
Field_T::value_type Data_T
boost::intrusive_ptr< FieldMapping > Ptr
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
This subclass of Field does not store any data.
void updateAuxMembers() const
Updates the dependent data members based on m_field.
const MIPField & init(const MIPField &rhs)
Copies from a second MIPField.
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
std::vector< V3i > m_mipRes
Resolution of each MIP level.
boost::intrusive_ptr< EmptyField > Ptr
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
boost::shared_ptr< boost::mutex > m_ioMutex
Mutex lock around IO. Used to make sure only one thread reads MIP level data at a time...
void sanityChecks(const T &fields)
Sanity checks to ensure that the provided Fields are a MIP representation.
void updateMapping(FieldRes::Ptr field)
Updates the mapping, extents and data window to match the given field. Used so that the MIPField will...
size_t m_numLevels
Number of MIP levels. The default is 1.
#define DECLARE_FIELD3D_GENERIC_EXCEPTION(name, base_class)
Used to declare a generic but named exception.
static const char * staticClassType()
std::vector< V3f > m_relativeResolution
Relative resolution of each MIP level. Pre-computed to avoid int-to-float conversions.
void loadLevelFromDisk(size_t level) const
Loads the given level from disk.
std::vector< FieldPtr > FieldVec
virtual V3i mipResolution(size_t level) const
Returns the resolution of a given MIP level.
Contains MIP-related utility functions.
virtual long long int memSize() const
Returns the memory usage (in bytes)
Contains the SparseField class.
std::vector< FieldPtr > m_fields
Storage of all MIP levels. Some or all of the pointers may be NULL. This is mutable because it needs ...
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Data_T fastMipValue(size_t level, int i, int j, int k) const
Read access to voxel at a given MIP level.
MIPField< Field_T > class_type
Used to return a string for the name of a nested templated field.
Field_T::Ptr concreteMipLevel(const size_t level) const
Returns a concretely typed pointer to a MIP level.
virtual Field< Data_T >::Ptr mipLevel(const size_t level) const
Returns a MIP level field.
std::vector< ProxyPtr > ProxyVec
MIPLinearInterp< MIPField< Field_T > > LinearInterp
boost::intrusive_ptr< Field > Ptr
virtual bool levelLoaded(const size_t level) const
Whether a given MIP level is loaded.
std::string name
Optional name of the field.
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...