#1073 Stable coloring of cases and wells in summary

This commit is contained in:
Bjørnar Grip Fjær 2017-04-19 16:38:13 +02:00
parent 66a42074c3
commit f7d72c2f60
5 changed files with 195 additions and 13 deletions

View File

@ -21,6 +21,7 @@
#include "RiaColorTables.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCase.h"
#include "cvfVector3.h"
@ -44,11 +45,14 @@ void caf::AppEnum< RimSummaryCurveAppearanceCalculator::CurveAppearanceType >::s
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCurveAppearanceCalculator::RimSummaryCurveAppearanceCalculator(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefinitions)
RimSummaryCurveAppearanceCalculator::RimSummaryCurveAppearanceCalculator(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefinitions, const std::set<std::string> allSummaryCaseNames, const std::set<std::string> allSummaryWellNames)
{
m_allSummaryCaseNames = allSummaryCaseNames;
m_allSummaryWellNames = allSummaryWellNames;
for(const std::pair<RimSummaryCase*, RifEclipseSummaryAddress>& curveDef : curveDefinitions)
{
if(curveDef.first) m_caseToAppearanceIdxMap[curveDef.first] = -1;
if(curveDef.first) m_caseToAppearanceIdxMap[curveDef.first] = -1;
if(!curveDef.second.wellName().empty()) m_welToAppearanceIdxMap[curveDef.second.wellName()] = -1;
if(!curveDef.second.wellGroupName().empty()) m_grpToAppearanceIdxMap[curveDef.second.wellGroupName()] = -1;
if(!(curveDef.second.regionNumber() == -1)) m_regToAppearanceIdxMap[curveDef.second.regionNumber()] = -1;
@ -106,16 +110,8 @@ RimSummaryCurveAppearanceCalculator::RimSummaryCurveAppearanceCalculator(const s
if (m_dimensionCount == 0) m_varAppearanceType = COLOR; // basically one curve
// Assign increasing indexes
{ int idx = 0; for(auto& pair : m_caseToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_varToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_welToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_grpToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_regToAppearanceIdxMap) pair.second = idx++; }
for (auto& charMapPair : m_secondCharToVarToAppearanceIdxMap)
{ int idx = 0; for(auto& pair : charMapPair.second) pair.second = idx++; }
updateApperanceIndices();
}
//--------------------------------------------------------------------------------------------------
@ -140,6 +136,126 @@ void RimSummaryCurveAppearanceCalculator::assignDimensions( CurveAppearanceType
if(m_wellAppearanceType != NONE) ++m_dimensionCount;
if(m_groupAppearanceType != NONE) ++m_dimensionCount;
if(m_regionAppearanceType != NONE) ++m_dimensionCount;
updateApperanceIndices();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurveAppearanceCalculator::updateApperanceIndices()
{
{
std::map<std::string, size_t> caseAppearanceIndices = mapNameToAppearanceIndex(m_caseAppearanceType, m_allSummaryCaseNames);
int idx = 0;
for (auto& pair : m_caseToAppearanceIdxMap)
{
pair.second = static_cast<int>(caseAppearanceIndices[pair.first->caseName().toUtf8().constData()]);
}
}
{
std::map<std::string, size_t> wellAppearanceIndices = mapNameToAppearanceIndex(m_wellAppearanceType, m_allSummaryWellNames);
int idx = 0;
for (auto& pair : m_welToAppearanceIdxMap)
{
pair.second = static_cast<int>(wellAppearanceIndices[pair.first]);
}
}
// Assign increasing indexes
{ int idx = 0; for(auto& pair : m_varToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_grpToAppearanceIdxMap) pair.second = idx++; }
{ int idx = 0; for(auto& pair : m_regToAppearanceIdxMap) pair.second = idx++; }
for (auto& charMapPair : m_secondCharToVarToAppearanceIdxMap)
{
int idx = 0;
for (auto& pair : charMapPair.second) pair.second = idx++;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<std::string, size_t> RimSummaryCurveAppearanceCalculator::mapNameToAppearanceIndex(CurveAppearanceType& appearance, const std::set<std::string>& names)
{
std::map<std::string, size_t> nameToIndex;
size_t numOptions;
if (appearance == CurveAppearanceType::COLOR)
{
numOptions = RiaColorTables::summaryCurveDefaultPaletteColors().size();
}
else if (appearance == CurveAppearanceType::SYMBOL)
{
numOptions = caf::AppEnum<RimPlotCurve::PointSymbolEnum>::size();
}
else if (appearance == CurveAppearanceType::LINE_STYLE)
{
numOptions = caf::AppEnum<RimPlotCurve::LineStyleEnum>::size();
}
else {
// If none of these styles are used, fall back to a simply incrementing index
size_t idx = 0;
for (const std::string& name : names)
{
nameToIndex[name] = idx;
++idx;
}
return nameToIndex;
}
std::hash<std::string> stringHasher;
std::vector< std::set<std::string> > nameIndices;
for (const std::string& name : names)
{
size_t nameHash = stringHasher(name);
nameHash = nameHash % numOptions;
size_t index = nameHash;
while (true)
{
while (nameIndices.size() <= index)
{
// Ensure there exists a set at the insertion index
nameIndices.push_back(std::set<std::string>());
}
std::set<std::string>& matches = nameIndices[index];
if (matches.empty())
{
// If there are no matches here, the summary case has not been added.
matches.insert(name);
break;
}
else if (matches.find(name) != matches.end())
{
// Check to see if the summary case exists at this index.
break;
}
else
{
// Simply increment index to check if the next bucket is available.
index = (index + 1) % numOptions;
if (index == nameHash)
{
// If we've reached `caseHash` again, no other slot was available, so add it here.
matches.insert(name);
break;
}
}
}
}
size_t index = 0;
for (std::set<std::string>& nameIndex : nameIndices)
{
for (const std::string& name : nameIndex)
{
nameToIndex[name] = index;
}
index++;
}
return nameToIndex;
}
//--------------------------------------------------------------------------------------------------

View File

@ -31,7 +31,7 @@ class RifEclipseSummaryAddress;
class RimSummaryCurveAppearanceCalculator
{
public:
explicit RimSummaryCurveAppearanceCalculator(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefinitions);
explicit RimSummaryCurveAppearanceCalculator(const std::set<std::pair<RimSummaryCase*, RifEclipseSummaryAddress> >& curveDefinitions, const std::set<std::string> allSummaryCaseNames, const std::set<std::string> allSummaryWellNames);
enum CurveAppearanceType
{
NONE,
@ -59,6 +59,8 @@ private:
void setOneCurveAppearance(CurveAppearanceType appeaType, size_t totalCount, int appeaIdx, RimSummaryCurve* curve);
void updateApperanceIndices();
std::map<std::string, size_t> mapNameToAppearanceIndex(CurveAppearanceType & appearance, const std::set<std::string>& names);
cvf::Color3f cycledPaletteColor(int colorIndex);
cvf::Color3f cycledNoneRGBBrColor(int colorIndex);
@ -98,6 +100,9 @@ private:
std::map<char, std::map< std::string, int> > m_secondCharToVarToAppearanceIdxMap;
std::set<std::string> m_allSummaryCaseNames;
std::set<std::string> m_allSummaryWellNames;
};

View File

@ -511,7 +511,7 @@ void RimSummaryCurveFilter::createCurvesFromCurveDefinitions(const std::set<std:
{
RimSummaryCase* prevCase = nullptr;
RimPlotCurve::LineStyleEnum lineStyle = RimPlotCurve::STYLE_SOLID;
RimSummaryCurveAppearanceCalculator curveLookCalc(curveDefinitions);
RimSummaryCurveAppearanceCalculator curveLookCalc(curveDefinitions, getAllSummaryCaseNames(), getAllSummaryWellNames());
if (!m_useAutoAppearanceAssignment())
{
@ -656,3 +656,57 @@ std::set<RifEclipseSummaryAddress> RimSummaryCurveFilter::findPossibleSummaryAdd
return addrUnion;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RimSummaryCurveFilter::getAllSummaryCaseNames()
{
std::set<std::string> summaryCaseHashes;
RimProject* proj = RiaApplication::instance()->project();
std::vector<RimSummaryCase*> cases;
proj->allSummaryCases(cases);
for (RimSummaryCase* rimCase : cases)
{
summaryCaseHashes.insert(rimCase->summaryHeaderFilename().toUtf8().constData());
}
return summaryCaseHashes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RimSummaryCurveFilter::getAllSummaryWellNames()
{
std::set<std::string> summaryWellNames;
RimProject* proj = RiaApplication::instance()->project();
std::vector<RimSummaryCase*> cases;
proj->allSummaryCases(cases);
for (RimSummaryCase* rimCase : cases)
{
RifReaderEclipseSummary* reader = nullptr;
if (rimCase && rimCase->caseData())
{
reader = rimCase->caseData()->summaryReader();
}
if (reader)
{
const std::vector<RifEclipseSummaryAddress> allAddresses = reader->allResultAddresses();
for (size_t i = 0; i < allAddresses.size(); i++)
{
if (allAddresses[i].category() == RifEclipseSummaryAddress::SUMMARY_WELL)
{
summaryWellNames.insert(allAddresses[i].wellName());
}
}
}
}
return summaryWellNames;
}

View File

@ -98,6 +98,9 @@ private:
void updatePlotAxisForCurves();
void loadDataAndUpdatePlot();
std::set<std::string> getAllSummaryCaseNames();
std::set<std::string> getAllSummaryWellNames();
private:
QPointer<QwtPlot> m_parentQwtPlot;
@ -128,5 +131,7 @@ private:
caf::PdmField< AppearanceTypeAppEnum > m_regionAppearanceType;
std::vector< caf::PdmPointer<RimSummaryCase> > m_selectionCache;
std::vector< std::set<RimSummaryCase*> > m_caseIndices;
};

View File

@ -65,6 +65,8 @@ public:
cvf::Color3ubArray color3ubArray() const;
cvf::Color3fArray color3fArray() const;
const size_t size() const { return m_colors.size(); }
static cvf::Color3ub fromQColor(const QColor& color);
static cvf::Color3ubArray interpolateColorArray(const cvf::Color3ubArray& colorArray, size_t targetColorCount);
private: