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;
99 virtual float support()
const = 0;
110 typedef boost::shared_ptr<BoxFilter>
Ptr;
111 typedef boost::shared_ptr<const BoxFilter>
CPtr;
120 virtual float eval(
const float x)
const 122 const float t = x / m_width;
131 return 0.5f * m_width;
144 typedef boost::shared_ptr<TriangleFilter>
Ptr;
145 typedef boost::shared_ptr<const TriangleFilter>
CPtr;
154 virtual float eval(
const float x)
const 156 const float t = x / m_width;
164 return 1.0f * m_width;
177 typedef boost::shared_ptr<GaussianFilter>
Ptr;
178 typedef boost::shared_ptr<const GaussianFilter>
CPtr;
182 m_exp(
std::exp(-alpha * width * width)),
186 virtual float eval(
const float t)
const 188 const float x = t / m_width;
189 return std::max(0.0f, std::exp(-m_alpha * x * x) - m_exp);
193 return 2.0f * m_width;
206 typedef boost::shared_ptr<MitchellFilter>
Ptr;
207 typedef boost::shared_ptr<const MitchellFilter>
CPtr;
210 const float B = 1.0 / 3.0,
const float C = 1.0 / 3.0)
211 : m_B(B), m_C(C), m_width(width)
214 virtual float eval(
const float x)
const 216 const float ax = std::abs(x / m_width);
218 return ((12 - 9 * m_B - 6 * m_C) * ax * ax * ax +
219 (-18 + 12 * m_B + 6 * m_C) * ax * ax + (6 - 2 * m_B)) / 6;
220 }
else if ((ax >= 1) && (ax < 2)) {
221 return ((-m_B - 6 * m_C) * ax * ax * ax +
222 (6 * m_B + 30 * m_C) * ax * ax + (-12 * m_B - 48 * m_C) *
223 ax + (8 * m_B + 24 * m_C)) / 6;
230 return 2.0f * m_width;
246 const V3f &srcSize,
const V3f &tgtSize);
251 srcSupportBBox(
const float &tgtP,
const float support,
const bool doUpres,
252 const float &srcSize,
const float &tgtSize);
257 const V3f &srcSize,
const V3f &tgtSize);
261 float getDist(
const bool doUpres,
const float &srcP,
const float &tgtP,
262 const float &srcSize,
const float &tgtSize);
266 template <
typename Field_T,
typename FilterOp_T>
268 const FilterOp_T &filterOp,
const size_t dim)
270 typedef typename Field_T::value_type T;
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;
279 const float support = filterOp.support();
282 const bool doUpres = newRes[dim] > srcRes[dim] ? 1 : 0;
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;
296 std::pair<int, int> srcInterval =
300 std::max(srcInterval.first, src.dataWindow().min[dim]);
302 std::min(srcInterval.second, src.dataWindow().max[dim]);
304 for (
int s = srcInterval.first; s <= srcInterval.second; ++s) {
306 const int xIdx = dim == 0 ? s : i;
307 const int yIdx = dim == 1 ? s : j;
308 const int zIdx = dim == 2 ? s : k;
310 const T value = src.fastValue(xIdx, yIdx, zIdx);
313 const float dist =
getDist(doUpres, srcP, tgtP, srcSize, tgtSize);
314 const float weight = filterOp.eval(dist);
316 accumWeight += weight;
317 accumValue += value * weight;
320 if (accumWeight > 0.0f && accumValue != static_cast<T>(0.0)) {
321 tgt.fastLValue(i, j, k) = accumValue / accumWeight;
334 template <
typename Field_T,
typename FilterOp_T>
336 const FilterOp_T &filterOp)
340 typedef typename Field_T::value_type T;
342 if (!src.dataWindow().hasVolume()) {
346 if (src.dataWindow().min !=
V3i(0)) {
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);
368 tgt.attribute = src.attribute;
369 tgt.setMapping(src.mapping());
370 tgt.copyMetadata(src);
383 template <
typename Field_T,
typename FilterOp_T>
384 bool resample(
const Field_T &src, Field_T &tgt,
const V3i &newRes,
385 const FilterOp_T &filterOp)
396 #endif // Include guard #define FIELD3D_NAMESPACE_HEADER_CLOSE
Contains the DenseField class.
virtual float support() const
Radial width of the filter (half of diameter)
boost::shared_ptr< const BoxFilter > CPtr
virtual float support() const
Radial width of the filter (half of diameter)
boost::shared_ptr< GaussianFilter > Ptr
GaussianFilter(const float alpha=2.0, const float width=2.0)
boost::shared_ptr< TriangleFilter > Ptr
boost::shared_ptr< const GaussianFilter > CPtr
boost::shared_ptr< const MitchellFilter > CPtr
void separable(const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filterOp, const size_t dim)
TriangleFilter(const float width)
boost::shared_ptr< Filter > Ptr
std::pair< int, int > srcSupportBBox(const float &tgtP, const float support, const bool doUpres, const float &srcSize, const float &tgtSize)
float getDist(const bool doUpres, const float &srcP, const float &tgtP, const float &srcSize, const float &tgtSize)
virtual float eval(const float t) const =0
Evaluates the filter at coordinate 't'.
virtual float eval(const float x) const
Evaluates the filter at coordinate '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 res...
virtual float eval(const float t) const
Evaluates the filter at coordinate 't'.
MitchellFilter(const float width=1.0, const float B=1.0/3.0, const float C=1.0/3.0)
boost::shared_ptr< const Filter > CPtr
static int filter(std::string &name, const char *suffix)
FIELD3D_NAMESPACE_OPEN bool resample(const Field_T &src, Field_T &tgt, const V3i &newRes, const FilterOp_T &filter)
Resamples the source field into the target field, such that the new data window is ...
virtual float eval(const float x) const
Evaluates the filter at coordinate 't'.
virtual float support() const
Radial width of the filter (half of diameter)
BoxFilter(const float width)
boost::shared_ptr< MitchellFilter > Ptr
Contains the SparseField class.
virtual float eval(const float x) const
Evaluates the filter at coordinate 't'.
virtual float support() const
Radial width of the filter (half of diameter)
boost::shared_ptr< const TriangleFilter > CPtr
boost::shared_ptr< BoxFilter > Ptr
virtual float support() const =0
Radial width of the filter (half of diameter)
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel...