Field3D
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. More...
 
template<typename Field_T >
bool checkInputEmpty (const Field_T &, const Field_T &, const Box3i &, const float, const size_t)
 Fallback version always returns false. More...
 
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< V3dcornerPoints (const Box3d &box)
 
template<typename T >
FIELD3D_VEC3_T< T > floor (const FIELD3D_VEC3_T< T > &v)
 Floor function for Vec3. More...
 
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. More...
 
template<typename T , typename T2 >
max (const T a, const T2 b)
 Max operation on mixed types. More...
 
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. More...
 
template<typename T , typename T2 >
min (const T a, const T2 b)
 Min operation on mixed types. More...
 
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. More...
 
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(). More...
 
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. More...
 
template<typename Data_T >
size_t threadingBlockSize (const SparseField< Data_T > &f)
 Use block size for sparse fields. More...
 
std::vector< V3dunitCornerPoints ()
 

Variables

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

Function Documentation

◆ floor()

◆ 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.

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

Referenced by checkInputEmpty(), discreteBounds(), mipResample(), mipResolution(), detail::MIPSeparableThreadOp< Field_T, FilterOp_T, IsAnalytic_T >::operator()(), SparseField< Data_T >::setupBlocks(), and srcSupportBBox().

◆ cornerPoints()

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

Definition at line 211 of file FieldGroup.h.

212 {
213  std::vector<V3d> result;
214  result.push_back(V3d(box.min.x, box.min.y, box.min.z));
215  result.push_back(V3d(box.max.x, box.min.y, box.min.z));
216  result.push_back(V3d(box.min.x, box.max.y, box.min.z));
217  result.push_back(V3d(box.max.x, box.max.y, box.min.z));
218  result.push_back(V3d(box.min.x, box.min.y, box.max.z));
219  result.push_back(V3d(box.max.x, box.min.y, box.max.z));
220  result.push_back(V3d(box.min.x, box.max.y, box.max.z));
221  result.push_back(V3d(box.max.x, box.max.y, box.max.z));
222  return result;
223 }

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

◆ unitCornerPoints()

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

Definition at line 228 of file FieldGroup.h.

229 {
230  std::vector<V3d> result;
231  result.push_back(V3d(0.0, 0.0, 0.0));
232  result.push_back(V3d(1.0, 0.0, 0.0));
233  result.push_back(V3d(0.0, 1.0, 0.0));
234  result.push_back(V3d(1.0, 1.0, 0.0));
235  result.push_back(V3d(0.0, 0.0, 1.0));
236  result.push_back(V3d(1.0, 0.0, 1.0));
237  result.push_back(V3d(0.0, 1.0, 1.0));
238  result.push_back(V3d(1.0, 1.0, 1.0));
239  return result;
240 }

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.

246 {
247  double tNear = -std::numeric_limits<double>::max();
248  double tFar = std::numeric_limits<double>::max();
249  const double epsilon = std::numeric_limits<double>::epsilon() * 10.0;
250 
251  for (size_t dim = 0; dim < 3; ++dim) {
252  double t0, t1;
253  if (std::abs(ray.dir[dim]) < epsilon) {
254  // Ray is parallel, check if inside slab
255  if (ray.pos[dim] < box.min[dim] || ray.pos[dim] > box.max[dim]) {
256  return false;
257  }
258  }
259  t0 = (box.min[dim] - ray.pos[dim]) / ray.dir[dim];
260  t1 = (box.max[dim] - ray.pos[dim]) / ray.dir[dim];
261  if (t0 > t1) {
262  std::swap(t0, t1);
263  }
264  tNear = std::max(tNear, t0);
265  tFar = std::min(tFar, t1);
266  if (tNear > tFar) {
267  return false;
268  }
269  if (tFar < 0.0) {
270  return false;
271  }
272  }
273  outT0 = tNear;
274  outT1 = tFar;
275  return true;
276 }

