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  MakeDense
 
struct  MakeMIPDense
 
struct  MakeMIPSparse
 
struct  MakeSparse
 
struct  MIPInstance
 We need to instantiate MIPSparseField rather than MIPField<SparseField>. This traits class does that. More...
 
struct  MIPInstance< DenseField< Data_T > >
 
struct  MIPInstance< SparseField< Data_T > >
 Specialization for sparse field. More...
 
struct  MIPSeparableThreadOp
 

Functions

FIELD3D_API FieldMapping::Ptr adjustedMIPFieldMapping (const FieldMapping::Ptr baseMapping, 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 Data_T >
bool checkInputEmpty (const SparseField< Data_T > &src, const SparseField< Data_T > &, const Box3i &tgtBox, const float support, const size_t dim)
 
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...
 
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...
 
V3f getDist (const V3i &doUpres, const V3f &srcP, const V3f &tgtP, const V3f &srcSize, const V3f &tgtSize)
 
float getDist (const bool doUpres, const float &srcP, const float &tgtP, const float &srcSize, const float &tgtSize)
 
bool intersect (const Ray3d &ray, const Box3d &box, double &outT0, double &outT1)
 
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 FilterOp_T &filterOp, const size_t numThreads)
 
FIELD3D_API V3i mipResolution (const V3i &baseRes, const size_t level)
 
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 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 >
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...
 
Box3i srcSupportBBox (const V3f &tgtP, const float support, const V3i &doUpres, const V3f &srcSize, const V3f &tgtSize)
 
