Change 18603 on 2012/09/11 by fredrik@fredrik_MBP-BootCamp

Added glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); to get proper orientation of textures on point sprites
This commit is contained in:
CeetronResInsight 2012-09-11 09:22:36 +02:00
parent 2bbd48588e
commit b3c142cc9a
21 changed files with 840 additions and 61 deletions

View File

@ -22,6 +22,7 @@ include_directories(
${CMAKE_BINARY_DIR}/Generated
)
#-----------------------------------------------------------------
# Configuration of ERT depdendence
#-----------------------------------------------------------------
@ -160,7 +161,7 @@ list( APPEND CPP_SOURCES
ProjectDataModel/RimCalcScript.cpp
ProjectDataModel/RimExportInputPropertySettings.cpp
ProjectDataModel/RimBinaryExportSettings.cpp
ProjectDataModel/Rim3dOverlayInfoConfig.cpp
ProjectDataModel/RimUiTreeModelPdm.cpp
ProjectDataModel/RimUiTreeView.cpp
)
@ -182,6 +183,8 @@ list( APPEND CPP_SOURCES
UserInterface/RIPreferencesDialog.cpp
UserInterface/RIResultInfoPanel.cpp
UserInterface/RIViewer.cpp
UserInterface/RiuSimpleHistogramWidget.cpp
UserInterface/RIProcessMonitor.cpp
)
@ -240,6 +243,8 @@ list( REMOVE_ITEM RAW_SOURCES
FileInterface/RifEclipseUnifiedRestartFileAccess.cpp
FileInterface/RifReaderEclipseInput.cpp
FileInterface/RifReaderEclipseOutput.cpp
UserInterface/RiuSimpleHistogramWidget.cpp
)
include( CustomPCH.cmake )

View File

@ -27,9 +27,9 @@ include_directories(
#-----------------------------------------------------------------
# Ert configuration
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/../ThirdParty/Ert" CACHE PATH "Root path for ERT distribution to link with")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/ThirdParty/Ert" CACHE PATH "Root path for ERT distribution to link with")
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/../ThirdParty/Ert-windows" CACHE PATH "Root path for ERT distribution to link with")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/ThirdParty/Ert-windows" CACHE PATH "Root path for ERT distribution to link with")
endif()
set( ERT_ECL_PREFIX "ecl" CACHE STRING "Prefix path to use for ecl code in ert")
set( ERT_UTIL_PREFIX "util" CACHE STRING "Prefix path to use for util code in ert")

View File