References max(), and min().

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.

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

References min().

Referenced by DenseField< Data_T >::begin(), WritableField< Data_T >::begin(), SparseField< Data_T >::begin(), DenseField< Data_T >::cbegin(), SparseField< Data_T >::cbegin(), DenseField< Data_T >::cend(), SparseField< Data_T >::cend(), clampForType(), clipBounds(), DenseField< Data_T >::end(), WritableField< Data_T >::end(), SparseField< Data_T >::end(), DenseField< Data_T >::fastLValue(), SparseField< Data_T >::fastLValue(), DenseField< Data_T >::fastValue(), SparseField< Data_T >::fastValue(), SparseField< Data_T >::getGrainBounds(), FieldGroup< BaseTypeList_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxMIP(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxPrefilt(), intersect(), FieldGroup< BaseTypeList_T, Dims_T >::GetIntersections::intersectFrustumMapping(), FieldGroup< BaseTypeList_T, Dims_T >::GetIntersections::intersectMatrixMapping(), EmptyField< Data_T >::lvalue(), makeMinMax(), MIPLinearInterp< MIPField_T >::MIPLinearInterp(), mipSeparable(), MinFilter::op(), detail::MIPSeparableThreadOp< Field_T, FilterOp_T, IsAnalytic_T >::operator()(), SparseFile::Reference< Data_T >::operator=(), LinearFieldInterp< Data_T >::sample(), CubicFieldInterp< Data_T >::sample(), LinearGenericFieldInterp< Field_T >::sample(), CubicGenericFieldInterp< Field_T >::sample(), LinearMACFieldInterp< Data_T >::sample(), CubicMACFieldInterp< Data_T >::sample(), LinearSparseFieldInterp< Data_T >::sample(), separable(), SparseFile::Reference< Data_T >::setNumBlocks(), DenseField< Data_T >::sizeChanged(), MACField< Data_T >::sizeChanged(), MACField< Data_T >::u(), MACField< Data_T >::v(), EmptyField< Data_T >::value(), MACField< Data_T >::w(), and FrustumFieldMapping::wsVoxelSize().

◆ 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.

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

References max().

Referenced by SparseFile::Reference< Data_T >::averageLoads(), SparseFileManager::cacheEfficiency(), SparseFileManager::cacheFractionLoaded(), SparseFileManager::cacheLoadsPerBlock(), checkInputEmpty(), clampForType(), clipBounds(), GaussianFilter::eval(), DenseField< Data_T >::fastLValue(), SparseField< Data_T >::fastLValue(), DenseField< Data_T >::fastValue(), SparseField< Data_T >::fastValue(), FieldGroup< BaseTypeList_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMax(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxMIP(), FieldSampler< WrapperVec_T, Dims_T >::getMinMaxPrefilt(), MinFilter::initialValue(), MaxFilter::initialValue(), intersect(), FieldGroup< BaseTypeList_T, Dims_T >::GetIntersections::intersectFrustumMapping(), EmptyField< Data_T >::lvalue(), makeMinMax(), MaxFilter::op(), detail::MIPSeparableThreadOp< Field_T, FilterOp_T, IsAnalytic_T >::operator()(), LinearFieldInterp< Data_T >::sample(), CubicFieldInterp< Data_T >::sample(), LinearGenericFieldInterp< Field_T >::sample(), CubicGenericFieldInterp< Field_T >::sample(), LinearMACFieldInterp< Data_T >::sample(), CubicMACFieldInterp< Data_T >::sample(), LinearSparseFieldInterp< Data_T >::sample(), separable(), FieldWrapper< Field_T >::setOsToWs(), MIPFieldWrapper< Field_T >::setOsToWs(), DenseField< Data_T >::sizeChanged(), MACField< Data_T >::u(), MACField< Data_T >::v(), EmptyField< Data_T >::value(), MACField< Data_T >::w(), and FrustumFieldMapping::wsVoxelSize().

◆ 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.

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

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

◆ 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.

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

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

◆ mipResolution()

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

Definition at line 70 of file MIPUtil.cpp.

71  {
72  const float factor = 1.0 / (1 << level);
73  const V3f floatRes(baseRes);
74  return V3i(static_cast<int>(std::ceil(floatRes.x * factor)) + add.x,
75  static_cast<int>(std::ceil(floatRes.y * factor)) + add.y,
76  static_cast<int>(std::ceil(floatRes.z * factor)) + add.z);
77  }

References ceil().

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.

122  {
123  return 16;
124  }

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.

129  {
130  return f.blockSize();
131  }

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.

140  {
141  const int intSupport = static_cast<int>(std::ceil(support * 0.5));
142  const int pad = std::max(0, intSupport);
143  Box3i tgtBoxPad = tgtBox;
144  tgtBoxPad.min[dim] -= pad;
145  tgtBoxPad.max[dim] += pad;
146  Box3i srcBoxPad = tgtBoxPad;
147  srcBoxPad.min[dim] *= 2;
148  srcBoxPad.max[dim] *= 2;
149 
150  // Get the block coordinates
151  const Box3i dbsBounds = blockCoords(clipBounds(srcBoxPad, src.dataWindow()),
152  &src);
153 
154  static boost::mutex mutex;
155  boost::mutex::scoped_lock lock(mutex);
156 
157  // Check all blocks
158  for (int k = dbsBounds.min.z; k <= dbsBounds.max.z; ++k) {
159  for (int j = dbsBounds.min.y; j <= dbsBounds.max.y; ++j) {
160  for (int i = dbsBounds.min.x; i <= dbsBounds.max.x; ++i) {
161  if (src.blockIsAllocated(i, j, k) ||
162  src.getBlockEmptyValue(i, j, k) != static_cast<Data_T>(0)) {
163  return false;
164  }
165  }
166  }
167  }
168 
169  // No hits. Empty
170  return true;
171  }

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

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.

180  {
181  return false;
182  }

◆ 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.

358  {
359  using namespace std;
360 
361  // To ensure we don't sample outside source data
362  Box3i srcDw = src.dataWindow();
363 
364  // Compute new res
365  V3i res;
366  if (dim == 2) {
367  res = newRes;
368  } else if (dim == 1) {
369  res = V3i(newRes.x, newRes.y, oldRes.z);
370  } else {
371  res = V3i(newRes.x, oldRes.y, oldRes.z);
372  }
373 
374  // Resize new field
375  tgt.setSize(res);
376 
377  // Determine granularity
378  const size_t blockSize = threadingBlockSize(src);
379 
380  // Build block list
381  std::vector<Box3i> blocks;
382  for (int k = 0; k < res.z; k += blockSize) {
383  for (int j = 0; j < res.y; j += blockSize) {
384  for (int i = 0; i < res.x; i += blockSize) {
385  Box3i box;
386  // Initialize block size
387  box.min = V3i(i, j, k);
388  box.max = box.min + V3i(blockSize - 1);
389  // Clip against resolution
390  box.max.x = std::min(box.max.x, res.x - 1);
391  box.max.y = std::min(box.max.y, res.y - 1);
392  box.max.z = std::min(box.max.z, res.z - 1);
393  // Add to list
394  blocks.push_back(box);
395  }
396  }
397  }
398 
399  // Next index counter and mutex
400  size_t nextIdx = 0;
401  boost::mutex mutex;
402 
403  // Launch threads ---
404 
405  boost::thread_group threads;
406 
407  for (size_t i = 0; i < numThreads; ++i) {
408  threads.create_thread(
409  MIPSeparableThreadOp<Field_T, FilterOp_T, FilterOp_T::isAnalytic >
410  (src, tgt, level, add, filterOp,
411  dim, blocks, nextIdx, mutex));
412  }
413 
414  // Join
415  threads.join_all();
416  }

References min(), and 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.

425  {
426  using std::ceil;
427 
428  // Odd-numbered offsets need a pad of one in the negative directions
429  const V3i add((offset.x % 2 == 0) ? 0 : 1,
430  (offset.y % 2 == 0) ? 0 : 1,
431  (offset.z % 2 == 0) ? 0 : 1);
432 
433  // Compute new res
434  const Box3i baseDw = base.dataWindow();
435  const V3i baseRes = baseDw.size() + V3i(1);
436  const V3i newRes = mipResolution(baseRes, level, add);
437 
438  // Source res
439  const Box3i srcDw = src.dataWindow();
440  const V3i srcRes = srcDw.size() + V3i(1);
441 
442  // Temporary field for y component
443  Field_T tmp;
444 
445  // X axis (src into tgt)
446  mipSeparable(src, tgt, srcRes, newRes, level, add, filterOp, 0, numThreads);
447  // Y axis (tgt into temp)
448  mipSeparable(tgt, tmp, srcRes, newRes, level, add, filterOp, 1, numThreads);
449  // Z axis (temp into tgt)
450  mipSeparable(tmp, tgt, srcRes, newRes, level, add, filterOp, 2, numThreads);
451 
452  // Update final target with mapping and metadata
453  tgt.name = base.name;
454  tgt.attribute = base.attribute;
455  tgt.setMapping(base.mapping());
456  tgt.copyMetadata(base);
457  }

References ceil(), mipResolution(), and mipSeparable().

Referenced by makeMIP().

◆ 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.

86  {
87  typedef MatrixFieldMapping::MatrixCurve MatrixCurve;
88 
89  FieldMapping::Ptr mapping = base->mapping();
90 
91  const V3i zero = V3i(0);
92  const V3i mipOff = base->metadata().vecIntMetadata(k_mipOffsetStr, zero);
93  const float mult = 1 << level;
94  const V3i res = extents.size() + V3i(1);
95 
96  // Compute offset of current level
97  const V3i offset((mipOff.x >> level) << level,
98  (mipOff.y >> level) << level,
99  (mipOff.z >> level) << level);
100 
101  // Difference between current offset and base offset is num voxels
102  // to offset current level by
103  const V3d diff = offset - mipOff;
104 
105  if (MatrixFieldMapping::Ptr mfm =
106  field_dynamic_cast<MatrixFieldMapping>(mapping)) {
107  // Local space positions
108  const V3d lsOrigin(0.0), lsX(1.0, 0.0, 0.0), lsY(0.0, 1.0, 0.0),
109  lsZ(0.0, 0.0, 0.1);
110  // Find base voxel size
111  const V3f wsBaseVoxelSize = mfm->wsVoxelSize(0, 0, 0);
112  // Compute current levels' voxel size
113  const V3f wsVoxelSize = wsBaseVoxelSize * mult;
114  // Grab the matrices
115  const MatrixCurve::SampleVec lsToWsSamples = mfm->localToWorldSamples();
116  // New mapping to construct
118  // For each time sample
119  BOOST_FOREACH (const MatrixCurve::Sample &sample, lsToWsSamples){
120  // Find origin and orientation vectors
121  V3d wsOrigin, wsX, wsY, wsZ;
122  mfm->localToWorld(lsOrigin, wsOrigin, sample.first);
123  mfm->localToWorld(lsX, wsX, sample.first);
124  mfm->localToWorld(lsY, wsY, sample.first);
125  mfm->localToWorld(lsZ, wsZ, sample.first);
126  // Normalize orientation vectors
127  wsX = (wsX - wsOrigin).normalized();
128  wsY = (wsY - wsOrigin).normalized();
129  wsZ = (wsZ - wsOrigin).normalized();
130  // Origin shift due to mip offset
131  wsOrigin += wsX * wsBaseVoxelSize.x * diff.x;
132  wsOrigin += wsY * wsBaseVoxelSize.y * diff.y;
133  wsOrigin += wsZ * wsBaseVoxelSize.z * diff.z;
134  // Mult by voxel size
135  wsX *= wsVoxelSize.x * res.x;
136  wsY *= wsVoxelSize.y * res.y;
137  wsZ *= wsVoxelSize.z * res.z;
138  // Construct new mapping
139  M44d mtx = coordinateSystem(wsX, wsY, wsZ, wsOrigin);
140  // Update mapping
141  newMapping->setLocalToWorld(sample.first, mtx);
142  }
143  // Done
144  return newMapping;
145  } else {
146  // For non-uniform grids, there is nothing we can do.
147  return mapping;
148  }
149  }

References coordinateSystem(), 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.

58  {
59  Box3i srcBox;
60  for (int dim = 0; dim < 3; ++dim) {
61  if (doUpres[dim]) {
62  srcBox.min[dim] =
63  static_cast<int>(std::floor(tgtP[dim] * tgtSize[dim] / srcSize[dim] -
64  support));
65  srcBox.max[dim] =
66  static_cast<int>(std::ceil(tgtP[dim] * tgtSize[dim] / srcSize[dim] +
67  support)) - 1;
68  } else {
69  srcBox.min[dim] =
70  static_cast<int>(std::floor((tgtP[dim] - support) *
71  tgtSize[dim] / srcSize[dim]));
72  srcBox.max[dim] =
73  static_cast<int>(std::ceil((tgtP[dim] + support) *
74  tgtSize[dim] / srcSize[dim]));
75  }
76  }
77  return srcBox;
78  }

References ceil(), and floor().

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.

85  {
86  std::pair<int, int> srcInterval;
87  if (doUpres) {
88  srcInterval.first =
89  static_cast<int>(std::floor(tgtP * tgtSize / srcSize - support));
90  srcInterval.second =
91  static_cast<int>(std::ceil(tgtP * tgtSize / srcSize + support)) - 1;
92  } else {
93  srcInterval.first =
94  static_cast<int>(std::floor((tgtP - support) * tgtSize / srcSize));
95  srcInterval.second =
96  static_cast<int>(std::ceil((tgtP + support) * tgtSize / srcSize));
97  }
98  return srcInterval;
99  }

References ceil(), and floor().

◆ 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.

105  {
106  V3f dist;
107  for (int dim = 0; dim < 3; ++dim) {
108  if (doUpres[dim]) {
109  const float tgtSrc = tgtP[dim] * tgtSize[dim] / srcSize[dim];
110  dist[dim] = std::abs(tgtSrc - srcP[dim]);
111  } else {
112  const float srcTgt = srcP[dim] * srcSize[dim] / tgtSize[dim];
113  dist[dim] = std::abs(srcTgt - tgtP[dim]);
114  }
115  }
116  return dist;
117  }

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.

123  {
124  if (doUpres) {
125  const float tgtSrc = tgtP * tgtSize / srcSize;
126  return std::abs(tgtSrc - srcP);
127  } else {
128  const float srcTgt = srcP * srcSize / tgtSize;
129  return std::abs(srcTgt - tgtP);
130  }
131  }

◆ 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.

412  {
413  typedef typename Field_T::value_type T;
414 
415  const V3i srcRes = src.dataWindow().size() + V3i(1);
416  const float srcDomain = V3f(srcRes)[dim];
417  const float tgtDomain = V3f(newRes)[dim];
418  const float srcSize = 1.0 / srcDomain;
419  const float tgtSize = 1.0 / tgtDomain;
420 
421  // Filter info
422  const float support = filterOp.support();
423 
424  // Check if we're up-res'ing
425  const bool doUpres = newRes[dim] > srcRes[dim] ? 1 : 0;
426 
427  // Resize the target
428  tgt.setSize(newRes);
429 
430  // For each output voxel
431  for (int k = 0; k < newRes.z; ++k) {
432  for (int j = 0; j < newRes.y; ++j) {
433  for (int i = 0; i < newRes.x; ++i) {
434  T accumValue(filterOp.initialValue());
435  if (IsAnalytic_T) {
436  // Current position in target coordinates
437  const float tgtP = discToCont(V3i(i, j ,k)[dim]);
438  // Transform support to source coordinates
439  std::pair<int, int> srcInterval =
440  srcSupportBBox(tgtP, support, doUpres, srcSize, tgtSize);
441  // Clip against new data window
442  srcInterval.first =
443  std::max(srcInterval.first, src.dataWindow().min[dim]);
444  srcInterval.second =
445  std::min(srcInterval.second, src.dataWindow().max[dim]);
446  // For each input voxel
447  for (int s = srcInterval.first; s <= srcInterval.second; ++s) {
448  // Index
449  const int xIdx = dim == 0 ? s : i;
450  const int yIdx = dim == 1 ? s : j;
451  const int zIdx = dim == 2 ? s : k;
452  // Value
453  const T value = src.fastValue(xIdx, yIdx, zIdx);
454  // Weights
455  const float srcP = discToCont(V3i(xIdx, yIdx, zIdx)[dim]);
456  const float dist = getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
457  const float weight = filterOp.eval(dist);
458  // Update
459  if (weight > 0.0f) {
460  FilterOp_T::op(accumValue, value);
461  }
462  }
463  // Update final value
464  if (accumValue != static_cast<T>(filterOp.initialValue())) {
465  tgt.fastLValue(i, j, k) = accumValue;
466  }
467  } else {
468  float accumWeight = 0.0f;
469  // Current position in target coordinates
470  const float tgtP = discToCont(V3i(i, j ,k)[dim]);
471  // Transform support to source coordinates
472  std::pair<int, int> srcInterval =
473  srcSupportBBox(tgtP, support, doUpres, srcSize, tgtSize);
474  // Clip against new data window
475  srcInterval.first =
476  std::max(srcInterval.first, src.dataWindow().min[dim]);
477  srcInterval.second =
478  std::min(srcInterval.second, src.dataWindow().max[dim]);
479  // For each input voxel
480  for (int s = srcInterval.first; s <= srcInterval.second; ++s) {
481  // Index
482  const int xIdx = dim == 0 ? s : i;
483  const int yIdx = dim == 1 ? s : j;
484  const int zIdx = dim == 2 ? s : k;
485  // Value
486  const T value = src.fastValue(xIdx, yIdx, zIdx);
487  // Weights
488  const float srcP = discToCont(V3i(xIdx, yIdx, zIdx)[dim]);
489  const float dist = getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
490  const float weight = filterOp.eval(dist);
491  // Update
492  accumWeight += weight;
493  accumValue += value * weight;
494  }
495  // Update final value
496  if (accumWeight > 0.0f && accumValue != static_cast<T>(0.0)) {
497  tgt.fastLValue(i, j, k) = accumValue / accumWeight;
498  }
499  }
500  }
501  }
502  }
503  }

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

◆ 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.

513  {
514  using namespace detail;
515 
516  typedef typename Field_T::value_type T;
517 
518  if (!src.dataWindow().hasVolume()) {
519  return false;
520  }
521 
522  if (src.dataWindow().min != V3i(0)) {
523  return false;
524  }
525 
526  // Temporary field for y component
527  Field_T tmp;
528 
529  // Cache the old resolution
530  V3i oldRes = src.dataWindow().size() + V3i(1);
531  V3i xRes(newRes.x, oldRes.y, oldRes.z);
532  V3i yRes(newRes.x, newRes.y, oldRes.z);
533  V3i zRes(newRes.x, newRes.y, newRes.z);
534 
535  // X axis (src into tgt)
536  separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(src, tgt, xRes, filterOp, 0);
537  // Y axis (tgt into temp)
538  separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tgt, tmp, yRes, filterOp, 1);
539  // Z axis (temp into tgt)
540  separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tmp, tgt, zRes, filterOp, 2);
541 
542  // Update final target with mapping and metadata
543  tgt.name = src.name;
544  tgt.attribute = src.attribute;
545  tgt.setMapping(src.mapping());
546  tgt.copyMetadata(src);
547 
548  return true;
549  }

