45 using namespace common;
46 using namespace details;
49 using namespace meshing;
64 _buildModel(callback);
98 void Astrocytes::_logRealismParams()
100 PLUGIN_INFO(1,
"----------------------------------------------------");
108 PLUGIN_INFO(1,
"----------------------------------------------------");
114 srand(animationParams.seed);
128 std::map<size_t, std::map<size_t, TriangleMesh>> microDomainMeshes;
130 PLUGIN_INFO(1,
"Building " << somas.size() <<
" astrocytes");
134 size_t baseMaterialId = 0;
135 const uint64_t userData = 0;
140 volatile bool flag =
false;
141 std::string flagMessage;
142 #pragma omp parallel for shared(flag, flagMessage) num_threads(nbDBConnections)
143 for (index = 0; index < somas.size(); ++index)
150 if (omp_get_thread_num() == 0)
152 PLUGIN_PROGRESS(
"Loading astrocytes...", index, somas.size() / nbDBConnections);
154 0.5f * ((
float)index / ((
float)(somas.size() / nbDBConnections))));
157 auto it = somas.begin();
158 std::advance(it, index);
159 const auto&
soma = it->second;
160 const auto somaId = it->first;
165 double somaRadius = 0.0;
177 for (
const auto& section : sections)
181 somaRadius += 0.75 * length(
Vector3d(point));
197 const auto somaMaterialId =
201 uint64_t somaGeometryIndex = 0;
206 somaGeometryIndex = container.addSphere(
207 somaPosition, somaRadius, somaMaterialId, useSdf,
NO_USER_DATA, {},
220 neighbours.insert(somaGeometryIndex);
221 for (
const auto& section : sections)
223 uint64_t geometryIndex = 0;
224 const auto& points =
section.second.points;
226 size_t sectionMaterialId = baseMaterialId;
227 const auto sectionId =
section.first;
231 sectionMaterialId = baseMaterialId +
section.second.type;
246 step = points.size() - 2;
256 uint64_t geometryIndex = 0;
260 const auto&
point = points[0];
263 const auto dstPosition =
265 geometryIndex = container.addCone(
266 somaPosition, srcRadius, dstPosition, dstRadius, somaMaterialId, useSdf, userData,
271 neighbours.insert(geometryIndex);
276 double distanceToSoma = 0.0;
285 double sectionLength = 0.0;
286 for (uint64_t i = 0; i < localPoints.size() - 1; i += step)
288 const auto srcPoint = localPoints[i];
299 dstPoint = localPoints[i + step];
302 }
while (length(
Vector3f(dstPoint) -
Vector3f(srcPoint)) < (srcRadius + dstRadius) &&
303 (i + step) < localPoints.size() - 1);
307 sectionLength += length(dstPoint - srcPoint);
308 _maxDistanceToSoma = std::max(_maxDistanceToSoma, distanceToSoma + sectionLength);
310 const size_t materialId =
319 geometryIndex = container.addSphere(dst, dstRadius, materialId, useSdf,
NO_USER_DATA);
321 geometryIndex = container.addCone(
322 src, srcRadius, dst, dstRadius, materialId, useSdf, userData, {geometryIndex},
337 _addEndFoot(container,
soma.center, endFeet, radii, baseMaterialId);
339 if (loadMicroDomains)
349 _buildMicroDomain(container, somaId, materialId);
354 auto&
mesh = microDomainMeshes[index][materialId];
355 _addMicroDomain(mesh, somaId);
361 containers.push_back(container);
363 catch (
const std::runtime_error& e)
366 flagMessage = e.what();
373 flagMessage =
"Loading was canceled";
382 for (uint64_t i = 0; i < containers.size(); ++i)
385 callback.
updateProgress(
"Compiling 3D geometry...", 0.5f + 0.5f * (
float)(1 + i) / (
float)containers.size());
386 auto& container = containers[i];
388 for (
const auto& mesh : microDomainMeshes[i])
389 container.addMesh(
mesh.first,
mesh.second);
390 container.commitToModel();
392 model->applyDefaultColormap();
394 const ModelMetadata metadata = {{
"Number of astrocytes", std::to_string(somas.size())},
396 {
"Max distance to soma", std::to_string(_maxDistanceToSoma)}};
403 void Astrocytes::_addEndFoot(ThreadSafeContainer& container,
const Vector3d& somaCenter,
const EndFootMap& endFeet,
404 const doubles& radii,
const size_t baseMaterialId)
415 for (
const auto& endFoot : endFeet)
417 for (
const auto& node : endFoot.second.nodes)
420 const auto vasculatureNodes =
422 "section_guid=" + std::to_string(endFoot.second.vasculatureSectionId));
424 uint64_t startIndex = 0;
425 uint64_t endIndex = 1;
426 const auto halfLength = endFoot.second.length / 2.0;
427 auto it = vasculatureNodes.begin();
428 std::advance(it, endFoot.second.vasculatureSegmentId);
429 const auto centerPosition = it->second.position;
435 while (length < halfLength && endFoot.second.vasculatureSegmentId + i >= 0)
437 const int64_t segmentId = endFoot.second.vasculatureSegmentId + i;
440 auto it = vasculatureNodes.begin();
441 std::advance(it, segmentId);
442 length = glm::length(centerPosition - it->second.position);
443 startIndex = segmentId;
450 while (length < halfLength && endFoot.second.vasculatureSegmentId + i < vasculatureNodes.size())
452 const int64_t segmentId = endFoot.second.vasculatureSegmentId + i;
453 auto it = vasculatureNodes.begin();
454 std::advance(it, segmentId);
455 length = glm::length(centerPosition - it->second.position);
456 endIndex = segmentId;
461 uint64_t geometryIndex = 0;
462 uint64_t endFootSegmentIndex = 0;
464 for (uint64_t i = startIndex; i < endIndex - 1; ++i)
466 auto it = vasculatureNodes.begin();
468 const auto& srcNode = it->second;
469 const auto srcUserData = it->first;
470 const auto srcVasculatureRadius =
476 const auto& dstNode = it->second;
477 const auto dstUserData = it->first;
478 const auto dstVasculatureRadius =
486 const Vector3d& shift = normalize(srcNode.position - somaCenter) * srcVasculatureRadius *
493 container.addSphere(srcPosition, srcEndFootRadius, materialId, useSdf, srcUserData);
494 geometryIndex = container.addCone(srcPosition, srcEndFootRadius, dstPosition, dstEndFootRadius,
495 materialId, useSdf, srcUserData, neighbours, displacement);
496 neighbours = {geometryIndex};
497 ++endFootSegmentIndex;
503 void Astrocytes::_addMicroDomain(
TriangleMesh& dstMesh,
const uint64_t astrocyteId)
506 const auto srcMesh = connector.getAstrocyteMicroDomain(_details.
populationName, astrocyteId);
507 auto vertexOffset = dstMesh.
vertices.size();
508 dstMesh.
vertices.insert(dstMesh.
vertices.end(), srcMesh.vertices.begin(), srcMesh.vertices.end());
510 auto indexOffset = dstMesh.
indices.size();
511 dstMesh.
indices.insert(dstMesh.
indices.end(), srcMesh.indices.begin(), srcMesh.indices.end());
512 for (uint64_t i = 0; i < srcMesh.indices.size(); ++i)
513 dstMesh.
indices[indexOffset + i] += vertexOffset;
514 dstMesh.
normals.insert(dstMesh.
normals.end(), srcMesh.normals.begin(), srcMesh.normals.end());
515 dstMesh.
colors.insert(dstMesh.
colors.end(), srcMesh.colors.begin(), srcMesh.colors.end());
518 void Astrocytes::_buildMicroDomain(ThreadSafeContainer& container,
const uint64_t astrocyteId,
const size_t materialId)
521 const auto mesh = connector.getAstrocyteMicroDomain(_details.
populationName, astrocyteId);
524 for (
const auto& v :
mesh.vertices)
525 cloud[materialId].push_back(
Vector4d(v.x, v.y, v.z, 0.5));
527 PointCloudMesher pcm;
528 if (!pcm.toConvexHull(container, cloud))
529 PLUGIN_THROW(
"Failed to generate convex hull from micro domain information");
537 const size_t nbFrames = (simulationReport.endTime - simulationReport.startTime) / simulationReport.timeStep;
539 PLUGIN_THROW(
"Report does not contain any simulation data: " + simulationReport.description);
541 if (details.
frame >= nbFrames)
542 PLUGIN_THROW(
"Invalid frame specified for report: " + simulationReport.description);
546 for (
const double radius : radii)
core::ModelDescriptorPtr _modelDescriptor
double _getCorrectedRadius(const double radius, const double radiusMultiplier) const
core::Quaterniond _rotation
details::CellAnimationDetails _animationDetails
core::Vector3d _animatedPosition(const core::Vector4d &position, const uint64_t index=0) const
core::Vector4fs _getProcessedSectionPoints(const morphology::MorphologyRepresentation &representation, const core::Vector4fs &points)
static DBConnector & getInstance()
Get the Instance object.
size_t getNbConnections() const
Get the number of connections to the database.
void setVasculatureRadiusReport(const details::VasculatureRadiusReportDetails &details)
Apply a vasculature radius report to the astrocyte. This modifies the end-feet of the astrocytes acco...
void _addSomaInternals(common::ThreadSafeContainer &container, const size_t materialId, const core::Vector3d &somaPosition, const double somaRadius, const double mitochondriaDensity, const bool useSdf, const double radiusMultiplier)
size_t _getMaterialFromDistanceToSoma(const double maxDistanceToSoma, const double distanceToSoma) const
double _getDistanceToSoma(const SectionMap §ions, const Section §ion)
void merge(const Box< T > &aabb)
void updateProgress(const std::string &message, const float fraction) const
The ModelDescriptor struct defines the metadata attached to a model.Model descriptor are exposed via ...
Scene object This object contains collections of geometries, materials and light sources that are use...
virtual PLATFORM_API ModelPtr createModel() const =0
Factory method to create an engine-specific model.
PLATFORM_API bool removeModel(const size_t id)
Removes a model from the scene.
double valueFromDoubles(const doubles &array, const size_t index, const double defaultValue)
Returns the value of an array of double at a given index. Default value if index is out of bounds.
std::set< size_t > Neighbours
size_t getMaterialIdFromOrientation(const Vector3d &orientation)
std::vector< ThreadSafeContainer > ThreadSafeContainers
double rnd2(const uint64_t index)
Return a predefined random double between -0.5 and 0.5.
std::string boolAsString(const bool value)
Return a Yes/No string representation of a boolean.
Vector3d doublesToVector3d(const doubles &value)
Converts a vector of doubles into a 3D vector.
bool andCheck(const uint32_t value, const uint32_t test)
Check is test is part of value using the AND operator.
MolecularSystemAnimationDetails doublesToMolecularSystemAnimationDetails(const doubles &values)
Converts a vector of doubles into molecular system animation details.
CellAnimationDetails doublesToCellAnimationDetails(const doubles &values)
Converts a vector of doubles into cell animation details.
std::map< size_t, Vector4ds > PointCloud
const double DEFAULT_MITOCHONDRIA_DENSITY
const size_t MATERIAL_OFFSET_MICRO_DOMAIN
std::map< uint64_t, EndFoot > EndFootMap
const double DEFAULT_ENDFOOT_RADIUS_RATIO
const size_t MATERIAL_OFFSET_END_FOOT
const double DEFAULT_ENDFOOT_RADIUS_SHIFTING_RATIO
const size_t NB_MATERIALS_PER_MORPHOLOGY
const size_t MATERIAL_OFFSET_SOMA
const int64_t SOMA_AS_PARENT
std::map< uint64_t, Section > SectionMap
const double DEFAULT_MORPHOLOGY_SECTION_STRENGTH
const double DEFAULT_MORPHOLOGY_MITOCHONDRION_STRENGTH
const double DEFAULT_MORPHOLOGY_SOMA_STRENGTH
const double DEFAULT_MORPHOLOGY_SECTION_FREQUENCY
const double DEFAULT_MORPHOLOGY_MITOCHONDRION_FREQUENCY
const double DEFAULT_MORPHOLOGY_SOMA_FREQUENCY
const double DEFAULT_MORPHOLOGY_NUCLEUS_STRENGTH
const double DEFAULT_VASCULATURE_SEGMENT_STRENGTH
const double DEFAULT_MORPHOLOGY_NUCLEUS_FREQUENCY
const double DEFAULT_VASCULATURE_SEGMENT_FREQUENCY
@ morphology_soma_strength
@ morphology_soma_frequency
@ morphology_nucleus_frequency
@ vasculature_segment_frequency
@ morphology_section_strength
@ vasculature_segment_strength
@ morphology_nucleus_strength
@ morphology_mitochondrion_frequency
@ morphology_section_frequency
@ morphology_mitochondrion_strength
std::map< std::string, std::string > ModelMetadata
glm::vec< 3, double > Vector3d
glm::tquat< double, glm::highp > Quaterniond
Double quaternion.
glm::vec< 4, double > Vector4d
morphology::MorphologyRepresentation morphologyRepresentation
morphology::PopulationColorScheme populationColorScheme
std::string vasculaturePopulationName
doubles displacementParams
morphology::MicroDomainRepresentation microDomainRepresentation
morphology::MorphologyColorScheme morphologyColorScheme
std::string populationName
uint64_t simulationReportId
std::string populationName
std::vector< Vector3ui > indices