detail Namespace Reference

## Classes

struct | ComputationType
| Used to delegate the choice of bit depth to process at. More...
struct | ComputationType< Field3D::half >
| Specialization for half float. More...
struct | LoadFields
struct | LoadFields< 1 >
struct | LoadFields< 3 >
struct | LoadFieldsParams
struct | MakeDense
| MPL utility. More...
struct | MakeMIPDense
| MPL utility. More...
struct | MakeMIPSparse
| MPL utility. More...
struct | MakeSparse
| MPL utility. More...
struct | MIPSeparableThreadOp
struct | ScalarOrVector
| Typedefs float or V3f, depending on Dims_T. More...
struct | ScalarOrVector< 1 >
struct | ScalarOrVector< 3 >

## Functions

FIELD3D_API FieldMapping::Ptr | adjustedMIPFieldMapping (const FieldRes *base, const V3i &baseRes, const Box3i &extents, const size_t level)
template<typename T>
FIELD3D_VEC3_T< T > | ceil (const FIELD3D_VEC3_T< T > &v)
| Ceil function for Vec3.
template<typename Field_T>
bool | checkInputEmpty (const Field_T &, const Field_T &, const Box3i &, const float, const size_t)
| Fallback version always returns false.
template<typename Data_T>
bool | checkInputEmpty (const SparseField< Data_T > &src, const SparseField< Data_T > &, const Box3i &tgtBox, const float support, const size_t dim)
std::vector< V3d > | cornerPoints (const Box3d &box)
template<typename T>
FIELD3D_VEC3_T< T > | floor (const FIELD3D_VEC3_T< T > &v)
| Floor function for Vec3.
float | getDist (const bool doUpres, const float &srcP, const float &tgtP, const float &srcSize, const float &tgtSize)
V3f | getDist (const V3i &doUpres, const V3f &srcP, const V3f &tgtP, const V3f &srcSize, const V3f &tgtSize)
bool | intersect (const Ray3d &ray, const Box3d &box, double &outT0, double &outT1)
template<typename T, typename T2>
FIELD3D_VEC3_T< T > | max (const FIELD3D_VEC3_T< T > &a, const FIELD3D_VEC3_T< T2 > &b)
| Max operation on mixed vector types.
template<typename T, typename T2>
T | max (const T a, const T2 b)
| Max operation on mixed types.
template<typename T, typename T2>
FIELD3D_VEC3_T< T > | min (const FIELD3D_VEC3_T< T > &a, const FIELD3D_VEC3_T< T2 > &b)
| Min operation on mixed vector types.
template<typename T, typename T2>
T | min (const T a, const T2 b)
| Min operation on mixed types.
template<typename Field_T, typename FilterOp_T>
void | mipResample (const Field_T &base, const Field_T &src, Field_T &tgt, const size_t level, const V3i &offset, const FilterOp_T &filterOp, const size_t numThreads)
FIELD3D_API V3i | mipResolution (const V3i &baseRes, const size_t level, const V3i &add)
template<typename Field_T, typename FilterOp_T>
void | mipSeparable (const Field_T &src, Field_T &tgt, const V3i &oldRes, const V3i &newRes, const size_t level, const V3i &add, const FilterOp_T &filterOp, const size_t dim, const size_t numThreads)
| Threaded implementation of separable MIP filtering.
template<typename Field_T, typename FilterOp_T, bool IsAnalytic_T>
void | separable (const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filterOp, const size_t dim)
template<typename Field_T, typename FilterOp_T>
bool | separableResample (const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filterOp)
| Resamples the source field into the target field, using separable execution, which is faster than resample().
std::pair< int, int > | srcSupportBBox (const float &tgtP, const float support, const bool doUpres, const float &srcSize, const float &tgtSize)
Box3i | srcSupportBBox (const V3f &tgtP, const float support, const V3i &doUpres, const V3f &srcSize, const V3f &tgtSize)
template<typename Data_T>
size_t | threadingBlockSize (const DenseField< Data_T > &)
| Constant size for all dense fields.
template<typename Data_T>
size_t | threadingBlockSize (const SparseField< Data_T > &f)
| Use block size for sparse fields.
std::vector< V3d > | unitCornerPoints ()

## Variables

