43#include <QMutexLocker>
62 QMutexLocker locker(&m_mutex);
65 if (m_lDataQ.size() <
static_cast<int>(m_dSFreq)) {
66 m_lDataQ.append(data);
71 m_lDataLoopQ.append(data);
73 if (m_lDataLoopQ.size() >
static_cast<int>(m_dSFreq) * 10) {
74 m_lDataLoopQ.removeFirst();
83 QMutexLocker locker(&m_mutex);
86 m_vecAverage = Eigen::VectorXf();
95 QMutexLocker locker(&m_mutex);
103 QMutexLocker locker(&m_mutex);
104 m_iNumAverages = qMax(1, numAvr);
111 QMutexLocker locker(&m_mutex);
112 m_sColormapType = name;
119 QMutexLocker locker(&m_mutex);
120 if (min == 0.0 && max == 0.0) {
121 m_bUseAutoNorm =
true;
125 m_bUseAutoNorm =
false;
135 QMutexLocker locker(&m_mutex);
136 m_bIsLooping = enabled;
143 QMutexLocker locker(&m_mutex);
144 m_dSFreq = qMax(1.0, sFreq);
151 QMutexLocker locker(&m_mutex);
152 m_bStreamSmoothedData = bStreamSmoothedData;
159 QMutexLocker locker(&m_mutex);
162 Eigen::VectorXf vecCurrentData;
164 if (!m_lDataQ.isEmpty()) {
165 vecCurrentData = m_lDataQ.takeFirst();
166 }
else if (m_bIsLooping && !m_lDataLoopQ.isEmpty()) {
168 vecCurrentData = m_lDataLoopQ[m_iCurrentSample % m_lDataLoopQ.size()];
176 if (m_iNumAverages > 1) {
177 if (m_vecAverage.size() != vecCurrentData.size()) {
178 m_vecAverage = vecCurrentData;
181 m_vecAverage += vecCurrentData;
185 if (m_iSampleCtr < m_iNumAverages) {
189 vecCurrentData = m_vecAverage /
static_cast<float>(m_iSampleCtr);
190 m_vecAverage = Eigen::VectorXf();
195 if (!m_bStreamSmoothedData) {
197 Eigen::VectorXf rawData = vecCurrentData;
204 QVector<uint32_t> colors = computeSurfaceColors(vecCurrentData);
209 if (!colors.isEmpty()) {
216QVector<uint32_t> RtSensorDataWorker::computeSurfaceColors(
const Eigen::VectorXf &sensorData)
const
218 if (sensorData.size() == 0 || !m_mappingMat || m_mappingMat->rows() == 0) {
219 return QVector<uint32_t>();
223 if (m_mappingMat->cols() != sensorData.size()) {
224 qWarning() <<
"RtSensorDataWorker: Mapping matrix cols" << m_mappingMat->cols()
225 <<
"!= sensor data size" << sensorData.size();
226 return QVector<uint32_t>();
230 Eigen::VectorXf mapped = (*m_mappingMat) * sensorData;
232 int nVertices = mapped.size();
235 float normMin, normMax;
236 if (m_bUseAutoNorm) {
239 for (
int i = 0; i < nVertices; ++i) {
240 maxAbs = std::max(maxAbs, std::abs(mapped(i)));
242 if (maxAbs <= 0.0f) maxAbs = 1.0f;
247 normMin =
static_cast<float>(m_dThreshMin);
248 normMax =
static_cast<float>(m_dThreshMax);
249 if (normMax <= normMin) normMax = normMin + 1.0f;
252 float range = normMax - normMin;
255 QVector<uint32_t> colors(nVertices);
257 for (
int i = 0; i < nVertices; ++i) {
259 double norm =
static_cast<double>(mapped(i) - normMin) /
static_cast<double>(range);
260 norm = qBound(0.0, norm, 1.0);
264 uint32_t r = qRed(rgb);
265 uint32_t g = qGreen(rgb);
266 uint32_t b = qBlue(rgb);
ColorMap class declaration.
RtSensorDataWorker class declaration.
Lightweight render-related enums shared across the disp3D_rhi library.
uint32_t packABGR(uint32_t r, uint32_t g, uint32_t b, uint32_t a=0xFF)
3-D brain visualisation using the Qt RHI rendering backend.
static QRgb valueToColor(double v, const QString &sMap)
void setSFreq(double sFreq)
void setMappingMatrix(QSharedPointer< Eigen::MatrixXf > mat)
void setLoopState(bool enabled)
void setThresholds(double min, double max)
void addData(const Eigen::VectorXf &data)
RtSensorDataWorker(QObject *parent=nullptr)
void newRtRawSensorData(const Eigen::VectorXf &data)
void newRtSensorColors(const QString &surfaceKey, const QVector< uint32_t > &colors)
void setColormapType(const QString &name)
void setStreamSmoothedData(bool bStreamSmoothedData)
void setNumberAverages(int numAvr)