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>
352template <
class Field_T>
366 for (
size_t i = 0, end =
m_fields.size(); i < end; ++i) {
374 std::cerr <<
"MIPField::op=(): Failed to clone." << std::endl;
388template <
class Field_T>
399template <
class Field_T>
416 for (
size_t i = 0; i < fields.size(); i++) {
426template <
class Field_T>
436 if (proxies.size() != actions.size()) {
437 throw MIPFieldException(
"Incorrect number of lazy load actions");
452 for (
size_t i = 0; i < proxies.size(); i++) {
454 m_mipRes[i] = proxies[i]->extents().size() +
V3i(1);
464template <
class Field_T>
468 assert(level < base::m_numLevels);
470 if (!m_rawFields[level]) {
471 loadLevelFromDisk(level);
473 return m_fields[level];
479template <
class Field_T>
494template <
class Field_T>
509template <
class Field_T>
518template <
class Field_T>
523 for (
size_t i = 0; i <
m_fields.size(); i++) {
533template <
class Field_T>
536 long long int mem = 0;
537 for (
size_t i = 0; i <
m_fields.size(); i++) {
542 return mem +
sizeof(*this);
547template <
class Field_T>
559 for (
size_t i = 1; i <
m_fields.size(); i++) {
571template <
class Field_T>
580template <
class Field_T>
589template <
class Field_T>
598template <
typename Field_T>
605 const V3i offset((mipOff.x >> level) << level,
606 (mipOff.y >> level) << level,
607 (mipOff.z >> level) << level);
611 const V3f diff = offset - mipOff;
614 outVsP = (vsP - diff) * pow(2.0, -
static_cast<float>(level));
619template <
typename Field_T>
634template <
class Field_T>
649template <
class Field_T>
653 for (
size_t i = 0; i <
m_fields.size(); i++) {
660template <
class Field_T>
669 m_fields[level]->copyMetadata(*
this);
674template <
class Field_T>
684template <
class Field_T>
689 boost::mutex::scoped_lock lock(*
m_ioMutex);
695 throw Exc::MIPFieldException(
"Couldn't load MIP level: " +
696 boost::lexical_cast<std::string>(level));
716template <
class Field_T>
721 using boost::lexical_cast;
723 using Exc::MIPFieldException;
726 if (fields.size() == 0) {
727 throw MIPFieldException(
"Zero fields in input");
730 for (
size_t i = 0; i < fields.size(); i++) {
732 throw MIPFieldException(
"Found null pointer in input");
736 V3i prevSize = fields[0]->extents().size();
737 for (
size_t i = 1; i < fields.size(); i++) {
738 V3i size = fields[i]->extents().size();
739 if (size.x > prevSize.x ||
740 size.y > prevSize.y ||
741 size.z > prevSize.z) {
742 throw MIPFieldException(
"Field " + lexical_cast<string>(i) +
743 " had greater resolution than previous"
746 if (size.x >= prevSize.x &&
747 size.y >= prevSize.y &&
748 size.z >= prevSize.z) {
749 throw MIPFieldException(
"Field " + lexical_cast<string>(i) +
750 " did not decrease in resolution from "
751 " previous level: " +
752 lexical_cast<string>(size) +
" > " +
753 lexical_cast<string>(prevSize));
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
FieldMetadata & metadata()
accessor to the m_metadata class
std::string attribute
Optional name of the attribute the field represents.
std::string name
Optional name of the field.
boost::intrusive_ptr< FieldMapping > Ptr
Box3i m_extents
Defines the extents of the the storage. This may be larger or smaller than the data window,...
void setMapping(FieldMapping::Ptr mapping)
Sets the field's mapping.
boost::intrusive_ptr< FieldRes > Ptr
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Box3i m_dataWindow
Defines the area where data is allocated. This should be treated as a closed (i.e....
const Box3i & extents() const
Returns the extents of the data. This signifies the relevant area that the data exists over....
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
boost::intrusive_ptr< Field > Ptr
const V3i & mipOffset() const
Returns the base MIP offset.
size_t m_lowestLevel
The lowest MIP level to use. Defaults to 0, but can be set higher to prevent high resolution levels f...
size_t m_numLevels
Number of MIP levels. The default is 1.
void setMIPOffset(const V3i &offset)
Sets the base MIP offset. This is used to indicate where voxel space coordinate (0,...
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.
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
static NestedFieldType< MIPField< Field_T > > ms_classType
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...
RefBase & operator=(const RefBase &)
Assignment operator.
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...
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.