static const char * | k_maxSuffix = "_max"
static const char * | k_minSuffix = "_min"
const std::string | k_mipOffsetStr = "mipoffset"

## Function Documentation

## floor()

template<typename T>

FIELD3D_VEC3_T< T > detail::floor | ( | const FIELD3D_VEC3_T< T > & | v | ) |

Floor function for Vec3.

Definition at line 104 of file CoordSys.h.

{
return FIELD3D_VEC3_T<T>(std::floor(v.x), std::floor(v.y), std::floor(v.z));
}
FIELD3D_VEC3_T
#define FIELD3D_VEC3_T
Definition SpiMathLib.h:88

References FIELD3D_VEC3_T.

Referenced by coordinateSystem().

## ceil()

template<typename T>

FIELD3D_VEC3_T< T > detail::ceil | ( | const FIELD3D_VEC3_T< T > & | v | ) |

Ceil function for Vec3.

Definition at line 114 of file CoordSys.h.

{
return FIELD3D_VEC3_T<T>(std::ceil(v.x), std::ceil(v.y), std::ceil(v.z));
}

References FIELD3D_VEC3_T.

Referenced by coordinateSystem().

## cornerPoints()

std::vector< V3d > detail::cornerPoints | ( | const Box3d & | box | ) |

inline

Definition at line 211 of file FieldGroup.h.

{
std::vector<V3d> result;
result.push_back(V3d(box.min.x, box.min.y, box.min.z));
result.push_back(V3d(box.max.x, box.min.y, box.min.z));
result.push_back(V3d(box.min.x, box.max.y, box.min.z));
result.push_back(V3d(box.max.x, box.max.y, box.min.z));
result.push_back(V3d(box.min.x, box.min.y, box.max.z));
result.push_back(V3d(box.max.x, box.min.y, box.max.z));
result.push_back(V3d(box.min.x, box.max.y, box.max.z));
result.push_back(V3d(box.max.x, box.max.y, box.max.z));
return result;
}
V3d
Imath::V3d V3d
Definition SpiMathLib.h:74

Referenced by FieldGroup< BaseTypeList_T, Dims_T >::GetIntersections::intersectFrustumMapping().

## unitCornerPoints()

std::vector< V3d > detail::unitCornerPoints | ( |  | ) |

inline

Definition at line 228 of file FieldGroup.h.

{
std::vector<V3d> result;
result.push_back(V3d(0.0, 0.0, 0.0));
result.push_back(V3d(1.0, 0.0, 0.0));
result.push_back(V3d(0.0, 1.0, 0.0));
result.push_back(V3d(1.0, 1.0, 0.0));
result.push_back(V3d(0.0, 0.0, 1.0));
result.push_back(V3d(1.0, 0.0, 1.0));
result.push_back(V3d(0.0, 1.0, 1.0));
result.push_back(V3d(1.0, 1.0, 1.0));
return result;
}

Referenced by FieldGroup< BaseTypeList_T, Dims_T >::GetWsBounds::operator()().

## intersect()

bool detail::intersect | ( | const Ray3d & | ray,
|  | const Box3d & | box,
|  | double & | outT0,
|  | double & | outT1 )

inline

Definition at line 245 of file FieldGroup.h.

{
double tNear = -std::numeric_limits<double>::max();
double tFar = std::numeric_limits<double>::max();
const double epsilon = std::numeric_limits<double>::epsilon() * 10.0;
for (size_t dim = 0; dim < 3; ++dim) {
double t0, t1;
if (std::abs(ray.dir[dim]) < epsilon) {
// Ray is parallel, check if inside slab
if (ray.pos[dim] < box.min[dim] || ray.pos[dim] > box.max[dim]) {
return false;
}
}
t0 = (box.min[dim] - ray.pos[dim]) / ray.dir[dim];
t1 = (box.max[dim] - ray.pos[dim]) / ray.dir[dim];
if (t0 > t1) {
std::swap(t0, t1);
}
tNear = std::max(tNear, t0);
tFar = std::min(tFar, t1);
if (tNear > tFar) {
return false;
}
if (tFar < 0.0) {
return false;
}
}
outT0 = tNear;
outT1 = tFar;
return true;
}

Referenced by FieldGroup< BaseTypeList_T, Dims_T >::GetIntersections::intersectMatrixMapping().

