VTK  9.0.1
Geometry.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../Types.h"
4 #include "Material.h"
5 
6 #include <VisRTX.h>
7 #include <cassert>
8 
9 namespace RTW
10 {
11  class Geometry : public Object
12  {
13  friend class Model;
14 
15  public:
17  {
18  VisRTX::Context* rtx = VisRTX_GetContext();
19 
20  if (type == "triangles" || type == "trianglemesh")
21  this->geometry = rtx->CreateTriangleGeometry();
22  else if (type == "spheres")
23  this->geometry = rtx->CreateSphereGeometry();
24  else if (type == "cylinders")
25  this->geometry = rtx->CreateCylinderGeometry();
26  else if (type == "isosurfaces")
27  ; // not implemented
28  else
29  {
30  std::cerr << "Error: Unhandled geometry type \"" << type << "\"" << std::endl;
31  assert(false);
32  }
33  }
34 
36  {
37  this->geometry->Release();
38  }
39 
40  void Commit() override
41  {
42  if (!this->geometry)
43  return;
44 
45  /*
46  * Triangles
47  */
48  if (this->geometry->GetType() == VisRTX::GeometryType::TRIANGLES)
49  {
50  VisRTX::TriangleGeometry* tri = dynamic_cast<VisRTX::TriangleGeometry*>(this->geometry);
51 
52  Data* vertex = this->GetObject<Data>({ "position", "vertex" });
53  Data* index = this->GetObject<Data>({ "index" });
54  if (vertex && index)
55  {
56  uint32_t numTriangles = static_cast<uint32_t>(index->GetNumElements());
57  VisRTX::Vec3ui* triangles = reinterpret_cast<VisRTX::Vec3ui*>(index->GetData());
58  assert(index->GetDataType() == RTW_INT3);
59 
60  uint32_t numVertices = static_cast<uint32_t>(vertex->GetNumElements());
61  VisRTX::Vec3f* vertices = reinterpret_cast<VisRTX::Vec3f*>(vertex->GetData());
62  assert(vertex->GetDataType() == RTW_FLOAT3);
63 
64  VisRTX::Vec3f* normals = nullptr;
65  Data* normal = this->GetObject<Data>({ "vertex.normal" });
66  if (normal)
67  {
68  normals = reinterpret_cast<VisRTX::Vec3f*>(normal->GetData());
69  assert(normal->GetDataType() == RTW_FLOAT3);
70  }
71 
72  tri->SetTriangles(numTriangles, triangles, numVertices, vertices, normals);
73 
74 
75  Data* color = this->GetObject<Data>({ "vertex.color" });
76  if (color)
77  {
78  VisRTX::Vec4f* colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
79  assert(color->GetDataType() == RTW_FLOAT4);
80  tri->SetColors(colors);
81  }
82  else
83  {
84  tri->SetColors(nullptr);
85  }
86 
87 
88  Data* texcoord = GetObject<Data>({ "vertex.texcoord" });
89  if (texcoord)
90  {
91  VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
92  assert(texcoord->GetDataType() == RTW_FLOAT2);
93  tri->SetTexCoords(texcoords);
94  }
95  else
96  {
97  tri->SetTexCoords(nullptr);
98  }
99 
100 
101  Data* materialList = GetObject<Data>({ "materialList" });
102  Data* materialIndices = GetObject<Data>({ "prim.materialID" });
103  if (materialList && materialIndices)
104  {
105  assert(materialList->GetDataType() == RTW_OBJECT);
106  assert(materialIndices->GetDataType() == RTW_INT);
107 
108  std::vector<VisRTX::Material*> triangleMaterials;
109  triangleMaterials.resize(numTriangles);
110 
111  Material** materials = reinterpret_cast<Material**>(materialList->GetData());
112  int* indices = reinterpret_cast<int*>(materialIndices->GetData());
113 
114  for (uint32_t i = 0; i < numTriangles; ++i)
115  {
116  int triIndex = indices[i];
117  if (triIndex >= 0)
118  {
119  Material* materialHandle = materials[triIndex];
120  if (materialHandle)
121  triangleMaterials[i] = materialHandle->material;
122  }
123  }
124 
125  tri->SetMaterials(triangleMaterials.data());
126  }
127  else
128  {
129  tri->SetMaterials(nullptr);
130  }
131  }
132  else
133  {
134  tri->SetTriangles(0, nullptr, 0, nullptr, nullptr);
135  assert(false);
136  }
137  }
138 
139  /*
140  * Spheres
141  */
142  else if (this->geometry->GetType() == VisRTX::GeometryType::SPHERES)
143  {
144  VisRTX::SphereGeometry* sphere = dynamic_cast<VisRTX::SphereGeometry*>(this->geometry);
145 
146  Data* spheres = GetObject<Data>({ "spheres" });
147  if (spheres)
148  {
149  VisRTX::Vec4f* colors = nullptr;
150  Data* color = GetObject<Data>({ "color" });
151  if (color)
152  {
153  colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
154  assert(color->GetDataType() == RTW_FLOAT4);
155  }
156 
157  int32_t bytesPerSphere = this->Get1i({ "bytes_per_sphere" }, 16, nullptr);
158  int32_t offsetCenter = this->Get1i({ "offset_center" }, 0, nullptr);
159  int32_t offsetRadius = this->Get1i({ "offset_radius" }, -1, nullptr);
160  int32_t offsetColorIndex = this->Get1i({ "offset_colorID" }, -1, nullptr);
161 
162  uint32_t numSpheres = spheres->GetNumElements() * spheres->GetElementSize() / bytesPerSphere;
163 
164  sphere->SetSpheresAndColors(numSpheres, spheres->GetData(), bytesPerSphere, offsetCenter, offsetRadius, offsetColorIndex, colors);
165 
166  Data* texcoord = GetObject<Data>({ "texcoord" });
167  if (texcoord)
168  {
169  VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
170  assert(texcoord->GetDataType() == RTW_FLOAT2);
171  sphere->SetTexCoords(texcoords);
172  }
173  else
174  {
175  sphere->SetTexCoords(nullptr);
176  }
177 
178  Data* materialList = GetObject<Data>({ "materialList" });
179  int offset_materialID = this->Get1i({ "offset_materialID" }, -1);
180  if (materialList && offset_materialID >= 0)
181  {
182  assert(materialList->GetDataType() == RTW_OBJECT);
183 
184  std::vector<VisRTX::Material*> sphereMaterials;
185  sphereMaterials.resize(numSpheres);
186 
187  Material** materials = reinterpret_cast<Material**>(materialList->GetData());
188 
189  const uint8_t* base = reinterpret_cast<const uint8_t*>(spheres->GetData());
190 
191  for (uint32_t i = 0; i < numSpheres; ++i)
192  {
193  int index = *reinterpret_cast<const int*>(base + i * bytesPerSphere + offset_materialID);
194  if (index >= 0)
195  {
196  Material* materialHandle = materials[index];
197  if (materialHandle)
198  sphereMaterials[i] = materialHandle->material;
199  }
200  }
201 
202  sphere->SetMaterials(sphereMaterials.data());
203  }
204  else
205  {
206  sphere->SetMaterials(nullptr);
207  }
208  }
209  else
210  {
211  assert(false);
212  }
213 
214  float radius;
215  if (this->Get1f({ "radius" }, &radius))
216  sphere->SetRadius(radius);
217  }
218 
219  /*
220  * Cylinders
221  */
222  else if (this->geometry->GetType() == VisRTX::GeometryType::CYLINDERS)
223  {
224  VisRTX::CylinderGeometry* cyl = dynamic_cast<VisRTX::CylinderGeometry*>(this->geometry);
225 
226  Data* cylinders = GetObject<Data>({ "cylinders" });
227  if (cylinders)
228  {
229  VisRTX::Vec4f* colors = nullptr;
230  Data* color = GetObject<Data>({ "color" });
231  if (color)
232  {
233  colors = reinterpret_cast<VisRTX::Vec4f*>(color->GetData());
234  assert(color->GetDataType() == RTW_FLOAT4);
235  }
236 
237  int32_t bytesPerCylinder = this->Get1i({ "bytes_per_cylinder" }, 24, nullptr);
238  int32_t offsetVertex0 = this->Get1i({ "offset_v0" }, 0, nullptr);
239  int32_t offsetVertex1 = this->Get1i({ "offset_v1" }, 12, nullptr);
240  int32_t offsetRadius = this->Get1i({ "offset_radius" }, -1, nullptr);
241 
242  uint32_t numCylinders = cylinders->GetNumElements() * cylinders->GetElementSize() / bytesPerCylinder;
243 
244  cyl->SetCylindersAndColors(numCylinders, cylinders->GetData(), bytesPerCylinder, offsetVertex0, offsetVertex1, offsetRadius, colors);
245 
246  Data* texcoord = GetObject<Data>({ "texcoord" });
247  if (texcoord)
248  {
249  VisRTX::Vec2f* texcoords = reinterpret_cast<VisRTX::Vec2f*>(texcoord->GetData());
250  assert(texcoord->GetDataType() == RTW_FLOAT2);
251  cyl->SetTexCoords(texcoords);
252  }
253  else
254  {
255  cyl->SetTexCoords(nullptr);
256  }
257 
258  Data* materialList = GetObject<Data>({ "materialList" });
259  int offset_materialID = this->Get1i({ "offset_materialID" }, -1);
260  if (materialList && offset_materialID >= 0)
261  {
262  assert(materialList->GetDataType() == RTW_OBJECT);
263 
264  std::vector<VisRTX::Material*> cylinderMaterials;
265  cylinderMaterials.resize(numCylinders);
266 
267  Material** materials = reinterpret_cast<Material**>(materialList->GetData());
268 
269  const uint8_t* base = reinterpret_cast<const uint8_t*>(cylinders->GetData());
270 
271  for (uint32_t i = 0; i < numCylinders; ++i)
272  {
273  int index = *reinterpret_cast<const int*>(base + i * bytesPerCylinder + offset_materialID);
274  if (index >= 0)
275  {
276  Material* materialHandle = materials[index];
277  if (materialHandle)
278  cylinderMaterials[i] = materialHandle->material;
279  }
280  }
281 
282  cyl->SetMaterials(cylinderMaterials.data());
283  }
284  else
285  {
286  cyl->SetMaterials(nullptr);
287  }
288  }
289  else
290  {
291  assert(false);
292  }
293 
294  float radius;
295  if (this->Get1f({ "radius" }, &radius))
296  cyl->SetRadius(radius);
297  }
298 
299  else
300  {
301  assert(false);
302  }
303 
304 
305  // Set a default material if none is set
306  if (!this->material)
307  {
308  VisRTX::Context* rtx = VisRTX_GetContext();
309  this->geometry->SetMaterial(rtx->CreateBasicMaterial());
310  }
311  }
312 
313  void SetMaterial(Material* material)
314  {
315  if (!this->geometry)
316  return;
317 
318  // Release current material
319  if (this->material)
320  this->material->Release();
321 
322  if (material)
323  {
324  this->geometry->SetMaterial(material->material);
325  this->material = material;
326  this->material->AddRef();
327  }
328  else
329  {
330  this->geometry->SetMaterial(nullptr);
331  this->material = nullptr;
332  }
333  }
334 
335  private:
336  VisRTX::Geometry* geometry = nullptr;
337  Material* material = nullptr;
338  };
339 }
RTW::Object::Get1f
float Get1f(const std::vector< std::string > &ids, float defaultValue=0.0f, bool *found=nullptr) const
Definition: Object.h:124
RTW::Data::GetData
void * GetData() const
Definition: Data.h:118
vtkX3D::type
@ type
Definition: vtkX3D.h:522
RTW::Model
Definition: Model.h:12
RTW
Definition: Backend.h:5
RTW::Data::GetElementSize
static size_t GetElementSize(RTWDataType type)
Definition: Data.h:12
RTW::Data::GetDataType
RTWDataType GetDataType() const
Definition: Data.h:108
RTW_INT3
@ RTW_INT3
Definition: Types.h:65
RTW::Geometry
Definition: Geometry.h:11
RTW::Object
Definition: Object.h:17
vtkX3D::color
@ color
Definition: vtkX3D.h:227
RTW_INT
@ RTW_INT
Definition: Types.h:65
RTW_FLOAT4
@ RTW_FLOAT4
Definition: Types.h:66
RTW::Data
Definition: Data.h:9
RTW::Geometry::SetMaterial
void SetMaterial(Material *material)
Definition: Geometry.h:313
RTW::Object::AddRef
void AddRef()
Definition: Object.h:36
RTW::Object::Get1i
int32_t Get1i(const std::vector< std::string > &ids, int32_t defaultValue=0, bool *found=nullptr) const
Definition: Object.h:107
RTW_FLOAT3
@ RTW_FLOAT3
Definition: Types.h:66
vtkX3D::string
@ string
Definition: vtkX3D.h:496
RTW::Material
Definition: Material.h:15
RTW_FLOAT2
@ RTW_FLOAT2
Definition: Types.h:66
RTW::Data::GetNumElements
size_t GetNumElements() const
Definition: Data.h:103
RTW::Geometry::~Geometry
~Geometry()
Definition: Geometry.h:35
RTW::Object::Release
void Release()
Definition: Object.h:41
vertices
std::pair< boost::graph_traits< vtkGraph * >::vertex_iterator, boost::graph_traits< vtkGraph * >::vertex_iterator > vertices(vtkGraph *g)
Definition: vtkBoostGraphAdapter.h:973
vtkX3D::radius
@ radius
Definition: vtkX3D.h:258
vtkX3D::index
@ index
Definition: vtkX3D.h:252
RTW_OBJECT
@ RTW_OBJECT
Definition: Types.h:61
RTW::Geometry::Geometry
Geometry(const std::string &type)
Definition: Geometry.h:16
RTW::Geometry::Commit
void Commit() override
Definition: Geometry.h:40
Material.h