@ -98,11 +98,13 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e
mainGrid->nodes().resize(nodeStartIndex + cellCount*8, cvf::Vec3d(0,0,0));
caf::ProgressInfo progInfo(cellCount, "");
int progTicks = 100;
double cellsPrProgressTick = cellCount/(float)progTicks;
caf::ProgressInfo progInfo(progTicks, "");
size_t computedCellCount = 0;
// Loop over cells and fill them with data
#pragma omp parallel for
#pragma omp parallel for
for (int gIdx = 0; gIdx < cellCount; ++gIdx)
{
RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx];
@ -149,8 +151,7 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e
#pragma omp atomic
computedCellCount++;
if (computedCellCount%5000 < 20)
progInfo.setProgress(computedCellCount);
progInfo.setProgress((int)(computedCellCount/cellsPrProgressTick));
}
return true;
}
@ -255,12 +256,13 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid,
mainGrid->cells().reserve(totalCellCount);
mainGrid->nodes().reserve(8*totalCellCount);
caf::ProgressInfo progInfo(1 + numLGRs, "");
caf::ProgressInfo progInfo(3 + numLGRs, "");
progInfo.setProgressDescription("Main Grid");
progInfo.setNextProgressIncrement(3);
transferGridCellData(mainGrid, mainGrid, mainEclGrid, 0);
progInfo.setProgress(1);
progInfo.setProgress(3);
size_t globalActiveSize = ecl_grid_get_active_size(mainEclGrid);
@ -271,7 +273,7 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid,
ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx);
transferGridCellData(mainGrid, static_cast<RigLocalGrid*>(mainGrid->gridByIndex(lgrIdx+1)), localEclGrid, globalActiveSize);
globalActiveSize += ecl_grid_get_active_size(localEclGrid);
progInfo.setProgress(1 + lgrIdx);
progInfo.setProgress(3 + lgrIdx);
}
#endif
@ -286,7 +288,7 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid,
bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservoir)
{
CVF_ASSERT(reservoir);
caf::ProgressInfo progInfo(4, "");
caf::ProgressInfo progInfo(10, "");
progInfo.setProgressDescription("Reading Grid");
@ -306,13 +308,15 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo
ecl_grid_type * mainEclGrid = ecl_grid_alloc( fileName.toAscii().data() );
progInfo.setProgress(1);
progInfo.setNextProgressIncrement(6);
progInfo.setProgressDescription("Transferring grid geometry");
if (!transferGeometry(mainEclGrid, reservoir)) return false;
progInfo.setProgress(7);
progInfo.setProgressDescription("Releasing reader memory");
ecl_grid_free( mainEclGrid );
progInfo.setProgress(2);
progInfo.setProgress(8);
progInfo.setProgressDescription("Reading Result index");
#endif
@ -320,7 +324,7 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo
// Build results meta data
if (!buildMetaData(reservoir)) return false;
progInfo.setProgress(3);
progInfo.setProgress(9);
progInfo.setProgressDescription("Reading Well information");
readWellCells(reservoir);

View File

@ -0,0 +1,154 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RIStdInclude.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimReservoirView.h"
#include "RIViewer.h"
#include "RimReservoir.h"
#include "RigReservoir.h"
#include "RigMainGrid.h"
#include "RigReservoirCellResults.h"
CAF_PDM_SOURCE_INIT(Rim3dOverlayInfoConfig, "3dOverlayInfoConfig");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dOverlayInfoConfig::Rim3dOverlayInfoConfig()
{
CAF_PDM_InitObject("Overlay 3D info", ":/Legend.png", "", "");
CAF_PDM_InitField(&showInfoText, "ShowInfoText", true, "Info Text", "", "", "");
CAF_PDM_InitField(&showAnimProgress, "ShowAnimProgress", true, "Animation progress", "", "", "");
CAF_PDM_InitField(&showHistogram, "ShowHistogram", true, "Histogram", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dOverlayInfoConfig::~Rim3dOverlayInfoConfig()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dOverlayInfoConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
this->update3DInfo();
m_reservoirView->viewer()->update();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dOverlayInfoConfig::setPosition(cvf::Vec2ui position)
{
m_position = position;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dOverlayInfoConfig::update3DInfo()
{
if (!m_reservoirView && m_reservoirView->viewer()) return;
m_reservoirView->viewer()->showInfoText(showInfoText());
m_reservoirView->viewer()->showHistogram(false);
m_reservoirView->viewer()->showAnimationProgress(showAnimProgress());
if (showInfoText())
{
QString caseName;
QString totCellCount;
QString activeCellCount;
QString iSize, jSize, kSize;
QString propName;
QString cellEdgeName;
if (m_reservoirView->eclipseCase())
{
caseName = m_reservoirView->eclipseCase()->caseName();
totCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cells().size());
activeCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->numActiveCells());
iSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountI());
jSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountJ());
kSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountK());
propName = m_reservoirView->cellResult()->resultVariable();
cellEdgeName = m_reservoirView->cellEdgeResult()->resultVariable();
}
QString infoText = QString(
"<p><b><center>-- %1 --</center></b><p> "
"<b>Cell count:</b> Total: %2 Active: %3 <br>"
"<b>Main Grid I,J,K:</b> %4, %5, %6 <br>").arg(caseName, totCellCount, activeCellCount, iSize, jSize, kSize);
if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult())
{
infoText += QString("<b>Cell Property:</b> %1 ").arg(propName);
double min, max;
double p10, p90;
size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex();
m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max);
m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90);
infoText += QString("<blockquote> Min: %1 P10: %2 P90: %3 Max: %4 </blockquote>").arg(min).arg(p10).arg(p90).arg(max);
}
if (m_reservoirView->animationMode() && m_reservoirView->cellEdgeResult()->hasResult())
{
double min, max;
m_reservoirView->cellEdgeResult()->minMaxCellEdgeValues(min, max);
infoText += QString("<b>Cell Edge Property:</b> %1 <blockquote>Min: %2 Max: %3 </blockquote>").arg(cellEdgeName).arg(min).arg(max);
}
if ( m_reservoirView->cellResult()->hasDynamicResult()
|| m_reservoirView->propertyFilterCollection()->hasActiveDynamicFilters()
|| m_reservoirView->wellCollection()->hasVisibleWellPipes())
{
int currentTimeStep = m_reservoirView->currentTimeStep();
QDateTime date = m_reservoirView->gridCellResults()->timeStepDate(0, currentTimeStep);
infoText += QString("<b>Time Step:</b> %1 <b>Time:</b> %2").arg(currentTimeStep).arg(date.toString("dd.MMM yyyy"));
}
m_reservoirView->viewer()->setInfoText(infoText);
}
if (showHistogram())
{
if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult())
{
double min, max;
double p10, p90;
size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex();
m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max);
m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90);
m_reservoirView->viewer()->showHistogram(true);
m_reservoirView->viewer()->setHistogram(min, max, m_reservoirView->gridCellResults()->cellScalarValuesHistogram(scalarIndex));
m_reservoirView->viewer()->setHistogramPercentiles(p10, p90);
}
}
}

View File

@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cafPdmField.h"
#include "cafAppEnum.h"
class RimReservoirView;
//==================================================================================================
///
///
//==================================================================================================
class Rim3dOverlayInfoConfig: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Rim3dOverlayInfoConfig();
virtual ~Rim3dOverlayInfoConfig();
void update3DInfo();
void setReservoirView(RimReservoirView* ownerReservoirView) {m_reservoirView = ownerReservoirView; }
void setPosition(cvf::Vec2ui position);
caf::PdmField<bool> showInfoText;
caf::PdmField<bool> showAnimProgress;
caf::PdmField<bool> showHistogram;
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
private:
caf::PdmPointer<RimReservoirView> m_reservoirView;
cvf::Vec2ui m_position;
};

