1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #include <sstream>
11 #include <vtkm/CellShape.h>
12 #include <vtkm/cont/ErrorBadValue.h>
13 #include <vtkm/cont/Timer.h>
14 #include <vtkm/cont/internal/DeviceAdapterListHelpers.h>
15 #include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
16 #include <vtkm/rendering/raytracing/Logger.h>
17 #include <vtkm/rendering/raytracing/MeshConnectivityBase.h>
18 #include <vtkm/rendering/raytracing/MeshConnectivityContainers.h>
19 #include <vtkm/rendering/raytracing/Ray.h>
20 #include <vtkm/rendering/raytracing/TriangleIntersector.h>
21 namespace vtkm
22 {
23 namespace rendering
24 {
25 namespace raytracing
26 {
27
MeshConnContainer()28 MeshConnContainer::MeshConnContainer(){};
~MeshConnContainer()29 MeshConnContainer::~MeshConnContainer(){};
30
31 template <typename T>
FindEntryImpl(Ray<T> & rays)32 VTKM_CONT void MeshConnContainer::FindEntryImpl(Ray<T>& rays)
33 {
34 bool getCellIndex = true;
35
36 Intersector.SetUseWaterTight(true);
37
38 Intersector.IntersectRays(rays, getCellIndex);
39 }
40
PrepareForExecution(const vtkm::cont::DeviceAdapterId deviceId,vtkm::cont::Token & token)41 MeshWrapper MeshConnContainer::PrepareForExecution(const vtkm::cont::DeviceAdapterId deviceId,
42 vtkm::cont::Token& token)
43 {
44 return MeshWrapper(const_cast<MeshConnectivityBase*>(this->Construct(deviceId, token)));
45 }
46
FindEntry(Ray<vtkm::Float32> & rays)47 void MeshConnContainer::FindEntry(Ray<vtkm::Float32>& rays)
48 {
49 this->FindEntryImpl(rays);
50 }
51
FindEntry(Ray<vtkm::Float64> & rays)52 void MeshConnContainer::FindEntry(Ray<vtkm::Float64>& rays)
53 {
54 this->FindEntryImpl(rays);
55 }
56
57 VTKM_CONT
UnstructuredContainer(const vtkm::cont::CellSetExplicit<> & cellset,const vtkm::cont::CoordinateSystem & coords,IdHandle & faceConn,IdHandle & faceOffsets,Id4Handle & triangles)58 UnstructuredContainer::UnstructuredContainer(const vtkm::cont::CellSetExplicit<>& cellset,
59 const vtkm::cont::CoordinateSystem& coords,
60 IdHandle& faceConn,
61 IdHandle& faceOffsets,
62 Id4Handle& triangles)
63 : FaceConnectivity(faceConn)
64 , FaceOffsets(faceOffsets)
65 , Cellset(cellset)
66 , Coords(coords)
67 {
68 this->Triangles = triangles;
69 //
70 // Grab the cell arrays
71 //
72 CellConn =
73 Cellset.GetConnectivityArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
74 CellOffsets =
75 Cellset.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
76 Shapes = Cellset.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
77
78 Intersector.SetData(Coords, Triangles);
79 }
80
~UnstructuredContainer()81 UnstructuredContainer::~UnstructuredContainer(){};
82
Construct(const vtkm::cont::DeviceAdapterId deviceId,vtkm::cont::Token & token)83 const MeshConnectivityBase* UnstructuredContainer::Construct(
84 const vtkm::cont::DeviceAdapterId deviceId,
85 vtkm::cont::Token& token)
86 {
87 switch (deviceId.GetValue())
88 {
89 #ifdef VTKM_ENABLE_OPENMP
90 case VTKM_DEVICE_ADAPTER_OPENMP:
91 using OMP = vtkm::cont::DeviceAdapterTagOpenMP;
92 {
93 MeshConnUnstructured<OMP> conn(this->FaceConnectivity,
94 this->FaceOffsets,
95 this->CellConn,
96 this->CellOffsets,
97 this->Shapes,
98 token);
99 Handle = make_MeshConnHandle(conn);
100 }
101 return Handle.PrepareForExecution(OMP(), token);
102 #endif
103 #ifdef VTKM_ENABLE_TBB
104 case VTKM_DEVICE_ADAPTER_TBB:
105 using TBB = vtkm::cont::DeviceAdapterTagTBB;
106 {
107 MeshConnUnstructured<TBB> conn(this->FaceConnectivity,
108 this->FaceOffsets,
109 this->CellConn,
110 this->CellOffsets,
111 this->Shapes,
112 token);
113 Handle = make_MeshConnHandle(conn);
114 }
115 return Handle.PrepareForExecution(TBB(), token);
116 #endif
117 #ifdef VTKM_ENABLE_CUDA
118 case VTKM_DEVICE_ADAPTER_CUDA:
119 using CUDA = vtkm::cont::DeviceAdapterTagCuda;
120 {
121 MeshConnUnstructured<CUDA> conn(this->FaceConnectivity,
122 this->FaceOffsets,
123 this->CellConn,
124 this->CellOffsets,
125 this->Shapes,
126 token);
127 Handle = make_MeshConnHandle(conn);
128 }
129 return Handle.PrepareForExecution(CUDA(), token);
130 #endif
131 #ifdef VTKM_ENABLE_KOKKOS
132 case VTKM_DEVICE_ADAPTER_KOKKOS:
133 using KOKKOS = vtkm::cont::DeviceAdapterTagKokkos;
134 {
135 MeshConnUnstructured<KOKKOS> conn(this->FaceConnectivity,
136 this->FaceOffsets,
137 this->CellConn,
138 this->CellOffsets,
139 this->Shapes,
140 token);
141 Handle = make_MeshConnHandle(conn);
142 }
143 return Handle.PrepareForExecution(KOKKOS(), token);
144 #endif
145 case VTKM_DEVICE_ADAPTER_SERIAL:
146 VTKM_FALLTHROUGH;
147 default:
148 using SERIAL = vtkm::cont::DeviceAdapterTagSerial;
149 {
150 MeshConnUnstructured<SERIAL> conn(this->FaceConnectivity,
151 this->FaceOffsets,
152 this->CellConn,
153 this->CellOffsets,
154 this->Shapes,
155 token);
156 Handle = make_MeshConnHandle(conn);
157 }
158 return Handle.PrepareForExecution(SERIAL(), token);
159 }
160 }
161
162 VTKM_CONT
UnstructuredSingleContainer()163 UnstructuredSingleContainer::UnstructuredSingleContainer() {}
164
165 VTKM_CONT
UnstructuredSingleContainer(const vtkm::cont::CellSetSingleType<> & cellset,const vtkm::cont::CoordinateSystem & coords,IdHandle & faceConn,Id4Handle & triangles)166 UnstructuredSingleContainer::UnstructuredSingleContainer(
167 const vtkm::cont::CellSetSingleType<>& cellset,
168 const vtkm::cont::CoordinateSystem& coords,
169 IdHandle& faceConn,
170 Id4Handle& triangles)
171 : FaceConnectivity(faceConn)
172 , Coords(coords)
173 , Cellset(cellset)
174 {
175
176 this->Triangles = triangles;
177
178 this->Intersector.SetUseWaterTight(true);
179
180 CellConnectivity =
181 Cellset.GetConnectivityArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
182 vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
183 Cellset.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
184
185 ShapeId = shapes.ReadPortal().Get(0);
186 CellTables tables;
187 NumIndices = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 2);
188
189 if (NumIndices == 0)
190 {
191 std::stringstream message;
192 message << "Unstructured Mesh Connecitity Single type Error: unsupported cell type: ";
193 message << ShapeId;
194 throw vtkm::cont::ErrorBadValue(message.str());
195 }
196 vtkm::Id start = 0;
197 NumFaces = tables.FaceLookUp(tables.CellTypeLookUp(ShapeId), 1);
198 vtkm::Id numCells = CellConnectivity.ReadPortal().GetNumberOfValues();
199 CellOffsets = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start, NumIndices, numCells);
200
201 Logger* logger = Logger::GetInstance();
202 logger->OpenLogEntry("mesh_conn_construction");
203
204 Intersector.SetData(Coords, Triangles);
205 }
206
Construct(const vtkm::cont::DeviceAdapterId deviceId,vtkm::cont::Token & token)207 const MeshConnectivityBase* UnstructuredSingleContainer::Construct(
208 const vtkm::cont::DeviceAdapterId deviceId,
209 vtkm::cont::Token& token)
210 {
211 switch (deviceId.GetValue())
212 {
213 #ifdef VTKM_ENABLE_OPENMP
214 case VTKM_DEVICE_ADAPTER_OPENMP:
215 using OMP = vtkm::cont::DeviceAdapterTagOpenMP;
216 {
217 MeshConnSingleType<OMP> conn(this->FaceConnectivity,
218 this->CellConnectivity,
219 this->CellOffsets,
220 this->ShapeId,
221 this->NumIndices,
222 this->NumFaces,
223 token);
224 Handle = make_MeshConnHandle(conn);
225 }
226 return Handle.PrepareForExecution(OMP(), token);
227 #endif
228 #ifdef VTKM_ENABLE_TBB
229 case VTKM_DEVICE_ADAPTER_TBB:
230 using TBB = vtkm::cont::DeviceAdapterTagTBB;
231 {
232 MeshConnSingleType<TBB> conn(this->FaceConnectivity,
233 this->CellConnectivity,
234 this->CellOffsets,
235 this->ShapeId,
236 this->NumIndices,
237 this->NumFaces,
238 token);
239 Handle = make_MeshConnHandle(conn);
240 }
241 return Handle.PrepareForExecution(TBB(), token);
242 #endif
243 #ifdef VTKM_ENABLE_CUDA
244 case VTKM_DEVICE_ADAPTER_CUDA:
245 using CUDA = vtkm::cont::DeviceAdapterTagCuda;
246 {
247 MeshConnSingleType<CUDA> conn(this->FaceConnectivity,
248 this->CellConnectivity,
249 this->CellOffsets,
250 this->ShapeId,
251 this->NumIndices,
252 this->NumFaces,
253 token);
254 Handle = make_MeshConnHandle(conn);
255 }
256 return Handle.PrepareForExecution(CUDA(), token);
257 #endif
258 #ifdef VTKM_ENABLE_KOKKOS
259 case VTKM_DEVICE_ADAPTER_KOKKOS:
260 using KOKKOS = vtkm::cont::DeviceAdapterTagKokkos;
261 {
262 MeshConnSingleType<KOKKOS> conn(this->FaceConnectivity,
263 this->CellConnectivity,
264 this->CellOffsets,
265 this->ShapeId,
266 this->NumIndices,
267 this->NumFaces,
268 token);
269 Handle = make_MeshConnHandle(conn);
270 }
271 return Handle.PrepareForExecution(KOKKOS(), token);
272 #endif
273 case VTKM_DEVICE_ADAPTER_SERIAL:
274 VTKM_FALLTHROUGH;
275 default:
276 using SERIAL = vtkm::cont::DeviceAdapterTagSerial;
277 {
278 MeshConnSingleType<SERIAL> conn(this->FaceConnectivity,
279 this->CellConnectivity,
280 this->CellOffsets,
281 this->ShapeId,
282 this->NumIndices,
283 this->NumFaces,
284 token);
285 Handle = make_MeshConnHandle(conn);
286 }
287 return Handle.PrepareForExecution(SERIAL(), token);
288 }
289 }
290
StructuredContainer(const vtkm::cont::CellSetStructured<3> & cellset,const vtkm::cont::CoordinateSystem & coords,Id4Handle & triangles)291 StructuredContainer::StructuredContainer(const vtkm::cont::CellSetStructured<3>& cellset,
292 const vtkm::cont::CoordinateSystem& coords,
293 Id4Handle& triangles)
294 : Coords(coords)
295 , Cellset(cellset)
296 {
297
298 Triangles = triangles;
299 Intersector.SetUseWaterTight(true);
300
301 PointDims = Cellset.GetPointDimensions();
302 CellDims = Cellset.GetCellDimensions();
303
304 this->Intersector.SetData(Coords, Triangles);
305 }
306
Construct(const vtkm::cont::DeviceAdapterId deviceId,vtkm::cont::Token & token)307 const MeshConnectivityBase* StructuredContainer::Construct(
308 const vtkm::cont::DeviceAdapterId deviceId,
309 vtkm::cont::Token& token)
310 {
311
312 MeshConnStructured conn(CellDims, PointDims);
313 Handle = make_MeshConnHandle(conn);
314
315 switch (deviceId.GetValue())
316 {
317 #ifdef VTKM_ENABLE_OPENMP
318 case VTKM_DEVICE_ADAPTER_OPENMP:
319 return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagOpenMP(), token);
320 #endif
321 #ifdef VTKM_ENABLE_TBB
322 case VTKM_DEVICE_ADAPTER_TBB:
323 return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagTBB(), token);
324 #endif
325 #ifdef VTKM_ENABLE_CUDA
326 case VTKM_DEVICE_ADAPTER_CUDA:
327 return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagCuda(), token);
328 #endif
329 #ifdef VTKM_ENABLE_KOKKOS
330 case VTKM_DEVICE_ADAPTER_KOKKOS:
331 return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagKokkos(), token);
332 #endif
333 case VTKM_DEVICE_ADAPTER_SERIAL:
334 VTKM_FALLTHROUGH;
335 default:
336 return Handle.PrepareForExecution(vtkm::cont::DeviceAdapterTagSerial(), token);
337 }
338 }
339 }
340 }
341 } //namespace vtkm::rendering::raytracing
342