## min() [1/2]

template<typename T, typename T2>

T detail::min | ( | const T | a,
|  | const T2 | b )

Min operation on mixed types.

Definition at line 25 of file FieldSampler.h.

{
return std::min(a, static_cast<T>(b));
}

Referenced by FieldSampler< WrapperVec_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxMIP(), and FieldSampler< WrapperVec_T, Dims_T >::getMinMaxPrefilt().

## max() [1/2]

template<typename T, typename T2>

T detail::max | ( | const T | a,
|  | const T2 | b )

Max operation on mixed types.

Definition at line 32 of file FieldSampler.h.

{
return std::max(a, static_cast<T>(b));
}

Referenced by FieldSampler< WrapperVec_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxMIP(), and FieldSampler< WrapperVec_T, Dims_T >::getMinMaxPrefilt().

## min() [2/2]

template<typename T, typename T2>

FIELD3D_VEC3_T< T > detail::min | ( | const FIELD3D_VEC3_T< T > & | a,
|  | const FIELD3D_VEC3_T< T2 > & | b )

Min operation on mixed vector types.

Definition at line 39 of file FieldSampler.h.

{
return FIELD3D_VEC3_T<T>(std::min(a.x, static_cast<T>(b.x)),
std::min(a.y, static_cast<T>(b.y)),
std::min(a.z, static_cast<T>(b.z)));
}

References FIELD3D_VEC3_T.

## max() [2/2]

template<typename T, typename T2>

FIELD3D_VEC3_T< T > detail::max | ( | const FIELD3D_VEC3_T< T > & | a,
|  | const FIELD3D_VEC3_T< T2 > & | b )

Max operation on mixed vector types.

Definition at line 49 of file FieldSampler.h.

{
return FIELD3D_VEC3_T<T>(std::max(a.x, static_cast<T>(b.x)),
std::max(a.y, static_cast<T>(b.y)),
std::max(a.z, static_cast<T>(b.z)));
}

References FIELD3D_VEC3_T.

## mipResolution()

V3i detail::mipResolution | ( | const V3i & | baseRes,
|  | const size_t | level,
|  | const V3i & | add )

Definition at line 70 of file MIPUtil.cpp.

{
const float factor = 1.0 / (1 << level);
const V3f floatRes(baseRes);
return V3i(static_cast<int>(std::ceil(floatRes.x * factor)) + add.x,
static_cast<int>(std::ceil(floatRes.y * factor)) + add.y,
static_cast<int>(std::ceil(floatRes.z * factor)) + add.z);
}
V3i
Imath::V3i V3i
Definition SpiMathLib.h:71
V3f
Imath::V3f V3f
Definition SpiMathLib.h:73

Referenced by mipResample().

## threadingBlockSize() [1/2]

template<typename Data_T>

size_t detail::threadingBlockSize | ( | const DenseField< Data_T > & |  | ) |

Constant size for all dense fields.

Definition at line 121 of file MIPUtil.h.

{
return 16;
}

Referenced by mipSeparable().

## threadingBlockSize() [2/2]

template<typename Data_T>

size_t detail::threadingBlockSize | ( | const SparseField< Data_T > & | f | ) |

Use block size for sparse fields.

Definition at line 128 of file MIPUtil.h.

{
return f.blockSize();
}
SparseField::blockSize
int blockSize() const
Returns the block size.
Definition SparseField.h:1483

References SparseField< Data_T >::blockSize().

## checkInputEmpty() [1/2]

template<typename Data_T>

bool detail::checkInputEmpty | ( | const SparseField< Data_T > & | src,
|  | const SparseField< Data_T > & | ,
|  | const Box3i & | tgtBox,
|  | const float | support,
|  | const size_t | dim )

Definition at line 136 of file MIPUtil.h.