View File

@ -294,3 +294,36 @@ void RimCellEdgeResultSlot::updateIgnoredScalarValue()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellEdgeResultSlot::minMaxCellEdgeValues(double& min, double& max)
{
CVF_ASSERT(min && max);
double globalMin, globalMax;
globalMin = HUGE_VAL;
globalMax = -HUGE_VAL;
size_t resultIndices[6];
this->gridScalarIndices(resultIndices);
size_t idx;
for (idx = 0; idx < 6; idx++)
{
if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue;
{
double cMin, cMax;
m_reservoirView->gridCellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax);
globalMin = CVF_MIN(globalMin, cMin);
globalMax = CVF_MAX(globalMax, cMax);
}
}
min = globalMin;
max = globalMax;
}

View File

@ -68,6 +68,7 @@ public:
void loadResult();
bool hasResult() const;
void minMaxCellEdgeValues(double& min, double& max);
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);

View File

@ -42,6 +42,7 @@
#include "cafCadNavigation.h"
#include "cafCeetronNavigation.h"
#include "RimReservoir.h"
#include "Rim3dOverlayInfoConfig.h"
namespace caf {
@ -87,6 +88,10 @@ RimReservoirView::RimReservoirView()
CAF_PDM_InitFieldNoDefault(&cellEdgeResult, "GridCellEdgeResult", "Cell Edge Result", ":/EdgeResult_1.png", "", "");
cellEdgeResult = new RimCellEdgeResultSlot();
CAF_PDM_InitFieldNoDefault(&overlayInfoConfig, "OverlayInfoConfig", "Overlay Info", "", "", "");
overlayInfoConfig = new Rim3dOverlayInfoConfig();
overlayInfoConfig->setReservoirView(this);
CAF_PDM_InitField(&name, "UserDescription", QString(""), "Name", "", "", "");
CAF_PDM_InitField(&scaleZ, "GridZScale", 1.0, "Z Scale", "", "Scales the scene in the Z direction", "");
CAF_PDM_InitField(&showWindow, "ShowWindow", true, "Show 3D viewer", "", "", "");
@ -144,6 +149,8 @@ RimReservoirView::~RimReservoirView()
{
delete this->cellResult();
delete this->cellEdgeResult();
delete this->overlayInfoConfig();
delete rangeFilterCollection();
delete propertyFilterCollection();
@ -645,6 +652,7 @@ void RimReservoirView::updateCurrentTimeStep()
}
}
overlayInfoConfig()->update3DInfo();
updateLegends();
}
@ -691,6 +699,7 @@ void RimReservoirView::loadDataAndUpdate()
createDisplayModel();
updateDisplayModelVisibility();
setDefaultView();
overlayInfoConfig()->update3DInfo();
if (animationMode && m_viewer)
{
@ -1018,31 +1027,8 @@ void RimReservoirView::updateLegends()
if (this->cellEdgeResult()->hasResult())
{
double localMin, localMax;
localMin = HUGE_VAL;
localMax = -HUGE_VAL;
double globalMin, globalMax;
globalMin = HUGE_VAL;
globalMax = -HUGE_VAL;
size_t resultIndices[6];
this->cellEdgeResult()->gridScalarIndices(resultIndices);
size_t idx;
for (idx = 0; idx < 6; idx++)
{
if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue;
{
double min, max;
results->minMaxCellScalarValues(resultIndices[idx], min, max);
globalMin = CVF_MIN(globalMin, min);
globalMax = CVF_MAX(globalMax, max);
}
}
this->cellEdgeResult()->minMaxCellEdgeValues(globalMin, globalMax);
this->cellEdgeResult()->legendConfig->setAutomaticRanges(globalMin, globalMax, globalMin, globalMax);
m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend());
this->cellEdgeResult()->legendConfig->legend()->setTitle(cvfqt::Utils::fromQString(QString("Edge Results: \n") + this->cellEdgeResult()->resultVariable));

View File

@ -30,6 +30,7 @@
#include "RimCellRangeFilterCollection.h"
#include "RimCellPropertyFilter.h"
#include "RimCellPropertyFilterCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "cvfMatrix4.h"
#include "cvfStructGridGeometryGenerator.h"
@ -86,6 +87,7 @@ public:
caf::PdmField<RimResultSlot*> cellResult;
caf::PdmField<RimCellEdgeResultSlot*> cellEdgeResult;
caf::PdmField<Rim3dOverlayInfoConfig*> overlayInfoConfig;
caf::PdmField<double> scaleZ;
caf::PdmField<bool> showWindow;

View File

@ -44,9 +44,10 @@ RimResultReservoir::RimResultReservoir()
//--------------------------------------------------------------------------------------------------
bool RimResultReservoir::openEclipseGridFile()
{
caf::ProgressInfo progInfo(2, "Reading Eclipse Grid File");
caf::ProgressInfo progInfo(20, "Reading Eclipse Grid File");
progInfo.setProgressDescription("Open Grid File");
progInfo.setNextProgressIncrement(19);
// Early exit if reservoir data is created
if (m_rigReservoir.notNull()) return true;
@ -83,7 +84,7 @@ bool RimResultReservoir::openEclipseGridFile()
m_rigReservoir = reservoir;
}
progInfo.setProgress(1);
progInfo.setProgress(19);
CVF_ASSERT(m_rigReservoir.notNull());
CVF_ASSERT(readerInterface.notNull());

View File

@ -121,6 +121,57 @@ void RigReservoirCellResults::minMaxCellScalarValues(size_t scalarResultIndex, s
m_maxMinValuesPrTs[scalarResultIndex][timeStepIndex].second= max;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<size_t>& RigReservoirCellResults::cellScalarValuesHistogram(size_t scalarResultIndex)
{
CVF_ASSERT(scalarResultIndex < resultCount());
// Extend array and cache vars
if (scalarResultIndex >= m_histograms.size() )
{
m_histograms.resize(resultCount());
m_p10p90.resize(resultCount(), std::make_pair(HUGE_VAL, HUGE_VAL));
}
if (m_histograms[scalarResultIndex].size())
{
return m_histograms[scalarResultIndex];
}
double min;
double max;
size_t nBins = 100;
this->minMaxCellScalarValues( scalarResultIndex, min, max );
RigHistogramCalculator histCalc(min, max, nBins, &m_histograms[scalarResultIndex]);
for (size_t tsIdx = 0; tsIdx < this->timeStepCount(scalarResultIndex); tsIdx++)
{
std::vector<double>& values = m_cellScalarResults[scalarResultIndex][tsIdx];
histCalc.addData(values);
}
m_p10p90[scalarResultIndex].first = histCalc.calculatePercentil(0.1);
m_p10p90[scalarResultIndex].second = histCalc.calculatePercentil(0.9);
return m_histograms[scalarResultIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigReservoirCellResults::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90)
{
const std::vector<size_t>& histogr = cellScalarValuesHistogram( scalarResultIndex);
p10 = m_p10p90[scalarResultIndex].first;
p90 = m_p10p90[scalarResultIndex].second;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -417,6 +468,17 @@ bool RigReservoirCellResults::isUsingGlobalActiveIndex(size_t scalarResultIndex)
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QDateTime RigReservoirCellResults::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const
{
if (scalarResultIndex < m_resultInfos.size() && (size_t)(m_resultInfos[scalarResultIndex].m_timeStepDates.size()) > timeStepIndex)
return m_resultInfos[scalarResultIndex].m_timeStepDates[timeStepIndex];
else
return QDateTime();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -496,4 +558,3 @@ void RigReservoirCellResults::clearAllResults()
m_cellScalarResults[i].clear();
}
}

View File

@ -21,6 +21,7 @@
#include "RimDefines.h"
#include <QDateTime>
#include <vector>
#include <cmath>
class RifReaderInterface;
class RigMainGrid;
@ -39,6 +40,8 @@ public:
void recalculateMinMax(size_t scalarResultIndex);
void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max);
void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max);
const std::vector<size_t>& cellScalarValuesHistogram(size_t scalarResultIndex);
void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90);
// Access meta-information about the results
size_t resultCount() const;
@ -46,6 +49,8 @@ public:
size_t maxTimeStepCount() const;
QStringList resultNames(RimDefines::ResultCatType type) const;
bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const;
QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const;
QList<QDateTime> timeStepDates(size_t scalarResultIndex) const;
void setTimeStepDates(size_t scalarResultIndex, const QList<QDateTime>& dates);
@ -69,6 +74,9 @@ public:
private:
std::vector< std::vector< std::vector<double> > > m_cellScalarResults; ///< Scalar results for each timestep for each Result index (ResultVariable)
std::vector< std::pair<double, double> > m_maxMinValues; ///< Max min values for each Result index
std::vector< std::vector<size_t> > m_histograms; ///< Histogram for each Result Index
std::vector< std::pair<double, double> > m_p10p90; ///< P10 and p90 values for each Result Index
std::vector< std::vector< std::pair<double, double> > > m_maxMinValuesPrTs; ///< Max min values for each timestep and Result index
class ResultInfo
@ -90,3 +98,80 @@ private:
};
class RigHistogramCalculator
{
public:
RigHistogramCalculator(double min, double max, size_t nBins, std::vector<size_t>* histogram)
{
CVF_ASSERT(histogram);
CVF_ASSERT(nBins > 0);
if (max == min) { nBins = 1; } // Avoid dividing on 0 range
m_histogram = histogram;
m_min = min;
m_observationCount = 0;
// Initialize bins
m_histogram->resize(nBins);
for (size_t i = 0; i < m_histogram->size(); ++i) (*m_histogram)[i] = 0;
m_range = max - min;
maxIndex = nBins-1;
}
void addData(const std::vector<double>& data)
{
CVF_ASSERT(m_histogram);
for (size_t i = 0; i < data.size(); ++i)
{
size_t index = 0;
if (maxIndex > 0) index = (size_t)(maxIndex*(data[i] - m_min)/m_range);
if(index < m_histogram->size()) // Just clip to the max min range (-index will overflow to positive )
{
(*m_histogram)[index]++;
m_observationCount++;
}
}
}
/// Calculates the estimated percentile from the histogram.
/// the percentile is the domain value at which pVal of the observations are below it.
/// Will only consider observed values between min and max, as all other values are discarded from the histogram
double calculatePercentil(double pVal)
{
CVF_ASSERT(m_histogram);
CVF_ASSERT(m_histogram->size());
CVF_ASSERT( 0.0 <= pVal && pVal <= 1.0);
double pValObservationCount = pVal*m_observationCount;
if (pValObservationCount == 0.0) return m_min;
size_t accObsCount = 0;
double binWidth = m_range/m_histogram->size();
for (size_t binIdx = 0; binIdx < m_histogram->size(); ++binIdx)
{
size_t binObsCount = (*m_histogram)[binIdx];
accObsCount += binObsCount;
if (accObsCount >= pValObservationCount)
{
double domainValueAtEndOfBin = m_min + (binIdx+1) * binWidth;
double unusedFractionOfLastBin = (double)(accObsCount - pValObservationCount)/binObsCount;
return domainValueAtEndOfBin - unusedFractionOfLastBin*binWidth;
}
}
CVF_ASSERT(false);
return HUGE_VAL;
}
private:
size_t maxIndex;
double m_range;
double m_min;
size_t m_observationCount;
std::vector<size_t>* m_histogram;
};