std::pair< int, int > srcSupportBBox (const float &tgtP, const float support, const bool doUpres, const float &srcSize, const float &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...
 

Function Documentation

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

Ceil function for Vec3.

Definition at line 105 of file CoordSys.h.

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

106  {
107  return FIELD3D_VEC3_T<T>(std::ceil(v.x), std::ceil(v.y), std::ceil(v.z));
108  }
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
std::vector<V3d> detail::cornerPoints ( const Box3d box)
inline

Definition at line 158 of file FieldGroup.h.

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

159 {
160  std::vector<V3d> result;
161  result.push_back(V3d(box.min.x, box.min.y, box.min.z));
162  result.push_back(V3d(box.max.x, box.min.y, box.min.z));
163  result.push_back(V3d(box.min.x, box.max.y, box.min.z));
164  result.push_back(V3d(box.max.x, box.max.y, box.min.z));
165  result.push_back(V3d(box.min.x, box.min.y, box.max.z));
166  result.push_back(V3d(box.max.x, box.min.y, box.max.z));
167  result.push_back(V3d(box.min.x, box.max.y, box.max.z));
168  result.push_back(V3d(box.max.x, box.max.y, box.max.z));
169  return result;
170 }
Imath::V3d V3d
Definition: SpiMathLib.h:74
bool detail::intersect ( const Ray3d ray,
const Box3d box,
double &  outT0,
double &  outT1 
)
inline

Definition at line 175 of file FieldGroup.h.

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

176 {
177  double tNear = -std::numeric_limits<double>::max();
178  double tFar = std::numeric_limits<double>::max();
179  const double epsilon = std::numeric_limits<double>::epsilon() * 10.0;
180 
181  for (size_t dim = 0; dim < 3; ++dim) {
182  double t0, t1;
183  if (std::abs(ray.dir[dim]) < epsilon) {
184  // Ray is parallel, check if inside slab
185  if (ray.pos[dim] < box.min[dim] || ray.pos[dim] > box.max[dim]) {
186  return false;
187  }
188  }
189  t0 = (box.min[dim] - ray.pos[dim]) / ray.dir[dim];
190  t1 = (box.max[dim] - ray.pos[dim]) / ray.dir[dim];
191  if (t0 > t1) {
192  std::swap(t0, t1);
193  }
194  tNear = std::max(tNear, t0);
195  tFar = std::min(tFar, t1);
196  if (tNear > tFar) {
197  return false;
198  }
199  if (tFar < 0.0) {
200  return false;
201  }
202  }
203  outT0 = tNear;
204  outT1 = tFar;
205  return true;
206 }
V3i detail::mipResolution ( const V3i baseRes,
const size_t  level 
)

Definition at line 66 of file MIPUtil.cpp.

References ceil().

Referenced by mipResample(), MIPBase< Field_T::value_type >::staticClassType(), and MIPField< DenseField< Data_T > >::staticClassType().

67  {
68  const float factor = 1.0 / (1 << level);
69  const V3f floatRes(baseRes);
70  return V3i(static_cast<int>(std::ceil(floatRes.x * factor)),
71  static_cast<int>(std::ceil(floatRes.y * factor)),
72  static_cast<int>(std::ceil(floatRes.z * factor)));
73  }
Imath::V3i V3i
Definition: SpiMathLib.h:71
Imath::V3f V3f
Definition: SpiMathLib.h:73
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
template<typename Data_T >
size_t detail::threadingBlockSize ( const DenseField< Data_T > &  )

Constant size for all dense fields.

Definition at line 104 of file MIPUtil.h.

Referenced by mipSeparable().

105  {
106  return 16;
107  }
template<typename Data_T >
size_t detail::threadingBlockSize ( const SparseField< Data_T > &  f)

Use block size for sparse fields.

Definition at line 111 of file MIPUtil.h.

References SparseField< Data_T >::blockSize().

112  {
113  return f.blockSize();
114  }
int blockSize() const
Returns the block size.
Definition: SparseField.h:1453
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 119 of file MIPUtil.h.

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

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

123  {
124  const int intSupport = static_cast<int>(std::ceil(support * 0.5));
125  const int pad = std::max(0, intSupport);
126  Box3i tgtBoxPad = tgtBox;
127  tgtBoxPad.min[dim] -= pad;
128  tgtBoxPad.max[dim] += pad;
129  Box3i srcBoxPad = tgtBoxPad;
130  srcBoxPad.min[dim] *= 2;
131  srcBoxPad.max[dim] *= 2;
132 
133  // Get the block coordinates
134  const Box3i dbsBounds = blockCoords(clipBounds(srcBoxPad, src.dataWindow()),
135  &src);
136 
137  static boost::mutex mutex;
138  boost::mutex::scoped_lock lock(mutex);
139 
140  // Check all blocks
141  for (int k = dbsBounds.min.z; k <= dbsBounds.max.z; ++k) {
142  for (int j = dbsBounds.min.y; j <= dbsBounds.max.y; ++j) {
143  for (int i = dbsBounds.min.x; i <= dbsBounds.max.x; ++i) {
144  if (src.blockIsAllocated(i, j, k) ||
145  src.getBlockEmptyValue(i, j, k) != static_cast<Data_T>(0)) {
146  return false;
147  }
148  }
149  }
150  }
151 
152  // No hits. Empty
153  return true;
154  }
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition: Field.h:1144
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Box3i blockCoords(const Box3i &dvsBounds, const SparseField< Data_T > *f)
Definition: SparseField.h:676
const Data_T getBlockEmptyValue(int bi, int bj, int bk) const
Returns the constant value of an block, whether it&#39;s allocated already or not..
Definition: SparseField.h:1481
bool blockIsAllocated(int bi, int bj, int bk) const
Checks if a block is allocated.
Definition: SparseField.h:1472
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
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:258
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 160 of file MIPUtil.h.

163  {
164  return false;
165  }
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 FilterOp_T &  filterOp,
const size_t  dim,
const size_t  numThreads 
)

Threaded implementation of separable MIP filtering.

Definition at line 293 of file MIPUtil.h.

References threadingBlockSize().

Referenced by mipResample().