{
const int intSupport = static_cast<int>(std::ceil(support * 0.5));
const int pad = std::max(0, intSupport);
Box3i tgtBoxPad = tgtBox;
tgtBoxPad.min[dim] -= pad;
tgtBoxPad.max[dim] += pad;
Box3i srcBoxPad = tgtBoxPad;
srcBoxPad.min[dim] *= 2;
srcBoxPad.max[dim] *= 2;
// Get the block coordinates
const Box3i dbsBounds = blockCoords(clipBounds(srcBoxPad, src.dataWindow()),
&src);
static boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
// Check all blocks
for (int k = dbsBounds.min.z; k <= dbsBounds.max.z; ++k) {
for (int j = dbsBounds.min.y; j <= dbsBounds.max.y; ++j) {
for (int i = dbsBounds.min.x; i <= dbsBounds.max.x; ++i) {
if (src.blockIsAllocated(i, j, k) ||
src.getBlockEmptyValue(i, j, k) != static_cast<Data_T>(0)) {
return false;
}
}
}
}
// No hits. Empty
return true;
}
clipBounds
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition Field.h:1145
blockCoords
Box3i blockCoords(const Box3i &dvsBounds, const SparseField< Data_T > *f)
Definition SparseField.h:676
Box3i
Imath::Box3i Box3i
Definition SpiMathLib.h:77
FieldRes::dataWindow
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
Definition Field.h:253
SparseField::getBlockEmptyValue
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..
Definition SparseField.h:1511
SparseField::blockIsAllocated
bool blockIsAllocated(int bi, int bj, int bk) const
Checks if a block is allocated.
Definition SparseField.h:1502

References blockCoords(), SparseField< Data_T >::blockIsAllocated(), clipBounds(), FieldRes::dataWindow(), and SparseField< Data_T >::getBlockEmptyValue().

Referenced by detail::MIPSeparableThreadOp< Field_T, FilterOp_T, IsAnalytic_T >::operator()().

## checkInputEmpty() [2/2]

template<typename Field_T>

bool detail::checkInputEmpty | ( | const Field_T & | ,
|  | const Field_T & | ,
|  | const Box3i & | ,
|  | const float | ,
|  | const size_t | )

Fallback version always returns false.

Definition at line 177 of file MIPUtil.h.

{
return false;
}

## mipSeparable()

template<typename Field_T, typename FilterOp_T>

void detail::mipSeparable | ( | const Field_T & | src,
|  | Field_T & | tgt,
|  | const V3i & | oldRes,
|  | const V3i & | newRes,
|  | const size_t | level,
|  | const V3i & | add,
|  | const FilterOp_T & | filterOp,
|  | const size_t | dim,
|  | const size_t | numThreads )

Threaded implementation of separable MIP filtering.

Definition at line 354 of file MIPUtil.h.

{
using namespace std;
// To ensure we don't sample outside source data
Box3i srcDw = src.dataWindow();
// Compute new res
V3i res;
if (dim == 2) {
res = newRes;
} else if (dim == 1) {
res = V3i(newRes.x, newRes.y, oldRes.z);
} else {
res = V3i(newRes.x, oldRes.y, oldRes.z);
}
// Resize new field
tgt.setSize(res);
// Determine granularity
const size_t blockSize = threadingBlockSize(src);
// Build block list
std::vector<Box3i> blocks;
for (int k = 0; k < res.z; k += blockSize) {
for (int j = 0; j < res.y; j += blockSize) {
for (int i = 0; i < res.x; i += blockSize) {
Box3i box;
// Initialize block size
box.min = V3i(i, j, k);
box.max = box.min + V3i(blockSize - 1);
// Clip against resolution
box.max.x = std::min(box.max.x, res.x - 1);
box.max.y = std::min(box.max.y, res.y - 1);
box.max.z = std::min(box.max.z, res.z - 1);
// Add to list
blocks.push_back(box);
}
}
}
// Next index counter and mutex
size_t nextIdx = 0;
boost::mutex mutex;
// Launch threads ---
boost::thread_group threads;
for (size_t i = 0; i < numThreads; ++i) {
threads.create_thread(
MIPSeparableThreadOp<Field_T, FilterOp_T, FilterOp_T::isAnalytic >
(src, tgt, level, add, filterOp,
dim, blocks, nextIdx, mutex));
}
// Join
threads.join_all();
}
detail::threadingBlockSize
size_t threadingBlockSize(const DenseField< Data_T > &)
Constant size for all dense fields.
Definition MIPUtil.h:121
detail::MIPSeparableThreadOp
Definition MIPUtil.h:188

References threadingBlockSize().

Referenced by mipResample().

## mipResample()

