1 // Copyright 2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "TestingVolume.h"
7 
8 namespace openvkl {
9   namespace testing {
10 
11     struct UnstructuredVolumeMixedSimple : public TestingVolume
12     {
UnstructuredVolumeMixedSimpleUnstructuredVolumeMixedSimple13       UnstructuredVolumeMixedSimple(){};
14 
generateVKLVolumeUnstructuredVolumeMixedSimple15       void generateVKLVolume(VKLDevice device)
16       {
17         // define hexahedron parameters
18         const float hSize = .4f;
19         const float hX = -.5f, hY = -.5f, hZ = 1.f;
20 
21         // define wedge parameters
22         const float wSize = .4f;
23         const float wX = .5f, wY = -.5f, wZ = 1.f;
24 
25         // define tetrahedron parameters
26         const float tSize = .4f;
27         const float tX = .5f, tY = .5f, tZ = 1.f;
28 
29         // define pyramid parameters
30         const float pSize = .4f;
31         const float pX = -.5f, pY = .5f, pZ = 1.f;
32 
33         // define vertex positions
34         std::vector<vec3f> vertices = {
35             // hexahedron
36             {-hSize + hX, -hSize + hY, hSize + hZ},  // bottom quad
37             {hSize + hX, -hSize + hY, hSize + hZ},
38             {hSize + hX, -hSize + hY, -hSize + hZ},
39             {-hSize + hX, -hSize + hY, -hSize + hZ},
40             {-hSize + hX, hSize + hY, hSize + hZ},  // top quad
41             {hSize + hX, hSize + hY, hSize + hZ},
42             {hSize + hX, hSize + hY, -hSize + hZ},
43             {-hSize + hX, hSize + hY, -hSize + hZ},
44 
45             // wedge
46             {-wSize + wX, -wSize + wY, wSize + wZ},  // bottom triangle
47             {wSize + wX, -wSize + wY, 0.f + wZ},
48             {-wSize + wX, -wSize + wY, -wSize + wZ},
49             {-wSize + wX, wSize + wY, wSize + wZ},  // top triangle
50             {wSize + wX, wSize + wY, 0.f + wZ},
51             {-wSize + wX, wSize + wY, -wSize + wZ},
52 
53             // tetrahedron
54             {-tSize + tX, -tSize + tY, tSize + tZ},
55             {tSize + tX, -tSize + tY, 0.f + tZ},
56             {-tSize + tX, -tSize + tY, -tSize + tZ},
57             {-tSize + tX, tSize + tY, 0.f + tZ},
58 
59             // pyramid
60             {-pSize + pX, -pSize + pY, pSize + pZ},
61             {pSize + pX, -pSize + pY, pSize + pZ},
62             {pSize + pX, -pSize + pY, -pSize + pZ},
63             {-pSize + pX, -pSize + pY, -pSize + pZ},
64             {pSize + pX, pSize + pY, 0.f + pZ}};
65 
66         // define per-vertex values
67         std::vector<float> vertexValues = {// hexahedron
68                                            0.f,
69                                            0.f,
70                                            0.f,
71                                            0.f,
72                                            0.f,
73                                            1.f,
74                                            1.f,
75                                            0.f,
76 
77                                            // wedge
78                                            0.f,
79                                            0.f,
80                                            0.f,
81                                            1.f,
82                                            0.f,
83                                            1.f,
84 
85                                            // tetrahedron
86                                            1.f,
87                                            0.f,
88                                            1.f,
89                                            0.f,
90 
91                                            // pyramid
92                                            0.f,
93                                            1.f,
94                                            1.f,
95                                            0.f,
96                                            0.f};
97 
98         // define vertex indices for both shared and separate case
99         std::vector<uint32_t> indicesSharedVert = {// hexahedron
100                                                    0,
101                                                    1,
102                                                    2,
103                                                    3,
104                                                    4,
105                                                    5,
106                                                    6,
107                                                    7,
108 
109                                                    // wedge
110                                                    1,
111                                                    9,
112                                                    2,
113                                                    5,
114                                                    12,
115                                                    6,
116 
117                                                    // tetrahedron
118                                                    5,
119                                                    12,
120                                                    6,
121                                                    17,
122 
123                                                    // pyramid
124                                                    4,
125                                                    5,
126                                                    6,
127                                                    7,
128                                                    17};
129 
130         std::vector<uint32_t> &indices = indicesSharedVert;
131 
132         // define cell offsets in indices array
133         std::vector<uint32_t> cells = {0, 8, 14, 18};
134 
135         // define cell types
136         std::vector<uint8_t> cellTypes = {
137             VKL_HEXAHEDRON, VKL_WEDGE, VKL_TETRAHEDRON, VKL_PYRAMID};
138 
139         volume = vklNewVolume(device, "unstructured");
140 
141         VKLData cellData =
142             vklNewData(device, cells.size(), VKL_UINT, cells.data());
143         vklSetData(volume, "cell.index", cellData);
144         vklRelease(cellData);
145 
146         VKLData celltypeData =
147             vklNewData(device, cellTypes.size(), VKL_UCHAR, cellTypes.data());
148         vklSetData(volume, "cell.type", celltypeData);
149         vklRelease(celltypeData);
150 
151         VKLData valuesData = vklNewData(
152             device, vertexValues.size(), VKL_FLOAT, vertexValues.data());
153         vklSetData(volume, "vertex.data", valuesData);
154         vklRelease(valuesData);
155 
156         VKLData vtxPositionsData =
157             vklNewData(device, vertices.size(), VKL_VEC3F, vertices.data());
158         vklSetData(volume, "vertex.position", vtxPositionsData);
159         vklRelease(vtxPositionsData);
160 
161         VKLData topologyData =
162             vklNewData(device, indices.size(), VKL_UINT, indices.data());
163         vklSetData(volume, "index", topologyData);
164         vklRelease(topologyData);
165 
166         vklCommit(volume);
167 
168         computedValueRange = computeValueRange(
169             VKL_FLOAT, vertexValues.data(), vertexValues.size());
170       };
171 
getComputedValueRangeUnstructuredVolumeMixedSimple172       range1f getComputedValueRange() const
173       {
174         if (computedValueRange.empty()) {
175           throw std::runtime_error(
176               "computedValueRange only available after VKL volume is "
177               "generated");
178         }
179 
180         return computedValueRange;
181       };
182 
183      private:
184       range1f computedValueRange = range1f(rkcommon::math::empty);
185     };
186   }  // namespace testing
187 }  // namespace openvkl
188