v2.0.0
Loading...
Searching...
No Matches
braintreemodel.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "braintreemodel.h"
26#include <mne/mne_hemisphere.h>
27
29 : QStandardItemModel(parent)
30{
31 // Set headers
32 setHorizontalHeaderLabels(QStringList() << "Data" << "Description");
33}
34
35SurfaceTreeItem* BrainTreeModel::addSurface(const QString &subject, const QString &hemi, const QString &surfType, const FSLIB::FsSurface &surface)
36{
37 QStandardItem* subjectItem = getSubjectItem(subject);
38
39 // Find or create Hemi item
40 QStandardItem* hemiItem = nullptr;
41 for(int i = 0; i < subjectItem->rowCount(); ++i) {
42 if (subjectItem->child(i)->text() == hemi) {
43 hemiItem = subjectItem->child(i);
44 break;
45 }
46 }
47
48 if (!hemiItem) {
49 hemiItem = new QStandardItem(hemi);
50 subjectItem->appendRow(hemiItem);
51 }
52
53 // Create FsSurface Item
54 SurfaceTreeItem* surfItem = new SurfaceTreeItem(surfType);
55 surfItem->setSurfaceData(surface);
56
57 hemiItem->appendRow(surfItem);
58 return surfItem;
59}
60
61bool BrainTreeModel::addAnnotation(const QString &subject, const QString &hemi, const FSLIB::FsAnnotation &annotation)
62{
63 QStandardItem* subjectItem = getSubjectItem(subject);
64 if (!subjectItem) return false;
65
66 QStandardItem* hemiItem = nullptr;
67 for(int i = 0; i < subjectItem->rowCount(); ++i) {
68 if (subjectItem->child(i)->text() == hemi) {
69 hemiItem = subjectItem->child(i);
70 break;
71 }
72 }
73
74 if (!hemiItem) return false;
75
76 // Apply annotation to ALL surfaces in this hemi? Or just one?
77 // Ex_brain_view logic applies atlas to the loaded surfaces of that hemi.
78 // So we iterate children of hemiItem and if they are SurfaceTreeItems, set annotation.
79 bool applied = false;
80 for(int i = 0; i < hemiItem->rowCount(); ++i) {
81 SurfaceTreeItem* item = dynamic_cast<SurfaceTreeItem*>(hemiItem->child(i));
82 if (item) {
83 item->setAnnotationData(annotation);
84 applied = true;
85 }
86 }
87 return applied;
88}
89
90QStandardItem* BrainTreeModel::getSubjectItem(const QString &subject)
91{
92 // Search top level
93 QList<QStandardItem*> items = findItems(subject);
94 if (!items.isEmpty()) {
95 return items.first();
96 }
97
98 // Create new
99 QStandardItem* item = new QStandardItem(subject);
100 appendRow(item);
101 return item;
102}
103
104BemTreeItem* BrainTreeModel::addBemSurface(const QString &subject, const QString &bemName, const MNELIB::MNEBemSurface &bemSurf)
105{
106 QStandardItem *subjItem = getSubjectItem(subject);
107
108 // Check if BEM item already exists to avoid duplicates?
109 // Usually BEM is added once.
110
111 BemTreeItem *bemItem = new BemTreeItem(bemName, bemSurf);
112 bemItem->setVisible(true); // Default to visible
113
114 // Set default colors based on type/name
115 // Set colors based on ID (matching zeiss-intent)
116 // 4=Head (Reddish), 3=OuterSkull (Greenish), 1=InnerSkull (Blueish)
117 if (bemSurf.id == 4) {
118 bemItem->setColor(QColor(128, 77, 77)); // Reddish
119 } else if (bemSurf.id == 3) {
120 bemItem->setColor(QColor(77, 128, 77)); // Greenish
121 } else if (bemSurf.id == 1) {
122 bemItem->setColor(QColor(77, 77, 128)); // Blueish
123 } else {
124 bemItem->setColor(QColor(100, 100, 100)); // Grey default
125 }
126
127 subjItem->appendRow(bemItem);
128
129 return bemItem;
130}
131
132//=============================================================================================================
133
134void BrainTreeModel::addSensors(const QString &type, const QList<QStandardItem*> &items)
135{
136 QStandardItem* parentItem = new QStandardItem(type);
137 parentItem->setCheckable(true);
138 parentItem->setCheckState(Qt::Checked);
139
140 for(auto* item : items) {
141 parentItem->appendRow(item);
142 }
143
144 this->appendRow(parentItem);
145}
146
147//=============================================================================================================
148
150{
151 DipoleTreeItem* item = new DipoleTreeItem("Dipoles", set);
152 item->setCheckable(true);
153 item->setCheckState(Qt::Checked);
154 this->appendRow(item);
155}
156
157//=============================================================================================================
158
160{
161 QStandardItem* parentItem = new QStandardItem("Source Space");
162 parentItem->setCheckable(true);
163 parentItem->setCheckState(Qt::Checked);
164
165 // Color: pinkish-red matching disp3D's source space rendering
166 QColor srcColor(212, 28, 92);
167
168 for (int h = 0; h < srcSpace.size(); ++h) {
169 const auto &hemi = srcSpace[h];
170 QString hemiLabel = (h == 0) ? "LH" : "RH";
171
172 // Collect all source point positions for this hemisphere
173 QVector<QVector3D> positions;
174 positions.reserve(hemi.vertno.size());
175 for (int i = 0; i < hemi.vertno.size(); ++i) {
176 int vIdx = hemi.vertno(i);
177 if (vIdx < 0 || vIdx >= hemi.rr.rows()) continue;
178 positions.append(QVector3D(hemi.rr(vIdx, 0), hemi.rr(vIdx, 1), hemi.rr(vIdx, 2)));
179 }
180
181 // One item per hemisphere with all positions batched (0.00075 = 0.75mm radius, same as disp3D)
182 parentItem->appendRow(new SourceSpaceTreeItem(hemiLabel, positions, srcColor, 0.00075f));
183 qDebug() << "BrainTreeModel: Source space" << hemiLabel
184 << "- points:" << positions.size()
185 << "coord_frame:" << hemi.coord_frame;
186 if (!positions.isEmpty()) {
187 qDebug() << " First point:" << positions.first()
188 << " Last point:" << positions.last();
189 }
190 }
191
192 this->appendRow(parentItem);
193}
194
195//=============================================================================================================
196
197void BrainTreeModel::addDigitizerData(const QList<FIFFLIB::FiffDigPoint> &digitizerPoints)
198{
199 if (digitizerPoints.isEmpty()) return;
200
201 auto *setItem = new DigitizerSetTreeItem("Digitizer", digitizerPoints);
202 this->appendRow(setItem);
203
204 qInfo() << "BrainTreeModel: Added digitizer set with"
205 << setItem->totalPointCount() << "points in"
206 << setItem->rowCount() << "categories";
207}
208
209//=============================================================================================================
210
212{
213 QString displayName = name;
214 if (displayName.isEmpty()) {
215 displayName = network.getConnectivityMethod();
216 if (displayName.isEmpty()) displayName = "Network";
217 }
218
219 QString objectKey = "net_" + displayName.toLower().replace(" ", "_");
220
221 auto *item = new NetworkTreeItem(displayName, objectKey);
222 item->setCheckable(true);
223 item->setCheckState(Qt::Checked);
224
225 this->appendRow(item);
226
227 qDebug() << "BrainTreeModel: Added network" << displayName
228 << "with" << network.getNodes().size() << "nodes and"
229 << network.getFullEdges().size() << "edges";
230
231 return item;
232}
Tree item wrapping a fitted INVLIB::InvEcdSet of equivalent current dipoles.
Tree item holding one hemisphere of source-space dipole positions rendered as batched spheres.
Tree item identifying a connectivity network rendered as instanced nodes and edges.
Container item that groups raw FIFF digitizer points by category (Cardinal, HPI, EEG,...
Tree item wrapping a single MNELIB::MNEBemSurface (brain / inner-skull / outer-skull / scalp shell).
Tree item for a single MEG / EEG sensor with position, optional coil orientation and rendered scale.
Tree item wrapping a FreeSurfer FSLIB::FsSurface plus optional FSLIB::FsAnnotation parcellation.
QStandardItemModel hierarchy that organises every 3-D scene object (surfaces, sensors,...
Per-hemisphere cortical surface bundle with decimation, patch info and rendering buffers.
Ordered set of INVLIB::InvEcd records — the result of a sequential dipole-fit run.
Graph container for one connectivity metric; nodes + weighted edges + threshold/visualisation state.
Definition network.h:98
QString getConnectivityMethod() const
Definition network.cpp:190
const QList< QSharedPointer< NetworkNode > > & getNodes() const
Definition network.cpp:136
const QList< QSharedPointer< NetworkEdge > > & getFullEdges() const
Definition network.cpp:122
void addDipoles(const INVLIB::InvEcdSet &set)
SurfaceTreeItem * addSurface(const QString &subject, const QString &hemi, const QString &surfType, const FSLIB::FsSurface &surface)
BemTreeItem * addBemSurface(const QString &subject, const QString &bemName, const MNELIB::MNEBemSurface &bemSurf)
void addDigitizerData(const QList< FIFFLIB::FiffDigPoint > &digitizerPoints)
void addSensors(const QString &type, const QList< QStandardItem * > &items)
NetworkTreeItem * addNetwork(const CONNECTIVITYLIB::Network &network, const QString &name="Network")
bool addAnnotation(const QString &subject, const QString &hemi, const FSLIB::FsAnnotation &annotation)
void addSourceSpace(const MNELIB::MNESourceSpaces &srcSpace)
BrainTreeModel(QObject *parent=nullptr)
void setColor(const QColor &color)
void setVisible(bool visible)
Tree item representing a BEM surface layer in the 3-D scene hierarchy.
Definition bemtreeitem.h:35
Digitizer point set container tree item.
Tree item representing a set of fitted dipoles in the 3-D scene hierarchy.
Tree item representing a connectivity network.
Source space point tree item.
Tree item representing a FreeSurfer cortical surface in the 3-D scene hierarchy.
void setSurfaceData(const FSLIB::FsSurface &surface)
void setAnnotationData(const FSLIB::FsAnnotation &annotation)
Single-hemisphere FreeSurfer parcellation: vertex → region label plus embedded colortable.
In-memory FreeSurfer triangular cortical surface for one hemisphere.
Definition fs_surface.h:92
Holds a set of Electric Current Dipoles.
Definition inv_ecd_set.h:64
BEM surface provides geometry information.
List of MNESourceSpace objects forming a subject source space.