v2.0.0
Loading...
Searching...
No Matches
brainview.h
Go to the documentation of this file.
1//=============================================================================================================
36
37#ifndef BRAINVIEW_H
38#define BRAINVIEW_H
39
40//=============================================================================================================
41// INCLUDES
42//=============================================================================================================
43
44#include "../disp3D_global.h"
45
46#include "../core/rendertypes.h"
47#include "multiviewlayout.h"
48#include "core/viewstate.h"
53
55#include <QRhiWidget>
56#include <QMap>
57#include <QElapsedTimer>
58#include <memory>
59#include <QQuaternion>
60#include <Eigen/Core>
61#include <QRect>
62
63//=============================================================================================================
64// FORWARD DECLARATIONS
65//=============================================================================================================
66
67class QLabel;
68class QStandardItem;
69class QFrame;
70class BrainTreeModel;
71class BrainRenderer;
72class BrainSurface;
73class DipoleObject;
74class NetworkObject;
75namespace CONNLIB { class Network; }
76
77//=============================================================================================================
84class DISP3DSHARED_EXPORT BrainView : public QRhiWidget
85{
86 Q_OBJECT
87
88public:
96
97public:
98 //=========================================================================================================
104 explicit BrainView(QWidget *parent = nullptr);
105
106 //=========================================================================================================
110 ~BrainView();
111
112 //=========================================================================================================
118 void setModel(BrainTreeModel *model);
119
120 //=========================================================================================================
127 void setInitialCameraRotation(const QQuaternion &rotation);
128
129public slots:
130 void onRowsInserted(const QModelIndex &parent, int first, int last);
131 void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
132 //=========================================================================================================
138 void setActiveSurface(const QString &type);
139
140 //=========================================================================================================
146 void setShaderMode(const QString &mode);
147
148 //=========================================================================================================
154 void setBemShaderMode(const QString &mode);
155
159 void syncBemShadersToBrainShaders();
160
161 //=========================================================================================================
167 void setVisualizationMode(const QString &mode);
168
169 //=========================================================================================================
176 void setHemiVisible(int hemiIdx, bool visible);
177
178 //=========================================================================================================
185 void setBemVisible(const QString &name, bool visible);
186
187 //=========================================================================================================
193 void setBemHighContrast(bool enabled);
194
195 //=========================================================================================================
202 void setSensorVisible(const QString &type, bool visible);
203
204 //=========================================================================================================
210 void setSensorTransEnabled(bool enabled);
211
212 //=========================================================================================================
218 void setMegHelmetOverride(const QString &path);
219
220 //=========================================================================================================
230 bool loadMegHelmetSurface(const QString &helmetFilePath);
231
232 //=========================================================================================================
238 void setDipoleVisible(bool visible);
239
240 //=========================================================================================================
248 bool loadNetwork(const CONNLIB::Network &network, const QString &name = "Network");
249
250 //=========================================================================================================
256 void setNetworkVisible(bool visible);
257
258 //=========================================================================================================
264 void setNetworkThreshold(double threshold);
265
266 //=========================================================================================================
272 void setNetworkColormap(const QString &name);
273
274 //=========================================================================================================
280 void setLightingEnabled(bool enabled);
281
282 //=========================================================================================================
286 void saveSnapshot();
287
288 //=========================================================================================================
292 void showSingleView();
293
294 //=========================================================================================================
298 void showMultiView();
299
300 //=========================================================================================================
307 void setViewCount(int count);
308
312 int viewCount() const { return m_viewCount; }
313
314 //=========================================================================================================
321 void setViewportEnabled(int index, bool enabled);
322
329 void setViewportCameraPreset(int index, int preset);
330
337 int viewportCameraPreset(int index) const;
338
342 void resetMultiViewLayout();
343
349 void setVisualizationEditTarget(int target);
350
356 int visualizationEditTarget() const;
357
361 QString activeSurfaceForTarget(int target) const;
362
366 QString shaderModeForTarget(int target) const;
367
371 QString bemShaderModeForTarget(int target) const;
372
376 QString overlayModeForTarget(int target) const;
377
385 bool objectVisibleForTarget(const QString &object, int target) const;
386
393 bool megFieldMapOnHeadForTarget(int target) const;
394
401 bool isViewportEnabled(int index) const;
402
403 //=========================================================================================================
409 void setInfoPanelVisible(bool visible);
410
411 //=========================================================================================================
417 bool isInfoPanelVisible() const { return m_infoPanelVisible; }
418
419 //=========================================================================================================
425 ViewMode viewMode() const { return m_viewMode; }
426
427 //=========================================================================================================
435 bool loadSourceEstimate(const QString &lhPath, const QString &rhPath);
436
437 //=========================================================================================================
444 bool loadSensors(const QString &fifPath);
445
446 //=========================================================================================================
453 bool loadDipoles(const QString &dipPath);
454
455 //=========================================================================================================
462 bool loadSourceSpace(const QString &fwdPath);
463
464 //=========================================================================================================
475 static QStringList probeEvokedSets(const QString &evokedPath);
476
484 bool loadSensorField(const QString &evokedPath, int aveIndex = 0);
485
486 //=========================================================================================================
492 void setSourceSpaceVisible(bool visible);
493
494 //=========================================================================================================
501 bool loadTransformation(const QString &transPath);
502
503 //=========================================================================================================
509 void setTimePoint(int index);
510
511 //=========================================================================================================
517 void castRay(const QPoint &pos);
518
519 //=========================================================================================================
525 void setSourceColormap(const QString &name);
526
527 //=========================================================================================================
535 void setSourceThresholds(float min, float mid, float max);
536
537 //=========================================================================================================
543 void setSensorFieldTimePoint(int index);
544
545 //=========================================================================================================
552 void setSensorFieldVisible(const QString &type, bool visible);
553
554 //=========================================================================================================
561 void setSensorFieldContourVisible(const QString &type, bool visible);
562
563 //=========================================================================================================
569 void setMegFieldMapOnHead(bool useHead);
570
571 //=========================================================================================================
577 void setSensorFieldColormap(const QString &name);
578
579 //=========================================================================================================
585 float stcStep() const;
586
587 //=========================================================================================================
593 float stcTmin() const;
594
595 //=========================================================================================================
601 int stcNumTimePoints() const;
602
603 //=========================================================================================================
610 int closestSensorFieldIndex(float timeSec) const;
611
612 //=========================================================================================================
619 int closestStcIndex(float timeSec) const;
620
621 //=========================================================================================================
627 void startRealtimeStreaming();
628
629 //=========================================================================================================
633 void stopRealtimeStreaming();
634
635 //=========================================================================================================
641 bool isRealtimeStreaming() const;
642
643 //=========================================================================================================
650 void pushRealtimeSourceData(const Eigen::VectorXd &data);
651
652 //=========================================================================================================
658 void setRealtimeInterval(int msec);
659
660 //=========================================================================================================
666 void setRealtimeLooping(bool enabled);
667
668 //=========================================================================================================
676 bool sensorFieldTimeRange(float &tmin, float &tmax) const;
677
678 //=========================================================================================================
679 // ── Real-time sensor data streaming ────────────────────────────────
680 //=========================================================================================================
681
692 void startRealtimeSensorStreaming(const QString &modality = QStringLiteral("MEG"));
693
694 //=========================================================================================================
698 void stopRealtimeSensorStreaming();
699
700 //=========================================================================================================
706 bool isRealtimeSensorStreaming() const;
707
708 //=========================================================================================================
716 void pushRealtimeSensorData(const Eigen::VectorXf &data);
717
718 //=========================================================================================================
724 void setRealtimeSensorInterval(int msec);
725
726 //=========================================================================================================
732 void setRealtimeSensorLooping(bool enabled);
733
734 //=========================================================================================================
740 void setRealtimeSensorAverages(int numAvr);
741
742 //=========================================================================================================
748 void setRealtimeSensorColormap(const QString &name);
749
750 // ── Data removal ───────────────────────────────────────────────────
751
755 void clearSurfaces();
756
760 void clearBem();
761
765 void clearSourceEstimate();
766
770 void clearDipoles();
771
775 void clearSourceSpace();
776
780 void clearSensors();
781
785 void clearEvoked();
786
790 void clearTransformation();
791
795 void clearNetwork();
796
797signals:
798 //=========================================================================================================
805 void timePointChanged(int index, float time);
806
807 //=========================================================================================================
813 void sourceEstimateLoaded(int numTimePoints);
814
815 //=========================================================================================================
821 void sensorFieldLoaded(int numTimePoints, int initialTimePoint = 0);
822
823 //=========================================================================================================
831 void sourceThresholdsUpdated(float min, float mid, float max);
832
833 //=========================================================================================================
840 void stcLoadingProgress(int percent, const QString &message);
841
842 //=========================================================================================================
849 void sensorFieldTimePointChanged(int index, float time);
850
851 //=========================================================================================================
857 void hoveredRegionChanged(const QString &regionName);
858
859 //=========================================================================================================
866
867private slots:
868 //=========================================================================================================
875 void onSourceEstimateLoaded(int numTimePoints);
876
877 //=========================================================================================================
885 void onRealtimeColorsAvailable(const QVector<uint32_t> &colorsLh,
886 const QVector<uint32_t> &colorsRh);
887
888 //=========================================================================================================
890 void onSensorStreamColorsAvailable(const QString &surfaceKey,
891 const QVector<uint32_t> &colors);
892
893private:
894 // Note: ViewVisibilityProfile and SubView are defined in core/viewstate.h.
895 // SplitterHit is defined in view/multiviewlayout.h.
896
898 SubView& subViewForTarget(int target);
899 const SubView& subViewForTarget(int target) const;
900
901 ViewVisibilityProfile& visibilityProfileForTarget(int target);
902 const ViewVisibilityProfile& visibilityProfileForTarget(int target) const;
903
904 void refreshSensorTransforms();
905 void removeSurfacesByPrefix(const QString &prefix);
906
907protected:
908 void initialize(QRhiCommandBuffer *cb) override;
909 void render(QRhiCommandBuffer *cb) override;
910
911 void mousePressEvent(QMouseEvent *event) override;
912 void mouseMoveEvent(QMouseEvent *event) override;
913 void mouseReleaseEvent(QMouseEvent *event) override;
914 void wheelEvent(QWheelEvent *event) override;
915 void keyPressEvent(QKeyEvent *event) override;
916 void resizeEvent(QResizeEvent *event) override;
917
918private:
919 // ── Layout helpers (delegate to MultiViewLayout) ───────────────────
920 QVector<int> enabledViewportIndices() const;
921 int enabledViewportCount() const;
922 int viewportIndexAt(const QPoint& pos) const;
923 QRect multiViewSlotRect(int slot, int numEnabled, const QSize& outputSize) const;
924 SplitterHit hitTestSplitter(const QPoint& pos, int numEnabled, const QSize& outputSize) const;
925
926 // ── Helpers ────────────────────────────────────────────────────────
927 void updateSplitterCursor(const QPoint& pos);
928 void updateViewportSeparators();
929 void updateOverlayLayout();
930 void updateViewportLabelHighlight();
931 void showViewportPresetMenu(int viewport, const QPoint &globalPos);
932 void logPerspectiveRotation(const QString& context) const;
933 void loadMultiViewSettings();
934 void saveMultiViewSettings() const;
935 void updateInflatedSurfaceTransforms();
936
937 // ── Rendering ───────────────────────────────────────────────────────
938 std::unique_ptr<BrainRenderer> m_renderer;
939 BrainTreeModel* m_model = nullptr;
940
941 QMap<const QStandardItem*, std::shared_ptr<BrainSurface>> m_itemSurfaceMap;
942 QMap<const QStandardItem*, std::shared_ptr<DipoleObject>> m_itemDipoleMap;
943
944 QMap<QString, std::shared_ptr<BrainSurface>> m_surfaces;
945 std::shared_ptr<BrainSurface> m_activeSurface;
946 QString m_activeSurfaceType;
947
948 // ── SubView state ──────────────────────────────────────────────────
949 static constexpr int kDefaultViewportCount = 4;
950 SubView m_singleView;
951 QVector<SubView> m_subViews;
952 int m_visualizationEditTarget = -1;
953
954 // ── Active (runtime) copies — kept in sync with selected SubView ──
955 ShaderMode m_brainShaderMode = Standard;
956 ShaderMode m_bemShaderMode = Standard;
957 VisualizationMode m_currentVisMode = ModeSurface;
958 bool m_lightingEnabled = true;
959
960 // ── Extracted components ───────────────────────────────────────────
961 CameraController m_camera;
962 MultiViewLayout m_layout;
963 SensorFieldMapper m_fieldMapper;
964 SourceEstimateManager m_sourceManager;
965 RtSensorStreamManager m_sensorStreamManager;
966
967 // ── Camera state ───────────────────────────────────────────────────
968 QQuaternion m_cameraRotation;
969 QVector3D m_sceneCenter = QVector3D(0, 0, 0);
970 float m_sceneSize = 0.3f;
971 float m_zoom = 0.0f;
972 QPoint m_lastMousePos;
973
974 // ── UI overlays ────────────────────────────────────────────────────
975 int m_frameCount = 0;
976 QElapsedTimer m_fpsTimer;
977 QLabel *m_fpsLabel = nullptr;
978 QLabel *m_singleViewInfoLabel = nullptr;
979 bool m_sceneDirty = true;
980 qint64 m_cachedVertexCount = 0;
981 bool m_vertexCountDirty = true;
982 int m_snapshotCounter = 0;
983 bool m_infoPanelVisible = true;
984
985 // ── Scene objects ──────────────────────────────────────────────────
986 std::unique_ptr<DipoleObject> m_dipoles;
987 std::unique_ptr<NetworkObject> m_network;
988
990 void updateSceneBounds();
991
992 // ── Coordinate transforms ──────────────────────────────────────────
993 FIFFLIB::FiffCoordTrans m_headToMriTrans;
994 bool m_applySensorTrans = true;
995 QString m_megHelmetOverridePath;
996 QMatrix4x4 m_devHeadTrans;
997 bool m_hasDevHead = false;
998 bool m_dipolesVisible = true;
999 bool m_networkVisible = false;
1000
1001 // ── Ray-pick hover state ───────────────────────────────────────────
1002 QStandardItem* m_hoveredItem = nullptr;
1003 int m_hoveredIndex = -1;
1004 QString m_hoveredRegion;
1005 QString m_hoveredSurfaceKey;
1006 QLabel* m_regionLabel = nullptr;
1007 QVector<QLabel*> m_viewportNameLabels;
1008 QVector<QLabel*> m_viewportInfoLabels;
1009
1010 // ── Debug intersection ─────────────────────────────────────────────
1011 std::shared_ptr<BrainSurface> m_debugPointerSurface;
1012 QVector3D m_lastIntersectionPoint;
1013 bool m_hasIntersection = false;
1014
1015
1016
1017 // ── Multi-view support ─────────────────────────────────────────────
1018 ViewMode m_viewMode = SingleView;
1019 int m_viewCount = 1;
1020 float m_multiSplitX = 0.5f;
1021 float m_multiSplitY = 0.5f;
1022 bool m_isDraggingSplitter = false;
1023 SplitterHit m_activeSplitter = SplitterHit::None;
1024 int m_splitterHitTolerancePx = 6;
1025 int m_splitterMinPanePx = 80;
1026 int m_separatorLinePx = 2;
1027 QFrame* m_verticalSeparator = nullptr;
1028 QFrame* m_horizontalSeparator = nullptr;
1029 bool m_perspectiveRotatedSincePress = false;
1030};
1031
1032#endif // BRAINVIEW_H
SourceEstimateManager class declaration — owns STC overlay, loading, and real-time streaming.
RtSensorStreamManager class declaration — real-time sensor data streaming.
SensorFieldMapper class declaration.
ViewState declarations — per-view data structures and conversion helpers.
Lightweight render-related enums shared across the disp3D library.
ShaderMode
Definition rendertypes.h:73
@ Standard
Definition rendertypes.h:74
VisualizationMode
Definition rendertypes.h:90
@ ModeSurface
Definition rendertypes.h:91
disp3D library export/import macros.
#define DISP3DSHARED_EXPORT
MultiViewLayout class declaration — viewport geometry and splitter logic.
SplitterHit
CameraController class declaration.
FiffCoordTrans class declaration.
Functional connectivity metrics (coherence, PLV, cross-correlation, etc.).
This class holds information about a network, can compute a distance table and provide network metric...
Definition network.h:92
Per-view toggle flags controlling which data layers (brain, sensors, sources, network) are visible.
Definition viewstate.h:74
Viewport subdivision holding its own camera, projection, and scissor rectangle.
Definition viewstate.h:148
Camera state and matrix computation.
Hierarchical item model organizing all 3-D scene objects (surfaces, sensors, sources,...
Renderable cortical surface mesh with per-vertex color, curvature data, and GPU buffer management.
Renderable dipole arrow set with instanced GPU rendering for QRhi.
Renderable network visualization for QRhi.
Real-time sensor streaming lifecycle manager.
Sensor-to-surface field mapper that interpolates MEG/EEG measurements onto cortical meshes and genera...
Source estimate lifecycle manager.
Qt RHI-based 3-D renderer managing scene objects, lighting, camera, and render pipeline for brain vis...
Top-level QWidget hosting the QRhi-based 3-D brain visualization with mouse interaction and multi-vie...
Definition brainview.h:85
ViewMode viewMode() const
Definition brainview.h:425
void sourceThresholdsUpdated(float min, float mid, float max)
void wheelEvent(QWheelEvent *event) override
void sourceEstimateLoaded(int numTimePoints)
void resizeEvent(QResizeEvent *event) override
void keyPressEvent(QKeyEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
void visualizationEditTargetChanged(int target)
void timePointChanged(int index, float time)
int viewCount() const
Definition brainview.h:312
void render(QRhiCommandBuffer *cb) override
void initialize(QRhiCommandBuffer *cb) override
void mouseReleaseEvent(QMouseEvent *event) override
BrainView(QWidget *parent=nullptr)
Definition brainview.cpp:90
void mousePressEvent(QMouseEvent *event) override
void sensorFieldTimePointChanged(int index, float time)
void hoveredRegionChanged(const QString &regionName)
void sensorFieldLoaded(int numTimePoints, int initialTimePoint=0)
bool isInfoPanelVisible() const
Definition brainview.h:417
void stcLoadingProgress(int percent, const QString &message)
Multi-view geometry computations.
Coordinate transformation description.