Field3D
FieldSampler.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 #ifndef __F3DUTIL_FIELDSAMPLER_H__
4 #define __F3DUTIL_FIELDSAMPLER_H__
5 
6 //------------------------------------------------------------------------------
7 
8 // Project includes
9 #include "Types.h"
10 
11 //----------------------------------------------------------------------------//
12 
13 #include "ns.h"
14 
16 
17 //------------------------------------------------------------------------------
18 // FieldSampler
19 //------------------------------------------------------------------------------
20 
22 template <typename WrapperVec_T, int Dims_T>
24 {
25  static void sample(const WrapperVec_T &f, const V3d &p, float *value,
26  bool isVs);
27  static void sampleMIP(const WrapperVec_T &f, const V3d &p,
28  const float wsSpotSize, float *value, bool isVs);
29  static void getMinMax(const WrapperVec_T &f,
30  const Box3d &wsBounds, float *min, float *max);
31  static void getMinMaxMIP(const WrapperVec_T &f,
32  const Box3d &wsBounds, float *min, float *max);
33 };
34 
35 //------------------------------------------------------------------------------
36 
38 template <typename WrapperVec_T>
39 struct FieldSampler<WrapperVec_T, 1>
40 {
41  // Ordinary fields
42  static void sample(const WrapperVec_T &f, const V3d &p, float *value,
43  bool isVs)
44  {
45  if (isVs) {
46  for (size_t i = 0, end = f.size(); i < end; ++i) {
47  if (f[i].vsBounds.intersects(p)) {
48  *value += f[i].interp.sample(*f[i].field, p);
49  }
50  }
51  } else {
52  V3d vsP;
53  for (size_t i = 0, end = f.size(); i < end; ++i) {
54  f[i].mapping->worldToVoxel(p, vsP);
55  if (f[i].vsBounds.intersects(vsP)) {
56  *value += f[i].interp.sample(*f[i].field, vsP);
57  }
58  }
59  }
60  }
61  // MIP fields
62  static void sampleMIP(const WrapperVec_T &f, const V3d &p,
63  const float wsSpotSize, float *value, bool isVs)
64  {
65  if (isVs) {
66  for (size_t i = 0, end = f.size(); i < end; ++i) {
67  if (f[i].vsBounds.intersects(p)) {
68  *value += f[i].interp->sample(p, wsSpotSize);
69  }
70  }
71  } else {
72  V3d vsP;
73  for (size_t i = 0, end = f.size(); i < end; ++i) {
74  f[i].mapping->worldToVoxel(p, vsP);
75  if (f[i].vsBounds.intersects(vsP)) {
76  *value += f[i].interp->sample(vsP, wsSpotSize);
77  }
78  }
79  }
80  }
81  // Get min/max
82  static void getMinMax(const WrapperVec_T &f,
83  const Box3d &wsBounds, float *min, float *max)
84  {
85  for (size_t field = 0, end = f.size(); field < end; ++field) {
86  // Data window
87  const Box3i dw = f[field].field->dataWindow();
88  // Transform corners to voxel space and compute bounds
89  Box3d vsBounds;
90  worldToVoxel(f[field].mapping, wsBounds, vsBounds);
91  Box3i dvsBounds = clipBounds(discreteBounds(vsBounds), dw);
92  // Early termination if no intersection
93  if (!dw.intersects(dvsBounds)) {
94  return;
95  }
96  for (int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
97  for (int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
98  for (int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
99  float val = f[field].field->fastValue(i, j, k);
100  min[0] = std::min(val, min[0]);
101  max[0] = std::max(val, max[0]);
102  }
103  }
104  }
105  }
106  }
107  // Get min/max
108  static void getMinMaxMIP(const WrapperVec_T &f,
109  const Box3d &wsBounds, float *min, float *max)
110  {
111  for (size_t field = 0, end = f.size(); field < end; ++field) {
112  // Data window
113  const Box3i dw = f[field].field->dataWindow();
114  // Transform corners to voxel space and compute bounds
115  Box3d vsBounds;
116  worldToVoxel(f[field].mapping, wsBounds, vsBounds);
117  Box3i dvsBounds = clipBounds(discreteBounds(vsBounds), dw);
118  // Early termination if no intersection
119  if (!dw.intersects(dvsBounds)) {
120  return;
121  }
122  for (int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
123  for (int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
124  for (int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
125  float val = f[field].field->fastMipValue(0, i, j, k);
126  min[0] = std::min(val, min[0]);
127  max[0] = std::max(val, max[0]);
128  }
129  }
130  }
131  }
132  }
133 };
134 
135 //------------------------------------------------------------------------------
136 
138 template <typename WrapperVec_T>
139 struct FieldSampler<WrapperVec_T, 3>
140 {
141  // Ordinary fields
142  static void sample(const WrapperVec_T &f, const V3d &p, float *value,
143  bool isVs)
144  {
145  V3f v(value[0], value[1], value[2]);
146  if (isVs) {
147  for (size_t i = 0, end = f.size(); i < end; ++i) {
148  if (f[i].vsBounds.intersects(p)) {
149  v += f[i].interp.sample(*f[i].field, p);
150  }
151  }
152  } else {
153  V3d vsP;
154  for (size_t i = 0, end = f.size(); i < end; ++i) {
155  f[i].mapping->worldToVoxel(p, vsP);
156  if (f[i].vsBounds.intersects(vsP)) {
157  v += f[i].interp.sample(*f[i].field, vsP);
158  }
159  }
160  }
161  memcpy(value, &v[0], sizeof(V3f));
162  }
163 
164  // MIP fields
165  static void sampleMIP(const WrapperVec_T &f, const V3d &p,
166  const float wsSpotSize, float *value, bool isVs)
167  {
168  V3f v(value[0], value[1], value[2]);
169  if (isVs) {
170  for (size_t i = 0, end = f.size(); i < end; ++i) {
171  if (f[i].vsBounds.intersects(p)) {
172  v += f[i].interp->sample(p, wsSpotSize);
173  }
174  }
175  } else {
176  V3d vsP;
177  for (size_t i = 0, end = f.size(); i < end; ++i) {
178  f[i].mapping->worldToVoxel(p, vsP);
179  if (f[i].vsBounds.intersects(vsP)) {
180  v += f[i].interp->sample(vsP, wsSpotSize);
181  }
182  }
183  }
184  memcpy(value, &v[0], sizeof(V3f));
185  }
186 
187  static void getMinMax(const WrapperVec_T &f,
188  const Box3d &wsBounds, float *min, float *max)
189  {
190  for (size_t field = 0, end = f.size(); field < end; ++field) {
191  // Data window
192  const Box3i dw = f[field].field->dataWindow();
193  // Transform corners to voxel space and compute bounds
194  Box3d vsBounds;
195  worldToVoxel(f[field].mapping, wsBounds, vsBounds);
196  Box3i dvsBounds = clipBounds(discreteBounds(vsBounds), dw);
197  // Early termination if no intersection
198  if (!dw.intersects(dvsBounds)) {
199  return;
200  }
201  for (int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
202  for (int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
203  for (int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
204  V3f val = f[field].field->fastValue(i, j, k);
205  min[0] = std::min(val.x, min[0]);
206  min[1] = std::min(val.y, min[1]);
207  min[2] = std::min(val.z, min[2]);
208  max[0] = std::max(val.x, max[0]);
209  max[1] = std::max(val.y, max[1]);
210  max[2] = std::max(val.z, max[2]);
211  }
212  }
213  }
214  }
215  }
216 
217  static void getMinMaxMIP(const WrapperVec_T &f,
218  const Box3d &wsBounds, float *min, float *max)
219  {
220  for (size_t field = 0, end = f.size(); field < end; ++field) {
221  // Data window
222  const Box3i dw = f[field].field->dataWindow();
223  // Transform corners to voxel space and compute bounds
224  Box3d vsBounds;
225  worldToVoxel(f[field].mapping, wsBounds, vsBounds);
226  Box3i dvsBounds = clipBounds(discreteBounds(vsBounds), dw);
227  // Early termination if no intersection
228  if (!dw.intersects(dvsBounds)) {
229  return;
230  }
231  for (int k = dvsBounds.min.z; k <= dvsBounds.max.z; ++k) {
232  for (int j = dvsBounds.min.y; j <= dvsBounds.max.y; ++j) {
233  for (int i = dvsBounds.min.x; i <= dvsBounds.max.x; ++i) {
234  V3f val = f[field].field->fastMipValue(0, i, j, k);
235  min[0] = std::min(val.x, min[0]);
236  min[1] = std::min(val.y, min[1]);
237  min[2] = std::min(val.z, min[2]);
238  max[0] = std::max(val.x, max[0]);
239  max[1] = std::max(val.y, max[1]);
240  max[2] = std::max(val.z, max[2]);
241  }
242  }
243  }
244  }
245  }
246 };
247 
248 //----------------------------------------------------------------------------//
249 
251 
252 //------------------------------------------------------------------------------
253 
254 #endif // include guard
255 
256 //------------------------------------------------------------------------------
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
Definition: Field.h:1144
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains typedefs for the commonly used types in Field3D.
static void sample(const WrapperVec_T &f, const V3d &p, float *value, bool isVs)
Definition: FieldSampler.h:142
Interface for sampling a vector of fields of the same type.
Definition: FieldSampler.h:23
static void sampleMIP(const WrapperVec_T &f, const V3d &p, const float wsSpotSize, float *value, bool isVs)
Definition: FieldSampler.h:165
static void sample(const WrapperVec_T &f, const V3d &p, float *value, bool isVs)
Definition: FieldSampler.h:42
static void getMinMax(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
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 ...
static void getMinMax(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
Definition: FieldSampler.h:187
static void getMinMaxMIP(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
static void getMinMaxMIP(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
Definition: FieldSampler.h:217
Imath::Box3d Box3d
Definition: SpiMathLib.h:79
Imath::V3d V3d
Definition: SpiMathLib.h:74
Box3i discreteBounds(const Box3d &bbox)
Definition: Field.h:1130
static void getMinMaxMIP(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
Definition: FieldSampler.h:108
Imath::V3f V3f
Definition: SpiMathLib.h:73
static void sample(const WrapperVec_T &f, const V3d &p, float *value, bool isVs)
static void sampleMIP(const WrapperVec_T &f, const V3d &p, const float wsSpotSize, float *value, bool isVs)
static void getMinMax(const WrapperVec_T &f, const Box3d &wsBounds, float *min, float *max)
Definition: FieldSampler.h:82
static void sampleMIP(const WrapperVec_T &f, const V3d &p, const float wsSpotSize, float *value, bool isVs)
Definition: FieldSampler.h:62