You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmPebiResultDisplayStateBui...

232 lines
7.7 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmPebiResultDisplayStateBuilder.h"
#include "nmPebiResultPropertyDisplayText.h"
#include "nmPebiResultSnapshot.h"
#include "nmVTKColorMapCatalog.h"
#include <QCoreApplication>
#include <QtGlobal>
#include <vtkLookupTable.h>
#include <vtkMath.h>
#include <math.h>
namespace {
QString displayStateText(const char* pText)
{
// 沿用原 SceneController 翻译上下文,避免迁移既有 TS 条目。
return QCoreApplication::translate(
"nmPebiResultSceneController", pText);
}
bool getInternalDisplayRange(const double dVisibleRange[2],
bool bLogarithmic,
bool bSingleValueMode,
double dInternalRange[2])
{
if(dVisibleRange == nullptr || dInternalRange == nullptr ||
!vtkMath::IsFinite(dVisibleRange[0]) ||
!vtkMath::IsFinite(dVisibleRange[1]) ||
dVisibleRange[0] > dVisibleRange[1] ||
(bLogarithmic && dVisibleRange[0] <= 0.0)) {
return false;
}
if(dVisibleRange[0] < dVisibleRange[1]) {
dInternalRange[0] = dVisibleRange[0];
dInternalRange[1] = dVisibleRange[1];
return true;
}
if(!bSingleValueMode || dVisibleRange[0] != dVisibleRange[1]) {
return false;
}
// VTK要求映射范围严格递增;微量扩展只供内部映射,不改变业务值。
const double dValue = dVisibleRange[0];
double dMaximum = 0.0;
if(bLogarithmic) {
dMaximum = dValue * (1.0 + 1.0e-6);
if(!vtkMath::IsFinite(dMaximum) || dMaximum <= dValue) {
dMaximum = dValue * 2.0;
}
} else {
const double dEpsilon = qMax(1.0, fabs(dValue)) * 1.0e-6;
dMaximum = dValue + dEpsilon;
}
if(!vtkMath::IsFinite(dMaximum) || dValue >= dMaximum ||
(bLogarithmic && dValue <= 0.0)) {
return false;
}
dInternalRange[0] = dValue;
dInternalRange[1] = dMaximum;
return true;
}
bool fillLookupTableWithFirstColor(vtkLookupTable* pLookupTable)
{
if(pLookupTable == nullptr ||
pLookupTable->GetNumberOfTableValues() <= 0) {
return false;
}
double dFirstColor[4] = { 0.0, 0.0, 0.0, 1.0 };
pLookupTable->GetTableValue(0, dFirstColor);
for(int nComponent = 0; nComponent < 4; ++nComponent) {
if(!vtkMath::IsFinite(dFirstColor[nComponent])) {
return false;
}
}
const int nTableValueCount = static_cast<int>(
pLookupTable->GetNumberOfTableValues());
for(int nIndex = 0; nIndex < nTableValueCount; ++nIndex) {
pLookupTable->SetTableValue(nIndex, dFirstColor);
}
return true;
}
}
nmPebiResultDisplayState::nmPebiResultDisplayState()
: m_pLookupTable(nullptr),
m_bSingleValueMode(false)
{
m_dBusinessRange[0] = m_dBusinessRange[1] = 0.0;
m_dVisibleRange[0] = m_dVisibleRange[1] = 0.0;
m_dInternalRange[0] = 0.0;
m_dInternalRange[1] = 1.0;
}
bool nmPebiResultDisplayStateBuilder::build(
const QSharedPointer<const nmPebiResultSnapshot>& pSnapshot,
const QString& sPropertyId,
const nmPebiResultDisplaySettings& oRequestedSettings,
nmPebiResultDisplayState& oState,
QString* pError)
{
if(pError != nullptr) {
pError->clear();
}
nmPebiResultDisplaySettings oSettings =
oRequestedSettings.normalized();
if(pSnapshot.isNull() || !pSnapshot->hasProperty(sPropertyId) ||
!oSettings.isStructurallyValid()) {
if(pError != nullptr) {
*pError = displayStateText("The color settings are invalid.");
}
return false;
}
if(!nmVTKColorMapCatalog::contains(oSettings.m_sColorMapId)) {
if(pError != nullptr) {
*pError = displayStateText(
"The selected color map is unavailable.");
}
return false;
}
double dBusinessRange[2] = { 0.0, 0.0 };
if(!pSnapshot->getPropertyRange(sPropertyId, dBusinessRange) ||
!vtkMath::IsFinite(dBusinessRange[0]) ||
!vtkMath::IsFinite(dBusinessRange[1]) ||
dBusinessRange[0] > dBusinessRange[1]) {
if(pError != nullptr) {
*pError = displayStateText(
"The result property range is invalid.");
}
return false;
}
double dVisibleRange[2] = {
dBusinessRange[0], dBusinessRange[1]
};
if(oSettings.m_bHasManualRange) {
if(!vtkMath::IsFinite(oSettings.m_dManualMinimum) ||
!vtkMath::IsFinite(oSettings.m_dManualMaximum) ||
oSettings.m_dManualMinimum >= oSettings.m_dManualMaximum) {
if(pError != nullptr) {
*pError = displayStateText(
"The manual range must contain two finite increasing values.");
}
return false;
}
dVisibleRange[0] = oSettings.m_dManualMinimum;
dVisibleRange[1] = oSettings.m_dManualMaximum;
}
const bool bSingleValueMode =
!oSettings.m_bHasManualRange &&
dBusinessRange[0] == dBusinessRange[1];
const bool bLogarithmic =
oSettings.m_eScaleMode == NM_PebiColorScale_Logarithmic;
if(bLogarithmic &&
(dBusinessRange[0] <= 0.0 || dVisibleRange[0] <= 0.0)) {
if(pError != nullptr) {
*pError = displayStateText(
"Logarithmic scale requires positive property and display ranges.");
}
return false;
}
double dInternalRange[2] = { 0.0, 1.0 };
vtkSmartPointer<vtkLookupTable> pLookupTable =
nmVTKColorMapCatalog::createLookupTable(
oSettings.m_sColorMapId);
if(pLookupTable == nullptr ||
!getInternalDisplayRange(dVisibleRange, bLogarithmic,
bSingleValueMode, dInternalRange)) {
if(pError != nullptr) {
*pError = displayStateText(
"Unable to construct the color mapping.");
}
return false;
}
pLookupTable->SetTableRange(dInternalRange);
if(bLogarithmic) {
pLookupTable->SetScaleToLog10();
} else {
pLookupTable->SetScaleToLinear();
}
// 单值自动范围固定到色带第0色,特殊越界色随后单独构造。
if(bSingleValueMode &&
!fillLookupTableWithFirstColor(pLookupTable)) {
if(pError != nullptr) {
*pError = displayStateText(
"Unable to construct the color mapping.");
}
return false;
}
const QColor oBelowColor = oSettings.m_oBelowRangeColor;
const QColor oAboveColor = oSettings.m_oAboveRangeColor;
pLookupTable->SetBelowRangeColor(
oBelowColor.redF(), oBelowColor.greenF(),
oBelowColor.blueF(), 1.0);
pLookupTable->SetAboveRangeColor(
oAboveColor.redF(), oAboveColor.greenF(),
oAboveColor.blueF(), 1.0);
pLookupTable->SetUseBelowRangeColor(
oSettings.m_bUseBelowRangeColor ? 1 : 0);
pLookupTable->SetUseAboveRangeColor(
oSettings.m_bUseAboveRangeColor ? 1 : 0);
pLookupTable->BuildSpecialColors();
pLookupTable->IndexedLookupOff();
pLookupTable->ResetAnnotations();
oState.m_oSettings = oSettings;
oState.m_dBusinessRange[0] = dBusinessRange[0];
oState.m_dBusinessRange[1] = dBusinessRange[1];
oState.m_dVisibleRange[0] = dVisibleRange[0];
oState.m_dVisibleRange[1] = dVisibleRange[1];
oState.m_dInternalRange[0] = dInternalRange[0];
oState.m_dInternalRange[1] = dInternalRange[1];
oState.m_pLookupTable = pLookupTable;
oState.m_sScalarBarTitle =
nmPebiResultPropertyDisplayText::getScalarBarTitle(
sPropertyId, bLogarithmic);
oState.m_bSingleValueMode = bSingleValueMode;
return true;
}