297  {
298  using namespace std;
299 
300  // Compute new res
301  V3i res;
302  if (dim == 2) {
303  res = newRes;
304  } else if (dim == 1) {
305  res = V3i(newRes.x, newRes.y, oldRes.z);
306  } else {
307  res = V3i(newRes.x, oldRes.y, oldRes.z);
308  }
309 
310  // Resize new field
311  tgt.setSize(res);
312 
313  // Determine granularity
314  const size_t blockSize = threadingBlockSize(src);
315 
316  // Build block list
317  std::vector<Box3i> blocks;
318  for (int k = 0; k < res.z; k += blockSize) {
319  for (int j = 0; j < res.y; j += blockSize) {
320  for (int i = 0; i < res.x; i += blockSize) {
321  Box3i box;
322  // Initialize block size
323  box.min = V3i(i, j, k);
324  box.max = box.min + V3i(blockSize - 1);
325  // Clip against resolution
326  box.max.x = std::min(box.max.x, res.x - 1);
327  box.max.y = std::min(box.max.y, res.y - 1);
328  box.max.z = std::min(box.max.z, res.z - 1);
329  // Add to list
330  blocks.push_back(box);
331  }
332  }
333  }
334 
335  // Next index counter and mutex
336  size_t nextIdx = 0;
337  boost::mutex mutex;
338 
339  // Launch threads ---
340 
341  boost::thread_group threads;
342 
343  for (size_t i = 0; i < numThreads; ++i) {
344  threads.create_thread(
345  MIPSeparableThreadOp<Field_T, FilterOp_T>(src, tgt, level, filterOp,
346  dim, blocks, nextIdx, mutex));
347  }
348 
349  // Join
350  threads.join_all();
351  }
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Imath::V3i V3i
Definition: SpiMathLib.h:71
size_t threadingBlockSize(const SparseField< Data_T > &f)
Use block size for sparse fields.
Definition: MIPUtil.h:111
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 FilterOp_T &  filterOp,
const size_t  numThreads 
)

Definition at line 356 of file MIPUtil.h.

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

Referenced by makeMIP().

359  {
360  using std::ceil;
361 
362  // Compute new res
363  const Box3i baseDw = base.dataWindow();
364  const V3i baseRes = baseDw.size() + V3i(1);
365  const V3i newRes = mipResolution(baseRes, level);
366 
367  // Source res
368  const Box3i srcDw = src.dataWindow();
369  const V3i srcRes = srcDw.size() + V3i(1);
370 
371  // Temporary field for y component
372  Field_T tmp;
373 
374  // X axis (src into tgt)
375  mipSeparable(src, tgt, srcRes, newRes, level, filterOp, 0, numThreads);
376  // Y axis (tgt into temp)
377  mipSeparable(tgt, tmp, srcRes, newRes, level, filterOp, 1, numThreads);
378  // Z axis (temp into tgt)
379  mipSeparable(tmp, tgt, srcRes, newRes, level, filterOp, 2, numThreads);
380 
381  // Update final target with mapping and metadata
382  tgt.name = base.name;
383  tgt.attribute = base.attribute;
384  tgt.setMapping(base.mapping());
385  tgt.copyMetadata(base);
386  }
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
void mipSeparable(const Field_T &src, Field_T &tgt, const V3i &oldRes, const V3i &newRes, const size_t level, const FilterOp_T &filterOp, const size_t dim, const size_t numThreads)
Threaded implementation of separable MIP filtering.
Definition: MIPUtil.h:293
Imath::V3i V3i
Definition: SpiMathLib.h:71
FIELD3D_API V3i mipResolution(const V3i &baseRes, const size_t level)
Definition: MIPUtil.cpp:66
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
FieldMapping::Ptr detail::adjustedMIPFieldMapping ( const FieldMapping::Ptr  baseMapping,
const V3i baseRes,
const Box3i extents,
const size_t  level 
)

Definition at line 77 of file MIPUtil.cpp.

References coordinateSystem(), and FIELD3D_NAMESPACE_SOURCE_CLOSE.

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

