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
71template <class Data_T>
72class FieldInterp : public RefBase
73{
74public:
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
105private:
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
135template <class Data_T>
136class 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
164private:
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
194template <class Data_T>
195class 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
223private:
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
252template <class Field_T>
254{
255public:
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
281private:
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
311template <class Data_T>
313{
314public:
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
345private:
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
374template <class Field_T>
376{
377public:
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
404private:
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
433template <class Data_T>
435{
436public:
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
462private:
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
492template <class Data_T>
494{
495public:
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
521private:
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
545template <class Data_T>
546Data_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
560bool isPointInField(const FieldRes::Ptr f, const V3d &wsP);
561
562//----------------------------------------------------------------------------//
563
566bool isLegalVoxelCoord(const V3d &vsP, const Box3d &vsDataWindow);
567
568//----------------------------------------------------------------------------//
569// Math functions
570//----------------------------------------------------------------------------//
571
574template <class S, class T>
576
577//----------------------------------------------------------------------------//
578// Interpolants
579//----------------------------------------------------------------------------//
580
585template <class Data_T>
586Data_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
596template <class Data_T>
597Data_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
605template <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.
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
650template <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));
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
771template <class Field_T>
772typename 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.
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
817template <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
940template <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;
953 V3i c1, c2;
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
1081template <class Field_T>
1082typename 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));
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
1204template <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
1545template <class Data_T>
1546Data_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
1557template <class S, class T>
1559{
1560 return FIELD3D_VEC3_T<T>(vec.x * s, vec.y * s, vec.z * s);
1561}
1562
1563//----------------------------------------------------------------------------//
1564
1565template<class T>
1566T 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
1596template <class Data_T>
1597Data_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
1630template<>
1631inline
1633 const V3h &f3, const V3h &f4, double t)
1634{
1635 return monotonicCubicInterpolantVec(f1, f2, f3, f4, t);
1636}
1637
1638//----------------------------------------------------------------------------//
1639
1640template<>
1641inline
1643 const V3f &f3, const V3f &f4, double t)
1644{
1645 return monotonicCubicInterpolantVec(f1, f2, f3, f4, t);
1646}
1647
1648//----------------------------------------------------------------------------//
1649
1650template<>
1651inline
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
Contains the DenseField class.
V3h monotonicCubicInterpolant< V3h >(const V3h &f1, const V3h &f2, const V3h &f3, const V3h &f4, double t)
V3f monotonicCubicInterpolant< V3f >(const V3f &f1, const V3f &f2, const V3f &f3, const V3f &f4, double t)
bool isPointInField(const FieldRes::Ptr f, const V3d &wsP)
Checks whether the point is within the given field.
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.
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
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...
V3d monotonicCubicInterpolant< V3d >(const V3d &f1, const V3d &f2, const V3d &f3, const V3d &f4, double t)
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_...
bool isLegalVoxelCoord(const V3d &vsP, const Box3d &vsDataWindow)
Checks whether the floating - point voxel coordinate is within the given (floating point) data window...
Contains Field, WritableField and ResizableField classes.
#define FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(field)
Definition Field.h:479
Contains the MACField class.
MACComponent
Definition MACField.h:71
@ MACCompV
Definition MACField.h:73
@ MACCompU
Definition MACField.h:72
@ MACCompW
Definition MACField.h:74
Contains the ProceduralField class.
Contains base class for reference counting with Mutex.
Imath::Box3d Box3d
Definition SpiMathLib.h:79
Imath::V3i V3i
Definition SpiMathLib.h:71
Imath::V3d V3d
Definition SpiMathLib.h:74
#define FIELD3D_VEC3_T
Definition SpiMathLib.h:88
Imath::Box3i Box3i
Definition SpiMathLib.h:77
Imath::Vec3< half > V3h
Definition SpiMathLib.h:72
Imath::V3f V3f
Definition SpiMathLib.h:73
static TemplatedFieldType< CubicFieldInterp< Data_T > > ms_classType
FieldInterp< Data_T > base
Convenience typedef for referring to base class.
static const char * staticClassName()
CubicFieldInterp class_type
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const
boost::intrusive_ptr< CubicFieldInterp > Ptr
static const char * staticClassType()
static const char * staticClassName()
static const char * staticClassType()
RefBase base
Convenience typedef for referring to base class.
Field_T::value_type value_type
CubicGenericFieldInterp class_type
boost::intrusive_ptr< CubicGenericFieldInterp > Ptr
static TemplatedFieldType< CubicGenericFieldInterp< Field_T > > ms_classType
value_type sample(const Field_T &data, const V3d &vsP) const
boost::intrusive_ptr< CubicMACFieldInterp > Ptr
static const char * staticClassName()
static const char * staticClassType()
RefBase base
Convenience typedef for referring to base class.
CubicMACFieldInterp class_type
Data_T sample(const MACField< Data_T > &data, const V3d &vsP) const
static TemplatedFieldType< CubicMACFieldInterp< Data_T > > ms_classType
Base class for interpolators.
Definition FieldInterp.h:73
static TemplatedFieldType< FieldInterp< Data_T > > ms_classType
FieldInterp class_type
Definition FieldInterp.h:83
DEFINE_FIELD_RTTI_ABSTRACT_CLASS
Definition FieldInterp.h:84
Data_T value_type
Definition FieldInterp.h:78
static const char * staticClassName()
Definition FieldInterp.h:86
virtual ~FieldInterp()
Definition FieldInterp.h:98
boost::intrusive_ptr< FieldInterp > Ptr
Definition FieldInterp.h:79
static const char * staticClassType()
Definition FieldInterp.h:91
RefBase base
Convenience typedef for referring to base class.
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const =0
boost::intrusive_ptr< FieldRes > Ptr
Definition Field.h:213
V3i const dataResolution() const
Definition Field.h:256
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition Field.h:263
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
Definition Field.h:390
boost::intrusive_ptr< Field > Ptr
Definition Field.h:395
virtual Data_T value(int i, int j, int k) const =0
Read access to a voxel. The coordinates are in integer voxel space .
virtual Data_T sample(const Field< Data_T > &data, const V3d &vsP) const
static TemplatedFieldType< LinearFieldInterp< Data_T > > ms_classType
boost::intrusive_ptr< LinearFieldInterp > Ptr
static const char * staticClassType()
FieldInterp< Data_T > base
Convenience typedef for referring to base class.
LinearFieldInterp class_type
static const char * staticClassName()
boost::intrusive_ptr< LinearGenericFieldInterp > Ptr
static TemplatedFieldType< LinearGenericFieldInterp< Field_T > > ms_classType
Field_T::value_type value_type
value_type sample(const Field_T &data, const V3d &vsP) const
static const char * staticClassType()
LinearGenericFieldInterp class_type
RefBase base
Convenience typedef for referring to base class.
static const char * staticClassName()
Data_T sample(const MACField< Data_T > &data, const V3d &vsP) const
boost::intrusive_ptr< LinearMACFieldInterp > Ptr
static const char * staticClassType()
classType for RTTI replacement
static TemplatedFieldType< LinearMACFieldInterp< Data_T > > ms_classType
static const char * staticClassName()
RefBase base
Convenience typedef for referring to base class.
LinearMACFieldInterp class_type
This subclass of Field implements a standard MAC field. Refer to your favorite fluid simulations book...
Definition MACField.h:96
const real_t & w(int i, int j, int k) const
Read access to value on w-facing wall.
Definition MACField.h:774
const real_t & u(int i, int j, int k) const
Read access to value on u-facing wall.
Definition MACField.h:698
const real_t & v(int i, int j, int k) const
Read access to value on v-facing wall.
Definition MACField.h:736
RefBase base
Convenience typedef for referring to base class.
static const char * staticClassType()
static const char * staticClassName()
boost::intrusive_ptr< ProceduralFieldLookup > Ptr
static TemplatedFieldType< ProceduralFieldLookup< Data_T > > ms_classType
ProceduralFieldLookup class_type
Data_T sample(const ProceduralField< Data_T > &data, const V3d &vsP) const
virtual Data_T lsSample(const V3d &lsP) const =0
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition ns.h:58
Used to return a string for the name of a templated field.
Definition Traits.h:283
const char * name()
Definition Traits.h:284