45 if (layer.
id.isEmpty()) {
46 qWarning(
"MultimodalScene::addLayer: refusing to add layer with empty id");
50 const auto it = m_indexById.constFind(layer.
id);
51 if (it != m_indexById.constEnd()) {
52 m_layers[*it] = std::move(layer);
54 m_indexById.insert(layer.
id, m_layers.size());
55 m_layers.append(std::move(layer));
65 const auto it = m_indexById.constFind(
id);
66 if (it == m_indexById.constEnd()) {
69 m_layers.removeAt(*it);
79 if (m_layers.isEmpty()) {
98 const auto it = m_indexById.constFind(
id);
99 if (it == m_indexById.constEnd()) {
102 return &m_layers.at(*it);
109 const auto it = m_indexById.constFind(
id);
110 if (it == m_indexById.constEnd()) {
113 if (m_layers[*it].visible == visible) {
116 m_layers[*it].
visible = visible;
124 const auto it = m_indexById.constFind(
id);
125 if (it == m_indexById.constEnd()) {
128 opacity = qBound(0.0f, opacity, 1.0f);
129 if (qFuzzyCompare(m_layers[*it].opacity + 1.0f, opacity + 1.0f)) {
132 m_layers[*it].opacity = opacity;
140 return m_currentTimeSample;
150 if (sample == m_currentTimeSample) {
153 m_currentTimeSample = sample;
168 if (qFuzzyCompare(seconds + 1.0, m_timeCursor + 1.0)) {
171 m_timeCursor = seconds;
179 return m_overlayFmin;
186 return m_overlayFmid;
193 return m_overlayFmax;
207 const bool same = qFuzzyCompare(fmin + 1.0f, m_overlayFmin + 1.0f)
208 && qFuzzyCompare(fmid + 1.0f, m_overlayFmid + 1.0f)
209 && qFuzzyCompare(fmax + 1.0f, m_overlayFmax + 1.0f);
213 m_overlayFmin = fmin;
214 m_overlayFmid = fmid;
215 m_overlayFmax = fmax;
238 constexpr float fmax = std::numeric_limits<float>::max();
239 constexpr float flow = std::numeric_limits<float>::lowest();
240 bbMin = QVector3D(fmax, fmax, fmax);
241 bbMax = QVector3D(flow, flow, flow);
244 for (
const auto& layer : m_layers) {
245 if (!layer.visible) {
248 const auto it = m_boundsFns.constFind(
static_cast<int>(layer.kind));
249 if (it == m_boundsFns.constEnd() || !*it) {
254 if (!(*it)(layer, mn, mx)) {
257 bbMin.setX(std::min(bbMin.x(), mn.x()));
258 bbMin.setY(std::min(bbMin.y(), mn.y()));
259 bbMin.setZ(std::min(bbMin.z(), mn.z()));
260 bbMax.setX(std::max(bbMax.x(), mx.x()));
261 bbMax.setY(std::max(bbMax.y(), mx.y()));
262 bbMax.setZ(std::max(bbMax.z(), mx.z()));
267 bbMin = QVector3D(-1.0f, -1.0f, -1.0f);
268 bbMax = QVector3D(1.0f, 1.0f, 1.0f);
276 m_boundsFns.insert(
static_cast<int>(kind), std::move(fn));
281void MultimodalScene::rebuildOrder()
284 std::stable_sort(m_layers.begin(), m_layers.end(),
286 if (a.kind != b.kind) {
287 return static_cast<int>(a.kind) < static_cast<int>(b.kind);
292 m_indexById.reserve(m_layers.size());
293 for (
int i = 0; i < m_layers.size(); ++i) {
294 m_indexById.insert(m_layers.at(i).id, i);
Host-agnostic controller that owns the ordered scene-layer stack (MRI slice, BEM, cortex,...
3-D brain visualisation using the Qt RHI rendering backend.
SceneLayerKind
Modality of a layer in the multimodal scene.
Opaque, type-erased handle to a layer payload.
const PickResult & lastPick() const
void timeCursorChanged(double seconds)
double timeCursor() const
void setLayerOpacity(const QString &id, float opacity)
int currentTimeSample() const
void reportPick(const PickResult &pick)
float overlayFmin() const
void setOverlayThresholds(float fmin, float fmid, float fmax)
void registerBoundsFn(SceneLayerKind kind, BoundsFn fn)
void setLayerVisible(const QString &id, bool visible)
std::function< bool(const SceneLayer &layer, QVector3D &bbMin, QVector3D &bbMax)> BoundsFn
void picked(const DISP3DLIB::PickResult &pick)
void setTimeCursor(double seconds)
MultimodalScene(QObject *parent=nullptr)
void worldBounds(QVector3D &bbMin, QVector3D &bbMax) const
void addLayer(SceneLayer layer)
QVector< SceneLayer > layers() const
~MultimodalScene() override
bool removeLayer(const QString &id)
const SceneLayer * findLayer(const QString &id) const
float overlayFmid() const
void setCurrentTimeSample(int sample)
void timeSampleChanged(int sample)
float overlayFmax() const
void overlayThresholdsChanged(float fmin, float fmid, float fmax)
Uniform payload for object-id picking across the multimodal scene.