81  {
82  typedef MatrixFieldMapping::MatrixCurve MatrixCurve;
83 
84  const float mult = 1 << level;
85  const V3i res = extents.size() + V3i(1);
86 
87  if (MatrixFieldMapping::Ptr mfm =
88  field_dynamic_cast<MatrixFieldMapping>(mapping)) {
89  // Local space positions
90  const V3d lsOrigin(0.0), lsX(1.0, 0.0, 0.0), lsY(0.0, 1.0, 0.0),
91  lsZ(0.0, 0.0, 0.1);
92  // Find base voxel size
93  const V3f wsBaseVoxelSize = mfm->wsVoxelSize(0, 0, 0);
94  // Compute current levels' voxel size
95  const V3f wsVoxelSize = wsBaseVoxelSize * mult;
96  // Grab the matrices
97  const MatrixCurve::SampleVec lsToWsSamples = mfm->localToWorldSamples();
98  // New mapping to construct
100  // For each time sample
101  BOOST_FOREACH (const MatrixCurve::Sample &sample, lsToWsSamples){
102  // Find origin and orientation vectors
103  V3d wsOrigin, wsX, wsY, wsZ;
104  mfm->localToWorld(lsOrigin, wsOrigin, sample.first);
105  mfm->localToWorld(lsX, wsX, sample.first);
106  mfm->localToWorld(lsY, wsY, sample.first);
107  mfm->localToWorld(lsZ, wsZ, sample.first);
108  // Normalize orientation vectors
109  wsX = (wsX - wsOrigin).normalized();
110  wsY = (wsY - wsOrigin).normalized();
111  wsZ = (wsZ - wsOrigin).normalized();
112  // Mult by voxel size
113  wsX *= wsVoxelSize.x * res.x;
114  wsY *= wsVoxelSize.y * res.y;
115  wsZ *= wsVoxelSize.z * res.z;
116  // Construct new mapping
117  M44d mtx = coordinateSystem(wsX, wsY, wsZ, wsOrigin);
118  // Update mapping
119  newMapping->setLocalToWorld(sample.first, mtx);
120  }
121  // Done
122  return newMapping;
123  } else {
124  // For non-uniform grids, there is nothing we can do.
125  return mapping;
126  }
127  }
Imath::M44d M44d
Definition: SpiMathLib.h:82
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:119
Imath::V3i V3i
Definition: SpiMathLib.h:71
Imath::V3d V3d
Definition: SpiMathLib.h:74
Imath::V3f V3f
Definition: SpiMathLib.h:73
Represents the mapping of a field by a matrix transform.
Definition: FieldMapping.h:327
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:334
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.

References ceil(), and floor().

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  }
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
FIELD3D_VEC3_T< T > floor(const FIELD3D_VEC3_T< T > &v)
Floor function for Vec3.
Definition: CoordSys.h:95
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
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.

References ceil(), and floor().

Referenced by separable().

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  }
FIELD3D_VEC3_T< T > floor(const FIELD3D_VEC3_T< T > &v)
Floor function for Vec3.
Definition: CoordSys.h:95
FIELD3D_VEC3_T< T > ceil(const FIELD3D_VEC3_T< T > &v)
Ceil function for Vec3.
Definition: CoordSys.h:105
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  }
Imath::V3f V3f
Definition: SpiMathLib.h:73
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.

References FIELD3D_NAMESPACE_SOURCE_CLOSE.

Referenced by separable().

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  }
template<typename Field_T , typename FilterOp_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 267 of file Resample.h.

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

Referenced by separableResample().