template<typename Field_T, typename FilterOp_T>

void detail::mipResample | ( | const Field_T & | base,
|  | const Field_T & | src,
|  | Field_T & | tgt,
|  | const size_t | level,
|  | const V3i & | offset,
|  | const FilterOp_T & | filterOp,
|  | const size_t | numThreads )

Definition at line 421 of file MIPUtil.h.

{
using std::ceil;
// Odd-numbered offsets need a pad of one in the negative directions
const V3i add((offset.x % 2 == 0) ? 0 : 1,
(offset.y % 2 == 0) ? 0 : 1,
(offset.z % 2 == 0) ? 0 : 1);
// Compute new res
const Box3i baseDw = base.dataWindow();
const V3i baseRes = baseDw.size() + V3i(1);
const V3i newRes = mipResolution(baseRes, level, add);
// Source res
const Box3i srcDw = src.dataWindow();
const V3i srcRes = srcDw.size() + V3i(1);
// Temporary field for y component
Field_T tmp;
// X axis (src into tgt)
mipSeparable(src, tgt, srcRes, newRes, level, add, filterOp, 0, numThreads);
// Y axis (tgt into temp)
mipSeparable(tgt, tmp, srcRes, newRes, level, add, filterOp, 1, numThreads);
// Z axis (temp into tgt)
mipSeparable(tmp, tgt, srcRes, newRes, level, add, filterOp, 2, numThreads);
// Update final target with mapping and metadata
tgt.name = base.name;
tgt.attribute = base.attribute;
tgt.setMapping(base.mapping());
tgt.copyMetadata(base);
}
detail::mipSeparable
void mipSeparable(const Field_T &src, Field_T &tgt, const V3i &oldRes, const V3i &newRes, const size_t level, const V3i &add, const FilterOp_T &filterOp, const size_t dim, const size_t numThreads)
Threaded implementation of separable MIP filtering.
Definition MIPUtil.h:354
detail::mipResolution
FIELD3D_API V3i mipResolution(const V3i &baseRes, const size_t level, const V3i &add)
Definition MIPUtil.cpp:70

References mipResolution(), and mipSeparable().

## adjustedMIPFieldMapping()

FieldMapping::Ptr detail::adjustedMIPFieldMapping | ( | const FieldRes * | base,
|  | const V3i & | ,
|  | const Box3i & | extents,
|  | const size_t | level )

Todo
  Update to use MIPField's mipOffset() instead of metadata

Definition at line 82 of file MIPUtil.cpp.

