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.
 
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< V3dcornerPoints (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 >
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 >
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, intsrcSupportBBox (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< V3dunitCornerPoints ()
 

Variables

static const chark_maxSuffix = "_max"
 
static const chark_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.

105 {
106 return FIELD3D_VEC3_T<T>(std::floor(v.x), std::floor(v.y), std::floor(v.z));
107 }
#define FIELD3D_MTX_T
Definition StdMathLib.h:99

References FIELD3D_MTX_T.

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

References FIELD3D_MTX_T.

◆ 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}
Imath::V3d V3d
Definition SpiMathLib.h:74

References FIELD3D_MTX_T.

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

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

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.

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

References FIELD3D_MTX_T.

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.

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 }

References FIELD3D_MTX_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.

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 }

References FIELD3D_MTX_T.

◆ 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 }
Imath::V3i V3i
Definition SpiMathLib.h:71
Imath::V3f V3f
Definition SpiMathLib.h:73

References FIELD3D_MTX_T.

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

◆ 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);
144 tgtBoxPad.min[dim] -= pad;
145 tgtBoxPad.max[dim] += pad;
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 }
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition Field.h:1145
Box3i blockCoords(const Box3i &dvsBounds, const SparseField< Data_T > *f)
Imath::Box3i Box3i
Definition SpiMathLib.h:77

References blockCoords(), clipBounds(), and FIELD3D_MTX_T.

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(
410 (src, tgt, level, add, filterOp,
411 dim, blocks, nextIdx, mutex));
412 }
413
414 // Join
415 threads.join_all();
416 }
size_t threadingBlockSize(const DenseField< Data_T > &)
Constant size for all dense fields.
Definition MIPUtil.h:121

References FIELD3D_MTX_T, 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);
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)
447 // Y axis (tgt into temp)
449 // Z axis (temp into tgt)
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 }
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
FIELD3D_API V3i mipResolution(const V3i &baseRes, const size_t level, const V3i &add)
Definition MIPUtil.cpp:70

References FIELD3D_MTX_T, 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.

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
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
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
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 }
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
Imath::M44d M44d
Definition SpiMathLib.h:82
FieldMetadata & metadata()
accessor to the m_metadata class
Definition Field.h:155
boost::intrusive_ptr< FieldMapping > Ptr
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.
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition Field.h:263
Represents the mapping of a field by a matrix transform.
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.

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

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

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

References FIELD3D_MTX_T.

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 }

References FIELD3D_MTX_T.

◆ 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 =
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 =
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
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 }
double discToCont(int discCoord)
Goes from discrete coordinates to continuous coordinates See Graphics Gems - What is a pixel.
Definition Field.h:1070
Box3i srcSupportBBox(const V3f &tgtP, const float support, const V3i &doUpres, const V3f &srcSize, const V3f &tgtSize)
Definition Resample.cpp:56
V3f getDist(const V3i &doUpres, const V3f &srcP, const V3f &tgtP, const V3f &srcSize, const V3f &tgtSize)
Definition Resample.cpp:103

References discToCont(), FIELD3D_MTX_T, getDist(), 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)
537 // Y axis (tgt into temp)
539 // Z axis (temp into tgt)
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 }

References FIELD3D_MTX_T.

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"