44#ifndef _INCLUDED_MIPField_H_
45#define _INCLUDED_MIPField_H_
49#include <boost/lexical_cast.hpp>
50#include <boost/thread/mutex.hpp>
108template <
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;
288 template <
typename T>
297template <
typename Data_T>
309template <
typename Data_T>
323template <
class Field_T>
333template <
class Field_T>
342template <
class Field_T>
346 base::operator=(
rhs);
352template <
class Field_T>
360 m_mipRes =
rhs.m_mipRes;
361 m_relativeResolution =
rhs.m_relativeResolution;
364 m_fields.resize(
rhs.m_fields.size());
365 m_rawFields.resize(
rhs.m_rawFields.size());
366 for (
size_t i = 0, end = m_fields.size();
i < end; ++
i) {
368 if (
rhs.m_fields[
i]) {
374 std::cerr <<
"MIPField::op=(): Failed to clone." << std::endl;
378 m_rawFields[
i] = m_fields[
i].get();
381 m_ioMutex.reset(
new boost::mutex);
388template <
class Field_T>
393 base::m_numLevels = 0;
394 base::m_lowestLevel = 0;
399template <
class Field_T>
405 sanityChecks(fields);
408 base::m_numLevels = fields.size();
409 base::m_lowestLevel = 0;
410 updateMapping(fields[0]);
413 m_mipRes.resize(base::m_numLevels);
414 m_relativeResolution.resize(base::m_numLevels);
416 for (
size_t i = 0;
i < fields.size();
i++) {
418 m_mipRes[
i] = m_fields[
i]->extents().size() +
V3i(1);
420 m_relativeResolution[
i] =
V3f(m_mipRes[
i]) / m_mipRes[0];
426template <
class Field_T>
444 base::m_numLevels =
proxies.size();
445 base::m_lowestLevel = 0;
446 m_fields.resize(base::m_numLevels);
450 m_mipRes.resize(base::m_numLevels);
451 m_relativeResolution.resize(base::m_numLevels);
456 m_relativeResolution[
i] =
V3f(m_mipRes[
i]) / m_mipRes[0];
464template <
class Field_T>
470 if (!m_rawFields[
level]) {
471 loadLevelFromDisk(
level);
473 return m_fields[
level];
479template <
class Field_T>
485 if (!m_rawFields[
level]) {
486 loadLevelFromDisk(
level);
489 return m_rawFields[
level];
494template <
class Field_T>
500 if (!m_rawFields[
level]) {
501 loadLevelFromDisk(
level);
504 return m_fields[
level];
509template <
class Field_T>
513 return fastMipValue(0,
i,
j,
k);
518template <
class Field_T>
523 for (
size_t i = 0;
i < m_fields.size();
i++) {
525 count += m_fields[
i]->voxelCount();
533template <
class Field_T>
536 long long int mem = 0;
537 for (
size_t i = 0;
i < m_fields.size();
i++) {
539 mem += m_fields[
i]->memSize();
542 return mem +
sizeof(*this);
547template <
class Field_T>
553 base::setMIPOffset(
offset);
557 m_fields[0]->setMapping(base::mapping());
559 for (
size_t i = 1;
i < m_fields.size();
i++) {
563 m_fields[
i]->extents(),
i);
564 m_fields[
i]->setMapping(mapping);
571template <
class Field_T>
575 return fastMipValue(
level,
i,
j,
k);
580template <
class Field_T>
584 return m_mipRes[
level];
589template <
class Field_T>
598template <
typename Field_T>
619template <
typename Field_T>
625 if (!m_rawFields[
level]) {
626 loadLevelFromDisk(
level);
629 return m_fields[
level];
634template <
class Field_T>
640 if (!m_rawFields[
level]) {
641 loadLevelFromDisk(
level);
644 return m_rawFields[
level]->fastValue(
i,
j,
k);
649template <
class Field_T>
652 m_rawFields.resize(m_fields.size());
653 for (
size_t i = 0;
i < m_fields.size();
i++) {
654 m_rawFields[
i] = m_fields[
i].get();
660template <
class Field_T>
666 m_fields[
level]->name = base::name;
667 m_fields[
level]->attribute = base::attribute;
669 m_fields[
level]->copyMetadata(*
this);
674template <
class Field_T>
677 base::m_extents = field->extents();
678 base::m_dataWindow = field->dataWindow();
679 base::setMapping(field->mapping());
684template <
class Field_T>
688 if (!m_rawFields[
level]) {
689 boost::mutex::scoped_lock lock(*m_ioMutex);
690 if (!m_rawFields[
level]) {
692 m_fields[
level] = m_loadActions[
level]->load();
694 if (!m_fields[
level]) {
695 throw Exc::MIPFieldException(
"Couldn't load MIP level: " +
696 boost::lexical_cast<std::string>(
level));
699 m_loadActions[
level].reset();
703 syncLevelInfo(
level);
709 m_fields[
level]->setMapping(mapping);
716template <
class Field_T>
721 using boost::lexical_cast;
723 using Exc::MIPFieldException;
726 if (fields.size() == 0) {
730 for (
size_t i = 0;
i < fields.size();
i++) {
737 for (
size_t i = 1;
i < fields.size();
i++) {
738 V3i size = fields[
i]->extents().size();
743 " had greater resolution than previous"
750 " did not decrease in resolution from "
751 " previous level: " +
764template <
typename Field_T>
Contains the DenseField class.
Contains the EmptyField class.
#define DECLARE_FIELD3D_GENERIC_EXCEPTION(name, base_class)
Used to declare a generic but named exception.
Contains MIPInterp class.
Contains MIP-related utility functions.
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Contains the SparseField class.
This subclass of Field does not store any data.
boost::intrusive_ptr< EmptyField > Ptr
boost::intrusive_ptr< FieldBase > Ptr
std::string name
Optional name of the field.
boost::intrusive_ptr< FieldMapping > Ptr
boost::intrusive_ptr< FieldRes > Ptr
boost::intrusive_ptr< Field > Ptr
size_t m_numLevels
Number of MIP levels. The default is 1.
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
This subclass stores a MIP representation of a Field_T field.
const Field_T * rawMipLevel(const size_t level) const
Returns a raw pointer to a MIP level.
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....
EmptyField< Data_T > ProxyField
virtual Data_T mipValue(size_t level, int i, int j, int k) const
Read access to a voxel in a given MIP level.
boost::intrusive_ptr< MIPField > Ptr
void syncLevelInfo(const size_t level) const
Updates the name, attribute and metadata for a given level.
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.
static NestedFieldType< MIPField< Field_T > > ms_classType
virtual bool levelLoaded(const size_t level) const
Whether a given MIP level is loaded.
MIPField()
Constructs an empty MIP field.
std::vector< FieldPtr > FieldVec
void updateMapping(FieldRes::Ptr field)
Updates the mapping, extents and data window to match the given field. Used so that the MIPField will...
MIPField< Field_T > class_type
virtual long long int memSize() const
Returns the memory usage (in bytes)
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
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...
CubicMIPFieldInterp< Data_T > CubicInterp
virtual Field< Data_T >::Ptr mipLevel(const size_t level) const
Returns a MIP level field.
Field_T::value_type Data_T
void loadLevelFromDisk(size_t level) const
Loads the given level from disk.
virtual void mappingChanged()
We need to know if the mapping changed so that we may update the MIP levels' mappings.
MIPLinearInterp< MIPField< Field_T > > LinearInterp
Field_T::Ptr concreteMipLevel(const size_t level) const
Returns a concretely typed pointer to a MIP level.
Data_T fastMipValue(size_t level, int i, int j, int k) const
Read access to voxel at a given MIP level.
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
virtual size_t voxelCount() const
Counts the number of voxels. For most fields, this is just the volume of the data window,...
void clear()
Clears all the levels of the MIP field.
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
virtual V3i mipResolution(size_t level) const
Returns the resolution of a given MIP level.
void setupLazyLoad(const ProxyVec &proxies, const typename LazyLoadAction< Field_T >::Vec &actions)
Sets up the MIP field in lazy-load mode.
void updateAuxMembers() const
Updates the dependent data members based on m_field.
std::vector< V3i > m_mipRes
Resolution of each MIP level.
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< ProxyPtr > ProxyVec
void sanityChecks(const T &fields)
Sanity checks to ensure that the provided Fields are a MIP representation.
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 ...
const MIPField & init(const MIPField &rhs)
Copies from a second MIPField.
static const char * staticClassType()
MIPField(const MIPField &other)
Copy constructor. We need this because a) we own a mutex and b) we own shared pointers and shallow co...
LazyLoadAction< Field_T >::Vec m_loadActions
Lazy load actions. Only used if setupLazyLoad() has been called.
std::vector< Field_T * > m_rawFields
Raw pointers to MIP levels.
const MIPField & operator=(const MIPField &rhs)
Assignment operator.
std::vector< V3f > m_relativeResolution
Relative resolution of each MIP level. Pre-computed to avoid int-to-float conversions.
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
Namespace for Exception objects.
const std::string k_mipOffsetStr
FIELD3D_API FieldMapping::Ptr adjustedMIPFieldMapping(const FieldRes *base, const V3i &baseRes, const Box3i &extents, const size_t level)
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Used to return a string for the name of a nested templated field.