1 // Copyright 2019-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "../common/ManagedObject.h"
7 #include "../common/export_util.h"
8 #include "../common/objectFactory.h"
9 #include "../iterator/Iterator.h"
10 #include "../sampler/Sampler.h"
11 #include "Volume_ispc.h"
12 #include "openvkl/openvkl.h"
13 #include "rkcommon/math/box.h"
14 
15 #define THROW_NOT_IMPLEMENTED                          \
16   throw std::runtime_error(std::string(__FUNCTION__) + \
17                            " not implemented in this volume!")
18 
19 using namespace rkcommon;
20 
21 namespace openvkl {
22   namespace cpu_device {
23 
24     // Helpers ////////////////////////////////////////////////////////////////
25 
26     // this helper may be used on both signed and unsigned int types
27     template <int W, typename INT_TYPE>
throwOnIllegalAttributeIndex(const Volume<W> * volume,INT_TYPE attributeIndex)28     inline void throwOnIllegalAttributeIndex(const Volume<W> *volume,
29                                              INT_TYPE attributeIndex)
30     {
31       if (attributeIndex < 0 || attributeIndex >= volume->getNumAttributes()) {
32         throw std::runtime_error("illegal attributeIndex requested on volume");
33       }
34     }
35 
36     // Volume /////////////////////////////////////////////////////////////////
37 
38     template <int W>
39     struct Volume : public ManagedObject
40     {
41       Volume()                   = default;
42       virtual ~Volume() override = default;
43 
44       static Volume *createInstance(Device *device, const std::string &type);
45 
46       virtual Sampler<W> *newSampler() = 0;
47 
48       virtual box3f getBoundingBox() const = 0;
49 
50       virtual unsigned int getNumAttributes() const = 0;
51 
52       virtual range1f getValueRange(unsigned int attributeIndex) const = 0;
53 
54       void *getISPCEquivalent() const;
55 
newObserverVolume56       virtual Observer<W> *newObserver(const char *type)
57       {
58         return nullptr;
59       }
60 
61      protected:
62       void *ispcEquivalent{nullptr};
63     };
64 
65     // Inlined definitions ////////////////////////////////////////////////////
66 
67     template <int W>
createInstance(Device * device,const std::string & type)68     inline Volume<W> *Volume<W>::createInstance(Device *device,
69                                                 const std::string &type)
70     {
71       return createInstanceHelper<Volume<W>, VKL_VOLUME>(device, type);
72     }
73 
74     template <int W>
getISPCEquivalent()75     inline void *Volume<W>::getISPCEquivalent() const
76     {
77       return ispcEquivalent;
78     }
79 
80 #define VKL_REGISTER_VOLUME(InternalClass, external_name) \
81   VKL_REGISTER_OBJECT(                                    \
82       ::openvkl::ManagedObject, volume, InternalClass, external_name)
83 
84   }  // namespace cpu_device
85 }  // namespace openvkl
86