{
typedef MatrixFieldMapping::MatrixCurve MatrixCurve;
FieldMapping::Ptr mapping = base->mapping();
const V3i zero = V3i(0);
const V3i mipOff = base->metadata().vecIntMetadata(k_mipOffsetStr, zero);
const float mult = 1 << level;
const V3i res = extents.size() + V3i(1);
// Compute offset of current level
const V3i offset((mipOff.x >> level) << level,
(mipOff.y >> level) << level,
(mipOff.z >> level) << level);
// Difference between current offset and base offset is num voxels
// to offset current level by
const V3d diff = offset - mipOff;
if (MatrixFieldMapping::Ptr mfm =
field_dynamic_cast<MatrixFieldMapping>(mapping)) {
// Local space positions
const V3d lsOrigin(0.0), lsX(1.0, 0.0, 0.0), lsY(0.0, 1.0, 0.0),
lsZ(0.0, 0.0, 0.1);
// Find base voxel size
const V3f wsBaseVoxelSize = mfm->wsVoxelSize(0, 0, 0);
// Compute current levels' voxel size
const V3f wsVoxelSize = wsBaseVoxelSize * mult;
// Grab the matrices
const MatrixCurve::SampleVec lsToWsSamples = mfm->localToWorldSamples();
// New mapping to construct
MatrixFieldMapping::Ptr newMapping(new MatrixFieldMapping);
// For each time sample
BOOST_FOREACH (const MatrixCurve::Sample &sample, lsToWsSamples){
// Find origin and orientation vectors
V3d wsOrigin, wsX, wsY, wsZ;
mfm->localToWorld(lsOrigin, wsOrigin, sample.first);
mfm->localToWorld(lsX, wsX, sample.first);
mfm->localToWorld(lsY, wsY, sample.first);
mfm->localToWorld(lsZ, wsZ, sample.first);
// Normalize orientation vectors
wsX = (wsX - wsOrigin).normalized();
wsY = (wsY - wsOrigin).normalized();
wsZ = (wsZ - wsOrigin).normalized();
// Origin shift due to mip offset
wsOrigin += wsX * wsBaseVoxelSize.x * diff.x;
wsOrigin += wsY * wsBaseVoxelSize.y * diff.y;
wsOrigin += wsZ * wsBaseVoxelSize.z * diff.z;
// Mult by voxel size
wsX *= wsVoxelSize.x * res.x;
wsY *= wsVoxelSize.y * res.y;
wsZ *= wsVoxelSize.z * res.z;
// Construct new mapping
M44d mtx = coordinateSystem(wsX, wsY, wsZ, wsOrigin);
// Update mapping
newMapping->setLocalToWorld(sample.first, mtx);
}
// Done
return newMapping;
} else {
// For non-uniform grids, there is nothing we can do.
return mapping;
}
}
coordinateSystem
FIELD3D_NAMESPACE_OPEN FIELD3D_MTX_T< T > coordinateSystem(const FIELD3D_VEC3_T< T > &e1, const FIELD3D_VEC3_T< T > &e2, const FIELD3D_VEC3_T< T > &e3, const FIELD3D_VEC3_T< T > &origin)
Constructs a coordinate systems given a set of basis vectors and an origin.
Definition CoordSys.h:128
M44d
Imath::M44d M44d
Definition SpiMathLib.h:82
FieldBase::metadata
FieldMetadata & metadata()
accessor to the m_metadata class
Definition Field.h:155
FieldMapping::Ptr
boost::intrusive_ptr< FieldMapping > Ptr
Definition FieldMapping.h:92
FieldMetadata::vecIntMetadata
V3i vecIntMetadata(const std::string &name, const V3i &defaultVal) const
Tries to retrieve a V3i metadata value. Returns the specified default value if no metadata was found.
Definition FieldMetadata.cpp:143
FieldRes::mapping
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition Field.h:263
MatrixFieldMapping
Represents the mapping of a field by a matrix transform.
Definition FieldMapping.h:335
MatrixFieldMapping::MatrixCurve
Curve< Imath::M44d > MatrixCurve
Time-varying matrix.
Definition FieldMapping.h:343
MatrixFieldMapping::Ptr
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition FieldMapping.h:341
field_dynamic_cast
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...
Definition RefCount.h:256
detail::k_mipOffsetStr
const std::string k_mipOffsetStr
Definition MIPUtil.cpp:66

References coordinateSystem(), field_dynamic_cast(), k_mipOffsetStr, FieldRes::mapping(), FieldBase::metadata(), and FieldMetadata::vecIntMetadata().

Referenced by MIPField< Field_T >::loadLevelFromDisk(), and MIPField< Field_T >::mappingChanged().

## srcSupportBBox() [1/2]

Box3i detail::srcSupportBBox | ( | const V3f & | tgtP,
|  | const float | support,
|  | const V3i & | doUpres,
|  | const V3f & | srcSize,
|  | const V3f & | tgtSize )

Definition at line 56 of file Resample.cpp.

{
Box3i srcBox;
for (int dim = 0; dim < 3; ++dim) {
if (doUpres[dim]) {
srcBox.min[dim] =
static_cast<int>(std::floor(tgtP[dim] * tgtSize[dim] / srcSize[dim] -
support));
srcBox.max[dim] =
static_cast<int>(std::ceil(tgtP[dim] * tgtSize[dim] / srcSize[dim] +
support)) - 1;
} else {
srcBox.min[dim] =
static_cast<int>(std::floor((tgtP[dim] - support) *
tgtSize[dim] / srcSize[dim]));
srcBox.max[dim] =
static_cast<int>(std::ceil((tgtP[dim] + support) *
tgtSize[dim] / srcSize[dim]));
}
}
return srcBox;
}

Referenced by separable().

## srcSupportBBox() [2/2]

std::pair< int, int > detail::srcSupportBBox | ( | const float & | tgtP,
|  | const float | support,
|  | const bool | doUpres,
|  | const float & | srcSize,
|  | const float & | tgtSize )

