VTK  9.4.20241219
Geometry.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3#pragma once
4
5#include "../Types.h"
6#include "Material.h"
7
8#include <VisRTX.h>
9#include <cassert>
10
11namespace RTW
12{
13VTK_ABI_NAMESPACE_BEGIN
14 class Geometry : public Object
15 {
16 friend class World;
17
18 public:
19 Geometry(const std::string& type)
21 {
22 VisRTX::Context* rtx = VisRTX_GetContext();
23
24 if (type == "mesh")
25 this->geometry = rtx->CreateTriangleGeometry();
26 else if (type == "sphere")
27 this->geometry = rtx->CreateSphereGeometry();
28 else if (type == "curve")
29 this->geometry = rtx->CreateCylinderGeometry();
30 else if (type == "isosurfaces")
31 ; // not implemented
32 else
33 {
34 assert(false);
35 }
36 }
37
39 {
40 if(this->geometry)
41 this->geometry->Release();
42 if(this->material)
43 this->material->Release();
44 }
45
46 void Commit() override
47 {
48 if (!this->geometry)
49 return;
50
51 /*
52 * Triangles
53 */
54 if (this->geometry->GetType() == VisRTX::GeometryType::TRIANGLES)
55 {
56 VisRTX::TriangleGeometry* tri = dynamic_cast<VisRTX::TriangleGeometry*>(this->geometry);
57
58 Data* vertex = this->GetObject<Data>({ "vertex.position", "position", "vertex" });
59 Data* index = this->GetObject<Data>({ "index" });
60 if (vertex && index)
61 {
62 uint32_t numTriangles = static_cast<uint32_t>(index->GetNumElements());
63 VisRTX::Vec3ui* triangles = reinterpret_cast<VisRTX::Vec3ui*>(index->GetData());
64 assert(index->GetElementDataType() == RTW_VEC3UI);
65
66 uint32_t numVertices = static_cast<uint32_t>(vertex->GetNumElements());
67 VisRTX::Vec3f* vertices = reinterpret_cast<VisRTX::Vec3f*>(vertex->GetData());
68 assert(vertex->GetElementDataType() == RTW_VEC3F);
69
70 VisRTX::Vec3f* normals = nullptr;
71 Data* normal = this->GetObject<Data>({ "vertex.normal" });
72 if (normal)
73 {
74 normals = reinterpret_cast<VisRTX::Vec3f*>(normal->GetData());
75 assert(normal->GetElementDataType() == RTW_VEC3F);
76 }
77
78
79 tri->SetTriangles(numTriangles, triangles, numVertices, vertices, normals);
80
81
82 Data* color = this->GetObject<Data>({ "vertex.color" });
83 if (color)
84 {
85 VisRTX::Vec4f* colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
86 assert(color->GetElementDataType() == RTW_VEC4F);
87 tri->SetColors(colors);
88 }
89 else
90 {
91 tri->SetColors(nullptr);
92 }
93
94
95 Data* texcoord = GetObject<Data>({ "vertex.texcoord" });
96 if (texcoord)
97 {
98 VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
99 assert(texcoord->GetElementDataType() == RTW_VEC2F);
100 tri->SetTexCoords(texcoords);
101 }
102 else
103 {
104 tri->SetTexCoords(nullptr);
105 }
106
107 Data* materialList = GetObject<Data>({ "material" });
108 if (materialList)
109 {
110 assert(materialList->GetElementDataType() == RTW_MATERIAL);
111
112 std::vector<VisRTX::Material*> triangleMaterials;
113 triangleMaterials.resize(numTriangles);
114
115 Material** materials = reinterpret_cast<Material**>(materialList->GetData());
116
117 for (uint32_t i = 0; i < numTriangles; ++i)
118 {
119 Material* materialHandle = materials[i];
120 if (materialHandle)
121 triangleMaterials[i] = materialHandle->material;
122 }
123
124 tri->SetMaterials(triangleMaterials.data());
125 }
126 else
127 {
128 tri->SetMaterials(nullptr);
129 }
130 }
131 else
132 {
133 tri->SetTriangles(0, nullptr, 0, nullptr, nullptr);
134 assert(false);
135 }
136 }
137
138 /*
139 * Spheres
140 */
141 else if (this->geometry->GetType() == VisRTX::GeometryType::SPHERES)
142 {
143 VisRTX::SphereGeometry* sphere = dynamic_cast<VisRTX::SphereGeometry*>(this->geometry);
144
145 Data* spheres = GetObject<Data>({ "sphere.position" });
146 if (spheres)
147 {
148 VisRTX::Vec4f* colors = nullptr;
149 Data* color = GetObject<Data>({ "color" });
150 if (color)
151 {
152 colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
153 assert(color->GetElementDataType() == RTW_VEC4F);
154 sphere->SetColors(reinterpret_cast<VisRTX::Vec4f *>(color->GetData()));
155 }
156 else
157 {
158 sphere->SetColors(nullptr);
159 }
160
161 Data *radii = GetObject<Data>({"sphere.radius"});
162 if (radii)
163 {
164 uint32_t numSpheres = spheres->GetNumElements();
165 sphere->SetSpheres(numSpheres,
166 reinterpret_cast<VisRTX::Vec3f *>(spheres->GetData()),
167 reinterpret_cast<float *>(radii->GetData()));
168 }
169 else
170 {
171 uint32_t numSpheres = spheres->GetNumElements();
172 sphere->SetSpheres(numSpheres,
173 reinterpret_cast<VisRTX::Vec3f *>(spheres->GetData()),
174 nullptr);
175 }
176
177
178 Data* texcoord = GetObject<Data>({ "sphere.texcoord" });
179 if (texcoord)
180 {
181 VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
182 assert(texcoord->GetElementDataType() == RTW_VEC2F);
183 sphere->SetTexCoords(texcoords);
184 }
185 else
186 {
187 sphere->SetTexCoords(nullptr);
188 }
189
190 Data* materialList = GetObject<Data>({ "material" });
191 if (materialList)
192 {
193 assert(materialList->GetElementDataType() == RTW_MATERIAL);
194
195 uint32_t numSpheres = spheres->GetNumElements();
196 std::vector<VisRTX::Material*> sphereMaterials;
197 sphereMaterials.resize(numSpheres);
198
199 Material** materials = reinterpret_cast<Material**>(materialList->GetData());
200
201 for (uint32_t i = 0; i < numSpheres; ++i)
202 {
203 Material* materialHandle = materials[i];
204 if (materialHandle)
205 sphereMaterials[i] = materialHandle->material;
206 }
207
208 sphere->SetMaterials(sphereMaterials.data());
209 }
210 else
211 {
212 sphere->SetMaterials(nullptr);
213 }
214 }
215 else
216 {
217 assert(false);
218 }
219
220 float radius;
221 if (this->GetFloat({ "radius" }, &radius))
222 sphere->SetRadius(radius);
223 }
224
225 /*
226 * Cylinders
227 */
228 else if (this->geometry->GetType() == VisRTX::GeometryType::CYLINDERS)
229 {
230 VisRTX::CylinderGeometry* cyl = dynamic_cast<VisRTX::CylinderGeometry*>(this->geometry);
231
232 //Non-scale-array variant
233 Data* cylinders = GetObject<Data>({ "vertex.position" });
234 if (cylinders)
235 {
236 VisRTX::Vec4f* colors = nullptr;
237 Data* color = GetObject<Data>({ "color" });
238 if (color)
239 {
240 colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
241 assert(color->GetElementDataType() == RTW_VEC4F);
242 }
243
244 int32_t bytesPerCylinder = this->GetInt({ "bytes_per_cylinder" }, 24, nullptr);
245 int32_t offsetVertex0 = this->GetInt({ "offset_v0" }, 0, nullptr);
246 int32_t offsetVertex1 = this->GetInt({ "offset_v1" }, 12, nullptr);
247 int32_t offsetRadius = this->GetInt({ "offset_radius" }, -1, nullptr);
248
249 uint32_t numCylinders = cylinders->GetNumElements() * cylinders->GetElementSize() / bytesPerCylinder;
250 cyl->SetCylindersAndColors(numCylinders, cylinders->GetData(), bytesPerCylinder, offsetVertex0, offsetVertex1, offsetRadius, colors);
251
252
253 Data* texcoord = GetObject<Data>({ "vertex.texcoord" });
254 if (texcoord)
255 {
256 VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
257 assert(texcoord->GetElementDataType() == RTW_VEC2F);
258 cyl->SetTexCoords(texcoords);
259 }
260 else
261 {
262 cyl->SetTexCoords(nullptr);
263 }
264
265 Data* materialList = GetObject<Data>({ "material" });
266 if (materialList)
267 {
268 assert(materialList->GetElementDataType() == RTW_MATERIAL);
269
270 std::vector<VisRTX::Material*> cylinderMaterials;
271 cylinderMaterials.resize(numCylinders);
272
273 Material** materials = reinterpret_cast<Material**>(materialList->GetData());
274
275 for (uint32_t i = 0; i < numCylinders; ++i)
276 {
277 Material* materialHandle = materials[i];
278 if (materialHandle)
279 cylinderMaterials[i] = materialHandle->material;
280 }
281
282 cyl->SetMaterials(cylinderMaterials.data());
283 }
284 else
285 {
286 cyl->SetMaterials(nullptr);
287 }
288 }
289 else if(cylinders = GetObject<Data>({"vertex.position_radius"}))
290 {
291 //Scale-array variant
292 VisRTX::Vec4f* colors = nullptr;
293 Data* color = GetObject<Data>({ "color" });
294 if (color)
295 {
296 colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
297 assert(color->GetElementDataType() == RTW_VEC4F);
298 }
299
300 int32_t bytesPerCylinder = this->GetInt({ "bytes_per_cylinder" }, 64, nullptr);
301 int32_t offsetVertex0 = this->GetInt({ "offset_v0" }, 0, nullptr);
302 int32_t offsetVertex1 = this->GetInt({ "offset_v1" }, 32, nullptr);
303 int32_t offsetRadius = this->GetInt({ "offset_radius" }, 12, nullptr);
304
305 uint32_t numCylinders = cylinders->GetNumElements() * cylinders->GetElementSize() / bytesPerCylinder;
306 cyl->SetCylindersAndColors(numCylinders, cylinders->GetData(), bytesPerCylinder, offsetVertex0, offsetVertex1, offsetRadius, colors);
307
308
309 Data* texcoord = GetObject<Data>({ "vertex.texcoord" });
310 if (texcoord)
311 {
312 VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
313 assert(texcoord->GetElementDataType() == RTW_VEC2F);
314 cyl->SetTexCoords(texcoords);
315 }
316 else
317 {
318 cyl->SetTexCoords(nullptr);
319 }
320
321 Data* materialList = GetObject<Data>({ "material" });
322 if (materialList)
323 {
324 assert(materialList->GetElementDataType() == RTW_MATERIAL);
325
326 std::vector<VisRTX::Material*> cylinderMaterials;
327 cylinderMaterials.resize(numCylinders);
328
329 Material** materials = reinterpret_cast<Material**>(materialList->GetData());
330
331 for (uint32_t i = 0; i < numCylinders; ++i)
332 {
333 Material* materialHandle = materials[i];
334 if (materialHandle)
335 cylinderMaterials[i] = materialHandle->material;
336 }
337
338 cyl->SetMaterials(cylinderMaterials.data());
339 }
340 else
341 {
342 cyl->SetMaterials(nullptr);
343 }
344 }
345 else
346 {
347 assert(false);
348 }
349
350 float radius;
351 if (this->GetFloat({ "radius" }, &radius))
352 cyl->SetRadius(radius);
353 }
354
355 else
356 {
357 assert(false);
358 }
359
360
361 // Set a default material if none is set
362 if (!this->material)
363 {
364 VisRTX::Context* rtx = VisRTX_GetContext();
365 this->geometry->SetMaterial(rtx->CreateBasicMaterial());
366 }
367 }
368
369 void SetMaterial(Material* material)
370 {
371 if (!this->geometry)
372 return;
373
374 // Release current material
375 if (this->material)
376 this->material->Release();
377
378 if (material)
379 {
380 this->geometry->SetMaterial(material->material);
381 this->material = material;
382 this->material->AddRef();
383 }
384 else
385 {
386 this->geometry->SetMaterial(nullptr);
387 this->material = nullptr;
388 }
389 }
390
391 private:
392 VisRTX::Geometry* geometry = nullptr;
393 Material* material = nullptr;
394 };
395VTK_ABI_NAMESPACE_END
396}
@ RTW_VEC3F
Definition Types.h:186
@ RTW_MATERIAL
Definition Types.h:148
@ RTW_VEC4F
Definition Types.h:186
@ RTW_VEC3UI
Definition Types.h:177
@ RTW_VEC2F
Definition Types.h:186
@ RTW_GEOMETRY
Definition Types.h:143
size_t GetNumElements() const
Definition Data.h:119
static size_t GetElementSize(RTWDataType type)
Definition Data.h:15
RTWDataType GetElementDataType() const
Definition Data.h:139
void * GetData() const
Definition Data.h:149
Geometry(const std::string &type)
Definition Geometry.h:19
void SetMaterial(Material *material)
Definition Geometry.h:369
void Commit() override
Definition Geometry.h:46
int32_t GetInt(const std::vector< std::string > &ids, int32_t defaultValue=0, bool *found=nullptr) const
Definition Object.h:119
void Release()
Definition Object.h:46
void AddRef()
Definition Object.h:41
float GetFloat(const std::vector< std::string > &ids, float defaultValue=0.0f, bool *found=nullptr) const
Definition Object.h:136
Definition Backend.h:8
std::pair< boost::graph_traits< vtkGraph * >::vertex_iterator, boost::graph_traits< vtkGraph * >::vertex_iterator > vertices(vtkGraph *g)