View File

@ -34,6 +34,8 @@
#include "cafFrameAnimationControl.h"
#include "cafNavigationPolicy.h"
#include "cafEffectGenerator.h"
#include "RiuSimpleHistogramWidget.h"
using cvf::ManipulatorTrackball;
@ -61,6 +63,47 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent)
m_mainRendering->addOverlayItem(axisCross, cvf::OverlayItem::BOTTOM_LEFT, cvf::OverlayItem::VERTICAL);
setReleaseOGLResourcesEachFrame(true);
QColor c;
QPalette p = QApplication::palette();
QColor frameAndTextColor(255, 255, 255, 200);
p.setColor(QPalette::Window, QColor(144, 173, 208, 180));
p.setColor(QPalette::WindowText, frameAndTextColor);
c = p.color(QPalette::Base );
c.setAlpha(100);
p.setColor(QPalette::Base, c);
//c = p.color(QPalette::AlternateBase );
//c.setAlpha(0);
//p.setColor(QPalette::AlternateBase, c);
p.setColor(QPalette::Highlight, QColor(20, 20, 130, 100));
p.setColor(QPalette::HighlightedText, frameAndTextColor);
p.setColor(QPalette::Dark, QColor(230, 250, 255, 100));
// Info Text
m_InfoLabel = new QLabel();
m_InfoLabel->setPalette(p);
m_InfoLabel->setFrameShape(QFrame::Box);
m_showInfoText = true;
// Animation progress bar
m_animationProgress = new QProgressBar();
m_animationProgress->setPalette(p);
m_animationProgress->setFormat("Time Step: %v/%m");
m_animationProgress->setTextVisible(true);
m_animationProgress->setStyle(new QCDEStyle());
m_showAnimProgress = false;
// Histogram
m_histogramWidget = new RiuSimpleHistogramWidget();
m_histogramWidget->setPalette(p);
m_showHistogram = false;
}
@ -356,3 +399,95 @@ cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, c
return NULL;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::paintOverlayItems(QPainter* painter)
{
int columnWidth = 200;
int margin = 5;
int yPos = margin;
bool showAnimBar = false;
if (isAnimationActive() && frameCount() > 1) showAnimBar = true;
//if (showAnimBar) columnWidth = CVF_MAX(columnWidth, m_animationProgress->width());
if (m_showInfoText) columnWidth = CVF_MAX(columnWidth, m_InfoLabel->sizeHint().width());
int columnPos = this->width() - columnWidth - margin;
if (showAnimBar && m_showAnimProgress)
{
m_animationProgress->setMinimum(0);
m_animationProgress->setMaximum(frameCount() - 1);
m_animationProgress->setValue(currentFrameIndex());
m_animationProgress->resize(columnWidth, m_animationProgress->sizeHint().height());
m_animationProgress->render(painter,QPoint(columnPos, yPos));
yPos += m_animationProgress->height() + margin;
}
if (m_showInfoText)
{
m_InfoLabel->resize(columnWidth, m_InfoLabel->sizeHint().height());
m_InfoLabel->render(painter, QPoint(columnPos, yPos));
yPos += m_InfoLabel->height() + margin;
}
if (m_showHistogram)
{
m_histogramWidget->resize(columnWidth, 40);
m_histogramWidget->render(painter,QPoint(columnPos, yPos));
yPos += m_InfoLabel->height() + margin;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::setInfoText(QString text)
{
m_InfoLabel->setText(text);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::showInfoText(bool enable)
{
m_showInfoText = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::setHistogram(double min, double max, const std::vector<size_t>& histogram)
{
m_histogramWidget->setHistogramData(min, max, histogram);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::setHistogramPercentiles(double pmin, double pmax)
{
m_histogramWidget->setPercentiles(pmin, pmax);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::showAnimationProgress(bool enable)
{
m_showAnimProgress = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::showHistogram(bool enable)
{
m_showHistogram = enable;
}

View File

@ -26,6 +26,9 @@
#include "cafMouseState.h"
class RimReservoirView;
class QLabel;
class QProgressBar;
class RiuSimpleHistogramWidget;
namespace cvf
{
@ -52,12 +55,21 @@ public:
void setPointOfInterest(cvf::Vec3d poi);
void setOwnerReservoirView(RimReservoirView * owner);
void setEnableMask(unsigned int mask);
void showInfoText(bool enable);
void setInfoText(QString text);
void showHistogram(bool enable);
void setHistogram(double min, double max, const std::vector<size_t>& histogram);
void setHistogramPercentiles(double pmin, double pmax);
void showAnimationProgress(bool enable);
public slots:
virtual void slotSetCurrentFrame(int frameIndex);
virtual void slotEndAnimation();
protected:
void paintOverlayItems(QPainter* painter);
void keyPressEvent(QKeyEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
@ -68,6 +80,16 @@ private:
void updateLegends();
caf::QtMouseState m_mouseState;
QLabel* m_InfoLabel;
bool m_showInfoText;;
QProgressBar* m_animationProgress;
bool m_showAnimProgress;
RiuSimpleHistogramWidget* m_histogramWidget;
bool m_showHistogram;
cvf::ref<cvf::OverlayColorLegend> m_legend1;
cvf::ref<cvf::OverlayColorLegend> m_legend2;

View File

@ -0,0 +1,97 @@
#include "RiuSimpleHistogramWidget.h"
#include <QPainter>
#include <cmath>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSimpleHistogramWidget::RiuSimpleHistogramWidget(QWidget * parent /*= 0*/, Qt::WindowFlags f /*= 0*/):
QWidget(parent, f)
{
m_minPercentile = HUGE_VAL;
m_maxPercentile = HUGE_VAL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSimpleHistogramWidget::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
this->draw(&painter, 0, 0, this->width()-1, this->height()-1);
}
void RiuSimpleHistogramWidget::draw(QPainter *painter,int x, int y, int width, int height )
{
// Initialize variables
m_x = x; m_y = y; m_width = width; m_height = height;
QRect r1(x,y,width, height);
// Frame around it all;
QColor windowColor = palette().color(QPalette::Window);// QColor(144, 173, 208, 180);
QColor frameColor = palette().color(QPalette::WindowText);//QColor(220, 240, 255, 100);
QColor foregroundColor = palette().color(QPalette::Dark);// QColor(100, 141, 189);
//painter->fillRect(r1, windowColor);
painter->setPen(frameColor);
painter->drawRect(r1);
// Columns
painter->setPen(foregroundColor);
int yColBottom = yPosFromCount(0);
for ( size_t colIdx = 0; colIdx < m_histogramData.size(); ++colIdx)
{
size_t colCount = m_histogramData[colIdx];
int yColTop = yPosFromCount(colCount);
int xColStart = xPosFromColIdx(colIdx);
int xColEnd = xPosFromColIdx(colIdx+1);
// First line
painter->drawLine(xColStart, yColBottom, xColStart, yColTop);
// If we span more than one pixel with :
++xColStart;
for (;xColStart < xColEnd; ++xColStart )
{
painter->drawLine(xColStart, yColBottom, xColStart, yColTop);
}
}
// Vertical lines for percentiles
if (m_minPercentile != HUGE_VAL)
{
int xpos = xPosFromDomainValue(m_minPercentile);
painter->setPen(QColor(255, 0, 0, 200));
painter->drawLine(xpos, y+1, xpos, y + height -1);
}
// Vertical lines for percentiles
if (m_maxPercentile != HUGE_VAL)
{
int xpos = xPosFromDomainValue(m_maxPercentile);
painter->setPen(QColor(255, 0, 0, 200));
painter->drawLine(xpos, y+1, xpos, y + height -1);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSimpleHistogramWidget::setHistogramData(double min, double max, const std::vector<size_t>& histogram)
{
m_min = min;
m_max = max;
m_histogramData = histogram;
m_maxHistogramCount = 0;
for (size_t colIdx = 0; colIdx < m_histogramData.size(); ++colIdx)
{
if (m_maxHistogramCount < m_histogramData[colIdx]) m_maxHistogramCount = m_histogramData[colIdx] ;
}
}

View File

@ -0,0 +1,37 @@
#include <QWidget>
class QPaintEvent;
class QString;
class QStringList;
class RiuSimpleHistogramWidget : public QWidget
{
public:
RiuSimpleHistogramWidget( QWidget * parent = 0, Qt::WindowFlags f = 0);
void setHistogramData(double min, double max, const std::vector<size_t>& histogram);
void setPercentiles(double pmin, double pmax) {m_minPercentile = pmin; m_maxPercentile = pmax;}
protected:
virtual void paintEvent(QPaintEvent* event);
private:
void draw(QPainter *painter,int x, int y, int width, int height );
int xPosFromColIdx(size_t colIdx) { return (int)(m_x + 1 + (m_width - 2 ) * colIdx/m_histogramData.size());}
int yPosFromCount(size_t colHeight) { return (int)(m_y + m_height - 1 - (m_height - 3 ) * colHeight/m_maxHistogramCount);}
int xPosFromDomainValue(double value) { double range = m_max - m_min; return (range == 0.0) ? (m_x + 1) : (int)(m_x + 1 + (m_width - 2 ) * (value - m_min)/(m_max - m_min));}
std::vector<size_t> m_histogramData;
double m_max;
double m_min;
double m_minPercentile;
double m_maxPercentile;
size_t m_maxHistogramCount;
double m_width;
double m_height;
double m_x;
double m_y;
};

View File

@ -34,13 +34,14 @@ ENDIF()
set(CMAKE_MAJOR_VERSION 0)
set(CMAKE_MINOR_VERSION 8)
set(CMAKE_PATCH_VERSION 6)
set(CMAKE_PATCH_VERSION 7)
set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION})
set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION})
################################################################################
# Qt
################################################################################

View File

@ -29,9 +29,25 @@ namespace caf {
//==================================================================================================
///
/// \class caf::ProgressInfo
/// This class provides a simple frontend to the Qt progressbar, allowing distributed
/// progress calculation.
///
/// Create an instance of this object in the method/function that needs progress information
/// Then call incrementProgress() or setProgress() at proper times in your method.
/// When the method returns, the ProgressInfo destructor will clean up and finish.
/// The real beauty is that this class will magically interact with possible ProgressInfo instances
/// instantiated in function your method calls, providing a complete, consistent and detailed progress bar
///
///
/// caf::ProgressInfo progInfo(3, "Open File");
/// progInfo.setProgressDescription("Reading");
/// ...readFile()
/// progInfo.incrementProgress();
/// progInfo.setProgressDescription("Validating");
/// ... validateData();
/// progInfo.incrementProgress();
/// progInfo.setProgressDescription("Building geometry");
/// ... buildGeometry();
/// progInfo.incrementProgress(); // not needed really, caus destructor will send progress to top.
//==================================================================================================
//--------------------------------------------------------------------------------------------------
@ -51,7 +67,8 @@ ProgressInfo::~ProgressInfo()
}
//--------------------------------------------------------------------------------------------------
///
/// Sets a description of the step currently being executed.
/// Used to create a nice text in the progressDialog
//--------------------------------------------------------------------------------------------------
void ProgressInfo::setProgressDescription(const QString& description)
{
@ -66,6 +83,31 @@ void ProgressInfo::setProgress(int progressValue)
ProgressInfoStatic::setProgress(progressValue);
}
//--------------------------------------------------------------------------------------------------
/// Increments progress by 1, or by the amount set by setNextProgressStepSize
//--------------------------------------------------------------------------------------------------
void ProgressInfo::incrementProgress()
{
ProgressInfoStatic::incrementProgress();
}
//--------------------------------------------------------------------------------------------------
/// To make a certain operation span more of the progress bar than one tick,
/// set the number of progress ticks that you want it to use before calling it.
/// Eg.
/// caf::ProgressInfo progInfo(5, "Doing things");
/// // ... Do one small thing
/// progInfo.incrementProgress();
/// progInfo.setNextProgressStepSize(3);
/// // ... Some heavy function call with its own progress handling
/// progInfo.incrementProgress();
///
//--------------------------------------------------------------------------------------------------
void ProgressInfo::setNextProgressIncrement(int nextStepSize)
{
ProgressInfoStatic::setNextProgressIncrement(nextStepSize);
}
@ -97,7 +139,7 @@ static QProgressDialog* progressDialog()
}
//--------------------------------------------------------------------------------------------------
/// A static vector containing the maximum values for the progress on each sublevel
/// A static vector containing the maximum values for the progress on each sublevel (call stack level)
//--------------------------------------------------------------------------------------------------
static std::vector<int>& maxProgressStack()
{
@ -127,7 +169,7 @@ static std::vector<QString>& descriptionStack()
}
//--------------------------------------------------------------------------------------------------
///
/// The actual progress value on each level (call stack level) 0 corresponds to the outermost function
//--------------------------------------------------------------------------------------------------
static std::vector<int>& progressStack()
{
@ -136,6 +178,18 @@ static std::vector<int>& progressStack()
return m_progressStack;
}
//--------------------------------------------------------------------------------------------------
/// The number of progress ticks (span) on each callstack level that the level deeper (in callstack) shall fill
/// used to balance the progress, making some (heavy) operations span more of the progress bar
//--------------------------------------------------------------------------------------------------
static std::vector<int>& progressSpanStack()
{
static std::vector<int> m_progressSpanStack;
return m_progressSpanStack;
}
//--------------------------------------------------------------------------------------------------
/// Calculate the total number of progress values we would need if we only look at the levels from
/// \a levelDepth and below (increasing subdivision)
@ -158,7 +212,8 @@ static int currentTotalProgress()
int progress = 0;
for (size_t i = 0; i < progressStack().size(); ++i)
{
progress = progress + progressStack()[i]* subLevelsMaxProgressValue(i+1);
int span = (i < 1) ? 1 : progressSpanStack()[i-1];
progress = progress + span*progressStack()[i]* subLevelsMaxProgressValue(i+1);
}
return progress;
}
@ -185,8 +240,9 @@ static QString currentComposedLabel()
if (!descriptionStack()[i].isEmpty()) labelText += descriptionStack()[i] ;
if (!(titleStack()[i].isEmpty() && descriptionStack()[i].isEmpty())) labelText += "\n";
}
return labelText;
labelText += "\n ";
return labelText;
}
static bool isWrongThread()
@ -220,6 +276,7 @@ void ProgressInfoStatic::start(int maxProgressValue, const QString& title)
maxProgressStack().push_back(maxProgressValue);
progressStack().push_back(0);
progressSpanStack().push_back(1);
titleStack().push_back(title);
descriptionStack().push_back("");
@ -250,12 +307,14 @@ void ProgressInfoStatic::setProgressDescription(const QString& description)
void ProgressInfoStatic::setProgress(int progressValue)
{
if (isWrongThread()) return;
if (progressValue == progressStack().back()) return; // Do nothing if no progress.
// Guard against the max value set for theis level
if (progressValue < 0 ) progressValue = 0;
if (progressValue > maxProgressStack().back() ) progressValue = maxProgressStack().back();
progressStack().back() = progressValue;
progressSpanStack().back() = 1;
assert(currentTotalProgress() <= progressDialog()->maximum());
int totProg = currentTotalProgress();
@ -265,6 +324,27 @@ void ProgressInfoStatic::setProgress(int progressValue)
QCoreApplication::processEvents();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ProgressInfoStatic::incrementProgress()
{
assert(progressStack().size());
ProgressInfoStatic::setProgress(progressStack().back() += progressSpanStack().back());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ProgressInfoStatic::setNextProgressIncrement(int nextStepSize)
{
assert(progressSpanStack().size());
progressSpanStack().back() = nextStepSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -272,16 +352,16 @@ void ProgressInfoStatic::finished()
{
if (isWrongThread()) return;
assert(maxProgressStack().size() && progressStack().size() && titleStack().size() && descriptionStack().size());
assert(maxProgressStack().size() && progressStack().size() && progressSpanStack().size() && titleStack().size() && descriptionStack().size());
// Set progress to max value, and leave it there until somebody touches the progress again
progressStack().back() = maxProgressStack().back();
progressDialog()->setValue(currentTotalProgress());
ProgressInfoStatic::setProgress(maxProgressStack().back());
// Pop all the stacks
maxProgressStack().pop_back();
progressStack().pop_back();
progressSpanStack().pop_back();
titleStack().pop_back();
descriptionStack().pop_back();
@ -303,6 +383,4 @@ void ProgressInfoStatic::finished()
}
} // namespace caf

View File

@ -31,6 +31,9 @@ public:
~ProgressInfo();
void setProgressDescription(const QString& description);
void setProgress(int progressValue);
void incrementProgress();
void setNextProgressIncrement(int nextStepSize);
};
@ -41,6 +44,8 @@ public:
static void setProgressDescription(const QString& description);
static void setProgress(int progressValue);
static void incrementProgress();
static void setNextProgressIncrement(int nextStepSize);
static void finished();
};

View File

@ -414,6 +414,9 @@ void caf::Viewer::paintEvent(QPaintEvent* event)
painter.endNativePainting();
#endif
// Call virtual method to allow subclasses to paint on the OpenGlCanvas
this->paintOverlayItems(&painter);
if (m_showPerfInfoHud && isShadersSupported())
{
cvfqt::PerformanceInfoHud hud;
@ -664,3 +667,12 @@ void caf::Viewer::enableForcedImmediateMode(bool enable)
m_mainRendering->renderEngine()->enableForcedImmediateMode(enable);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::Viewer::currentFrameIndex()
{
if (m_animationControl) return m_animationControl->currentFrame();
else return 0;
}

View File

@ -112,8 +112,18 @@ public:
public slots:
virtual void slotSetCurrentFrame(int frameIndex);
virtual void slotEndAnimation();
int currentFrameIndex();
protected:
// Method to override if painting directly on the OpenGl Canvas is needed.
virtual void paintOverlayItems(QPainter* painter) {};
// Overridable methods to setup the render system
virtual void setupMainRendering();
virtual void setupRenderingSequence();
virtual void optimizeClippingPlanes();
// Standard overrides. Not for overriding
virtual void resizeGL(int width, int height);
virtual void paintEvent(QPaintEvent* event);
@ -123,13 +133,6 @@ protected:
m_navigationPolicy;
bool m_navigationPolicyEnabled;
// Overridable methods to setup the render system
virtual void setupMainRendering();
virtual void setupRenderingSequence();
virtual void optimizeClippingPlanes();
void updateCamera(int width, int height);
// Actual rendering objects
cvf::ref<cvf::RenderSequence> m_renderingSequence;
cvf::ref<cvf::Scene> m_mainScene;
@ -140,6 +143,8 @@ protected:
double m_maxFarPlaneDistance;
private:
void updateCamera(int width, int height);
void releaseOGlResourcesForCurrentFrame();
void debugShowRenderingSequencePartNames();