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>
39 FIELD3D_VEC3_T<T>
min(
const FIELD3D_VEC3_T<T> &a,
40 const FIELD3D_VEC3_T<T2> &b)
42 return FIELD3D_VEC3_T<T>(
std::min(a.x, static_cast<T>(b.x)),
48 template <
typename T,
typename T2>
49 FIELD3D_VEC3_T<T>
max(
const FIELD3D_VEC3_T<T> &a,
50 const FIELD3D_VEC3_T<T2> &b)
52 return FIELD3D_VEC3_T<T>(
std::max(a.x, static_cast<T>(b.x)),
80 template <
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,
97 Input_T *data = reinterpret_cast<Input_T*>(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];
133 Input_T *data = reinterpret_cast<Input_T*>(value);
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);
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)
192 Input_T *data = reinterpret_cast<Input_T*>(value);
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];
231 Input_T *data = reinterpret_cast<Input_T*>(value);
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);
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);
322 Input_T *minData = reinterpret_cast<Input_T*>(
min);
323 Input_T *maxData = reinterpret_cast<Input_T*>(
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);
364 Input_T *minData = reinterpret_cast<Input_T*>(
min);
365 Input_T *maxData = reinterpret_cast<Input_T*>(
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,
408 Input_T *data = reinterpret_cast<Input_T*>(result);
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(),
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);
468 #endif // include guard