3#ifndef __F3DUTIL_FIELDSAMPLER_H__
4#define __F3DUTIL_FIELDSAMPLER_H__
24 template <
typename T,
typename T2>
25 T
min(
const T a,
const T2 b)
27 return std::min(a,
static_cast<T
>(b));
31 template <
typename T,
typename T2>
32 T
max(
const T a,
const T2 b)
34 return std::max(a,
static_cast<T
>(b));
38 template <
typename T,
typename T2>
43 std::min(a.y,
static_cast<T
>(b.y)),
44 std::min(a.z,
static_cast<T
>(b.z)));
48 template <
typename T,
typename T2>
53 std::max(a.y,
static_cast<T
>(b.y)),
54 std::max(a.z,
static_cast<T
>(b.z)));
80template <
typename WrapperVec_T,
int Dims_T>
88 typedef typename WrapperVec_T::value_type::field_type
Field_T;
89 typedef typename Field_T::value_type
Data_T;
93 static void sample(
const WrapperVec_T &f,
const V3d &wsP,
float *value,
99 for (
size_t i = 0, end = f.size(); i < end; ++i) {
104 f[i].wsToOs.multVecMatrix(wsP, osP);
105 f[i].mapping->worldToVoxel(osP, vsP);
107 f[i].mapping->worldToVoxel(wsP, vsP);
110 if (f[i].vsBounds.intersects(vsP)) {
114 if (f[i].valueRemapOp) {
115 const Data_T unremapped = f[i].interp.sample(*f[i].field, vsP);
116 *data += f[i].valueRemapOp->remap(unremapped);
118 *data += f[i].interp.sample(*f[i].field, vsP);
126 const float *wsPs,
float *value,
size_t *numHits)
129 for (
size_t i = 0; i < f.size(); ++i) {
130 const typename WrapperVec_T::value_type &field = f[i];
135 if (field.doOsToWs || field.valueRemapOp) {
138 for (
size_t ieval = 0; ieval < neval; ++ieval) {
139 const V3d wsP(*
reinterpret_cast<const V3f*
>(wsPs + 3 * ieval));
142 if (field.doOsToWs) {
144 field.wsToOs.multVecMatrix(wsP, osP);
145 field.mapping->worldToVoxel(osP, vsP);
147 field.mapping->worldToVoxel(wsP, vsP);
150 if (field.vsBounds.intersects(vsP)) {
154 if (field.valueRemapOp) {
155 const Data_T unremapped = field.interp.sample(*field.field, vsP);
156 data[ieval] += field.valueRemapOp->remap(unremapped);
158 data[ieval] += field.interp.sample(*field.field, vsP);
165 const Imath::Box3d &vsBounds_d = field.vsBounds;
168 for (
size_t ieval = 0; ieval < neval; ++ieval) {
169 const V3d wsP(*
reinterpret_cast<const V3f*
>(wsPs + 3 * ieval));
173 field.mapping->worldToVoxel(wsP, vsP);
176 if (vsBounds_d.intersects(vsP)) {
180 data[ieval] += field.interp.sample(*field.field, vsP);
189 const float wsSpotSize,
float *value,
size_t &numHits)
194 for (
size_t i = 0, end = f.size(); i < end; ++i) {
196 float spotSize = wsSpotSize / f[i].worldScale;
200 f[i].wsToOs.multVecMatrix(wsP, osP);
201 f[i].mapping->worldToVoxel(osP, vsP);
202 spotSize = wsSpotSize / f[i].worldScale;
204 f[i].mapping->worldToVoxel(wsP, vsP);
207 if (f[i].vsBounds.intersects(vsP)) {
211 if (f[i].valueRemapOp) {
212 const Data_T unremapped = f[i].interp->sample(vsP, spotSize);
213 *data += f[i].valueRemapOp->remap(unremapped);
215 *data += f[i].interp->sample(vsP, spotSize);
223 const float *wsPs,
const float *wsSpotSizes,
224 float *value,
size_t *numHits)
227 for (
size_t i = 0; i < f.size(); ++i) {
228 const typename WrapperVec_T::value_type &field = f[i];
233 if (field.doOsToWs || field.valueRemapOp) {
235 if (field.valueRemapOp && field.doWsBoundsOptimization) {
238 for (
size_t ieval = 0; ieval < neval; ++ieval) {
239 const V3f &wsP = *
reinterpret_cast<const V3f*
>(wsPs + 3 * ieval);
241 if (field.wsBounds.intersects(wsP)) {
246 field.wsToVs.multVecMatrix(
V3d(wsP), vsP);
249 if (field.vsBounds.intersects(vsP)) {
252 const float spotSize = wsSpotSizes[ieval] / field.worldScale;
253 const Data_T unremapped = field.interp->sample(vsP, spotSize);
254 data[ieval] += field.valueRemapOp->remap(unremapped);
261 for (
size_t ieval = 0; ieval < neval; ++ieval) {
262 const V3d wsP(*
reinterpret_cast<const V3f*
>(wsPs + 3 * ieval));
263 const float wsSpotSize = wsSpotSizes[ieval];
267 float spotSize = wsSpotSize / field.worldScale;
269 if (field.doOsToWs) {
272 field.wsToOs.multVecMatrix(wsP, osP);
273 field.mapping->worldToVoxel(osP, vsP);
274 spotSize = wsSpotSize / field.worldScale;
276 field.mapping->worldToVoxel(wsP, vsP);
279 if (field.vsBounds.intersects(vsP)) {
282 if (field.valueRemapOp) {
283 const Data_T unremapped = field.interp->sample(vsP, spotSize);
284 *idata += field.valueRemapOp->remap(unremapped);
286 *idata += field.interp->sample(vsP, spotSize);
293 const Imath::Box3d &vsBounds_d = field.vsBounds;
294 const double worldScale = field.worldScale;
297 for (
size_t ieval = 0; ieval < neval; ++ieval) {
298 const V3d wsP(*
reinterpret_cast<const V3f*
>(wsPs + 3 * ieval));
302 field.mapping->worldToVoxel(wsP, vsP);
305 if (vsBounds_d.intersects(vsP)) {
308 const double spotSize = wsSpotSizes[ieval] / worldScale;
310 data[ieval] += field.interp->sample(vsP, spotSize);
319 const Box3d &wsBounds,
float *min,
float *max)
325 for (
size_t field = 0, end = f.size(); field < end; ++field) {
327 const Box3i dw = f[field].field->dataWindow();
330 if (wsBounds.isInfinite()) {
334 if (f[field].doOsToWs) {
343 if (!dw.intersects(dvsBounds)) {
347 for (
int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
348 for (
int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
349 for (
int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
350 const Data_T val = f[field].field->fastValue(i, j, k);
361 const Box3d &wsBounds,
float *min,
float *max)
367 for (
size_t field = 0, end = f.size(); field < end; ++field) {
369 const Box3i dw = f[field].field->dataWindow();
372 if (wsBounds.isInfinite()) {
376 if (f[field].doOsToWs) {
385 if (!dw.intersects(dvsBounds)) {
389 for (
int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
390 for (
int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
391 for (
int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
392 const Data_T val = f[field].field->fastMipValue(0, i, j, k);
403 const Box3d &wsBounds,
410 for (
size_t field = 0, end = f.size(); field < end; ++field) {
412 const size_t numLevels = f[field].field->numLevels();
416 if (wsBounds.isInfinite()) {
418 level = numLevels - 1;
419 dvsBounds = f[field].field->mipLevel(level)->dataWindow();
421 for (
size_t i = 0; i < numLevels; ++i) {
425 const Box3i dw = f[field].field->mipLevel(level)->dataWindow();
427 if (f[field].doOsToWs) {
430 worldToVoxel(f[field].field->mipLevel(level)->mapping().get(),
433 worldToVoxel(f[field].field->mipLevel(level)->mapping().get(),
438 Imath::V3i size = dvsBounds.size();
439 if (std::max(size.x, std::max(size.y, size.z)) <= 2) {
445 for (
int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
446 for (
int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
447 for (
int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
448 const Data_T val = f[field].field->fastMipValue(level, i, j, k);
void worldToVoxel(const Field3D::FieldMapping *mapping, const Box3d &wsBounds, Box3d &vsBounds)
Computes a voxel space bounds given a bounding box in world space. This is done by transforming each ...
void transformBounds(const M44d &mtx, const Box3d &fromBounds, Box3d &toBounds)
Transforms a bounding box by a 4x4 matrix This is done by transforming each corner vertex from world ...
Box3i discreteBounds(const Box3d &bbox)
Converts a floating point bounding box to an integer bounding box.
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Contains typedefs for the commonly used types in Field3D.
T max(const T a, const T2 b)
Max operation on mixed types.
T min(const T a, const T2 b)
Min operation on mixed types.
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Interface for sampling a vector of fields of the same type.
WrapperVec_T::value_type::field_type Field_T
static void sampleMIP(const WrapperVec_T &f, const V3d &wsP, const float wsSpotSize, float *value, size_t &numHits)
static void sample(const WrapperVec_T &f, const V3d &wsP, float *value, size_t &numHits)
Field_T::value_type Data_T
static void sampleMultiple(const WrapperVec_T &f, const size_t neval, const float *wsPs, float *value, size_t *numHits)
static void getMinMaxMIP(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
static void getMinMax(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
static void sampleMIPMultiple(const WrapperVec_T &f, const size_t neval, const float *wsPs, const float *wsSpotSizes, float *value, size_t *numHits)
static void getMinMaxPrefilt(const WrapperVec_T &f, const Box3d &wsBounds, float *result, const Mode mode)
detail::ScalarOrVector< Dims_T >::type Input_T
Typedefs float or V3f, depending on Dims_T.