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