136 lines
6.1 KiB
C++
136 lines
6.1 KiB
C++
#pragma once
|
|
#include "Afterglow.h"
|
|
#include "../Axis/FrequentAxis.h"
|
|
#include "../Axis/FrequentAxis_p.h"
|
|
#include "../base/PerformanceShower_p.h"
|
|
#include "../base/Plot_p.h"
|
|
#include "../base/Global.h"
|
|
|
|
namespace YSG {
|
|
|
|
|
|
|
|
struct AfterglowRenderState : RenderState, Afterglow_Prop {
|
|
};
|
|
struct AfterglowInputData : InputData {
|
|
std::list<QVector<double>> mDataList;
|
|
void clear() override {
|
|
mDataList.clear();
|
|
}
|
|
};
|
|
struct AfterglowPrivate : RenderData {
|
|
D_Ptr(Afterglow)
|
|
QImage image;
|
|
bool cacheImageDirty = false;
|
|
int curIndex = 0;
|
|
int cacheFrequentPointSize{};
|
|
int cachePowerPointSize{};
|
|
int cacheBufferSize{};
|
|
QVector<double> cachedPowerData;
|
|
QVector<double> oldCachePowerData;
|
|
QVector<double> mergedPowerData;
|
|
[[nodiscard]] int strengthValue(const AfterglowRenderState* s) const {return (int)((double)s->initStrongValue / (1.0 - s->attenuationRate));}
|
|
void updateCacheSize(int frequentPointSize, int powerPointSize) {
|
|
cacheFrequentPointSize = frequentPointSize;
|
|
cachePowerPointSize = powerPointSize;
|
|
cacheBufferSize = frequentPointSize * powerPointSize;
|
|
cachedPowerData.resize(cacheBufferSize);
|
|
cachedPowerData.fill(0);
|
|
oldCachePowerData.resize(cacheBufferSize);
|
|
oldCachePowerData.fill(0);
|
|
mergedPowerData.resize(cacheBufferSize);
|
|
mergedPowerData.fill(0);
|
|
curIndex = 0;
|
|
}
|
|
void pushData(const QVector<double>& powerRangeData, const AfterglowRenderState* s);
|
|
void draw(QPainter* painter) override {
|
|
AfterglowRenderState* s = renderState();
|
|
PerformanceShower *shower = q()->mPlot->d->mShower;
|
|
if(shower) {
|
|
shower->setPerformanceLine("colCount, rowCount", PerformanceLine(QString("colCount:%1, rowCount:%2").arg(s->frequentPointSize).arg(s->powerPointSize)));
|
|
}
|
|
AbsAxis *hAxis = s->frequentAxis, *vAxis = s->powerAxis, *valueAxis = s->powerAxis;
|
|
Range &hRange = s->frequentRange, &vRange = s->powerRange;
|
|
|
|
int colCount = s->frequentPointSize, rowCount = s->powerPointSize;
|
|
if(image.width() != colCount || image.height() != rowCount) {
|
|
image = QImage(colCount, rowCount, QImage::Format_ARGB32_Premultiplied);
|
|
image.fill(0);
|
|
}
|
|
{
|
|
if(cacheImageDirty) {
|
|
QVector<QRgb>& mColorMap = Global::instance()->mColorMap;
|
|
Cacl c("Afterglow setTime:%1 SRTT:%2 RTTVAR:%3", q()->mPlot->d->mShower);
|
|
//double rate = 1.0/s->strengthValue() * 256.0;
|
|
for (int row = 0; row < rowCount; ++row) {
|
|
QRgb* scanLine = reinterpret_cast<QRgb*>(image.scanLine(row));
|
|
double* list = oldCachePowerData.data() + row*colCount;
|
|
for (int col = 0; col < colCount; ++col) {
|
|
int colorOffset = (int)(list[col] * 255);
|
|
if (colorOffset < 0 || colorOffset > 255) {
|
|
qDebug() << "colorOffset:" << colorOffset << " value: " << list[col]
|
|
<< " startCoord:" << valueAxis->startCoord() << " endCoord:" << valueAxis->endCoord();
|
|
}
|
|
//std::cout << " " << list[col];
|
|
scanLine[col] = mColorMap.at(colorOffset);
|
|
}
|
|
//std::cout << std::endl;
|
|
}
|
|
cacheImageDirty = false;
|
|
}
|
|
}
|
|
double x = hAxis->coordToPixel(hRange.lower, SRC::Render);
|
|
double y = vAxis->coordToPixel(vRange.lower, SRC::Render);
|
|
double w = hAxis->coordToPixel(hRange.upper, SRC::Render) - x;
|
|
double h = vAxis->coordToPixel(vRange.upper, SRC::Render) - y;
|
|
|
|
Range &&hAxisRange = hAxis->coordRange(), &&vAxisRange = vAxis->coordRange();
|
|
double hr = ((hAxisRange.lower < hAxisRange.upper) ^ (hRange.lower < hRange.upper)) ? -1 : 1;
|
|
double vr = ((vAxisRange.lower < vAxisRange.upper) ^ (vRange.lower < vRange.upper)) ? -1 : 1;
|
|
|
|
painter->save();
|
|
painter->scale(hr, vr);
|
|
painter->drawImage(QRectF(hr * x, vr * y, hr * w, vr * h), image);
|
|
painter->restore();
|
|
}
|
|
|
|
void prepareData() override {
|
|
syncStatePipeline();
|
|
AfterglowRenderState* s = renderState();
|
|
if(cacheFrequentPointSize != s->frequentPointSize || cachePowerPointSize != s->powerPointSize) {
|
|
updateCacheSize(s->frequentPointSize, s->powerPointSize);
|
|
}
|
|
AfterglowInputData* input = renderInputData();
|
|
for(const QVector<double>& data : input->mDataList) {
|
|
pushData(data, s);
|
|
}
|
|
clearRenderInput();
|
|
}
|
|
};
|
|
template <typename That>
|
|
void Afterglow::BuilderT<That>::init(FrequentAxis* frequentAxis, Axis* powerAxis) {
|
|
ASSERT(frequentAxis->mPlot != nullptr, "Afterglow build error! frequentAxis->mPlot == nullptr");
|
|
ASSERT(frequentAxis->mPlot == powerAxis->mPlot, "Afterglow build error! frequentAxis->mPlot != powerAxis->mPlot");
|
|
plot = frequentAxis->mPlot;
|
|
static_cast<That*>(this)->frequentAxis = frequentAxis;
|
|
static_cast<That*>(this)->powerAxis = powerAxis;
|
|
}
|
|
template <typename That>
|
|
void Afterglow::BuilderT<That>::set(Afterglow* ret) {
|
|
ret->init(plot, layerName);
|
|
AfterglowPrivate* pd = ret->d();
|
|
AfterglowRenderState* sc = reinterpret_cast<AfterglowRenderState*>(pd->state(State_Edit));
|
|
PROP_RT(FrequentAxis*, frequentAxis)
|
|
PROP_RT(Axis*, powerAxis)
|
|
PROP_RT(Range, frequentRange)
|
|
PROP_RT(Range, powerRange)
|
|
PROP_RT(int, frequentPointSize)
|
|
PROP_RT(int, powerPointSize)
|
|
PROP_RT(int, bufferSize)
|
|
PROP_RT(bool, interpolate)
|
|
PROP_RT(double, attenuationRate)
|
|
PROP_RT(int, initStrongValue)
|
|
}
|
|
|
|
}
|