44 #ifndef _INCLUDED_Field3D_Resample_H_
45 #define _INCLUDED_Field3D_Resample_H_
79 template <
typename Field_T,
typename FilterOp_T>
80 bool resample(
const Field_T &src, Field_T &tgt,
const V3i &newRes,
91 typedef boost::shared_ptr<Filter>
Ptr;
92 typedef boost::shared_ptr<const Filter>
CPtr;
97 virtual float eval(
const float t)
const = 0;
116 typedef boost::shared_ptr<BoxFilter>
Ptr;
117 typedef boost::shared_ptr<const BoxFilter>
CPtr;
129 virtual float eval(
const float x)
const
142 template <
typename Value_T>
143 static void op(Value_T &accumValue,
const Value_T value)
156 typedef boost::shared_ptr<MinFilter>
Ptr;
157 typedef boost::shared_ptr<const MinFilter>
CPtr;
169 virtual float eval(
const float x)
const
187 template <
typename T>
188 static void op(Imath::Vec3<T> &accumValue,
const Imath::Vec3<T> value)
190 accumValue.x =
std::min(accumValue.x, value.x);
191 accumValue.y =
std::min(accumValue.y, value.y);
192 accumValue.z =
std::min(accumValue.z, value.z);
195 template <
typename Value_T>
196 static void op(Value_T &accumValue,
const Value_T value)
198 accumValue =
std::min(accumValue, value);
212 typedef boost::shared_ptr<MaxFilter>
Ptr;
213 typedef boost::shared_ptr<const MaxFilter>
CPtr;
225 virtual float eval(
const float x)
const
244 template <
typename T>
245 static void op(Imath::Vec3<T> &accumValue,
const Imath::Vec3<T> value)
247 accumValue.x =
std::max(accumValue.x, value.x);
248 accumValue.y =
std::max(accumValue.y, value.y);
249 accumValue.z =
std::max(accumValue.z, value.z);
252 template <
typename Value_T>
253 static void op(Value_T &accumValue,
const Value_T value)
255 accumValue =
std::max(accumValue, value);
269 typedef boost::shared_ptr<TriangleFilter>
Ptr;
270 typedef boost::shared_ptr<const TriangleFilter>
CPtr;
282 virtual float eval(
const float x)
const
294 template <
typename Value_T>
295 static void op(Value_T &,
const Value_T )
308 typedef boost::shared_ptr<GaussianFilter>
Ptr;
309 typedef boost::shared_ptr<const GaussianFilter>
CPtr;
316 m_exp(std::exp(-alpha * width * width)),
320 virtual float eval(
const float t)
const
329 template <
typename Value_T>
330 static void op(Value_T &accumValue,
const Value_T value)
343 typedef boost::shared_ptr<MitchellFilter>
Ptr;
344 typedef boost::shared_ptr<const MitchellFilter>
CPtr;
350 const float B = 1.0 / 3.0,
const float C = 1.0 / 3.0)
354 virtual float eval(
const float x)
const
356 const float ax = std::abs(x /
m_width);
358 return ((12 - 9 *
m_B - 6 *
m_C) * ax * ax * ax +
359 (-18 + 12 *
m_B + 6 *
m_C) * ax * ax + (6 - 2 *
m_B)) / 6;
360 }
else if ((ax >= 1) && (ax < 2)) {
361 return ((-
m_B - 6 *
m_C) * ax * ax * ax +
362 (6 *
m_B + 30 *
m_C) * ax * ax + (-12 *
m_B - 48 *
m_C) *
363 ax + (8 *
m_B + 24 *
m_C)) / 6;
372 template <
typename Value_T>
373 static void op(Value_T &accumValue,
const Value_T value)
389 const V3f &srcSize,
const V3f &tgtSize);
394 srcSupportBBox(
const float &tgtP,
const float support,
const bool doUpres,
395 const float &srcSize,
const float &tgtSize);
400 const V3f &srcSize,
const V3f &tgtSize);
404 float getDist(
const bool doUpres,
const float &srcP,
const float &tgtP,
405 const float &srcSize,
const float &tgtSize);
409 template <
typename Field_T,
typename FilterOp_T,
bool IsAnalytic_T>
411 const FilterOp_T &filterOp,
const size_t dim)
413 typedef typename Field_T::value_type T;
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;
422 const float support = filterOp.support();
425 const bool doUpres = newRes[dim] > srcRes[dim] ? 1 : 0;
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());
439 std::pair<int, int> srcInterval =
443 std::max(srcInterval.first, src.dataWindow().min[dim]);
445 std::min(srcInterval.second, src.dataWindow().max[dim]);
447 for (
int s = srcInterval.first; s <= srcInterval.second; ++s) {
449 const int xIdx = dim == 0 ? s : i;
450 const int yIdx = dim == 1 ? s : j;
451 const int zIdx = dim == 2 ? s : k;
453 const T value = src.fastValue(xIdx, yIdx, zIdx);
456 const float dist =
getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
457 const float weight = filterOp.eval(dist);
460 FilterOp_T::op(accumValue, value);
464 if (accumValue !=
static_cast<T
>(filterOp.initialValue())) {
465 tgt.fastLValue(i, j, k) = accumValue;
468 float accumWeight = 0.0f;
472 std::pair<int, int> srcInterval =
476 std::max(srcInterval.first, src.dataWindow().min[dim]);
478 std::min(srcInterval.second, src.dataWindow().max[dim]);
480 for (
int s = srcInterval.first; s <= srcInterval.second; ++s) {
482 const int xIdx = dim == 0 ? s : i;
483 const int yIdx = dim == 1 ? s : j;
484 const int zIdx = dim == 2 ? s : k;
486 const T value = src.fastValue(xIdx, yIdx, zIdx);
489 const float dist =
getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
490 const float weight = filterOp.eval(dist);
492 accumWeight += weight;
493 accumValue += value * weight;
496 if (accumWeight > 0.0f && accumValue !=
static_cast<T
>(0.0)) {
497 tgt.fastLValue(i, j, k) = accumValue / accumWeight;
510 template <
typename Field_T,
typename FilterOp_T>
512 const FilterOp_T &filterOp)
516 typedef typename Field_T::value_type T;
518 if (!src.dataWindow().hasVolume()) {
522 if (src.dataWindow().min !=
V3i(0)) {
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);
536 separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(src, tgt, xRes, filterOp, 0);
538 separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tgt, tmp, yRes, filterOp, 1);
540 separable<Field_T, FilterOp_T, FilterOp_T::isAnalytic>(tmp, tgt, zRes, filterOp, 2);
544 tgt.attribute = src.attribute;
545 tgt.setMapping(src.mapping());
546 tgt.copyMetadata(src);
559 template <
typename Field_T,
typename FilterOp_T>
560 bool resample(
const Field_T &src, Field_T &tgt,
const V3i &newRes,
561 const FilterOp_T &filterOp)
572 #endif // Include guard