269  {
270  typedef typename Field_T::value_type T;
271 
272  const V3i srcRes = src.dataWindow().size() + V3i(1);
273  const float srcDomain = V3f(srcRes)[dim];
274  const float tgtDomain = V3f(newRes)[dim];
275  const float srcSize = 1.0 / srcDomain;
276  const float tgtSize = 1.0 / tgtDomain;
277 
278  // Filter info
279  const float support = filterOp.support();
280 
281  // Check if we're up-res'ing
282  const bool doUpres = newRes[dim] > srcRes[dim] ? 1 : 0;
283 
284  // Resize the target
285  tgt.setSize(newRes);
286 
287  // For each output voxel
288  for (int k = 0; k < newRes.z; ++k) {
289  for (int j = 0; j < newRes.y; ++j) {
290  for (int i = 0; i < newRes.x; ++i) {
291  T accumValue = static_cast<T>(0.0);
292  float accumWeight = 0.0f;
293  // Current position in target coordinates
294  const float tgtP = discToCont(V3i(i, j ,k)[dim]);
295  // Transform support to source coordinates
296  std::pair<int, int> srcInterval =
297  srcSupportBBox(tgtP, support, doUpres, srcSize, tgtSize);
298  // Clip against new data window
299  srcInterval.first =
300  std::max(srcInterval.first, src.dataWindow().min[dim]);
301  srcInterval.second =
302  std::min(srcInterval.second, src.dataWindow().max[dim]);
303  // For each input voxel
304  for (int s = srcInterval.first; s <= srcInterval.second; ++s) {
305  // Index
306  const int xIdx = dim == 0 ? s : i;
307  const int yIdx = dim == 1 ? s : j;
308  const int zIdx = dim == 2 ? s : k;
309  // Value
310  const T value = src.fastValue(xIdx, yIdx, zIdx);
311  // Weights
312  const float srcP = discToCont(V3i(xIdx, yIdx, zIdx)[dim]);
313  const float dist = getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
314  const float weight = filterOp.eval(dist);
315  // Update
316  accumWeight += weight;
317  accumValue += value * weight;
318  }
319  // Update final value
320  if (accumWeight > 0.0f && accumValue != static_cast<T>(0.0)) {
321  tgt.fastLValue(i, j, k) = accumValue / accumWeight;
322  }
323  }
324  }
325  }
326 
327  }
Imath::V3i V3i
Definition: SpiMathLib.h:71
std::pair< int, int > srcSupportBBox(const float &tgtP, const float support, const bool doUpres, const float &srcSize, const float &tgtSize)
Definition: Resample.cpp:83
float getDist(const bool doUpres, const float &srcP, const float &tgtP, const float &srcSize, const float &tgtSize)
Definition: Resample.cpp:121
Imath::V3f V3f
Definition: SpiMathLib.h:73
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...
Definition: Field.h:1075
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 335 of file Resample.h.

References separable().

Referenced by resample().

337  {
338  using namespace detail;
339 
340  typedef typename Field_T::value_type T;
341 
342  if (!src.dataWindow().hasVolume()) {
343  return false;
344  }
345 
346  if (src.dataWindow().min != V3i(0)) {
347  return false;
348  }
349 
350  // Temporary field for y component
351  Field_T tmp;
352 
353  // Cache the old resolution
354  V3i oldRes = src.dataWindow().size() + V3i(1);
355  V3i xRes(newRes.x, oldRes.y, oldRes.z);
356  V3i yRes(newRes.x, newRes.y, oldRes.z);
357  V3i zRes(newRes.x, newRes.y, newRes.z);
358 
359  // X axis (src into tgt)
360  separable(src, tgt, xRes, filterOp, 0);
361  // Y axis (tgt into temp)
362  separable(tgt, tmp, yRes, filterOp, 1);
363  // Z axis (temp into tgt)
364  separable(tmp, tgt, zRes, filterOp, 2);
365 
366  // Update final target with mapping and metadata
367  tgt.name = src.name;
368  tgt.attribute = src.attribute;
369  tgt.setMapping(src.mapping());
370  tgt.copyMetadata(src);
371 
372  return true;
373  }
void separable(const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filterOp, const size_t dim)
Definition: Resample.h:267
Imath::V3i V3i
Definition: SpiMathLib.h:71