Referenced by resample().

Variable Documentation

◆ k_minSuffix

const char* detail::k_minSuffix = "_min"
static

◆ k_maxSuffix

const char* detail::k_maxSuffix = "_max"
static

◆ k_mipOffsetStr

const std::string detail::k_mipOffsetStr = "mipoffset"
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
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
V3i
Imath::V3i V3i
Definition: SpiMathLib.h:71
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
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
V3d
Imath::V3d V3d
Definition: SpiMathLib.h:74
discToCont
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel.
Definition: Field.h:1070
FieldBase::metadata
FieldMetadata & metadata()
accessor to the m_metadata class
Definition: Field.h:155
detail::mipResolution
FIELD3D_API V3i mipResolution(const V3i &baseRes, const size_t level, const V3i &add)
Definition: MIPUtil.cpp:70
detail
Definition: CoordSys.h:97
FieldMapping::Ptr
boost::intrusive_ptr< FieldMapping > Ptr
Definition: FieldMapping.h:92
V3f
Imath::V3f V3f
Definition: SpiMathLib.h:73
detail::srcSupportBBox
std::pair< int, int > srcSupportBBox(const float &tgtP, const float support, const bool doUpres, const float &srcSize, const float &tgtSize)
Definition: Resample.cpp:83
Curve< Imath::M44d >
blockCoords
Box3i blockCoords(const Box3i &dvsBounds, const SparseField< Data_T > *f)
Definition: SparseField.h:676
detail::floor
FIELD3D_VEC3_T< T > floor(const FIELD3D_VEC3_T< T > &v)
Floor function for Vec3.
Definition: CoordSys.h:104
FieldRes::mapping
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition: Field.h:263
detail::max
T max(const T a, const T2 b)
Max operation on mixed types.
Definition: FieldSampler.h:32
detail::k_mipOffsetStr
const std::string k_mipOffsetStr
Definition: MIPUtil.cpp:66
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
detail::getDist
float getDist(const bool doUpres, const float &srcP, const float &tgtP, const float &srcSize, const float &tgtSize)
Definition: Resample.cpp:121
detail::ceil
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:114
MatrixFieldMapping
Represents the mapping of a field by a matrix transform.
Definition: FieldMapping.h:335
M44d
Imath::M44d M44d
Definition: SpiMathLib.h:82
detail::max
FIELD3D_VEC3_T< T > max(const FIELD3D_VEC3_T< T > &a, const FIELD3D_VEC3_T< T2 > &b)
Max operation on mixed vector types.
Definition: FieldSampler.h:49
detail::min
FIELD3D_VEC3_T< T > min(const FIELD3D_VEC3_T< T > &a, const FIELD3D_VEC3_T< T2 > &b)
Min operation on mixed vector types.
Definition: FieldSampler.h:39
Box3i
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
clipBounds
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition: Field.h:1145
MatrixFieldMapping::Ptr
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:341
detail::min
T min(const T a, const T2 b)
Min operation on mixed types.
Definition: FieldSampler.h:25
SparseField::blockSize
int blockSize() const
Returns the block size.
Definition: SparseField.h:1483
SparseField::blockIsAllocated
bool blockIsAllocated(int bi, int bj, int bk) const
Checks if a block is allocated.
Definition: SparseField.h:1502
detail::threadingBlockSize
size_t threadingBlockSize(const SparseField< Data_T > &f)
Use block size for sparse fields.
Definition: MIPUtil.h:128