1 // Copyright 2020-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "../common/export_util.h"
7 #include "../iterator/DefaultIterator.h"
8 #include "../iterator/GridAcceleratorIterator.h"
9 #include "../sampler/Sampler.h"
10 #include "Sampler_ispc.h"
11 #include "SharedStructuredVolume_ispc.h"
12 #include "StructuredRegularVolume.h"
13 #include "StructuredSphericalVolume.h"
14 #include "StructuredVolume.h"
15 #include "Volume_ispc.h"
16 #include "openvkl/VKLFilter.h"
17 
18 namespace openvkl {
19   namespace cpu_device {
20 
21     template <int W,
22               template <int>
23               class IntervalIteratorFactory,
24               template <int>
25               class HitIteratorFactory>
26     struct StructuredSampler : public SamplerBase<W,
27                                                   StructuredVolume,
28                                                   IntervalIteratorFactory,
29                                                   HitIteratorFactory>
30     {
31       StructuredSampler(StructuredVolume<W> *volume);
32       ~StructuredSampler() override;
33 
34       void commit() override;
35 
36       // single attribute /////////////////////////////////////////////////////
37 
38       void computeSample(const vvec3fn<1> &objectCoordinates,
39                          vfloatn<1> &samples,
40                          unsigned int attributeIndex,
41                          const vfloatn<1> &time) const override final;
42 
43       void computeSampleV(const vintn<W> &valid,
44                           const vvec3fn<W> &objectCoordinates,
45                           vfloatn<W> &samples,
46                           unsigned int attributeIndex,
47                           const vfloatn<W> &time) const override final;
48 
49       void computeSampleN(unsigned int N,
50                           const vvec3fn<1> *objectCoordinates,
51                           float *samples,
52                           unsigned int attributeIndex,
53                           const float *times) const override final;
54 
55       void computeGradientV(const vintn<W> &valid,
56                             const vvec3fn<W> &objectCoordinates,
57                             vvec3fn<W> &gradients,
58                             unsigned int attributeIndex,
59                             const vfloatn<W> &time) const override final;
60 
61       void computeGradientN(unsigned int N,
62                             const vvec3fn<1> *objectCoordinates,
63                             vvec3fn<1> *gradients,
64                             unsigned int attributeIndex,
65                             const float *times) const override final;
66 
67       // multi-attribute //////////////////////////////////////////////////////
68 
69       void computeSampleM(const vvec3fn<1> &objectCoordinates,
70                           float *samples,
71                           unsigned int M,
72                           const unsigned int *attributeIndices,
73                           const vfloatn<1> &time) const override final;
74 
75       void computeSampleMV(const vintn<W> &valid,
76                            const vvec3fn<W> &objectCoordinates,
77                            float *samples,
78                            unsigned int M,
79                            const unsigned int *attributeIndices,
80                            const vfloatn<W> &time) const override final;
81 
82       void computeSampleMN(unsigned int N,
83                            const vvec3fn<1> *objectCoordinates,
84                            float *samples,
85                            unsigned int M,
86                            const unsigned int *attributeIndices,
87                            const float *times) const override final;
88 
89       /////////////////////////////////////////////////////////////////////////
90 
91      protected:
92       using Sampler<W>::ispcEquivalent;
93       using SamplerBase<W,
94                         StructuredVolume,
95                         IntervalIteratorFactory,
96                         HitIteratorFactory>::volume;
97 
98       VKLFilter filter;
99       VKLFilter gradientFilter;
100     };
101 
102     // Inlined definitions ////////////////////////////////////////////////////
103 
104     template <int W,
105               template <int>
106               class IntervalIteratorFactory,
107               template <int>
108               class HitIteratorFactory>
109     inline StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
StructuredSampler(StructuredVolume<W> * volume)110         StructuredSampler(StructuredVolume<W> *volume)
111         : SamplerBase<W,
112                       StructuredVolume,
113                       IntervalIteratorFactory,
114                       HitIteratorFactory>(*volume),
115           filter(volume->getFilter()),
116           gradientFilter(volume->getGradientFilter())
117     {
118       assert(volume);
119       ispcEquivalent =
120           CALL_ISPC(StructuredSampler_create, volume->getISPCEquivalent());
121     }
122 
123     template <int W,
124               template <int>
125               class IntervalIteratorFactory,
126               template <int>
127               class HitIteratorFactory>
128     inline StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
~StructuredSampler()129         ~StructuredSampler()
130     {
131       CALL_ISPC(StructuredSampler_destroy, ispcEquivalent);
132       ispcEquivalent = nullptr;
133     }
134 
135     template <int W,
136               template <int>
137               class IntervalIteratorFactory,
138               template <int>
139               class HitIteratorFactory>
140     inline void
commit()141     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::commit()
142     {
143       filter = (VKLFilter)this->template getParam<int>("filter", filter);
144 
145       // Note: We fall back to the sampler object filter parameter if it is set.
146       //       This enables users to specify *only* the field filter override.
147       //       This does mean that users must set the gradientFilter explicitly
148       //       if they set filter and want gradientFilter to be different.
149       gradientFilter = (VKLFilter)this->template getParam<int>(
150           "gradientFilter", this->hasParam("filter") ? filter : gradientFilter);
151 
152       CALL_ISPC(Sampler_setFilters,
153                 ispcEquivalent,
154                 (ispc::VKLFilter)filter,
155                 (ispc::VKLFilter)gradientFilter);
156     }
157 
158     template <int W,
159               template <int>
160               class IntervalIteratorFactory,
161               template <int>
162               class HitIteratorFactory>
163     inline void
164     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSample(const vvec3fn<1> & objectCoordinates,vfloatn<1> & samples,unsigned int attributeIndex,const vfloatn<1> & time)165         computeSample(const vvec3fn<1> &objectCoordinates,
166                       vfloatn<1> &samples,
167                       unsigned int attributeIndex,
168                       const vfloatn<1> &time) const
169     {
170       assert(attributeIndex < volume->getNumAttributes());
171       assertValidTime(time[0]);
172       CALL_ISPC(SharedStructuredVolume_sample_uniform_export,
173                 ispcEquivalent,
174                 &objectCoordinates,
175                 attributeIndex,
176                 &time,
177                 &samples);
178     }
179 
180     template <int W,
181               template <int>
182               class IntervalIteratorFactory,
183               template <int>
184               class HitIteratorFactory>
185     inline void
186     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSampleV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,vfloatn<W> & samples,unsigned int attributeIndex,const vfloatn<W> & time)187         computeSampleV(const vintn<W> &valid,
188                        const vvec3fn<W> &objectCoordinates,
189                        vfloatn<W> &samples,
190                        unsigned int attributeIndex,
191                        const vfloatn<W> &time) const
192     {
193       assert(attributeIndex < volume->getNumAttributes());
194       assertValidTimes(valid, time);
195       CALL_ISPC(SharedStructuredVolume_sample_export,
196                 static_cast<const int *>(valid),
197                 ispcEquivalent,
198                 &objectCoordinates,
199                 attributeIndex,
200                 &time,
201                 &samples);
202     }
203 
204     template <int W,
205               template <int>
206               class IntervalIteratorFactory,
207               template <int>
208               class HitIteratorFactory>
209     inline void
210     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSampleN(unsigned int N,const vvec3fn<1> * objectCoordinates,float * samples,unsigned int attributeIndex,const float * times)211         computeSampleN(unsigned int N,
212                        const vvec3fn<1> *objectCoordinates,
213                        float *samples,
214                        unsigned int attributeIndex,
215                        const float *times) const
216     {
217       assert(attributeIndex < volume->getNumAttributes());
218       assertAllValidTimes(N, times);
219       CALL_ISPC(SharedStructuredVolume_sample_N_export,
220                 ispcEquivalent,
221                 N,
222                 (ispc::vec3f *)objectCoordinates,
223                 attributeIndex,
224                 times,
225                 samples);
226     }
227 
228     template <int W,
229               template <int>
230               class IntervalIteratorFactory,
231               template <int>
232               class HitIteratorFactory>
233     inline void
234     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeGradientV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,vvec3fn<W> & gradients,unsigned int attributeIndex,const vfloatn<W> & time)235         computeGradientV(const vintn<W> &valid,
236                          const vvec3fn<W> &objectCoordinates,
237                          vvec3fn<W> &gradients,
238                          unsigned int attributeIndex,
239                          const vfloatn<W> &time) const
240     {
241       assert(attributeIndex < volume->getNumAttributes());
242       assertValidTimes(valid, time);
243       CALL_ISPC(SharedStructuredVolume_gradient_export,
244                 static_cast<const int *>(valid),
245                 ispcEquivalent,
246                 &objectCoordinates,
247                 attributeIndex,
248                 time,
249                 &gradients);
250     }
251 
252     template <int W,
253               template <int>
254               class IntervalIteratorFactory,
255               template <int>
256               class HitIteratorFactory>
257     inline void
258     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeGradientN(unsigned int N,const vvec3fn<1> * objectCoordinates,vvec3fn<1> * gradients,unsigned int attributeIndex,const float * times)259         computeGradientN(unsigned int N,
260                          const vvec3fn<1> *objectCoordinates,
261                          vvec3fn<1> *gradients,
262                          unsigned int attributeIndex,
263                          const float *times) const
264     {
265       assert(attributeIndex < volume->getNumAttributes());
266       assertAllValidTimes(N, times);
267       CALL_ISPC(SharedStructuredVolume_gradient_N_export,
268                 ispcEquivalent,
269                 N,
270                 (ispc::vec3f *)objectCoordinates,
271                 attributeIndex,
272                 times,
273                 (ispc::vec3f *)gradients);
274     }
275 
276     template <int W,
277               template <int>
278               class IntervalIteratorFactory,
279               template <int>
280               class HitIteratorFactory>
281     inline void
282     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSampleM(const vvec3fn<1> & objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const vfloatn<1> & time)283         computeSampleM(const vvec3fn<1> &objectCoordinates,
284                        float *samples,
285                        unsigned int M,
286                        const unsigned int *attributeIndices,
287                        const vfloatn<1> &time) const
288     {
289       assertValidAttributeIndices(volume, M, attributeIndices);
290       assertValidTime(time[0]);
291       CALL_ISPC(SharedStructuredVolume_sampleM_uniform_export,
292                 ispcEquivalent,
293                 &objectCoordinates,
294                 M,
295                 attributeIndices,
296                 &time,
297                 samples);
298     }
299 
300     template <int W,
301               template <int>
302               class IntervalIteratorFactory,
303               template <int>
304               class HitIteratorFactory>
305     inline void
306     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSampleMV(const vintn<W> & valid,const vvec3fn<W> & objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const vfloatn<W> & time)307         computeSampleMV(const vintn<W> &valid,
308                         const vvec3fn<W> &objectCoordinates,
309                         float *samples,
310                         unsigned int M,
311                         const unsigned int *attributeIndices,
312                         const vfloatn<W> &time) const
313     {
314       assertValidAttributeIndices(volume, M, attributeIndices);
315       assertValidTimes(valid, time);
316       CALL_ISPC(SharedStructuredVolume_sampleM_export,
317                 static_cast<const int *>(valid),
318                 ispcEquivalent,
319                 &objectCoordinates,
320                 M,
321                 attributeIndices,
322                 &time,
323                 samples);
324     }
325 
326     template <int W,
327               template <int>
328               class IntervalIteratorFactory,
329               template <int>
330               class HitIteratorFactory>
331     inline void
332     StructuredSampler<W, IntervalIteratorFactory, HitIteratorFactory>::
computeSampleMN(unsigned int N,const vvec3fn<1> * objectCoordinates,float * samples,unsigned int M,const unsigned int * attributeIndices,const float * times)333         computeSampleMN(unsigned int N,
334                         const vvec3fn<1> *objectCoordinates,
335                         float *samples,
336                         unsigned int M,
337                         const unsigned int *attributeIndices,
338                         const float *times) const
339     {
340       assertValidAttributeIndices(volume, M, attributeIndices);
341       assertAllValidTimes(N, times);
342       CALL_ISPC(SharedStructuredVolume_sampleM_N_export,
343                 ispcEquivalent,
344                 N,
345                 (ispc::vec3f *)objectCoordinates,
346                 M,
347                 attributeIndices,
348                 times,
349                 samples);
350     }
351 
352     template <int W>
353     using StructuredRegularSampler =
354         StructuredSampler<W,
355                           GridAcceleratorIntervalIteratorFactory,
356                           GridAcceleratorHitIteratorFactory>;
357 
358     template <int W>
359     using StructuredSphericalIntervalIteratorFactory =
360         ConcreteIteratorFactory<W,
361                                 IntervalIterator,
362                                 DefaultIntervalIterator,
363                                 IntervalIteratorContext,
364                                 IntervalIteratorContext>;
365 
366     template <int W>
367     using StructuredSphericalHitIterator =
368         DefaultHitIterator<W, DefaultIntervalIterator<W>>;
369 
370     template <int W>
371     using StructuredSphericalHitIteratorFactory =
372         ConcreteIteratorFactory<W,
373                                 HitIterator,
374                                 StructuredSphericalHitIterator,
375                                 HitIteratorContext,
376                                 HitIteratorContext>;
377 
378     template <int W>
379     using StructuredSphericalSampler =
380         StructuredSampler<W,
381                           StructuredSphericalIntervalIteratorFactory,
382                           StructuredSphericalHitIteratorFactory>;
383 
384   }  // namespace cpu_device
385 }  // namespace openvkl
386