Definition at line 83 of file Resample.cpp.

{
std::pair<int, int> srcInterval;
if (doUpres) {
srcInterval.first =
static_cast<int>(std::floor(tgtP * tgtSize / srcSize - support));
srcInterval.second =
static_cast<int>(std::ceil(tgtP * tgtSize / srcSize + support)) - 1;
} else {
srcInterval.first =
static_cast<int>(std::floor((tgtP - support) * tgtSize / srcSize));
srcInterval.second =
static_cast<int>(std::ceil((tgtP + support) * tgtSize / srcSize));
}
return srcInterval;
}

## getDist() [1/2]

V3f detail::getDist | ( | const V3i & | doUpres,
|  | const V3f & | srcP,
|  | const V3f & | tgtP,
|  | const V3f & | srcSize,
|  | const V3f & | tgtSize )

Definition at line 103 of file Resample.cpp.

{
V3f dist;
for (int dim = 0; dim < 3; ++dim) {
if (doUpres[dim]) {
const float tgtSrc = tgtP[dim] * tgtSize[dim] / srcSize[dim];
dist[dim] = std::abs(tgtSrc - srcP[dim]);
} else {
const float srcTgt = srcP[dim] * srcSize[dim] / tgtSize[dim];
dist[dim] = std::abs(srcTgt - tgtP[dim]);
}
}
return dist;
}

Referenced by separable().

## getDist() [2/2]

float detail::getDist | ( | const bool | doUpres,
|  | const float & | srcP,
|  | const float & | tgtP,
|  | const float & | srcSize,
|  | const float & | tgtSize )

Definition at line 121 of file Resample.cpp.

{
if (doUpres) {
const float tgtSrc = tgtP * tgtSize / srcSize;
return std::abs(tgtSrc - srcP);
} else {
const float srcTgt = srcP * srcSize / tgtSize;
return std::abs(srcTgt - tgtP);
}
}

## separable()

template<typename Field_T, typename FilterOp_T, bool IsAnalytic_T>

void detail::separable | ( | const Field_T & | src,
|  | Field_T & | tgt,
|  | const V3i & | newRes,
|  | const FilterOp_T & | filterOp,
|  | const size_t | dim )

Definition at line 410 of file Resample.h.

{
typedef typename Field_T::value_type T;
const V3i srcRes = src.dataWindow().size() + V3i(1);
const float srcDomain = V3f(srcRes)[dim];
const float tgtDomain = V3f(newRes)[dim];
const float srcSize = 1.0 / srcDomain;
const float tgtSize = 1.0 / tgtDomain;
// Filter info
const float support = filterOp.support();
// Check if we're up-res'ing
const bool doUpres = newRes[dim] > srcRes[dim] ? 1 : 0;
// Resize the target
tgt.setSize(newRes);
// For each output voxel
for (int k = 0; k < newRes.z; ++k) {
for (int j = 0; j < newRes.y; ++j) {
for (int i = 0; i < newRes.x; ++i) {
T accumValue(filterOp.initialValue());
if (IsAnalytic_T) {
// Current position in target coordinates
const float tgtP = discToCont(V3i(i, j ,k)[dim]);
// Transform support to source coordinates
std::pair<int, int> srcInterval =
srcSupportBBox(tgtP, support, doUpres, srcSize, tgtSize);
// Clip against new data window
srcInterval.first =
std::max(srcInterval.first, src.dataWindow().min[dim]);
srcInterval.second =
std::min(srcInterval.second, src.dataWindow().max[dim]);
// For each input voxel
for (int s = srcInterval.first; s <= srcInterval.second; ++s) {
// Index
const int xIdx = dim == 0 ? s : i;
const int yIdx = dim == 1 ? s : j;
const int zIdx = dim == 2 ? s : k;
// Value
const T value = src.fastValue(xIdx, yIdx, zIdx);
// Weights
const float srcP = discToCont(V3i(xIdx, yIdx, zIdx)[dim]);
const float dist = getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
const float weight = filterOp.eval(dist);
// Update
if (weight > 0.0f) {
FilterOp_T::op(accumValue, value);
}
}
// Update final value
if (accumValue != static_cast<T>(filterOp.initialValue())) {
tgt.fastLValue(i, j, k) = accumValue;
}
} else {
float accumWeight = 0.0f;
// Current position in target coordinates
const float tgtP = discToCont(V3i(i, j ,k)[dim]);
// Transform support to source coordinates
std::pair<int, int> srcInterval =
srcSupportBBox(tgtP, support, doUpres, srcSize, tgtSize);
// Clip against new data window
srcInterval.first =
std::max(srcInterval.first, src.dataWindow().min[dim]);
srcInterval.second =
std::min(srcInterval.second, src.dataWindow().max[dim]);
// For each input voxel
for (int s = srcInterval.first; s <= srcInterval.second; ++s) {
// Index
const int xIdx = dim == 0 ? s : i;
const int yIdx = dim == 1 ? s : j;
const int zIdx = dim == 2 ? s : k;
// Value
const T value = src.fastValue(xIdx, yIdx, zIdx);
// Weights
const float srcP = discToCont(V3i(xIdx, yIdx, zIdx)[dim]);
const float dist = getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
const float weight = filterOp.eval(dist);
// Update
accumWeight += weight;
accumValue += value * weight;
}
// Update final value
if (accumWeight > 0.0f && accumValue != static_cast<T>(0.0)) {
tgt.fastLValue(i, j, k) = accumValue / accumWeight;
}
}
}
}
}
}
discToCont
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel.
Definition Field.h:1070
detail::srcSupportBBox
Box3i srcSupportBBox(const V3f &tgtP, const float support, const V3i &doUpres, const V3f &srcSize, const V3f &tgtSize)
Definition Resample.cpp:56
detail::getDist
V3f getDist(const V3i &doUpres, const V3f &srcP, const V3f &tgtP, const V3f &srcSize, const V3f &tgtSize)
Definition Resample.cpp:103

