Field3D
FieldInterp.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
44 //----------------------------------------------------------------------------//
45 
46 #ifndef _INCLUDED_Field3D_FieldInterp_H_
47 #define _INCLUDED_Field3D_FieldInterp_H_
48 
49 #include "Field.h"
50 #include "DenseField.h"
51 #include "MACField.h"
52 #include "ProceduralField.h"
53 #include "RefCount.h"
54 
55 //----------------------------------------------------------------------------//
56 
57 #include "ns.h"
58 
60 
61 //----------------------------------------------------------------------------//
62 // FieldInterp
63 //----------------------------------------------------------------------------//
64 
71 template <class Data_T>
72 class FieldInterp : public RefBase
73 {
74 public:
75 
76  // Typedefs ------------------------------------------------------------------
77 
78  typedef Data_T value_type;
79  typedef boost::intrusive_ptr<FieldInterp> Ptr;
80 
81  // RTTI replacement ----------------------------------------------------------
82 
85 
86  static const char *staticClassName()
87  {
88  return "FieldInterp";
89  }
90 
91  static const char* staticClassType()
92  {
93  return ms_classType.name();
94  }
95 
96  // Ctor, dtor ----------------------------------------------------------------
97 
98  virtual ~FieldInterp()
99  { }
100 
101  // Main methods --------------------------------------------------------------
102 
103  virtual Data_T sample(const Field<Data_T> &data, const V3d &vsP) const = 0;
104 
105 private:
106 
107  // Static data members -------------------------------------------------------
108 
110 
111  // Typedefs ------------------------------------------------------------------
112 
114  typedef RefBase base;
115 
116 };
117 
118 //----------------------------------------------------------------------------//
119 // Static member instantiation
120 //----------------------------------------------------------------------------//
121 
123 
124 //----------------------------------------------------------------------------//
125 // LinearFieldInterp
126 //----------------------------------------------------------------------------//
127 
128 /* \class LinearFieldInterp
129  \ingroup field
130  \brief Basic linear interpolator using voxel access through Field base class
131 */
132 
133 //----------------------------------------------------------------------------//
134 
135 template <class Data_T>
136 class LinearFieldInterp : public FieldInterp<Data_T>
137 {
138  public:
139 
140  // Typedefs ------------------------------------------------------------------
141 
142  typedef Data_T value_type;
143  typedef boost::intrusive_ptr<LinearFieldInterp> Ptr;
144 
145  // RTTI replacement ----------------------------------------------------------
146 
149 
150  static const char *staticClassName()
151  {
152  return "LinearFieldInterp";
153  }
154 
155  static const char* staticClassType()
156  {
157  return ms_classType.name();
158  }
159 
160  // From FieldInterp ----------------------------------------------------------
161 
162  virtual Data_T sample(const Field<Data_T> &data, const V3d &vsP) const;
163 
164 private:
165 
166  // Static data members -------------------------------------------------------
167 
169 
170  // Typedefs ------------------------------------------------------------------
171 
174 
175 };
176 
177 //----------------------------------------------------------------------------//
178 // Static data member instantiation
179 //----------------------------------------------------------------------------//
180 
182 
183 //----------------------------------------------------------------------------//
184 // CubicFieldInterp
185 //----------------------------------------------------------------------------//
186 
187 /* \class CubicFieldInterp
188  \ingroup field
189  \brief Basic cubic interpolator using voxel access through Field base class
190 */
191 
192 //----------------------------------------------------------------------------//
193 
194 template <class Data_T>
195 class CubicFieldInterp : public FieldInterp<Data_T>
196 {
197  public:
198 
199  // Typedefs ------------------------------------------------------------------
200 
201  typedef Data_T value_type;
202  typedef boost::intrusive_ptr<CubicFieldInterp> Ptr;
203 
204  // RTTI replacement ----------------------------------------------------------
205 
208 
209  static const char *staticClassName()
210  {
211  return "CubicFieldInterp";
212  }
213 
214  static const char* staticClassType()
215  {
216  return ms_classType.name();
217  }
218 
219  // From FieldInterp ----------------------------------------------------------
220 
221  virtual Data_T sample(const Field<Data_T> &data, const V3d &vsP) const;
222 
223 private:
224 
225  // Static data members -------------------------------------------------------
226 
228 
229  // Typedefs ------------------------------------------------------------------
230 
233 };
234 
235 //----------------------------------------------------------------------------//
236 // Static data member instantiation
237 //----------------------------------------------------------------------------//
238 
240 
241 //----------------------------------------------------------------------------//
242 // LinearGenericFieldInterp
243 //----------------------------------------------------------------------------//
244 
245 /* \class LinearGenericFieldInterp
246  \ingroup field
247  \brief Linear interpolator optimized for fields with a fastValue function
248 */
249 
250 //----------------------------------------------------------------------------//
251 
252 template <class Field_T>
253 class LinearGenericFieldInterp : public RefBase
254 {
255 public:
256 
257  // Typedefs ------------------------------------------------------------------
258 
259  typedef typename Field_T::value_type value_type;
260  typedef boost::intrusive_ptr<LinearGenericFieldInterp> Ptr;
261 
262  // RTTI replacement ----------------------------------------------------------
263 
266 
267  static const char *staticClassName()
268  {
269  return "LinearGenericFieldInterp";
270  }
271 
272  static const char* staticClassType()
273  {
274  return ms_classType.name();
275  }
276 
277  // Main methods --------------------------------------------------------------
278 
279  value_type sample(const Field_T &data, const V3d &vsP) const;
280 
281 private:
282 
283  // Static data members -------------------------------------------------------
284 
286 
287  // Typedefs ------------------------------------------------------------------
288 
290  typedef RefBase base;
291 
292 };
293 
294 //----------------------------------------------------------------------------//
295 // Static data member instantiation
296 //----------------------------------------------------------------------------//
297 
299 
300 //----------------------------------------------------------------------------//
301 // LinearMACFieldInterp
302 //----------------------------------------------------------------------------//
303 
304 /* \class LinearMACFieldInterp
305  \ingroup field
306  \brief Linear interpolator optimized for the MAC fields
307 */
308 
309 //----------------------------------------------------------------------------//
310 
311 template <class Data_T>
313 {
314 public:
315 
316  // Typedefs ------------------------------------------------------------------
317 
318  typedef Data_T value_type;
319  typedef boost::intrusive_ptr<LinearMACFieldInterp> Ptr;
320 
321  // RTTI replacement ----------------------------------------------------------
322 
325 
326  static const char *staticClassName()
327  {
328  return "LinearMACFieldInterp";
329  }
330 
332  static const char* staticClassType()
333  {
334  return ms_classType.name();
335  }
336 
337  // Main methods --------------------------------------------------------------
338 
339  Data_T sample(const MACField<Data_T> &data, const V3d &vsP) const;
340 
341  double sample(const MACField<Data_T> &data,
342  const MACComponent &comp,
343  const V3d &vsP) const;
344 
345 private:
346 
347  // Static data members -------------------------------------------------------
348 
350 
351  // Typedefs ------------------------------------------------------------------
352 
354  typedef RefBase base;
355 };
356 
357 //----------------------------------------------------------------------------//
358 // Static data member instantiation
359 //----------------------------------------------------------------------------//
360 
362 
363 //----------------------------------------------------------------------------//
364 // CubicGenericFieldInterp
365 //----------------------------------------------------------------------------//
366 
367 /* \class CubicGenericFieldInterp
368  \ingroup field
369  \brief Cubic interpolator optimized for fields with a fastValue function
370 */
371 
372 //----------------------------------------------------------------------------//
373 
374 template <class Field_T>
375 class CubicGenericFieldInterp : public RefBase
376 {
377 public:
378 
379  // Typedefs ------------------------------------------------------------------
380 
381  typedef typename Field_T::value_type value_type;
382  typedef boost::intrusive_ptr<CubicGenericFieldInterp> Ptr;
383 
384  // RTTI replacement ----------------------------------------------------------
385 
388 
389  static const char *staticClassName()
390  {
391  return "CubicGenericFieldInterp";
392  }
393 
394  static const char* staticClassType()
395  {
396  return ms_classType.name();
397  }
398 
399  // Main methods --------------------------------------------------------------
400 
401  value_type sample(const Field_T &data, const V3d &vsP) const;
402 
403 
404 private:
405 
406  // Static data members -------------------------------------------------------
407 
409 
410  // Typedefs ------------------------------------------------------------------
411 
413  typedef RefBase base;
414 };
415 
416 //----------------------------------------------------------------------------//
417 // Static data member instantiation
418 //----------------------------------------------------------------------------//
419 
421 
422 //----------------------------------------------------------------------------//
423 // CubicMACFieldInterp
424 //----------------------------------------------------------------------------//
425 
426 /* \class CubicMACFieldInterp
427  \ingroup field
428  \brief Linear interpolator optimized for MAC fields
429 */
430 
431 //----------------------------------------------------------------------------//
432 
433 template <class Data_T>
435 {
436 public:
437 
438  // Typedefs ------------------------------------------------------------------
439 
440  typedef Data_T value_type;
441  typedef boost::intrusive_ptr<CubicMACFieldInterp> Ptr;
442 
443  // RTTI replacement ----------------------------------------------------------
444 
447 
448  static const char *staticClassName()
449  {
450  return "CubicMACFieldInterp";
451  }
452 
453  static const char* staticClassType()
454  {
456  }
457 
458  // Main methods --------------------------------------------------------------
459 
460  Data_T sample(const MACField<Data_T> &data, const V3d &vsP) const;
461 
462 private:
463 
464  // Static data members -------------------------------------------------------
465 
467 
468  // Typedefs ------------------------------------------------------------------
469 
471  typedef RefBase base;
472 };
473 
474 //----------------------------------------------------------------------------//
475 // Static data member instantiation
476 //----------------------------------------------------------------------------//
477 
479 
480 //----------------------------------------------------------------------------//
481 // ProceduralFieldLookup
482 //----------------------------------------------------------------------------//
483 
484 /* \class ProceduralFieldLookup
485  \ingroup field
486  \brief "Interpolator" for procedural fields - point samples instead of
487  interpolating.
488 */
489 
490 //----------------------------------------------------------------------------//
491 
492 template <class Data_T>
494 {
495 public:
496 
497  // Typedefs ------------------------------------------------------------------
498 
499  typedef Data_T value_type;
500  typedef boost::intrusive_ptr<ProceduralFieldLookup> Ptr;
501 
502  // RTTI replacement ----------------------------------------------------------
503 
506 
507  static const char *staticClassName()
508  {
509  return "ProceduralFieldLookup";
510  }
511 
512  static const char* staticClassType()
513  {
515  }
516 
517  // Main methods --------------------------------------------------------------
518 
519  Data_T sample(const ProceduralField<Data_T> &data, const V3d &vsP) const;
520 
521 private:
522 
523  // Static data members -------------------------------------------------------
524 
526 
527  // Typedefs ------------------------------------------------------------------
528 
530  typedef RefBase base;
531 
532 };
533 
534 //----------------------------------------------------------------------------//
535 // Static data member instantiation
536 //----------------------------------------------------------------------------//
537 
539 
540 //----------------------------------------------------------------------------//
541 // Interpolation functions
542 //----------------------------------------------------------------------------//
543 
545 template <class Data_T>
546 Data_T wsSample(const typename Field<Data_T>::Ptr f,
547  const FieldInterp<Data_T> &interp,
548  const V3d &wsP)
549 {
550  V3d vsP;
551  f->mapping()->worldToVoxel(wsP, vsP);
552  return interp.sample(*f, vsP);
553 }
554 
555 //----------------------------------------------------------------------------//
556 // Interpolation helper functions
557 //----------------------------------------------------------------------------//
558 
560 bool isPointInField(const FieldRes::Ptr f, const V3d &wsP);
561 
562 //----------------------------------------------------------------------------//
563 
566 bool isLegalVoxelCoord(const V3d &vsP, const Box3d &vsDataWindow);
567 
568 //----------------------------------------------------------------------------//
569 // Math functions
570 //----------------------------------------------------------------------------//
571 
574 template <class S, class T>
575 FIELD3D_VEC3_T<T> operator * (S s, const FIELD3D_VEC3_T<T> vec);
576 
577 //----------------------------------------------------------------------------//
578 // Interpolants
579 //----------------------------------------------------------------------------//
580 
585 template <class Data_T>
586 Data_T monotonicCubicInterpolant(const Data_T &f1, const Data_T &f2,
587  const Data_T &f3, const Data_T &f4,
588  double t);
589 
590 //----------------------------------------------------------------------------//
591 
596 template <class Data_T>
597 Data_T monotonicCubicInterpolantVec(const Data_T &f1, const Data_T &f2,
598  const Data_T &f3, const Data_T &f4,
599  double t);
600 
601 //----------------------------------------------------------------------------//
602 // Implementations
603 //----------------------------------------------------------------------------//
604 
605 template <class Data_T>
607  const V3d &vsP) const
608 {
609  // Voxel centers are at .5 coordinates
610  // NOTE: Don't use contToDisc for this, we're looking for sample
611  // point locations, not coordinate shifts.
612  FIELD3D_VEC3_T<double> p(vsP - FIELD3D_VEC3_T<double>(0.5));
613 
614  // Lower left corner
615  V3i c1(static_cast<int>(floor(p.x)),
616  static_cast<int>(floor(p.y)),
617  static_cast<int>(floor(p.z)));
618  // Upper right corner
619  V3i c2(c1 + V3i(1));
620  // C1 fractions
621  FIELD3D_VEC3_T<double> f1(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
622  // C2 fraction
623  FIELD3D_VEC3_T<double> f2(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
624 
625  // Clamp the indexing coordinates
626  if (true) {
627  const Box3i &dataWindow = data.dataWindow();
628  c1.x = std::max(dataWindow.min.x, std::min(c1.x, dataWindow.max.x));
629  c2.x = std::max(dataWindow.min.x, std::min(c2.x, dataWindow.max.x));
630  c1.y = std::max(dataWindow.min.y, std::min(c1.y, dataWindow.max.y));
631  c2.y = std::max(dataWindow.min.y, std::min(c2.y, dataWindow.max.y));
632  c1.z = std::max(dataWindow.min.z, std::min(c1.z, dataWindow.max.z));
633  c2.z = std::max(dataWindow.min.z, std::min(c2.z, dataWindow.max.z));
634  }
635 
636  return static_cast<Data_T>
637  (f1.x * (f1.y * (f1.z * data.value(c1.x, c1.y, c1.z) +
638  f2.z * data.value(c1.x, c1.y, c2.z)) +
639  f2.y * (f1.z * data.value(c1.x, c2.y, c1.z) +
640  f2.z * data.value(c1.x, c2.y, c2.z))) +
641  f2.x * (f1.y * (f1.z * data.value(c2.x, c1.y, c1.z) +
642  f2.z * data.value(c2.x, c1.y, c2.z)) +
643  f2.y * (f1.z * data.value(c2.x, c2.y, c1.z) +
644  f2.z * data.value(c2.x, c2.y, c2.z))));
645 
646 }
647 
648 //----------------------------------------------------------------------------//
649 
650 template <class Data_T>
652  const V3d &vsP) const
653 {
654  // Voxel centers are at .5 coordinates
655  // NOTE: Don't use contToDisc for this, we're looking for sample
656  // point locations, not coordinate shifts.
657  V3d clampedVsP(std::max(0.5, vsP.x),
658  std::max(0.5, vsP.y),
659  std::max(0.5, vsP.z));
660  FIELD3D_VEC3_T<double> p(clampedVsP - FIELD3D_VEC3_T<double>(0.5));
661 
662  // Lower left corner
663  V3i c(static_cast<int>(floor(p.x)),
664  static_cast<int>(floor(p.y)),
665  static_cast<int>(floor(p.z)));
666 
667  // Fractions
668  FIELD3D_VEC3_T<double> t(p - static_cast<FIELD3D_VEC3_T<double> >(c));
669 
670  const Box3i &dataWindow = data.dataWindow();
671 
672  // Clamp the coordinates
673  int im, jm, km;
674  im = std::max(dataWindow.min.x, std::min(c.x, dataWindow.max.x));
675  jm = std::max(dataWindow.min.y, std::min(c.y, dataWindow.max.y));
676  km = std::max(dataWindow.min.z, std::min(c.z, dataWindow.max.z));
677  int im_1, jm_1, km_1;
678  im_1 = std::max(dataWindow.min.x, std::min(im - 1, dataWindow.max.x));
679  jm_1 = std::max(dataWindow.min.y, std::min(jm - 1, dataWindow.max.y));
680  km_1 = std::max(dataWindow.min.z, std::min(km - 1, dataWindow.max.z));
681  int im1, jm1, km1;
682  im1 = std::max(dataWindow.min.x, std::min(im + 1, dataWindow.max.x));
683  jm1 = std::max(dataWindow.min.y, std::min(jm + 1, dataWindow.max.y));
684  km1 = std::max(dataWindow.min.z, std::min(km + 1, dataWindow.max.z));
685  int im2, jm2, km2;
686  im2 = std::max(dataWindow.min.x, std::min(im + 2, dataWindow.max.x));
687  jm2 = std::max(dataWindow.min.y, std::min(jm + 2, dataWindow.max.y));
688  km2 = std::max(dataWindow.min.z, std::min(km + 2, dataWindow.max.z));
689 
690  // interpolate 16 lines in z:
691  Data_T z11 = monotonicCubicInterpolant(data.value(im_1, jm_1, km_1),
692  data.value(im_1, jm_1, km),
693  data.value(im_1, jm_1, km1),
694  data.value(im_1, jm_1, km2), t.z);
695  Data_T z12 = monotonicCubicInterpolant(data.value(im_1, jm, km_1),
696  data.value(im_1, jm, km),
697  data.value(im_1, jm, km1),
698  data.value(im_1, jm, km2), t.z);
699  Data_T z13 = monotonicCubicInterpolant(data.value(im_1, jm1, km_1),
700  data.value(im_1, jm1, km),
701  data.value(im_1, jm1, km1),
702  data.value(im_1, jm1, km2), t.z);
703  Data_T z14 = monotonicCubicInterpolant(data.value(im_1, jm2, km_1),
704  data.value(im_1, jm2, km),
705  data.value(im_1, jm2, km1),
706  data.value(im_1, jm2, km2), t.z);
707 
708  Data_T z21 = monotonicCubicInterpolant(data.value(im, jm_1, km_1),
709  data.value(im, jm_1, km),
710  data.value(im, jm_1, km1),
711  data.value(im, jm_1, km2), t.z);
712  Data_T z22 = monotonicCubicInterpolant(data.value(im, jm, km_1),
713  data.value(im, jm, km),
714  data.value(im, jm, km1),
715  data.value(im, jm, km2), t.z);
716  Data_T z23 = monotonicCubicInterpolant(data.value(im, jm1, km_1),
717  data.value(im, jm1, km),
718  data.value(im, jm1, km1),
719  data.value(im, jm1, km2), t.z);
720  Data_T z24 = monotonicCubicInterpolant(data.value(im, jm2, km_1),
721  data.value(im, jm2, km),
722  data.value(im, jm2, km1),
723  data.value(im, jm2, km2), t.z);
724 
725  Data_T z31 = monotonicCubicInterpolant(data.value(im1, jm_1, km_1),
726  data.value(im1, jm_1, km),
727  data.value(im1, jm_1, km1),
728  data.value(im1, jm_1, km2), t.z);
729  Data_T z32 = monotonicCubicInterpolant(data.value(im1, jm, km_1),
730  data.value(im1, jm, km),
731  data.value(im1, jm, km1),
732  data.value(im1, jm, km2), t.z);
733  Data_T z33 = monotonicCubicInterpolant(data.value(im1, jm1, km_1),
734  data.value(im1, jm1, km),
735  data.value(im1, jm1, km1),
736  data.value(im1, jm1, km2), t.z);
737  Data_T z34 = monotonicCubicInterpolant(data.value(im1, jm2, km_1),
738  data.value(im1, jm2, km),
739  data.value(im1, jm2, km1),
740  data.value(im1, jm2, km2), t.z);
741 
742  Data_T z41 = monotonicCubicInterpolant(data.value(im2, jm_1, km_1),
743  data.value(im2, jm_1, km),
744  data.value(im2, jm_1, km1),
745  data.value(im2, jm_1, km2), t.z);
746  Data_T z42 = monotonicCubicInterpolant(data.value(im2, jm, km_1),
747  data.value(im2, jm, km),
748  data.value(im2, jm, km1),
749  data.value(im2, jm, km2), t.z);
750  Data_T z43 = monotonicCubicInterpolant(data.value(im2, jm1, km_1),
751  data.value(im2, jm1, km),
752  data.value(im2, jm1, km1),
753  data.value(im2, jm1, km2), t.z);
754  Data_T z44 = monotonicCubicInterpolant(data.value(im2, jm2, km_1),
755  data.value(im2, jm2, km),
756  data.value(im2, jm2, km1),
757  data.value(im2, jm2, km2), t.z);
758 
759  Data_T y1 = monotonicCubicInterpolant(z11, z12, z13, z14, t.y);
760  Data_T y2 = monotonicCubicInterpolant(z21, z22, z23, z24, t.y);
761  Data_T y3 = monotonicCubicInterpolant(z31, z32, z33, z34, t.y);
762  Data_T y4 = monotonicCubicInterpolant(z41, z42, z43, z44, t.y);
763 
764  Data_T z0 = monotonicCubicInterpolant(y1, y2, y3, y4, t.x);
765 
766  return z0;
767 }
768 
769 //----------------------------------------------------------------------------//
770 
771 template <class Field_T>
772 typename Field_T::value_type
774  const V3d &vsP) const
775 {
776  typedef typename Field_T::value_type Data_T;
777 
778  // Pixel centers are at .5 coordinates
779  // NOTE: Don't use contToDisc for this, we're looking for sample
780  // point locations, not coordinate shifts.
781  FIELD3D_VEC3_T<double> p(vsP - FIELD3D_VEC3_T<double>(0.5));
782 
783  // Lower left corner
784  V3i c1(static_cast<int>(floor(p.x)),
785  static_cast<int>(floor(p.y)),
786  static_cast<int>(floor(p.z)));
787  // Upper right corner
788  V3i c2(c1 + V3i(1));
789  // C1 fractions
790  FIELD3D_VEC3_T<double> f1(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
791  // C2 fraction
792  FIELD3D_VEC3_T<double> f2(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
793 
794  const Box3i &dataWindow = data.dataWindow();
795 
796  // Clamp the coordinates
797  c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
798  c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
799  c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
800  c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
801  c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
802  c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
803 
804  return static_cast<Data_T>
805  (f1.x * (f1.y * (f1.z * data.fastValue(c1.x, c1.y, c1.z) +
806  f2.z * data.fastValue(c1.x, c1.y, c2.z)) +
807  f2.y * (f1.z * data.fastValue(c1.x, c2.y, c1.z) +
808  f2.z * data.fastValue(c1.x, c2.y, c2.z))) +
809  f2.x * (f1.y * (f1.z * data.fastValue(c2.x, c1.y, c1.z) +
810  f2.z * data.fastValue(c2.x, c1.y, c2.z)) +
811  f2.y * (f1.z * data.fastValue(c2.x, c2.y, c1.z) +
812  f2.z * data.fastValue(c2.x, c2.y, c2.z))));
813 }
814 
815 //----------------------------------------------------------------------------//
816 
817 template <class Data_T>
819  const V3d &vsP) const
820 {
821  // Pixel centers are at .5 coordinates
822  // NOTE: Don't use contToDisc for this, we're looking for sample
823  // point locations, not coordinate shifts.
824 
825  const Box3i &dataWindow = data.dataWindow();
826 
827  Data_T ret;
828 
829  FIELD3D_VEC3_T<double> p(vsP.x , vsP.y - 0.5, vsP.z - 0.5);
830 
831  // X component ---
832 
833  // Lower left corner
834  V3i c1(static_cast<int>(floor(p.x)),
835  static_cast<int>(floor(p.y)),
836  static_cast<int>(floor(p.z)));
837 
838  // Upper right corner
839  V3i c2(c1 + V3i(1));
840 
841  // C1 fractions
842  FIELD3D_VEC3_T<double> f1(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
843  // C2 fraction
844  FIELD3D_VEC3_T<double> f2(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
845 
846  // Clamp the coordinates
847  c1.x = std::min(dataWindow.max.x + 1, std::max(dataWindow.min.x, c1.x));
848  c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
849  c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
850  c2.x = std::min(dataWindow.max.x + 1, std::max(dataWindow.min.x, c2.x));
851  c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
852  c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
853 
854  ret.x = (f1.x * (f1.y * (f1.z * data.u(c1.x, c1.y, c1.z) +
855  f2.z * data.u(c1.x, c1.y, c2.z)) +
856  f2.y * (f1.z * data.u(c1.x, c2.y, c1.z) +
857  f2.z * data.u(c1.x, c2.y, c2.z))) +
858  f2.x * (f1.y * (f1.z * data.u(c2.x, c1.y, c1.z) +
859  f2.z * data.u(c2.x, c1.y, c2.z)) +
860  f2.y * (f1.z * data.u(c2.x, c2.y, c1.z) +
861  f2.z * data.u(c2.x, c2.y, c2.z))));
862 
863  // Y component ---
864 
865  p.setValue(vsP.x - 0.5, vsP.y , vsP.z - 0.5);
866 
867  // Lower left corner
868  c1.x = static_cast<int>(floor(p.x ));
869  c1.y = static_cast<int>(floor(p.y ));
870  c1.z = static_cast<int>(floor(p.z ));
871 
872  // Upper right corner
873  c2.x = c1.x + 1;
874  c2.y = c1.y + 1;
875  c2.z = c1.z + 1;
876 
877  // C1 fractions
878  f1.setValue(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
879  // C2 fraction
880  f2.setValue(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
881 
882  // Clamp the coordinates
883  c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
884  c1.y = std::min(dataWindow.max.y + 1, std::max(dataWindow.min.y, c1.y));
885  c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
886  c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
887  c2.y = std::min(dataWindow.max.y + 1, std::max(dataWindow.min.y, c2.y));
888  c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
889 
890  ret.y = (f1.x * (f1.y * (f1.z * data.v(c1.x, c1.y, c1.z) +
891  f2.z * data.v(c1.x, c1.y, c2.z)) +
892  f2.y * (f1.z * data.v(c1.x, c2.y, c1.z) +
893  f2.z * data.v(c1.x, c2.y, c2.z))) +
894  f2.x * (f1.y * (f1.z * data.v(c2.x, c1.y, c1.z) +
895  f2.z * data.v(c2.x, c1.y, c2.z)) +
896  f2.y * (f1.z * data.v(c2.x, c2.y, c1.z) +
897  f2.z * data.v(c2.x, c2.y, c2.z))));
898 
899  // Z component ---
900 
901  p.setValue(vsP.x - 0.5 , vsP.y - 0.5, vsP.z);
902 
903  // Lower left corner
904  c1.x = static_cast<int>(floor(p.x ));
905  c1.y = static_cast<int>(floor(p.y ));
906  c1.z = static_cast<int>(floor(p.z ));
907 
908  // Upper right corner
909  c2.x = c1.x + 1;
910  c2.y = c1.y + 1;
911  c2.z = c1.z + 1;
912 
913  // C1 fractions
914  f1.setValue(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
915  // C2 fraction
916  f2.setValue(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
917 
918  // Clamp the coordinates
919  c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
920  c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
921  c1.z = std::min(dataWindow.max.z + 1, std::max(dataWindow.min.z, c1.z));
922  c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
923  c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
924  c2.z = std::min(dataWindow.max.z + 1, std::max(dataWindow.min.z, c2.z));
925 
926  ret.z = (f1.x * (f1.y * (f1.z * data.w(c1.x, c1.y, c1.z) +
927  f2.z * data.w(c1.x, c1.y, c2.z)) +
928  f2.y * (f1.z * data.w(c1.x, c2.y, c1.z) +
929  f2.z * data.w(c1.x, c2.y, c2.z))) +
930  f2.x * (f1.y * (f1.z * data.w(c2.x, c1.y, c1.z) +
931  f2.z * data.w(c2.x, c1.y, c2.z)) +
932  f2.y * (f1.z * data.w(c2.x, c2.y, c1.z) +
933  f2.z * data.w(c2.x, c2.y, c2.z))));
934 
935  return ret;
936 }
937 
938 //----------------------------------------------------------------------------//
939 
940 template <class Data_T>
942  const MACComponent &comp,
943  const V3d &vsP) const
944 {
945  // Pixel centers are at .5 coordinates
946  // NOTE: Don't use contToDisc for this, we're looking for sample
947  // point locations, not coordinate shifts.
948 
949  const Box3i &dataWindow = data.dataWindow();
950 
951  double ret = 0.0;
952  FIELD3D_VEC3_T<double> p;
953  V3i c1, c2;
954  FIELD3D_VEC3_T<double> f1;
955  FIELD3D_VEC3_T<double> f2;
956 
957  switch(comp) {
958  // U component ---
959  case MACCompU:
960  {
961  p.setValue<>(vsP.x, vsP.y-0.5, vsP.z-0.5);
962 
963  // Lower left corner
964  c1.x = static_cast<int>(floor(p.x));
965  c1.y = static_cast<int>(floor(p.y));
966  c1.z = static_cast<int>(floor(p.z));
967 
968  // Upper right corner
969  c2.x = c1.x + 1;
970  c2.y = c1.y + 1;
971  c2.z = c1.z + 1;
972 
973  // C1 fractions
974  f1.setValue(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
975  // C2 fraction
976  f2.setValue(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
977 
978  // Clamp the coordinates
979  c1.x = std::min(dataWindow.max.x + 1, std::max(dataWindow.min.x, c1.x));
980  c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
981  c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
982  c2.x = std::min(dataWindow.max.x + 1, std::max(dataWindow.min.x, c2.x));
983  c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
984  c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
985 
986  ret = (f1.x * (f1.y * (f1.z * data.u(c1.x, c1.y, c1.z) +
987  f2.z * data.u(c1.x, c1.y, c2.z)) +
988  f2.y * (f1.z * data.u(c1.x, c2.y, c1.z) +
989  f2.z * data.u(c1.x, c2.y, c2.z))) +
990  f2.x * (f1.y * (f1.z * data.u(c2.x, c1.y, c1.z) +
991  f2.z * data.u(c2.x, c1.y, c2.z)) +
992  f2.y * (f1.z * data.u(c2.x, c2.y, c1.z) +
993  f2.z * data.u(c2.x, c2.y, c2.z))));
994  break;
995  }
996  // Y component ---
997  case MACCompV:
998  {
999  p.setValue(vsP.x-0.5, vsP.y, vsP.z-0.5);
1000 
1001  // Lower left corner
1002  c1.x = static_cast<int>(floor(p.x ));
1003  c1.y = static_cast<int>(floor(p.y ));
1004  c1.z = static_cast<int>(floor(p.z ));
1005 
1006  // Upper right corner
1007  c2.x = c1.x + 1;
1008  c2.y = c1.y + 1;
1009  c2.z = c1.z + 1;
1010 
1011  // C1 fractions
1012  f1.setValue(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
1013  // C2 fraction
1014  f2.setValue(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
1015 
1016  // Clamp the coordinates
1017  c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
1018  c1.y = std::min(dataWindow.max.y + 1, std::max(dataWindow.min.y, c1.y));
1019  c1.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c1.z));
1020  c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
1021  c2.y = std::min(dataWindow.max.y + 1, std::max(dataWindow.min.y, c2.y));
1022  c2.z = std::min(dataWindow.max.z, std::max(dataWindow.min.z, c2.z));
1023 
1024  ret = (f1.x * (f1.y * (f1.z * data.v(c1.x, c1.y, c1.z) +
1025  f2.z * data.v(c1.x, c1.y, c2.z)) +
1026  f2.y * (f1.z * data.v(c1.x, c2.y, c1.z) +
1027  f2.z * data.v(c1.x, c2.y, c2.z))) +
1028  f2.x * (f1.y * (f1.z * data.v(c2.x, c1.y, c1.z) +
1029  f2.z * data.v(c2.x, c1.y, c2.z)) +
1030  f2.y * (f1.z * data.v(c2.x, c2.y, c1.z) +
1031  f2.z * data.v(c2.x, c2.y, c2.z))));
1032  break;
1033  }
1034  // W component ---
1035  case MACCompW:
1036  {
1037  p.setValue(vsP.x-0.5, vsP.y-0.5, vsP.z);
1038 
1039  // Lower left corner
1040  c1.x = static_cast<int>(floor(p.x ));
1041  c1.y = static_cast<int>(floor(p.y ));
1042  c1.z = static_cast<int>(floor(p.z ));
1043 
1044  // Upper right corner
1045  c2.x = c1.x + 1;
1046  c2.y = c1.y + 1;
1047  c2.z = c1.z + 1;
1048 
1049  // C1 fractions
1050  f1.setValue(static_cast<FIELD3D_VEC3_T<double> >(c2) - p);
1051  // C2 fraction
1052  f2.setValue(static_cast<FIELD3D_VEC3_T<double> >(1.0) - f1);
1053 
1054  // Clamp the coordinates
1055  c1.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c1.x));
1056  c1.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c1.y));
1057  c1.z = std::min(dataWindow.max.z + 1, std::max(dataWindow.min.z, c1.z));
1058  c2.x = std::min(dataWindow.max.x, std::max(dataWindow.min.x, c2.x));
1059  c2.y = std::min(dataWindow.max.y, std::max(dataWindow.min.y, c2.y));
1060  c2.z = std::min(dataWindow.max.z + 1, std::max(dataWindow.min.z, c2.z));
1061 
1062  ret = (f1.x * (f1.y * (f1.z * data.w(c1.x, c1.y, c1.z) +
1063  f2.z * data.w(c1.x, c1.y, c2.z)) +
1064  f2.y * (f1.z * data.w(c1.x, c2.y, c1.z) +
1065  f2.z * data.w(c1.x, c2.y, c2.z))) +
1066  f2.x * (f1.y * (f1.z * data.w(c2.x, c1.y, c1.z) +
1067  f2.z * data.w(c2.x, c1.y, c2.z)) +
1068  f2.y * (f1.z * data.w(c2.x, c2.y, c1.z) +
1069  f2.z * data.w(c2.x, c2.y, c2.z))));
1070  break;
1071  }
1072  default:
1073  break;
1074  }
1075 
1076  return ret;
1077 }
1078 
1079 //----------------------------------------------------------------------------//
1080 
1081 template <class Field_T>
1082 typename Field_T::value_type
1084  const V3d &vsP) const
1085 {
1086  typedef typename Field_T::value_type Data_T;
1087 
1088  // Pixel centers are at .5 coordinates
1089  // NOTE: Don't use contToDisc for this, we're looking for sample
1090  // point locations, not coordinate shifts.
1091  V3d clampedVsP(std::max(0.5, vsP.x),
1092  std::max(0.5, vsP.y),
1093  std::max(0.5, vsP.z));
1094  FIELD3D_VEC3_T<double> p(clampedVsP - FIELD3D_VEC3_T<double>(0.5));
1095 
1096  const Box3i &dataWindow = data.dataWindow();
1097 
1098  // Lower left corner
1099  V3i c(static_cast<int>(floor(p.x)),
1100  static_cast<int>(floor(p.y)),
1101  static_cast<int>(floor(p.z)));
1102 
1103  // Fractions
1104  FIELD3D_VEC3_T<double> t(p - static_cast<FIELD3D_VEC3_T<double> >(c));
1105 
1106  // Clamp the coordinates
1107  int im, jm, km;
1108  im = std::max(dataWindow.min.x, std::min(c.x, dataWindow.max.x));
1109  jm = std::max(dataWindow.min.y, std::min(c.y, dataWindow.max.y));
1110  km = std::max(dataWindow.min.z, std::min(c.z, dataWindow.max.z));
1111  int im_1, jm_1, km_1;
1112  im_1 = std::max(dataWindow.min.x, std::min(im - 1, dataWindow.max.x));
1113  jm_1 = std::max(dataWindow.min.y, std::min(jm - 1, dataWindow.max.y));
1114  km_1 = std::max(dataWindow.min.z, std::min(km - 1, dataWindow.max.z));
1115  int im1, jm1, km1;
1116  im1 = std::max(dataWindow.min.x, std::min(im + 1, dataWindow.max.x));
1117  jm1 = std::max(dataWindow.min.y, std::min(jm + 1, dataWindow.max.y));
1118  km1 = std::max(dataWindow.min.z, std::min(km + 1, dataWindow.max.z));
1119  int im2, jm2, km2;
1120  im2 = std::max(dataWindow.min.x, std::min(im + 2, dataWindow.max.x));
1121  jm2 = std::max(dataWindow.min.y, std::min(jm + 2, dataWindow.max.y));
1122  km2 = std::max(dataWindow.min.z, std::min(km + 2, dataWindow.max.z));
1123 
1124  Data_T z11 = monotonicCubicInterpolant(data.fastValue(im_1, jm_1, km_1),
1125  data.fastValue(im_1, jm_1, km),
1126  data.fastValue(im_1, jm_1, km1),
1127  data.fastValue(im_1, jm_1, km2), t.z);
1128  Data_T z12 = monotonicCubicInterpolant(data.fastValue(im_1, jm, km_1),
1129  data.fastValue(im_1, jm, km),
1130  data.fastValue(im_1, jm, km1),
1131  data.fastValue(im_1, jm, km2), t.z);
1132  Data_T z13 = monotonicCubicInterpolant(data.fastValue(im_1, jm1, km_1),
1133  data.fastValue(im_1, jm1, km),
1134  data.fastValue(im_1, jm1, km1),
1135  data.fastValue(im_1, jm1, km2), t.z);
1136  Data_T z14 = monotonicCubicInterpolant(data.fastValue(im_1, jm2, km_1),
1137  data.fastValue(im_1, jm2, km),
1138  data.fastValue(im_1, jm2, km1),
1139  data.fastValue(im_1, jm2, km2), t.z);
1140 
1141  Data_T z21 = monotonicCubicInterpolant(data.fastValue(im, jm_1, km_1),
1142  data.fastValue(im, jm_1, km),
1143  data.fastValue(im, jm_1, km1),
1144  data.fastValue(im, jm_1, km2), t.z);
1145  Data_T z22 = monotonicCubicInterpolant(data.fastValue(im, jm, km_1),
1146  data.fastValue(im, jm, km),
1147  data.fastValue(im, jm, km1),
1148  data.fastValue(im, jm, km2), t.z);
1149  Data_T z23 = monotonicCubicInterpolant(data.fastValue(im, jm1, km_1),
1150  data.fastValue(im, jm1, km),
1151  data.fastValue(im, jm1, km1),
1152  data.fastValue(im, jm1, km2), t.z);
1153  Data_T z24 = monotonicCubicInterpolant(data.fastValue(im, jm2, km_1),
1154  data.fastValue(im, jm2, km),
1155  data.fastValue(im, jm2, km1),
1156  data.fastValue(im, jm2, km2), t.z);
1157 
1158  Data_T z31 = monotonicCubicInterpolant(data.fastValue(im1, jm_1, km_1),
1159  data.fastValue(im1, jm_1, km),
1160  data.fastValue(im1, jm_1, km1),
1161  data.fastValue(im1, jm_1, km2), t.z);
1162  Data_T z32 = monotonicCubicInterpolant(data.fastValue(im1, jm, km_1),
1163  data.fastValue(im1, jm, km),
1164  data.fastValue(im1, jm, km1),
1165  data.fastValue(im1, jm, km2), t.z);
1166  Data_T z33 = monotonicCubicInterpolant(data.fastValue(im1, jm1, km_1),
1167  data.fastValue(im1, jm1, km),
1168  data.fastValue(im1, jm1, km1),
1169  data.fastValue(im1, jm1, km2), t.z);
1170  Data_T z34 = monotonicCubicInterpolant(data.fastValue(im1, jm2, km_1),
1171  data.fastValue(im1, jm2, km),
1172  data.fastValue(im1, jm2, km1),
1173  data.fastValue(im1, jm2, km2), t.z);
1174 
1175  Data_T z41 = monotonicCubicInterpolant(data.fastValue(im2, jm_1, km_1),
1176  data.fastValue(im2, jm_1, km),
1177  data.fastValue(im2, jm_1, km1),
1178  data.fastValue(im2, jm_1, km2), t.z);
1179  Data_T z42 = monotonicCubicInterpolant(data.fastValue(im2, jm, km_1),
1180  data.fastValue(im2, jm, km),
1181  data.fastValue(im2, jm, km1),
1182  data.fastValue(im2, jm, km2), t.z);
1183  Data_T z43 = monotonicCubicInterpolant(data.fastValue(im2, jm1, km_1),
1184  data.fastValue(im2, jm1, km),
1185  data.fastValue(im2, jm1, km1),
1186  data.fastValue(im2, jm1, km2), t.z);
1187  Data_T z44 = monotonicCubicInterpolant(data.fastValue(im2, jm2, km_1),
1188  data.fastValue(im2, jm2, km),
1189  data.fastValue(im2, jm2, km1),
1190  data.fastValue(im2, jm2, km2), t.z);
1191 
1192  Data_T y1 = monotonicCubicInterpolant(z11, z12, z13, z14, t.y);
1193  Data_T y2 = monotonicCubicInterpolant(z21, z22, z23, z24, t.y);
1194  Data_T y3 = monotonicCubicInterpolant(z31, z32, z33, z34, t.y);
1195  Data_T y4 = monotonicCubicInterpolant(z41, z42, z43, z44, t.y);
1196 
1197  Data_T z0 = monotonicCubicInterpolant(y1, y2, y3, y4, t.x);
1198 
1199  return z0;
1200 }
1201 
1202 //----------------------------------------------------------------------------//
1203 
1204 template <class Data_T>
1206  const V3d &vsP) const
1207 {
1208  typedef typename Data_T::BaseType T;
1209 
1210  const Box3i &dataWindow = data.dataWindow();
1211 
1212  // Pixel centers are at .5 coordinates
1213  // NOTE: Don't use contToDisc for this, we're looking for sample
1214  // point locations, not coordinate shifts.
1215 
1216  Data_T ret;
1217 
1218  // X component ---
1219 
1220  V3d clampedVsP(std::max(0.5, vsP.x),
1221  std::max(0.5, vsP.y),
1222  std::max(0.5, vsP.z));
1223  FIELD3D_VEC3_T<double> p(vsP.x,
1224  clampedVsP.y - 0.5,
1225  clampedVsP.z - 0.5);
1226 
1227  // Lower left corner
1228  V3i c(static_cast<int>(floor(p.x)),
1229  static_cast<int>(floor(p.y)),
1230  static_cast<int>(floor(p.z)));
1231 
1232  FIELD3D_VEC3_T<double> t(p - static_cast<FIELD3D_VEC3_T<double> >(c));
1233 
1234  {
1235  // Clamp the coordinates
1236  int im, jm, km;
1237  im = std::max(dataWindow.min.x, std::min(c.x, dataWindow.max.x + 1));
1238  jm = std::max(dataWindow.min.y, std::min(c.y, dataWindow.max.y));
1239  km = std::max(dataWindow.min.z, std::min(c.z, dataWindow.max.z));
1240  int im_1, jm_1, km_1;
1241  im_1 = std::max(dataWindow.min.x, std::min(im - 1, dataWindow.max.x + 1));
1242  jm_1 = std::max(dataWindow.min.y, std::min(jm - 1, dataWindow.max.y));
1243  km_1 = std::max(dataWindow.min.z, std::min(km - 1, dataWindow.max.z));
1244  int im1, jm1, km1;
1245  im1 = std::max(dataWindow.min.x, std::min(im + 1, dataWindow.max.x + 1));
1246  jm1 = std::max(dataWindow.min.y, std::min(jm + 1, dataWindow.max.y));
1247  km1 = std::max(dataWindow.min.z, std::min(km + 1, dataWindow.max.z));
1248  int im2, jm2, km2;
1249  im2 = std::max(dataWindow.min.x, std::min(im + 2, dataWindow.max.x + 1));
1250  jm2 = std::max(dataWindow.min.y, std::min(jm + 2, dataWindow.max.y));
1251  km2 = std::max(dataWindow.min.z, std::min(km + 2, dataWindow.max.z));
1252 
1253  T z11 = monotonicCubicInterpolant(data.u(im_1, jm_1, km_1),
1254  data.u(im_1, jm_1, km),
1255  data.u(im_1, jm_1, km1),
1256  data.u(im_1, jm_1, km2), t.z);
1257  T z12 = monotonicCubicInterpolant(data.u(im_1, jm, km_1),
1258  data.u(im_1, jm, km),
1259  data.u(im_1, jm, km1),
1260  data.u(im_1, jm, km2), t.z);
1261  T z13 = monotonicCubicInterpolant(data.u(im_1, jm1, km_1),
1262  data.u(im_1, jm1, km),
1263  data.u(im_1, jm1, km1),
1264  data.u(im_1, jm1, km2), t.z);
1265  T z14 = monotonicCubicInterpolant(data.u(im_1, jm2, km_1),
1266  data.u(im_1, jm2, km),
1267  data.u(im_1, jm2, km1),
1268  data.u(im_1, jm2, km2), t.z);
1269 
1270  T z21 = monotonicCubicInterpolant(data.u(im, jm_1, km_1),
1271  data.u(im, jm_1, km),
1272  data.u(im, jm_1, km1),
1273  data.u(im, jm_1, km2), t.z);
1274  T z22 = monotonicCubicInterpolant(data.u(im, jm, km_1),
1275  data.u(im, jm, km),
1276  data.u(im, jm, km1),
1277  data.u(im, jm, km2), t.z);
1278  T z23 = monotonicCubicInterpolant(data.u(im, jm1, km_1),
1279  data.u(im, jm1, km),
1280  data.u(im, jm1, km1),
1281  data.u(im, jm1, km2), t.z);
1282  T z24 = monotonicCubicInterpolant(data.u(im, jm2, km_1),
1283  data.u(im, jm2, km),
1284  data.u(im, jm2, km1),
1285  data.u(im, jm2, km2), t.z);
1286 
1287  T z31 = monotonicCubicInterpolant(data.u(im1, jm_1, km_1),
1288  data.u(im1, jm_1, km),
1289  data.u(im1, jm_1, km1),
1290  data.u(im1, jm_1, km2), t.z);
1291  T z32 = monotonicCubicInterpolant(data.u(im1, jm, km_1),
1292  data.u(im1, jm, km),
1293  data.u(im1, jm, km1),
1294  data.u(im1, jm, km2), t.z);
1295  T z33 = monotonicCubicInterpolant(data.u(im1, jm1, km_1),
1296  data.u(im1, jm1, km),
1297  data.u(im1, jm1, km1),
1298  data.u(im1, jm1, km2), t.z);
1299  T z34 = monotonicCubicInterpolant(data.u(im1, jm2, km_1),
1300  data.u(im1, jm2, km),
1301  data.u(im1, jm2, km1),
1302  data.u(im1, jm2, km2), t.z);
1303 
1304  T z41 = monotonicCubicInterpolant(data.u(im2, jm_1, km_1),
1305  data.u(im2, jm_1, km),
1306  data.u(im2, jm_1, km1),
1307  data.u(im2, jm_1, km2), t.z);
1308  T z42 = monotonicCubicInterpolant(data.u(im2, jm, km_1),
1309  data.u(im2, jm, km),
1310  data.u(im2, jm, km1),
1311  data.u(im2, jm, km2), t.z);
1312  T z43 = monotonicCubicInterpolant(data.u(im2, jm1, km_1),
1313  data.u(im2, jm1, km),
1314  data.u(im2, jm1, km1),
1315  data.u(im2, jm1, km2), t.z);
1316  T z44 = monotonicCubicInterpolant(data.u(im2, jm2, km_1),
1317  data.u(im2, jm2, km),
1318  data.u(im2, jm2, km1),
1319  data.u(im2, jm2, km2), t.z);
1320 
1321  T y1 = monotonicCubicInterpolant(z11, z12, z13, z14, t.y);
1322  T y2 = monotonicCubicInterpolant(z21, z22, z23, z24, t.y);
1323  T y3 = monotonicCubicInterpolant(z31, z32, z33, z34, t.y);
1324  T y4 = monotonicCubicInterpolant(z41, z42, z43, z44, t.y);
1325 
1326  ret.x = monotonicCubicInterpolant(y1, y2, y3, y4, t.x);
1327  }
1328 
1329 
1330  // Y component ---
1331 
1332  p.setValue(clampedVsP.x - 0.5, vsP.y , clampedVsP.z - 0.5);
1333 
1334  // Lower left corner
1335  c.x = static_cast<int>(floor(p.x));
1336  c.y = static_cast<int>(floor(p.y));
1337  c.z = static_cast<int>(floor(p.z));
1338 
1339  t.setValue(p - static_cast<FIELD3D_VEC3_T<double> >(c));
1340  {
1341  // Clamp the coordinates
1342  int im, jm, km;
1343  im = std::max(dataWindow.min.x, std::min(c.x, dataWindow.max.x));
1344  jm = std::max(dataWindow.min.y, std::min(c.y, dataWindow.max.y + 1));
1345  km = std::max(dataWindow.min.z, std::min(c.z, dataWindow.max.z));
1346  int im_1, jm_1, km_1;
1347  im_1 = std::max(dataWindow.min.x, std::min(im - 1, dataWindow.max.x));
1348  jm_1 = std::max(dataWindow.min.y, std::min(jm - 1, dataWindow.max.y + 1));
1349  km_1 = std::max(dataWindow.min.z, std::min(km - 1, dataWindow.max.z));
1350  int im1, jm1, km1;
1351  im1 = std::max(dataWindow.min.x, std::min(im + 1, dataWindow.max.x));
1352  jm1 = std::max(dataWindow.min.y, std::min(jm + 1, dataWindow.max.y + 1));
1353  km1 = std::max(dataWindow.min.z, std::min(km + 1, dataWindow.max.z));
1354  int im2, jm2, km2;
1355  im2 = std::max(dataWindow.min.x, std::min(im + 2, dataWindow.max.x));
1356  jm2 = std::max(dataWindow.min.y, std::min(jm + 2, dataWindow.max.y + 1));
1357  km2 = std::max(dataWindow.min.z, std::min(km + 2, dataWindow.max.z));
1358 
1359  T z11 = monotonicCubicInterpolant(data.v(im_1, jm_1, km_1),
1360  data.v(im_1, jm_1, km),
1361  data.v(im_1, jm_1, km1),
1362  data.v(im_1, jm_1, km2), t.z);
1363  T z12 = monotonicCubicInterpolant(data.v(im_1, jm, km_1),
1364  data.v(im_1, jm, km),
1365  data.v(im_1, jm, km1),
1366  data.v(im_1, jm, km2), t.z);
1367  T z13 = monotonicCubicInterpolant(data.v(im_1, jm1, km_1),
1368  data.v(im_1, jm1, km),
1369  data.v(im_1, jm1, km1),
1370  data.v(im_1, jm1, km2), t.z);
1371  T z14 = monotonicCubicInterpolant(data.v(im_1, jm2, km_1),
1372  data.v(im_1, jm2, km),
1373  data.v(im_1, jm2, km1),
1374  data.v(im_1, jm2, km2), t.z);
1375 
1376  T z21 = monotonicCubicInterpolant(data.v(im, jm_1, km_1),
1377  data.v(im, jm_1, km),
1378  data.v(im, jm_1, km1),
1379  data.v(im, jm_1, km2), t.z);
1380  T z22 = monotonicCubicInterpolant(data.v(im, jm, km_1),
1381  data.v(im, jm, km),
1382  data.v(im, jm, km1),
1383  data.v(im, jm, km2), t.z);
1384  T z23 = monotonicCubicInterpolant(data.v(im, jm1, km_1),
1385  data.v(im, jm1, km),
1386  data.v(im, jm1, km1),
1387  data.v(im, jm1, km2), t.z);
1388  T z24 = monotonicCubicInterpolant(data.v(im, jm2, km_1),
1389  data.v(im, jm2, km),
1390  data.v(im, jm2, km1),
1391  data.v(im, jm2, km2), t.z);
1392 
1393  T z31 = monotonicCubicInterpolant(data.v(im1, jm_1, km_1),
1394  data.v(im1, jm_1, km),
1395  data.v(im1, jm_1, km1),
1396  data.v(im1, jm_1, km2), t.z);
1397  T z32 = monotonicCubicInterpolant(data.v(im1, jm, km_1),
1398  data.v(im1, jm, km),
1399  data.v(im1, jm, km1),
1400  data.v(im1, jm, km2), t.z);
1401  T z33 = monotonicCubicInterpolant(data.v(im1, jm1, km_1),
1402  data.v(im1, jm1, km),
1403  data.v(im1, jm1, km1),
1404  data.v(im1, jm1, km2), t.z);
1405  T z34 = monotonicCubicInterpolant(data.v(im1, jm2, km_1),
1406  data.v(im1, jm2, km),
1407  data.v(im1, jm2, km1),
1408  data.v(im1, jm2, km2), t.z);
1409 
1410  T z41 = monotonicCubicInterpolant(data.v(im2, jm_1, km_1),
1411  data.v(im2, jm_1, km),
1412  data.v(im2, jm_1, km1),
1413  data.v(im2, jm_1, km2), t.z);
1414  T z42 = monotonicCubicInterpolant(data.v(im2, jm, km_1),
1415  data.v(im2, jm, km),
1416  data.v(im2, jm, km1),
1417  data.v(im2, jm, km2), t.z);
1418  T z43 = monotonicCubicInterpolant(data.v(im2, jm1, km_1),
1419  data.v(im2, jm1, km),
1420  data.v(im2, jm1, km1),
1421  data.v(im2, jm1, km2), t.z);
1422  T z44 = monotonicCubicInterpolant(data.v(im2, jm2, km_1),
1423  data.v(im2, jm2, km),
1424  data.v(im2, jm2, km1),
1425  data.v(im2, jm2, km2), t.z);
1426 
1427  T y1 = monotonicCubicInterpolant(z11, z12, z13, z14, t.y);
1428  T y2 = monotonicCubicInterpolant(z21, z22, z23, z24, t.y);
1429  T y3 = monotonicCubicInterpolant(z31, z32, z33, z34, t.y);
1430  T y4 = monotonicCubicInterpolant(z41, z42, z43, z44, t.y);
1431 
1432  ret.y = monotonicCubicInterpolant(y1, y2, y3, y4, t.x);
1433  }
1434 
1435  // Z component ---
1436 
1437  p.setValue(clampedVsP.x - 0.5 , clampedVsP.y - 0.5, vsP.z);
1438 
1439  // Lower left corner
1440  c.x = static_cast<int>(floor(p.x));
1441  c.y = static_cast<int>(floor(p.y));
1442  c.z = static_cast<int>(floor(p.z));
1443 
1444  t.setValue(p - static_cast<FIELD3D_VEC3_T<double> >(c));
1445  {
1446  // Clamp the coordinates
1447  int im, jm, km;
1448  im = std::max(dataWindow.min.x, std::min(c.x, dataWindow.max.x));
1449  jm = std::max(dataWindow.min.y, std::min(c.y, dataWindow.max.y));
1450  km = std::max(dataWindow.min.z, std::min(c.z, dataWindow.max.z + 1));
1451  int im_1, jm_1, km_1;
1452  im_1 = std::max(dataWindow.min.x, std::min(im - 1, dataWindow.max.x));
1453  jm_1 = std::max(dataWindow.min.y, std::min(jm - 1, dataWindow.max.y));
1454  km_1 = std::max(dataWindow.min.z, std::min(km - 1, dataWindow.max.z + 1));
1455  int im1, jm1, km1;
1456  im1 = std::max(dataWindow.min.x, std::min(im + 1, dataWindow.max.x));
1457  jm1 = std::max(dataWindow.min.y, std::min(jm + 1, dataWindow.max.y));
1458  km1 = std::max(dataWindow.min.z, std::min(km + 1, dataWindow.max.z + 1));
1459  int im2, jm2, km2;
1460  im2 = std::max(dataWindow.min.x, std::min(im + 2, dataWindow.max.x));
1461  jm2 = std::max(dataWindow.min.y, std::min(jm + 2, dataWindow.max.y));
1462  km2 = std::max(dataWindow.min.z, std::min(km + 2, dataWindow.max.z + 1));
1463 
1464  T z11 = monotonicCubicInterpolant(data.w(im_1, jm_1, km_1),
1465  data.w(im_1, jm_1, km),
1466  data.w(im_1, jm_1, km1),
1467  data.w(im_1, jm_1, km2), t.z);
1468  T z12 = monotonicCubicInterpolant(data.w(im_1, jm, km_1),
1469  data.w(im_1, jm, km),
1470  data.w(im_1, jm, km1),
1471  data.w(im_1, jm, km2), t.z);
1472  T z13 = monotonicCubicInterpolant(data.w(im_1, jm1, km_1),
1473  data.w(im_1, jm1, km),
1474  data.w(im_1, jm1, km1),
1475  data.w(im_1, jm1, km2), t.z);
1476  T z14 = monotonicCubicInterpolant(data.w(im_1, jm2, km_1),
1477  data.w(im_1, jm2, km),
1478  data.w(im_1, jm2, km1),
1479  data.w(im_1, jm2, km2), t.z);
1480 
1481  T z21 = monotonicCubicInterpolant(data.w(im, jm_1, km_1),
1482  data.w(im, jm_1, km),
1483  data.w(im, jm_1, km1),
1484  data.w(im, jm_1, km2), t.z);
1485  T z22 = monotonicCubicInterpolant(data.w(im, jm, km_1),
1486  data.w(im, jm, km),
1487  data.w(im, jm, km1),
1488  data.w(im, jm, km2), t.z);
1489  T z23 = monotonicCubicInterpolant(data.w(im, jm1, km_1),
1490  data.w(im, jm1, km),
1491  data.w(im, jm1, km1),
1492  data.w(im, jm1, km2), t.z);
1493  T z24 = monotonicCubicInterpolant(data.w(im, jm2, km_1),
1494  data.w(im, jm2, km),
1495  data.w(im, jm2, km1),
1496  data.w(im, jm2, km2), t.z);
1497 
1498  T z31 = monotonicCubicInterpolant(data.w(im1, jm_1, km_1),
1499  data.w(im1, jm_1, km),
1500  data.w(im1, jm_1, km1),
1501  data.w(im1, jm_1, km2), t.z);
1502  T z32 = monotonicCubicInterpolant(data.w(im1, jm, km_1),
1503  data.w(im1, jm, km),
1504  data.w(im1, jm, km1),
1505  data.w(im1, jm, km2), t.z);
1506  T z33 = monotonicCubicInterpolant(data.w(im1, jm1, km_1),
1507  data.w(im1, jm1, km),
1508  data.w(im1, jm1, km1),
1509  data.w(im1, jm1, km2), t.z);
1510  T z34 = monotonicCubicInterpolant(data.w(im1, jm2, km_1),
1511  data.w(im1, jm2, km),
1512  data.w(im1, jm2, km1),
1513  data.w(im1, jm2, km2), t.z);
1514 
1515  T z41 = monotonicCubicInterpolant(data.w(im2, jm_1, km_1),
1516  data.w(im2, jm_1, km),
1517  data.w(im2, jm_1, km1),
1518  data.w(im2, jm_1, km2), t.z);
1519  T z42 = monotonicCubicInterpolant(data.w(im2, jm, km_1),
1520  data.w(im2, jm, km),
1521  data.w(im2, jm, km1),
1522  data.w(im2, jm, km2), t.z);
1523  T z43 = monotonicCubicInterpolant(data.w(im2, jm1, km_1),
1524  data.w(im2, jm1, km),
1525  data.w(im2, jm1, km1),
1526  data.w(im2, jm1, km2), t.z);
1527  T z44 = monotonicCubicInterpolant(data.w(im2, jm2, km_1),
1528  data.w(im2, jm2, km),
1529  data.w(im2, jm2, km1),
1530  data.w(im2, jm2, km2), t.z);
1531 
1532  T y1 = monotonicCubicInterpolant(z11, z12, z13, z14, t.y);
1533  T y2 = monotonicCubicInterpolant(z21, z22, z23, z24, t.y);
1534  T y3 = monotonicCubicInterpolant(z31, z32, z33, z34, t.y);
1535  T y4 = monotonicCubicInterpolant(z41, z42, z43, z44, t.y);
1536 
1537  ret.z = monotonicCubicInterpolant(y1, y2, y3, y4, t.x);
1538  }
1539 
1540  return ret;
1541 }
1542 
1543 //----------------------------------------------------------------------------//
1544 
1545 template <class Data_T>
1546 Data_T
1548  const V3d &vsP) const
1549 {
1550  V3d voxelScale = V3d(1.0) / data.dataResolution();
1551  V3d lsP = vsP * voxelScale;
1552  return data.lsSample(lsP);
1553 }
1554 
1555 //----------------------------------------------------------------------------//
1556 
1557 template <class S, class T>
1558 FIELD3D_VEC3_T<T> operator * (S s, const FIELD3D_VEC3_T<T> vec)
1559 {
1560  return FIELD3D_VEC3_T<T>(vec.x * s, vec.y * s, vec.z * s);
1561 }
1562 
1563 //----------------------------------------------------------------------------//
1564 
1565 template<class T>
1566 T monotonicCubicInterpolant(const T &f1, const T &f2, const T &f3, const T &f4,
1567  double t)
1568 {
1569  T d_k = T(.5) * (f3 - f1);
1570  T d_k1 = T(.5) * (f4 - f2);
1571  T delta_k = f3 - f2;
1572 
1573  if (delta_k == static_cast<T>(0)) {
1574  d_k = static_cast<T>(0);
1575  d_k1 = static_cast<T>(0);
1576  }
1577 
1578  T a0 = f2;
1579  T a1 = d_k;
1580  T a2 = (T(3) * delta_k) - (T(2) * d_k) - d_k1;
1581  T a3 = d_k + d_k1 - (T(2) * delta_k);
1582 
1583  T t1 = t;
1584  T t2 = t1 * t1;
1585  T t3 = t2 * t1;
1586 
1587  return a3 * t3 + a2 * t2 + a1 * t1 + a0;
1588 }
1589 
1590 //----------------------------------------------------------------------------//
1591 
1593 // References:
1594 // http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
1595 // http://en.wikipedia.org/wiki/Cubic_Hermite_spline
1596 template <class Data_T>
1597 Data_T monotonicCubicInterpolantVec(const Data_T &f1, const Data_T &f2,
1598  const Data_T &f3, const Data_T &f4,
1599  double t)
1600 {
1601  typedef typename Data_T::BaseType T;
1602 
1603  Data_T d_k = T(.5) * (f3 - f1);
1604  Data_T d_k1 = T(.5) * (f4 - f2);
1605  Data_T delta_k = f3 - f2;
1606 
1607  for (int i = 0; i < 3; i++) {
1608  if (delta_k[i] == static_cast<T>(0)) {
1609  d_k[i] = static_cast<T>(0);
1610  d_k1[i]= static_cast<T>(0);
1611  }
1612  }
1613 
1614  Data_T a0 = f2;
1615  Data_T a1 = d_k;
1616  Data_T a2 = (delta_k * T(3)) - (d_k * T(2)) - d_k1;
1617  Data_T a3 = d_k + d_k1 - (delta_k * T(2));
1618 
1619  T t1 = t;
1620  T t2 = t1 * t1;
1621  T t3 = t2 * t1;
1622 
1623  return a3 * t3 + a2 * t2 + a1 * t1 + a0;
1624 }
1625 
1626 //----------------------------------------------------------------------------//
1627 // Template specializations
1628 //----------------------------------------------------------------------------//
1629 
1630 template<>
1631 inline
1633  const V3h &f3, const V3h &f4, double t)
1634 {
1635  return monotonicCubicInterpolantVec(f1, f2, f3, f4, t);
1636 }
1637 
1638 //----------------------------------------------------------------------------//
1639 
1640 template<>
1641 inline
1643  const V3f &f3, const V3f &f4, double t)
1644 {
1645  return monotonicCubicInterpolantVec(f1, f2, f3, f4, t);
1646 }
1647 
1648 //----------------------------------------------------------------------------//
1649 
1650 template<>
1651 inline
1653  const V3d &f3, const V3d &f4, double t)
1654 {
1655  return monotonicCubicInterpolantVec(f1, f2, f3, f4, t);
1656 }
1657 
1658 //----------------------------------------------------------------------------//
1659 
1661 
1662 //----------------------------------------------------------------------------//
1663 
1664 #endif // Include guard
CubicGenericFieldInterp::class_type
CubicGenericFieldInterp class_type
Definition: FieldInterp.h:386
LinearFieldInterp::base
FieldInterp< Data_T > base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:173
LinearFieldInterp::sample
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const
Definition: FieldInterp.h:606
CubicFieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:214
LinearGenericFieldInterp::class_type
LinearGenericFieldInterp class_type
Definition: FieldInterp.h:264
FIELD3D_NAMESPACE_HEADER_CLOSE
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION
FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(FieldInterp)
MACCompV
@ MACCompV
Definition: MACField.h:73
FieldInterp::class_type
FieldInterp class_type
Definition: FieldInterp.h:83
CubicGenericFieldInterp::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:413
FieldRes::dataWindow
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
Definition: Field.h:253
CubicFieldInterp::class_type
CubicFieldInterp class_type
Definition: FieldInterp.h:206
V3i
Imath::V3i V3i
Definition: SpiMathLib.h:71
CubicMACFieldInterp::Ptr
boost::intrusive_ptr< CubicMACFieldInterp > Ptr
Definition: FieldInterp.h:441
ProceduralFieldLookup::ms_classType
static TemplatedFieldType< ProceduralFieldLookup< Data_T > > ms_classType
Definition: FieldInterp.h:525
ProceduralField
Definition: ProceduralField.h:121
LinearGenericFieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:272
FieldInterp::sample
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const =0
V3d
Imath::V3d V3d
Definition: SpiMathLib.h:74
operator*
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
Definition: FieldInterp.h:1558
monotonicCubicInterpolant
Data_T monotonicCubicInterpolant(const Data_T &f1, const Data_T &f2, const Data_T &f3, const Data_T &f4, double t)
Monotonic cubic interpolation References: http://en.wikipedia.org/wiki/Monotone_cubic_interpolation h...
LinearMACFieldInterp::sample
Data_T sample(const MACField< Data_T > &data, const V3d &vsP) const
Definition: FieldInterp.h:818
LinearMACFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:326
CubicMACFieldInterp
Definition: FieldInterp.h:435
Field::Ptr
boost::intrusive_ptr< Field > Ptr
Definition: Field.h:395
CubicMACFieldInterp::ms_classType
static TemplatedFieldType< CubicMACFieldInterp< Data_T > > ms_classType
Definition: FieldInterp.h:466
CubicMACFieldInterp::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:471
MACField::v
const real_t & v(int i, int j, int k) const
Read access to value on v-facing wall.
Definition: MACField.h:736
ProceduralFieldLookup::Ptr
boost::intrusive_ptr< ProceduralFieldLookup > Ptr
Definition: FieldInterp.h:500
ProceduralFieldLookup
Definition: FieldInterp.h:494
MACField.h
Contains the MACField class.
ProceduralField.h
Contains the ProceduralField class.
FieldInterp::Ptr
boost::intrusive_ptr< FieldInterp > Ptr
Definition: FieldInterp.h:79
CubicFieldInterp::value_type
Data_T value_type
Definition: FieldInterp.h:201
LinearGenericFieldInterp::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:290
ProceduralFieldLookup::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:505
LinearMACFieldInterp::Ptr
boost::intrusive_ptr< LinearMACFieldInterp > Ptr
Definition: FieldInterp.h:319
MACField::u
const real_t & u(int i, int j, int k) const
Read access to value on u-facing wall.
Definition: MACField.h:698
monotonicCubicInterpolant< V3d >
V3d monotonicCubicInterpolant< V3d >(const V3d &f1, const V3d &f2, const V3d &f3, const V3d &f4, double t)
Definition: FieldInterp.h:1652
V3f
Imath::V3f V3f
Definition: SpiMathLib.h:73
FieldInterp::~FieldInterp
virtual ~FieldInterp()
Definition: FieldInterp.h:98
ProceduralFieldLookup::sample
Data_T sample(const ProceduralField< Data_T > &data, const V3d &vsP) const
Definition: FieldInterp.h:1547
CubicGenericFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:387
RefCount.h
Contains base class for reference counting with Mutex.
FieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:91
FieldRes::dataResolution
V3i const dataResolution() const
Definition: Field.h:256
LinearFieldInterp::value_type
Data_T value_type
Definition: FieldInterp.h:142
LinearFieldInterp
Definition: FieldInterp.h:137
CubicMACFieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:453
LinearMACFieldInterp::staticClassType
static const char * staticClassType()
classType for RTTI replacement
Definition: FieldInterp.h:332
detail::floor
FIELD3D_VEC3_T< T > floor(const FIELD3D_VEC3_T< T > &v)
Floor function for Vec3.
Definition: CoordSys.h:104
LinearFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:148
monotonicCubicInterpolant< V3h >
V3h monotonicCubicInterpolant< V3h >(const V3h &f1, const V3h &f2, const V3h &f3, const V3h &f4, double t)
Definition: FieldInterp.h:1632
FieldRes::mapping
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition: Field.h:263
LinearGenericFieldInterp::sample
value_type sample(const Field_T &data, const V3d &vsP) const
Definition: FieldInterp.h:773
LinearGenericFieldInterp::ms_classType
static TemplatedFieldType< LinearGenericFieldInterp< Field_T > > ms_classType
Definition: FieldInterp.h:285
ProceduralFieldLookup::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:512
ProceduralFieldLookup::value_type
Data_T value_type
Definition: FieldInterp.h:499
CubicFieldInterp
Definition: FieldInterp.h:196
ns.h
CubicMACFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:448
CubicGenericFieldInterp::value_type
Field_T::value_type value_type
Definition: FieldInterp.h:381
CubicGenericFieldInterp
Definition: DenseField.h:66
FieldRes::Ptr
boost::intrusive_ptr< FieldRes > Ptr
Definition: Field.h:213
CubicGenericFieldInterp::Ptr
boost::intrusive_ptr< CubicGenericFieldInterp > Ptr
Definition: FieldInterp.h:382
CubicMACFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:446
MACCompW
@ MACCompW
Definition: MACField.h:74
detail::max
T max(const T a, const T2 b)
Max operation on mixed types.
Definition: FieldSampler.h:32
CubicFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:207
CubicGenericFieldInterp::ms_classType
static TemplatedFieldType< CubicGenericFieldInterp< Field_T > > ms_classType
Definition: FieldInterp.h:408
LinearMACFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:324
wsSample
Data_T wsSample(const typename Field< Data_T >::Ptr f, const FieldInterp< Data_T > &interp, const V3d &wsP)
Helper function for interpolating in world space.
Definition: FieldInterp.h:546
CubicFieldInterp::sample
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const
Definition: FieldInterp.h:651
TemplatedFieldType::name
const char * name()
Definition: Traits.h:284
LinearGenericFieldInterp::value_type
Field_T::value_type value_type
Definition: FieldInterp.h:259
Box3d
Imath::Box3d Box3d
Definition: SpiMathLib.h:79
MACField::w
const real_t & w(int i, int j, int k) const
Read access to value on w-facing wall.
Definition: MACField.h:774
FieldInterp::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:114
LinearFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:150
CubicMACFieldInterp::value_type
Data_T value_type
Definition: FieldInterp.h:440
LinearFieldInterp::class_type
LinearFieldInterp class_type
Definition: FieldInterp.h:147
LinearGenericFieldInterp::DEFINE_FIELD_RTTI_CONCRETE_CLASS
DEFINE_FIELD_RTTI_CONCRETE_CLASS
Definition: FieldInterp.h:265
ProceduralFieldLookup::class_type
ProceduralFieldLookup class_type
Definition: FieldInterp.h:504
LinearGenericFieldInterp::Ptr
boost::intrusive_ptr< LinearGenericFieldInterp > Ptr
Definition: FieldInterp.h:260
Field.h
Contains Field, WritableField and ResizableField classes.
MACField
This subclass of Field implements a standard MAC field. Refer to your favorite fluid simulations book...
Definition: MACField.h:96
isLegalVoxelCoord
bool isLegalVoxelCoord(const V3d &vsP, const Box3d &vsDataWindow)
Checks whether the floating - point voxel coordinate is within the given (floating point) data window...
Definition: FieldInterp.cpp:63
CubicMACFieldInterp::sample
Data_T sample(const MACField< Data_T > &data, const V3d &vsP) const
Definition: FieldInterp.h:1205
DenseField.h
Contains the DenseField class.
CubicFieldInterp::Ptr
boost::intrusive_ptr< CubicFieldInterp > Ptr
Definition: FieldInterp.h:202
ProceduralField::lsSample
virtual Data_T lsSample(const V3d &lsP) const =0
MACCompU
@ MACCompU
Definition: MACField.h:72
CubicFieldInterp::ms_classType
static TemplatedFieldType< CubicFieldInterp< Data_T > > ms_classType
Definition: FieldInterp.h:227
CubicGenericFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:389
LinearFieldInterp::ms_classType
static TemplatedFieldType< LinearFieldInterp< Data_T > > ms_classType
Definition: FieldInterp.h:168
V3h
Imath::Vec3< half > V3h
Definition: SpiMathLib.h:72
isPointInField
bool isPointInField(const FieldRes::Ptr f, const V3d &wsP)
Checks whether the point is within the given field.
Definition: FieldInterp.cpp:52
LinearGenericFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:267
FieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:86
ProceduralFieldLookup::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:530
MACComponent
MACComponent
Definition: MACField.h:71
LinearMACFieldInterp::class_type
LinearMACFieldInterp class_type
Definition: FieldInterp.h:323
LinearMACFieldInterp::value_type
Data_T value_type
Definition: FieldInterp.h:318
LinearMACFieldInterp::base
RefBase base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:354
CubicGenericFieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:394
monotonicCubicInterpolantVec
Data_T monotonicCubicInterpolantVec(const Data_T &f1, const Data_T &f2, const Data_T &f3, const Data_T &f4, double t)
Monotonic cubic interpolation on 3 - vectors References: http://en.wikipedia.org/wiki/Monotone_cubic_...
Definition: FieldInterp.h:1597
FieldInterp::DEFINE_FIELD_RTTI_ABSTRACT_CLASS
DEFINE_FIELD_RTTI_ABSTRACT_CLASS
Definition: FieldInterp.h:84
LinearFieldInterp::Ptr
boost::intrusive_ptr< LinearFieldInterp > Ptr
Definition: FieldInterp.h:143
CubicFieldInterp::base
FieldInterp< Data_T > base
Convenience typedef for referring to base class.
Definition: FieldInterp.h:232
CubicGenericFieldInterp::sample
value_type sample(const Field_T &data, const V3d &vsP) const
Definition: FieldInterp.h:1083
FIELD3D_NAMESPACE_OPEN
Definition: FieldMapping.cpp:74
ProceduralFieldLookup::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:507
Box3i
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
LinearFieldInterp::staticClassType
static const char * staticClassType()
Definition: FieldInterp.h:155
CubicMACFieldInterp::class_type
CubicMACFieldInterp class_type
Definition: FieldInterp.h:445
Field
Definition: Field.h:390
FieldInterp::value_type
Data_T value_type
Definition: FieldInterp.h:78
LinearMACFieldInterp
Definition: FieldInterp.h:313
LinearGenericFieldInterp
Definition: DenseField.h:64
TemplatedFieldType
Used to return a string for the name of a templated field.
Definition: Traits.h:283
RefBase
Definition: RefCount.h:107
LinearMACFieldInterp::ms_classType
static TemplatedFieldType< LinearMACFieldInterp< Data_T > > ms_classType
Definition: FieldInterp.h:349
CubicFieldInterp::staticClassName
static const char * staticClassName()
Definition: FieldInterp.h:209
detail::min
T min(const T a, const T2 b)
Min operation on mixed types.
Definition: FieldSampler.h:25
monotonicCubicInterpolant< V3f >
V3f monotonicCubicInterpolant< V3f >(const V3f &f1, const V3f &f2, const V3f &f3, const V3f &f4, double t)
Definition: FieldInterp.h:1642
FieldInterp::ms_classType
static TemplatedFieldType< FieldInterp< Data_T > > ms_classType
Definition: FieldInterp.h:109
Field::value
virtual Data_T value(int i, int j, int k) const =0
Read access to a voxel. The coordinates are in integer voxel space .
FieldInterp
Base class for interpolators.
Definition: FieldInterp.h:73