Blue Brain BioExplorer
Model.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2024, EPFL/Blue Brain Project
3  *
4  * The Blue Brain BioExplorer is a tool for scientists to extract and analyse
5  * scientific data from visualization
6  *
7  * This file is part of Blue Brain BioExplorer <https://github.com/BlueBrain/BioExplorer>
8  *
9  * This library is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU Lesser General Public License version 3.0 as published
11  * by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include "Model.h"
24 
31 
36 
37 #include <set>
38 
39 namespace core
40 {
41 namespace
42 {
43 void _bindMaterials(const AbstractSimulationHandlerPtr& simulationHandler, MaterialMap& materials)
44 {
45  if (!simulationHandler)
46  return;
47  for (const auto& material : materials)
48  simulationHandler->bind(material.second);
49 }
50 
51 void _unbindMaterials(const AbstractSimulationHandlerPtr& simulationHandler, MaterialMap& materials)
52 {
53  if (!simulationHandler)
54  return;
55  for (const auto& material : materials)
56  simulationHandler->unbind(material.second);
57 }
58 } // namespace
59 ModelParams::ModelParams(const std::string& path)
60  : _name(fs::path(path).stem())
61  , _path(path)
62 {
63 }
64 
65 ModelParams::ModelParams(const std::string& name, const std::string& path)
66  : _name(name)
67  , _path(path)
68 {
69 }
70 
71 ModelParams::ModelParams(const std::string& name, const std::string& path, const PropertyMap& loaderProperties)
72  : _name(name)
73  , _path(path)
74  , _loaderProperties(loaderProperties)
75 {
76 }
77 
78 ModelDescriptor::ModelDescriptor(ModelPtr model, const std::string& path)
79  : ModelParams(path)
80  , _model(std::move(model))
81 {
82  _model->updateBounds();
83  computeBounds();
84 }
85 
86 ModelDescriptor::ModelDescriptor(ModelPtr model, const std::string& path, const ModelMetadata& metadata)
87  : ModelParams(path)
88  , _metadata(metadata)
89  , _model(std::move(model))
90 {
91  _model->updateBounds();
92  computeBounds();
93 }
94 
95 ModelDescriptor::ModelDescriptor(ModelPtr model, const std::string& name, const std::string& path,
96  const ModelMetadata& metadata)
97  : ModelParams(name, path)
98  , _metadata(metadata)
99  , _model(std::move(model))
100 {
101  _model->updateBounds();
102  computeBounds();
103 }
104 
106 {
107  if (this == &rhs)
108  return *this;
110  if (rhs.getName().empty())
111  _updateValue(_name, fs::path(rhs.getPath()).stem().string());
112  else
113  _updateValue(_name, rhs.getName());
114  _updateValue(_path, rhs.getPath());
116 
117 #if 0 // WTF ?!?
118  // Transformation
119  const auto oldRotationCenter = _transformation.getRotationCenter();
120  const auto newRotationCenter = rhs.getTransformation().getRotationCenter();
122  if (newRotationCenter == Vector3d(0))
123  // If no rotation center is specified in the model params, the one set
124  // by the model loader is used
125  _transformation.setRotationCenter(oldRotationCenter);
126 #endif
127 
128  return *this;
129 }
130 
132 {
133  _instances.push_back(instance);
134  _instances.rbegin()->setInstanceID(_nextInstanceID++);
135  if (_model)
136  _model->markInstancesDirty();
137 }
138 
139 void ModelDescriptor::removeInstance(const size_t id)
140 {
141  auto i = std::remove_if(_instances.begin(), _instances.end(),
142  [id](const auto& instance) { return id == instance.getInstanceID(); });
143  if (i == _instances.end())
144  return;
145 
146  _instances.erase(i, _instances.end());
147 
148  if (_model)
149  _model->markInstancesDirty();
150 }
151 
153 {
154  _instances.clear();
155 
156  if (_model)
157  _model->markInstancesDirty();
158 }
159 
161 {
162  auto i = std::find_if(_instances.begin(), _instances.end(),
163  [id](const auto& instance) { return id == instance.getInstanceID(); });
164  return i == _instances.end() ? nullptr : &(*i);
165 }
166 
168 {
169  _bounds.reset();
170  if (!_model)
171  return;
172 
173  _bounds.merge(_model->getBounds());
174 
175  for (const auto& instance : getInstances())
176  {
177  if (!instance.getVisible())
178  continue;
179 
180  _bounds.merge(transformBox(getModel().getBounds(), getTransformation() * instance.getTransformation()));
181  }
182 }
183 
185 {
186  auto newModelDesc = std::make_shared<ModelDescriptor>(std::move(model), getPath());
187 
188  *newModelDesc = static_cast<const ModelParams&>(*this);
189 
190  newModelDesc->_bounds = _bounds;
191  newModelDesc->_metadata = _metadata;
192  newModelDesc->_model->copyFrom(getModel());
193  newModelDesc->_instances = _instances;
194  newModelDesc->_properties = _properties;
195  newModelDesc->_model->buildBoundingBox();
196  return newModelDesc;
197 }
198 
199 Model::Model(AnimationParameters& animationParameters, VolumeParameters& volumeParameters,
200  GeometryParameters& geometryParameters, FieldParameters& fieldParameters)
201  : _animationParameters(animationParameters)
202  , _volumeParameters(volumeParameters)
203  , _geometryParameters(geometryParameters)
204  , _fieldParameters(fieldParameters)
205 {
206 }
207 
209 {
212 }
213 
214 bool Model::empty() const
215 {
216  return _geometries->isEmpty() && _bounds.isEmpty();
217 }
218 
219 uint64_t Model::addSphere(const size_t materialId, const Sphere& sphere)
220 {
221  _spheresDirty = true;
222  _geometries->_spheres[materialId].push_back(sphere);
223  return _geometries->_spheres[materialId].size() - 1;
224 }
225 
226 uint64_t Model::addCylinder(const size_t materialId, const Cylinder& cylinder)
227 {
228  _cylindersDirty = true;
229  _geometries->_cylinders[materialId].push_back(cylinder);
230  return _geometries->_cylinders[materialId].size() - 1;
231 }
232 
233 uint64_t Model::addCone(const size_t materialId, const Cone& cone)
234 {
235  _conesDirty = true;
236  _geometries->_cones[materialId].push_back(cone);
237  return _geometries->_cones[materialId].size() - 1;
238 }
239 
240 void Model::addStreamline(const size_t materialId, const Streamline& streamline)
241 {
242  if (streamline.position.size() < 2)
243  throw std::runtime_error(
244  "Number of vertices is less than two which is minimum needed for a "
245  "streamline.");
246 
247  if (streamline.position.size() != streamline.color.size())
248  throw std::runtime_error("Number of vertices and colors do not match.");
249 
250  if (streamline.position.size() != streamline.radius.size())
251  throw std::runtime_error("Number of vertices and radii do not match.");
252 
253  auto& streamlinesData = _geometries->_streamlines[materialId];
254 
255  const size_t startIndex = streamlinesData.vertex.size();
256  const size_t endIndex = startIndex + streamline.position.size() - 1;
257 
258  for (size_t index = startIndex; index < endIndex; ++index)
259  streamlinesData.indices.push_back(index);
260 
261  for (size_t i = 0; i < streamline.position.size(); i++)
262  streamlinesData.vertex.push_back(Vector4f(streamline.position[i], streamline.radius[i]));
263 
264  for (const auto& color : streamline.color)
265  streamlinesData.vertexColor.push_back(color);
266 
267  _streamlinesDirty = true;
268 }
269 
270 void Model::addCurve(const size_t materialId, const Curve& curve)
271 {
272  if (curve.vertices.size() < 2)
273  throw std::runtime_error(
274  "Number of vertices is less than two which is minimum needed for a "
275  "curve");
276 
277  if (curve.vertices.size() != curve.indices.size())
278  throw std::runtime_error("Number of vertices and indices do not match.");
279 
280  if (curve.vertices.size() != curve.normals.size())
281  throw std::runtime_error("Number of vertices and normals do not match.");
282 
283  if (curve.vertices.size() != curve.tangents.size())
284  throw std::runtime_error("Number of vertices and tangents do not match.");
285 
286  _geometries->_curves[materialId].push_back(curve);
287  _curvesDirty = true;
288 }
289 
290 uint64_t Model::addSDFGeometry(const size_t materialId, const SDFGeometry& geom, const uint64_ts& neighbourIndices)
291 {
292  const uint64_t geomIdx = _geometries->_sdf.geometries.size();
293  _geometries->_sdf.geometryIndices[materialId].push_back(geomIdx);
294  _geometries->_sdf.neighbours.push_back(neighbourIndices);
295  _geometries->_sdf.geometries.push_back(geom);
296  _sdfGeometriesDirty = true;
297  return geomIdx;
298 }
299 
300 void Model::updateSDFGeometryNeighbours(size_t geometryIdx, const uint64_ts& neighbourIndices)
301 {
302  _geometries->_sdf.neighbours[geometryIdx] = neighbourIndices;
303  _sdfGeometriesDirty = true;
304 }
305 
306 void Model::addVolume(const size_t materialId, VolumePtr volume)
307 {
308  _geometries->_volumes[materialId] = volume;
309  _volumesDirty = true;
310 }
311 
312 void Model::addField(const size_t materialId, FieldPtr field)
313 {
314  _geometries->_fields[materialId] = field;
315  _fieldsDirty = true;
316 }
317 
318 void Model::removeVolume(const size_t materialId)
319 {
320  auto iter = _geometries->_volumes.find(materialId);
321  if (iter == _geometries->_volumes.end())
322  return;
323 
324  _geometries->_volumes.erase(iter);
325  _volumesDirty = true;
326 }
327 
328 bool Model::isDirty() const
329 {
331 }
332 
334 {
335  size_t index = 0;
336  for (auto material : _materials)
337  {
338  material.second->setSpecularColor(Vector3f(0.f));
339  material.second->setOpacity(1.f);
340  material.second->setReflectionIndex(0.f);
341  material.second->setEmission(0.f);
342 
343  switch (colorMap)
344  {
346  {
347  const float a = float(index) / float(_materials.size() - 1);
348  material.second->setDiffuseColor(Vector3f(a * a, std::sqrt(a), 1.f - a));
349  break;
350  }
352  material.second->setDiffuseColor(Vector3f(0.5f + float(std::rand() % 127) / 255.f,
353  0.5f + float(std::rand() % 127) / 255.f,
354  0.5f + float(std::rand() % 127) / 255.f));
355  break;
357  material.second->setDiffuseColor(
358  Vector3f(float(rand() % 255) / 255.f, float(rand() % 255) / 255.f, float(rand() % 255) / 255.f));
359  switch (rand() % 10)
360  {
361  case 0:
362  // Transparency only
363  material.second->setOpacity(float(std::rand() % 100) / 100.f);
364  material.second->setRefractionIndex(1.2f);
365  material.second->setSpecularColor(Vector3f(1.f));
366  material.second->setSpecularExponent(10.f);
367  break;
368  case 1:
369  // Light emission
370  material.second->setEmission(std::rand() % 20);
371  break;
372  case 2:
373  // Reflection only
374  material.second->setReflectionIndex(float(std::rand() % 100) / 100.f);
375  material.second->setSpecularColor(Vector3f(1.f));
376  material.second->setSpecularExponent(10.f);
377  break;
378  case 3:
379  // Reflection and refraction
380  material.second->setReflectionIndex(float(std::rand() % 100) / 100.f);
381  material.second->setOpacity(float(std::rand() % 100) / 100.f);
382  material.second->setRefractionIndex(1.2f);
383  material.second->setSpecularColor(Vector3f(1.f));
384  material.second->setSpecularExponent(10.f);
385  break;
386  case 4:
387  // Reflection and glossiness
388  material.second->setReflectionIndex(float(std::rand() % 100) / 100.f);
389  material.second->setSpecularColor(Vector3f(1.f));
390  material.second->setSpecularExponent(10.f);
391  material.second->setGlossiness(float(std::rand() % 100) / 100.f);
392  break;
393  case 5:
394  // Transparency and glossiness
395  material.second->setOpacity(float(std::rand() % 100) / 100.f);
396  material.second->setRefractionIndex(1.2f);
397  material.second->setSpecularColor(Vector3f(1.f));
398  material.second->setSpecularExponent(10.f);
399  material.second->setGlossiness(float(std::rand() % 100) / 100.f);
400  break;
401  }
402  break;
404  float value = float(std::rand() % 255) / 255.f;
405  material.second->setDiffuseColor(Vector3f(value, value, value));
406  break;
407  }
408  material.second->commit();
409  ++index;
410  }
411 }
412 
414 {
415 #ifdef DEBUG
417 
418  uint64_t nbSpheres = 0;
419  uint64_t nbCylinders = 0;
420  uint64_t nbCones = 0;
421  uint64_t nbMeshes = _geometries->_triangleMeshes.size();
422  for (const auto& spheres : _geometries->_spheres)
423  nbSpheres += spheres.second.size();
424  for (const auto& cylinders : _geometries->_cylinders)
425  nbCylinders += cylinders.second.size();
426  for (const auto& cones : _geometries->_cones)
427  nbCones += cones.second.size();
428 
429  CORE_INFO("Spheres: " << nbSpheres << ", Cylinders: " << nbCylinders << ", Cones: " << nbCones
430  << ", Meshes: " << nbMeshes << ", Memory: " << _sizeInBytes << " bytes ("
431  << _sizeInBytes / 1048576 << " MB), Bounds: " << _bounds);
432 #endif
433 }
434 
435 MaterialPtr Model::getMaterial(const size_t materialId) const
436 {
437  const auto it = _materials.find(materialId);
438  if (it == _materials.end())
439  CORE_THROW("Material " + std::to_string(materialId) + " is not registered in the model");
440  return it->second;
441 }
442 
444 {
445  _sizeInBytes = 0;
446  for (const auto& spheres : _geometries->_spheres)
447  _sizeInBytes += spheres.second.size() * sizeof(Sphere);
448  for (const auto& cylinders : _geometries->_cylinders)
449  _sizeInBytes += cylinders.second.size() * sizeof(Cylinder);
450  for (const auto& cones : _geometries->_cones)
451  _sizeInBytes += cones.second.size() * sizeof(Cones);
452  for (const auto& triangleMesh : _geometries->_triangleMeshes)
453  {
454  const auto& mesh = triangleMesh.second;
455  _sizeInBytes += mesh.indices.size() * sizeof(Vector3f);
456  _sizeInBytes += mesh.normals.size() * sizeof(Vector3f);
457  _sizeInBytes += mesh.colors.size() * sizeof(Vector4f);
458  _sizeInBytes += mesh.indices.size() * sizeof(Vector3ui);
459  _sizeInBytes += mesh.textureCoordinates.size() * sizeof(Vector2f);
460  }
461  for (const auto& streamline : _geometries->_streamlines)
462  {
463  _sizeInBytes += streamline.second.indices.size() * sizeof(int32_t);
464  _sizeInBytes += streamline.second.vertex.size() * sizeof(Vector4f);
465  _sizeInBytes += streamline.second.vertexColor.size() * sizeof(Vector4f);
466  }
467 
468  _sizeInBytes += _geometries->_sdf.geometries.size() * sizeof(SDFGeometry);
469  _sizeInBytes += _geometries->_sdf.neighboursFlat.size() * sizeof(uint64_t);
470  for (const auto& sdfIndices : _geometries->_sdf.geometryIndices)
471  _sizeInBytes += sdfIndices.second.size() * sizeof(uint64_t);
472  for (const auto& sdfNeighbours : _geometries->_sdf.neighbours)
473  _sizeInBytes += sdfNeighbours.size() * sizeof(size_t);
474 }
475 
476 void Model::copyFrom(const Model& rhs)
477 {
478  if (this == &rhs)
479  return;
480 
481  if (rhs._simulationHandler)
482  _simulationHandler = rhs._simulationHandler->clone();
483 
485  _materials.clear();
486  for (const auto& material : rhs._materials)
487  {
488  auto newMaterial = createMaterialImpl(material.second->getPropertyMap());
489  *newMaterial = *material.second;
490  _materials[material.first] = newMaterial;
491  }
492  _bounds = rhs._bounds;
493  _bvhFlags = rhs._bvhFlags;
495 
496  // reference only to save memory
497  _geometries = rhs._geometries;
498 
499  _spheresDirty = !_geometries->_spheres.empty();
500  _cylindersDirty = !_geometries->_cylinders.empty();
501  _conesDirty = !_geometries->_cones.empty();
502  _triangleMeshesDirty = !_geometries->_triangleMeshes.empty();
503  _streamlinesDirty = !_geometries->_streamlines.empty();
504  _sdfGeometriesDirty = !_geometries->_sdf.geometries.empty();
505  _volumesDirty = !_geometries->_volumes.empty();
506  _curvesDirty = !_geometries->_curves.empty();
507 }
508 
510 {
511  if (_spheresDirty)
512  {
513  _geometries->_sphereBounds.reset();
514  for (const auto& spheres : _geometries->_spheres)
515  if (spheres.first != BOUNDINGBOX_MATERIAL_ID)
516  for (const auto& sphere : spheres.second)
517  {
518  _geometries->_sphereBounds.merge(sphere.center + sphere.radius);
519  _geometries->_sphereBounds.merge(sphere.center - sphere.radius);
520  }
521  }
522 
523  if (_cylindersDirty)
524  {
525  _geometries->_cylindersBounds.reset();
526  for (const auto& cylinders : _geometries->_cylinders)
527  if (cylinders.first != BOUNDINGBOX_MATERIAL_ID)
528  for (const auto& cylinder : cylinders.second)
529  {
530  _geometries->_cylindersBounds.merge(cylinder.center);
531  _geometries->_cylindersBounds.merge(cylinder.up);
532  }
533  }
534 
535  if (_conesDirty)
536  {
537  _geometries->_conesBounds.reset();
538  for (const auto& cones : _geometries->_cones)
539  if (cones.first != BOUNDINGBOX_MATERIAL_ID)
540  for (const auto& cone : cones.second)
541  {
542  _geometries->_conesBounds.merge(cone.center);
543  _geometries->_conesBounds.merge(cone.up);
544  }
545  }
546 
548  {
549  _geometries->_triangleMeshesBounds.reset();
550  for (const auto& mesh : _geometries->_triangleMeshes)
551  if (mesh.first != BOUNDINGBOX_MATERIAL_ID)
552  for (const auto& vertex : mesh.second.vertices)
553  _geometries->_triangleMeshesBounds.merge(vertex);
554  }
555 
556  if (_streamlinesDirty)
557  {
558  _geometries->_streamlinesBounds.reset();
559  for (const auto& streamline : _geometries->_streamlines)
560  for (size_t index = 0; index < streamline.second.vertex.size(); ++index)
561  {
562  const auto& pos = Vector3f(streamline.second.vertex[index]);
563  const float radius = streamline.second.vertex[index][3];
564  const auto radiusVec = Vector3f(radius, radius, radius);
565  _geometries->_streamlinesBounds.merge(pos + radiusVec);
566  _geometries->_streamlinesBounds.merge(pos - radiusVec);
567  }
568  }
569 
571  {
572  _geometries->_sdfGeometriesBounds.reset();
573  for (const auto& geom : _geometries->_sdf.geometries)
574  _geometries->_sdfGeometriesBounds.merge(getSDFBoundingBox(geom));
575  }
576 
577  if (_volumesDirty)
578  {
579  _geometries->_volumesBounds.reset();
580  for (const auto& volume : _geometries->_volumes)
581  _geometries->_volumesBounds.merge(volume.second->getBounds());
582  }
583 
584  if (_curvesDirty)
585  {
586  _geometries->_curvesBounds.reset();
587  for (const auto& curves : _geometries->_curves)
588  for (const auto& curve : curves.second)
589  for (const auto& vertex : curve.vertices)
590  _geometries->_curvesBounds.merge(vertex);
591  }
592 
593  if (_fieldsDirty)
594  {
595  _geometries->_fieldsBounds.reset();
596  for (const auto& field : _geometries->_fields)
597  _geometries->_fieldsBounds.merge(field.second->getBounds());
598  }
599 
600  _bounds.reset();
601  _bounds.merge(_geometries->_sphereBounds);
602  _bounds.merge(_geometries->_cylindersBounds);
603  _bounds.merge(_geometries->_conesBounds);
604  _bounds.merge(_geometries->_triangleMeshesBounds);
605  _bounds.merge(_geometries->_streamlinesBounds);
606  _bounds.merge(_geometries->_sdfGeometriesBounds);
607  _bounds.merge(_geometries->_volumesBounds);
608  _bounds.merge(_geometries->_curvesBounds);
609  _bounds.merge(_geometries->_fieldsBounds);
610 }
611 
613 {
614  _spheresDirty = false;
615  _cylindersDirty = false;
616  _conesDirty = false;
617  _triangleMeshesDirty = false;
618  _streamlinesDirty = false;
619  _sdfGeometriesDirty = false;
620  _volumesDirty = false;
621  _curvesDirty = false;
622  _fieldsDirty = false;
623 }
624 
625 MaterialPtr Model::createMaterial(const size_t materialId, const std::string& name, const PropertyMap& properties)
626 {
627  auto material = _materials[materialId] = createMaterialImpl(properties);
628  material->setName(name);
629  if (_simulationHandler && materialId != BOUNDINGBOX_MATERIAL_ID)
630  _simulationHandler->bind(material);
631  return material;
632 }
633 
635 {
636  if (_simulationHandler != handler)
637  _unbindMaterials(_simulationHandler, _materials);
638  _simulationHandler = handler;
639  _bindMaterials(_simulationHandler, _materials);
640 }
641 
642 size_t Model::getSizeInBytes() const
643 {
644  size_t volumeSizeInBytes = 0;
645  for (const auto& volume : _geometries->_volumes)
646  volumeSizeInBytes += volume.second->getSizeInBytes();
647  return _sizeInBytes + volumeSizeInBytes;
648 }
649 
651 {
652  return _simulationHandler;
653 }
654 
656 {
658  return false;
659 
662 
664  return true;
665 }
666 
668 {
669  if (!_simulationHandler)
670  return false;
671 
673  {
674  auto& ap = _animationParameters;
675  ap.setIsReadyCallback([handler = _simulationHandler] { return handler->isReady(); });
676  ap.setDt(_simulationHandler->getDt(), false);
677  ap.setUnit(_simulationHandler->getUnit(), false);
678  ap.setNumFrames(_simulationHandler->getNbFrames(), false);
679  ap.markModified();
680  _isReadyCallbackSet = true;
681  }
682 
683  const auto animationFrame = _animationParameters.getFrame();
684 
685  if (_simulationHandler->getCurrentFrame() == animationFrame)
686  return false;
687 
688  auto frameData = _simulationHandler->getFrameData(animationFrame);
689  if (!frameData)
690  return false;
691 
692  _commitSimulationDataImpl((float*)frameData, _simulationHandler->getFrameSize());
693  return true;
694 }
695 
697 {
698  const auto colormap = getRainbowColormap(_materials.size());
699  uint32_t i = 0;
700  for (auto& material : _materials)
701  {
702  material.second->setShadingMode(MaterialShadingMode::basic);
703  material.second->setDiffuseColor(colormap[i]);
704  material.second->setSpecularColor(colormap[i]);
705  ++i;
706  }
707 }
708 } // namespace core
void setIsReadyCallback(const IsReadyCallback &callback)
void _updateValue(T &member, const T &newValue, const bool triggerCallback=true)
Definition: BaseObject.h:87
void resetModified()
Definition: BaseObject.h:64
bool isModified() const
Definition: BaseObject.h:60
void reset()
Definition: MathTypes.h:82
void merge(const Box< T > &aabb)
Definition: MathTypes.h:64
bool isEmpty() const
Definition: MathTypes.h:88
The ModelDescriptor struct defines the metadata attached to a model.Model descriptor are exposed via ...
Definition: Model.h:285
void removeInstance(const size_t id)
Definition: Model.cpp:139
const Model & getModel() const
Definition: Model.h:360
ModelDescriptor & operator=(ModelDescriptor &&rhs)=default
const ModelInstances & getInstances() const
Definition: Model.h:396
void addInstance(const ModelInstance &instance)
Definition: Model.cpp:131
ModelInstance * getInstance(const size_t id)
Definition: Model.cpp:160
ModelDescriptorPtr clone(ModelPtr model) const
Definition: Model.cpp:184
Boxd getBounds() const
Definition: Model.h:402
A class representing an instance of a 3D model.
Definition: Model.h:80
PLATFORM_API bool getBoundingBox() const
Get the value of _boundingBox.
Definition: Model.h:116
PLATFORM_API bool getVisible() const
Get the value of _visible.
Definition: Model.h:104
Transformation _transformation
Definition: Model.h:168
PLATFORM_API const Transformation & getTransformation() const
Get the value of _transformation.
Definition: Model.h:128
The ModelParams class represents the parameters needed for initializing a model instance.
Definition: Model.h:178
std::string _name
Definition: Model.h:265
PLATFORM_API ModelParams()=default
PLATFORM_API const std::string & getPath() const
getPath gets the path of the model
Definition: Model.h:238
PLATFORM_API const std::string & getName() const
getName gets the name of the model
Definition: Model.h:226
std::string _path
Definition: Model.h:266
The abstract Model class holds the geometry attached to an asset of the scene (mesh,...
Definition: Model.h:469
virtual PLATFORM_API ~Model()
Virtual destructor for Model class.
Definition: Model.cpp:208
PLATFORM_API void removeVolume(const size_t materialId)
Remove a volume from the model.
Definition: Model.cpp:318
PLATFORM_API void copyFrom(const Model &rhs)
Copies the model data from another model.
Definition: Model.cpp:476
std::set< BVHFlag > _bvhFlags
Definition: Model.h:903
PLATFORM_API bool empty() const
Definition: Model.cpp:214
Boxd _bounds
Definition: Model.h:901
TransferFunction _transferFunction
Definition: Model.h:847
AbstractSimulationHandlerPtr _simulationHandler
Definition: Model.h:846
bool _cylindersDirty
Definition: Model.h:886
virtual PLATFORM_API MaterialPtr createMaterialImpl(const PropertyMap &properties={})=0
PLATFORM_API void addVolume(const size_t materialId, VolumePtr)
Add a volume to the model.
Definition: Model.cpp:306
PLATFORM_API void updateBounds()
Updates the bounds of the geometries.
Definition: Model.cpp:509
void _markGeometriesClean()
Definition: Model.cpp:612
PLATFORM_API AbstractSimulationHandlerPtr getSimulationHandler() const
Returns the simulation handler.
Definition: Model.cpp:650
bool _curvesDirty
Definition: Model.h:892
bool _areGeometriesDirty() const
Definition: Model.h:895
PLATFORM_API void updateSDFGeometryNeighbours(size_t geometryIdx, const uint64_ts &neighbourIndices)
Update the list of neighbours for an SDF geometry.
Definition: Model.cpp:300
bool _sdfGeometriesDirty
Definition: Model.h:890
size_t _sizeInBytes
Definition: Model.h:904
bool _streamlinesDirty
Definition: Model.h:889
bool _triangleMeshesDirty
Definition: Model.h:888
PLATFORM_API bool commitSimulationData()
Function to commit simulation data.
Definition: Model.cpp:667
PLATFORM_API uint64_t addSphere(const size_t materialId, const Sphere &sphere)
Adds a sphere to the model.
Definition: Model.cpp:219
PLATFORM_API uint64_t addSDFGeometry(const size_t materialId, const SDFGeometry &geom, const uint64_ts &neighbourIndices)
Adds an SDFGeometry to the scene.
Definition: Model.cpp:290
PLATFORM_API uint64_t addCylinder(const size_t materialId, const Cylinder &cylinder)
Adds a cylinder to the model.
Definition: Model.cpp:226
PLATFORM_API MaterialPtr createMaterial(const size_t materialId, const std::string &name, const PropertyMap &properties={})
Factory method to create an engine-specific material.
Definition: Model.cpp:625
MaterialMap _materials
Definition: Model.h:849
void _updateSizeInBytes()
Definition: Model.cpp:443
std::shared_ptr< Geometries > _geometries
Definition: Model.h:883
bool _conesDirty
Definition: Model.h:887
virtual void _commitSimulationDataImpl(const float *frameData, const size_t frameSize)=0
PLATFORM_API Model(AnimationParameters &animationParameters, VolumeParameters &volumeParameters, GeometryParameters &geometryParameters, FieldParameters &fieldParameters)
Constructor for Model class.
Definition: Model.cpp:199
PLATFORM_API void addField(const size_t materialId, FieldPtr)
Add a field to the model.
Definition: Model.cpp:312
PLATFORM_API uint64_t addCone(const size_t materialId, const Cone &cone)
Adds a cone to the model.
Definition: Model.cpp:233
bool _spheresDirty
Definition: Model.h:885
bool _fieldsDirty
Definition: Model.h:893
AnimationParameters & _animationParameters
Definition: Model.h:841
bool _instancesDirty
Definition: Model.h:902
PLATFORM_API void applyDefaultColormap()
Applies a default color map (rainbow) to the model.
Definition: Model.cpp:696
PLATFORM_API void addCurve(const size_t materialId, const Curve &curve)
Adds a curve to the model.
Definition: Model.cpp:270
PLATFORM_API void logInformation()
Logs information about the model, like the number of primitives, and the associated memory footprint.
Definition: Model.cpp:413
PLATFORM_API void setSimulationHandler(AbstractSimulationHandlerPtr handler)
Sets the simulation handler.
Definition: Model.cpp:634
PLATFORM_API bool commitTransferFunction()
Function to commit transfer function.
Definition: Model.cpp:655
bool _volumesDirty
Definition: Model.h:891
PLATFORM_API bool isDirty() const
Definition: Model.cpp:328
PLATFORM_API void addStreamline(const size_t materialId, const Streamline &streamline)
Adds a streamline to the model.
Definition: Model.cpp:240
PLATFORM_API MaterialPtr getMaterial(const size_t materialId) const
Returns a pointer to a specific material.
Definition: Model.cpp:435
PLATFORM_API size_t getSizeInBytes() const
Returns the size in bytes of all geometries.
Definition: Model.cpp:642
virtual void _commitTransferFunctionImpl(const Vector3fs &colors, const floats &opacities, const Vector2d valueRange)=0
PLATFORM_API void setMaterialsColorMap(const MaterialsColorMap colorMap)
Sets the materials handled by the model, and available to the geometry.
Definition: Model.cpp:333
bool _isReadyCallbackSet
Definition: Model.h:907
const ColorMap & getColorMap() const
const Vector2d & getValuesRange() const
floats calculateInterpolatedOpacities() const
const Vector3d & getRotationCenter() const
void setRotationCenter(const Vector3d &value)
std::map< std::string, std::string > ModelMetadata
Definition: Types.h:104
std::shared_ptr< Volume > VolumePtr
Definition: Types.h:153
glm::vec3 Vector3f
Definition: MathTypes.h:137
std::map< size_t, MaterialPtr > MaterialMap
Definition: Types.h:118
glm::vec< 3, uint32_t > Vector3ui
Definition: MathTypes.h:134
glm::vec2 Vector2f
Definition: MathTypes.h:136
std::shared_ptr< AbstractSimulationHandler > AbstractSimulationHandlerPtr
Definition: Types.h:179
MaterialsColorMap
Definition: Types.h:287
glm::vec< 3, double > Vector3d
Definition: MathTypes.h:143
glm::vec4 Vector4f
Definition: MathTypes.h:138
Boxd getSDFBoundingBox(const SDFGeometry &geom)
Definition: SDFGeometry.h:164
Vector3fs getRainbowColormap(const uint32_t colormapSize)
Get the Rainbow Colormap.
Definition: Utils.cpp:126
std::shared_ptr< ModelDescriptor > ModelDescriptorPtr
Definition: Types.h:112
std::shared_ptr< Field > FieldPtr
Definition: Types.h:147
std::vector< Cone > Cones
Definition: Types.h:133
std::unique_ptr< Model > ModelPtr
Definition: Types.h:103
std::shared_ptr< Material > MaterialPtr
Definition: Types.h:117
Boxd transformBox(const Boxd &box, const Transformation &transformation)
@ basic
Definition: CommonTypes.h:46
@ sphere
Definition: CommonTypes.h:40
#define CORE_THROW(__msg)
Definition: Logs.h:42
#define CORE_INFO(__msg)
Definition: Logs.h:33
std::vector< uint64_t > uint64_ts
Definition: Types.h:55
Definition: Cone.h:35
Definition: Sphere.h:35
uint64_ts indices
Definition: Curve.h:78
Vector3fs tangents
Definition: Curve.h:84
Vector3fs normals
Definition: Curve.h:81
Vector4fs vertices
Definition: Curve.h:75