References discToCont(), getDist(), and srcSupportBBox().

Referenced by separableResample().

## separableResample()

template<typename Field_T, typename FilterOp_T>

bool detail::separableResample | ( | const Field_T & | src,
|  | Field_T & | tgt,
|  | const V3i & | newRes,
|  | const FilterOp_T & | filterOp )

Resamples the source field into the target field, using separable execution, which is faster than resample().

Note
  The extents of the field will be reset to match the data window.

Definition at line 511 of file Resample.h.

{
using namespace detail;
typedef typename Field_T::value_type T;
if (!src.dataWindow().hasVolume()) {
return false;
}
if (src.dataWindow().min != V3i(0)) {
return false;
}
// Temporary field for y component
Field_T tmp;
// Cache the old resolution
V3i oldRes = src.dataWindow().size() + V3i(1);
V3i xRes(newRes.x, oldRes.y, oldRes.z);
V3i yRes(newRes.x, newRes.y, oldRes.z);
V3i zRes(newRes.x, newRes.y, newRes.z);
// X axis (src into tgt)
separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(src, tgt, xRes, filterOp, 0);
// Y axis (tgt into temp)
separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tgt, tmp, yRes, filterOp, 1);
// Z axis (temp into tgt)
separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tmp, tgt, zRes, filterOp, 2);
// Update final target with mapping and metadata
tgt.name = src.name;
tgt.attribute = src.attribute;
tgt.setMapping(src.mapping());
tgt.copyMetadata(src);
return true;
}
detail
Definition CoordSys.h:97
detail::separable
void separable(const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filterOp, const size_t dim)
Definition Resample.h:410

References separable().

Referenced by resample().

## Variable Documentation

## k_minSuffix

const char* detail::k_minSuffix = "_min"

static

Definition at line 61 of file FieldGroup.h.

Referenced by detail::LoadFields< 1 >::operator()(), and detail::LoadFields< 3 >::operator()().

## k_maxSuffix

const char* detail::k_maxSuffix = "_max"

static

Definition at line 62 of file FieldGroup.h.

Referenced by detail::LoadFields< 1 >::operator()(), and detail::LoadFields< 3 >::operator()().

## k_mipOffsetStr

const std::string detail::k_mipOffsetStr = "mipoffset"

Definition at line 66 of file MIPUtil.cpp.

Referenced by adjustedMIPFieldMapping(), MIPField< Field_T >::mappingChanged(), and MIPBase< Data_T >::setMIPOffset().