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
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 QTimer;
69class QStandardItem;
70class QFrame;
71class BrainTreeModel;
72class BrainRenderer;
73class BrainSurface;
74class DipoleObject;
75class NetworkObject;
76namespace CONNECTIVITYLIB { class Network; }
77
78//=============================================================================================================
85class DISP3DRHISHARED_EXPORT BrainView : public QRhiWidget
86{
87 Q_OBJECT
88
89public:
97
98public:
99 //=========================================================================================================
105 explicit BrainView(QWidget *parent = nullptr);
106
107 //=========================================================================================================
111 ~BrainView();
112
113 //=========================================================================================================
119 void setModel(BrainTreeModel *model);
120
121 //=========================================================================================================
128 void setInitialCameraRotation(const QQuaternion &rotation);
129
130public slots:
131 void onRowsInserted(const QModelIndex &parent, int first, int last);
132 void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
133 //=========================================================================================================
139 void setActiveSurface(const QString &type);
140
141 //=========================================================================================================
147 void setShaderMode(const QString &mode);
148
149 //=========================================================================================================
155 void setBemShaderMode(const QString &mode);
156
160 void syncBemShadersToBrainShaders();
161
162 //=========================================================================================================
168 void setVisualizationMode(const QString &mode);
169
170 //=========================================================================================================
177 void setHemiVisible(int hemiIdx, bool visible);
178
179 //=========================================================================================================
186 void setBemVisible(const QString &name, bool visible);
187
188 //=========================================================================================================
194 void setBemHighContrast(bool enabled);
195
196 //=========================================================================================================
203 void setSensorVisible(const QString &type, bool visible);
204
205 //=========================================================================================================
211 void setSensorTransEnabled(bool enabled);
212
213 //=========================================================================================================
219 void setMegHelmetOverride(const QString &path);
220
221 //=========================================================================================================
231 bool loadMegHelmetSurface(const QString &helmetFilePath);
232
233 //=========================================================================================================
239 void setDipoleVisible(bool visible);
240
241 //=========================================================================================================
249 bool loadNetwork(const CONNECTIVITYLIB::Network &network, const QString &name = "Network");
250
251 //=========================================================================================================
257 void setNetworkVisible(bool visible);
258
259 //=========================================================================================================
265 void setNetworkThreshold(double threshold);
266
267 //=========================================================================================================
273 void setNetworkColormap(const QString &name);
274
275 //=========================================================================================================
281 void setLightingEnabled(bool enabled);
282
283 //=========================================================================================================
287 void saveSnapshot();
288
289 //=========================================================================================================
293 void showSingleView();
294
295 //=========================================================================================================
299 void showMultiView();
300
301 //=========================================================================================================
308 void setViewCount(int count);
309
313 int viewCount() const { return m_viewCount; }
314
315 //=========================================================================================================
322 void setViewportEnabled(int index, bool enabled);
323
330 void setViewportCameraPreset(int index, int preset);
331
338 int viewportCameraPreset(int index) const;
339
343 void resetMultiViewLayout();
344
350 void setVisualizationEditTarget(int target);
351
357 int visualizationEditTarget() const;
358
362 QString activeSurfaceForTarget(int target) const;
363
367 QString shaderModeForTarget(int target) const;
368
372 QString bemShaderModeForTarget(int target) const;
373
377 QString overlayModeForTarget(int target) const;
378
386 bool objectVisibleForTarget(const QString &object, int target) const;
387
394 bool megFieldMapOnHeadForTarget(int target) const;
395
402 bool isViewportEnabled(int index) const;
403
404 //=========================================================================================================
410 void setInfoPanelVisible(bool visible);
411
412 //=========================================================================================================
418 bool isInfoPanelVisible() const { return m_infoPanelVisible; }
419
420 //=========================================================================================================
426 ViewMode viewMode() const { return m_viewMode; }
427
428 //=========================================================================================================
436 bool loadSourceEstimate(const QString &lhPath, const QString &rhPath);
437
438 //=========================================================================================================
445 bool loadSensors(const QString &fifPath);
446
447 //=========================================================================================================
454 bool loadDipoles(const QString &dipPath);
455
456 //=========================================================================================================
463 bool loadSourceSpace(const QString &fwdPath);
464
465 //=========================================================================================================
476 static QStringList probeEvokedSets(const QString &evokedPath);
477
485 bool loadSensorField(const QString &evokedPath, int aveIndex = 0);
486
487 //=========================================================================================================
493 void setSourceSpaceVisible(bool visible);
494
495 //=========================================================================================================
502 bool loadTransformation(const QString &transPath);
503
504 //=========================================================================================================
510 void setTimePoint(int index);
511
512 //=========================================================================================================
518 void castRay(const QPoint &pos);
519
520 //=========================================================================================================
526 void setSourceColormap(const QString &name);
527
528 //=========================================================================================================
536 void setSourceThresholds(float min, float mid, float max);
537
538 //=========================================================================================================
544 void setSensorFieldTimePoint(int index);
545
546 //=========================================================================================================
553 void setSensorFieldVisible(const QString &type, bool visible);
554
555 //=========================================================================================================
562 void setSensorFieldContourVisible(const QString &type, bool visible);
563
564 //=========================================================================================================
570 void setMegFieldMapOnHead(bool useHead);
571
572 //=========================================================================================================
578 void setSensorFieldColormap(const QString &name);
579
580 //=========================================================================================================
586 float stcStep() const;
587
588 //=========================================================================================================
594 float stcTmin() const;
595
596 //=========================================================================================================
602 int stcNumTimePoints() const;
603
604 //=========================================================================================================
611 int closestSensorFieldIndex(float timeSec) const;
612
613 //=========================================================================================================
620 int closestStcIndex(float timeSec) const;
621
622 //=========================================================================================================
628 void startRealtimeStreaming();
629
630 //=========================================================================================================
634 void stopRealtimeStreaming();
635
636 //=========================================================================================================
642 bool isRealtimeStreaming() const;
643
644 //=========================================================================================================
651 void pushRealtimeSourceData(const Eigen::VectorXd &data);
652
653 //=========================================================================================================
659 void setRealtimeInterval(int msec);
660
661 //=========================================================================================================
667 void setRealtimeLooping(bool enabled);
668
669 //=========================================================================================================
677 bool sensorFieldTimeRange(float &tmin, float &tmax) const;
678
679 //=========================================================================================================
680 // ── Real-time sensor data streaming ────────────────────────────────
681 //=========================================================================================================
682
693 void startRealtimeSensorStreaming(const QString &modality = QStringLiteral("MEG"));
694
695 //=========================================================================================================
699 void stopRealtimeSensorStreaming();
700
701 //=========================================================================================================
707 bool isRealtimeSensorStreaming() const;
708
709 //=========================================================================================================
717 void pushRealtimeSensorData(const Eigen::VectorXf &data);
718
719 //=========================================================================================================
725 void setRealtimeSensorInterval(int msec);
726
727 //=========================================================================================================
733 void setRealtimeSensorLooping(bool enabled);
734
735 //=========================================================================================================
741 void setRealtimeSensorAverages(int numAvr);
742
743 //=========================================================================================================
749 void setRealtimeSensorColormap(const QString &name);
750
751signals:
752 //=========================================================================================================
759 void timePointChanged(int index, float time);
760
761 //=========================================================================================================
767 void sourceEstimateLoaded(int numTimePoints);
768
769 //=========================================================================================================
775 void sensorFieldLoaded(int numTimePoints, int initialTimePoint = 0);
776
777 //=========================================================================================================
785 void sourceThresholdsUpdated(float min, float mid, float max);
786
787 //=========================================================================================================
794 void stcLoadingProgress(int percent, const QString &message);
795
796 //=========================================================================================================
803 void sensorFieldTimePointChanged(int index, float time);
804
805 //=========================================================================================================
811 void hoveredRegionChanged(const QString &regionName);
812
813 //=========================================================================================================
820
821private slots:
822 //=========================================================================================================
829 void onSourceEstimateLoaded(int numTimePoints);
830
831 //=========================================================================================================
839 void onRealtimeColorsAvailable(const QVector<uint32_t> &colorsLh,
840 const QVector<uint32_t> &colorsRh);
841
842 //=========================================================================================================
844 void onSensorStreamColorsAvailable(const QString &surfaceKey,
845 const QVector<uint32_t> &colors);
846
847private:
848 // Note: ViewVisibilityProfile and SubView are defined in core/viewstate.h.
849 // SplitterHit is defined in view/multiviewlayout.h.
850
852 SubView& subViewForTarget(int target);
853 const SubView& subViewForTarget(int target) const;
854
855 ViewVisibilityProfile& visibilityProfileForTarget(int target);
856 const ViewVisibilityProfile& visibilityProfileForTarget(int target) const;
857
858 void refreshSensorTransforms();
859
860protected:
861 void initialize(QRhiCommandBuffer *cb) override;
862 void render(QRhiCommandBuffer *cb) override;
863
864 void mousePressEvent(QMouseEvent *event) override;
865 void mouseMoveEvent(QMouseEvent *event) override;
866 void mouseReleaseEvent(QMouseEvent *event) override;
867 void wheelEvent(QWheelEvent *event) override;
868 void keyPressEvent(QKeyEvent *event) override;
869 void resizeEvent(QResizeEvent *event) override;
870
871private:
872 // ── Layout helpers (delegate to MultiViewLayout) ───────────────────
873 QVector<int> enabledViewportIndices() const;
874 int enabledViewportCount() const;
875 int viewportIndexAt(const QPoint& pos) const;
876 QRect multiViewSlotRect(int slot, int numEnabled, const QSize& outputSize) const;
877 SplitterHit hitTestSplitter(const QPoint& pos, int numEnabled, const QSize& outputSize) const;
878
879 // ── Helpers ────────────────────────────────────────────────────────
880 void updateSplitterCursor(const QPoint& pos);
881 void updateViewportSeparators();
882 void updateOverlayLayout();
883 void updateViewportLabelHighlight();
884 void showViewportPresetMenu(int viewport, const QPoint &globalPos);
885 void logPerspectiveRotation(const QString& context) const;
886 void loadMultiViewSettings();
887 void saveMultiViewSettings() const;
888 void updateInflatedSurfaceTransforms();
889
890 // ── Rendering ───────────────────────────────────────────────────────
891 std::unique_ptr<BrainRenderer> m_renderer;
892 BrainTreeModel* m_model = nullptr;
893
894 QMap<const QStandardItem*, std::shared_ptr<BrainSurface>> m_itemSurfaceMap;
895 QMap<const QStandardItem*, std::shared_ptr<DipoleObject>> m_itemDipoleMap;
896
897 QMap<QString, std::shared_ptr<BrainSurface>> m_surfaces;
898 std::shared_ptr<BrainSurface> m_activeSurface;
899 QString m_activeSurfaceType;
900
901 // ── SubView state ──────────────────────────────────────────────────
902 static constexpr int kDefaultViewportCount = 4;
903 SubView m_singleView;
904 QVector<SubView> m_subViews;
905 int m_visualizationEditTarget = -1;
906
907 // ── Active (runtime) copies — kept in sync with selected SubView ──
908 ShaderMode m_brainShaderMode = Standard;
909 ShaderMode m_bemShaderMode = Standard;
910 VisualizationMode m_currentVisMode = ModeSurface;
911 bool m_lightingEnabled = true;
912
913 // ── Extracted components ───────────────────────────────────────────
914 CameraController m_camera;
915 MultiViewLayout m_layout;
916 SensorFieldMapper m_fieldMapper;
917 SourceEstimateManager m_sourceManager;
918 RtSensorStreamManager m_sensorStreamManager;
919
920 // ── Camera state ───────────────────────────────────────────────────
921 QQuaternion m_cameraRotation;
922 QVector3D m_sceneCenter = QVector3D(0, 0, 0);
923 float m_sceneSize = 0.3f;
924 float m_zoom = 0.0f;
925 QPoint m_lastMousePos;
926
927 // ── UI overlays ────────────────────────────────────────────────────
928 int m_frameCount = 0;
929 QElapsedTimer m_fpsTimer;
930 QLabel *m_fpsLabel = nullptr;
931 QLabel *m_singleViewInfoLabel = nullptr;
932 QTimer *m_updateTimer = nullptr;
933 int m_snapshotCounter = 0;
934 bool m_infoPanelVisible = true;
935
936 // ── Scene objects ──────────────────────────────────────────────────
937 std::unique_ptr<DipoleObject> m_dipoles;
938 std::unique_ptr<NetworkObject> m_network;
939
941 void updateSceneBounds();
942
943 // ── Coordinate transforms ──────────────────────────────────────────
944 FIFFLIB::FiffCoordTrans m_headToMriTrans;
945 bool m_applySensorTrans = true;
946 QString m_megHelmetOverridePath;
947 QMatrix4x4 m_devHeadTrans;
948 bool m_hasDevHead = false;
949 bool m_dipolesVisible = true;
950 bool m_networkVisible = false;
951
952 // ── Ray-pick hover state ───────────────────────────────────────────
953 QStandardItem* m_hoveredItem = nullptr;
954 int m_hoveredIndex = -1;
955 QString m_hoveredRegion;
956 QString m_hoveredSurfaceKey;
957 QLabel* m_regionLabel = nullptr;
958 QVector<QLabel*> m_viewportNameLabels;
959 QVector<QLabel*> m_viewportInfoLabels;
960
961 // ── Debug intersection ─────────────────────────────────────────────
962 std::shared_ptr<BrainSurface> m_debugPointerSurface;
963 QVector3D m_lastIntersectionPoint;
964 bool m_hasIntersection = false;
965
966
967
968 // ── Multi-view support ─────────────────────────────────────────────
969 ViewMode m_viewMode = SingleView;
970 int m_viewCount = 1;
971 float m_multiSplitX = 0.5f;
972 float m_multiSplitY = 0.5f;
973 bool m_isDraggingSplitter = false;
974 SplitterHit m_activeSplitter = SplitterHit::None;
975 int m_splitterHitTolerancePx = 6;
976 int m_splitterMinPanePx = 80;
977 int m_separatorLinePx = 2;
978 QFrame* m_verticalSeparator = nullptr;
979 QFrame* m_horizontalSeparator = nullptr;
980 bool m_perspectiveRotatedSincePress = false;
981};
982
983#endif // BRAINVIEW_H
FiffCoordTrans class declaration.
disp3D_rhi library export/import macros.
#define DISP3DRHISHARED_EXPORT
RtSensorStreamManager class declaration — real-time sensor data streaming.
SensorFieldMapper class declaration.
SourceEstimateManager class declaration — owns STC overlay, loading, and real-time streaming.
CameraController class declaration.
MultiViewLayout class declaration — viewport geometry and splitter logic.
SplitterHit
ViewState declarations — per-view data structures and conversion helpers.
Lightweight render-related enums shared across the disp3D_rhi library.
ShaderMode
Definition rendertypes.h:73
@ Standard
Definition rendertypes.h:74
VisualizationMode
Definition rendertypes.h:90
@ ModeSurface
Definition rendertypes.h:91
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:86
ViewMode viewMode() const
Definition brainview.h:426
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:313
void render(QRhiCommandBuffer *cb) override
void initialize(QRhiCommandBuffer *cb) override
void mouseReleaseEvent(QMouseEvent *event) override
BrainView(QWidget *parent=nullptr)
Definition brainview.cpp:91
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:418
void stcLoadingProgress(int percent, const QString &message)
Multi-view geometry computations.
Coordinate transformation description.