Merge pull request #194 from OPM/dev

Copy up dev to master for release 1.2.0
This commit is contained in:
Jacob Støren
2014-07-02 15:14:52 +02:00
150 changed files with 5047 additions and 842 deletions

View File

@@ -699,7 +699,7 @@ bool RiaApplication::openInputEclipseCaseFromFileNames(const QStringList& fileNa
//--------------------------------------------------------------------------------------------------
void RiaApplication::createMockModel()
{
openEclipseCase("Result Mock Debug Model Simple", "Result Mock Debug Model Simple");
openEclipseCase(RimDefines::mockModelBasic(), RimDefines::mockModelBasic());
}
//--------------------------------------------------------------------------------------------------
@@ -707,7 +707,7 @@ void RiaApplication::createMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createResultsMockModel()
{
openEclipseCase("Result Mock Debug Model With Results", "Result Mock Debug Model With Results");
openEclipseCase(RimDefines::mockModelBasicWithResults(), RimDefines::mockModelBasicWithResults());
}
@@ -716,7 +716,16 @@ void RiaApplication::createResultsMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createLargeResultsMockModel()
{
openEclipseCase("Result Mock Debug Model Large With Results", "Result Mock Debug Model Large With Results");
openEclipseCase(RimDefines::mockModelLargeWithResults(), RimDefines::mockModelLargeWithResults());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::createMockModelCustomized()
{
openEclipseCase(RimDefines::mockModelCustomized(), RimDefines::mockModelCustomized());
}
//--------------------------------------------------------------------------------------------------
@@ -724,7 +733,7 @@ void RiaApplication::createLargeResultsMockModel()
//--------------------------------------------------------------------------------------------------
void RiaApplication::createInputMockModel()
{
openInputEclipseCaseFromFileNames(QStringList("Input Mock Debug Model Simple"));
openInputEclipseCaseFromFileNames(QStringList(RimDefines::mockModelBasicInputCase()));
}
//--------------------------------------------------------------------------------------------------
@@ -834,7 +843,12 @@ bool RiaApplication::parseArguments()
bool parseOk = progOpt.parse(cvfqt::Utils::toStringVector(arguments));
if (!parseOk || progOpt.hasOption("help") || progOpt.hasOption("?"))
// If positional parameter functionality is to be supported, the test for existence of positionalParameters must be removed
// This is based on a pull request by @andlaus https://github.com/OPM/ResInsight/pull/162
if (!parseOk ||
progOpt.hasOption("help") ||
progOpt.hasOption("?") ||
progOpt.positionalParameters().size() > 0)
{
#if defined(_MSC_VER) && defined(_WIN32)
showFormattedTextInMessageBox(m_helpText);

View File

@@ -81,6 +81,7 @@ public:
void createMockModel();
void createResultsMockModel();
void createLargeResultsMockModel();
void createMockModelCustomized();
void createInputMockModel();
QString defaultFileDialogDirectory(const QString& dialogName);

View File

@@ -43,7 +43,6 @@ set( APPLICATION_FILES
set( USER_INTERFACE_FILES
UserInterface/RiuCursors.cpp
UserInterface/RiuMainWindow.cpp
UserInterface/RiuPreferencesDialog.cpp
UserInterface/RiuResultInfoPanel.cpp
UserInterface/RiuViewer.cpp
UserInterface/RiuSimpleHistogramWidget.cpp
@@ -59,6 +58,7 @@ set( SOCKET_INTERFACE_FILES
SocketInterface/RiaPropertyDataCommands.cpp
SocketInterface/RiaWellDataCommands.cpp
SocketInterface/RiaSocketTools.cpp
SocketInterface/RiaSocketDataTransfer.cpp
)
@@ -98,7 +98,6 @@ set ( QT_MOC_HEADERS
ProjectDataModel/RimMimeData.h
UserInterface/RiuMainWindow.h
UserInterface/RiuPreferencesDialog.h
UserInterface/RiuResultInfoPanel.h
UserInterface/RiuViewer.h
UserInterface/RiuProcessMonitor.h
@@ -155,6 +154,8 @@ list( REMOVE_ITEM RAW_SOURCES
Application/RiaImageCompareReporter.cpp
Application/RiaRegressionTest.cpp
SocketInterface/RiaSocketDataTransfer.cpp
FileInterface/RifEclipseInputFileTools.cpp
FileInterface/RifEclipseOutputFileTools.cpp
FileInterface/RifEclipseRestartFilesetAccess.cpp

View File

@@ -17,15 +17,17 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RifEclipseInputFileTools.h"
#include "RifReaderEclipseOutput.h"
#include "RigCaseCellResultsData.h"
#include "RigCaseData.h"
#include "cafProgressInfo.h"
#include <vector>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
#include <QFile>
#include <QFileInfo>
@@ -34,10 +36,8 @@
#include <QDebug>
#include "ecl_grid.h"
#include "well_state.h"
#include "util.h"
#include <fstream>
#include "well_state.h"
QString includeKeyword("INCLUDE");
@@ -46,6 +46,73 @@ QString editKeyword("EDIT");
QString gridKeyword("GRID");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t findOrCreateResult(const QString& newResultName, RigCaseData* reservoir)
{
size_t resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName);
if (resultIndex == cvf::UNDEFINED_SIZE_T)
{
resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false);
}
return resultIndex;
}
//--------------------------------------------------------------------------------------------------
/// Read all double values from input file. To reduce memory footprint, the alternative method
/// readDoubleValuesForActiveCells() can be used, and will skip all cell values for inactive cells
//--------------------------------------------------------------------------------------------------
bool readDoubleValues(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* eclKeyWordData)
{
if (resultIndex == cvf::UNDEFINED_SIZE_T) return false;
std::vector< std::vector<double> >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex);
newPropertyData.push_back(std::vector<double>());
newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool readDoubleValuesForActiveCells(RigCaseData* reservoir, size_t resultIndex, ecl_kw_type* eclKeyWordData)
{
if (resultIndex == cvf::UNDEFINED_SIZE_T) return false;
std::vector< std::vector<double> >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex);
newPropertyData.push_back(std::vector<double>());
RigActiveCellInfo* activeCellInfo = reservoir->activeCellInfo(RifReaderInterface::MATRIX_RESULTS);
if (activeCellInfo->globalCellCount() > 0 && activeCellInfo->globalCellCount() != activeCellInfo->globalActiveCellCount())
{
std::vector<double> valuesAllCells;
valuesAllCells.resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, valuesAllCells.data());
newPropertyData[0].resize(activeCellInfo->globalActiveCellCount(), HUGE_VAL);
std::vector<double>& valuesActiveCells = newPropertyData[0];
size_t acIdx = 0;
for (size_t gcIdx = 0; gcIdx < activeCellInfo->globalCellCount(); gcIdx++)
{
size_t activeCellResultIndex = activeCellInfo->cellResultIndex(gcIdx);
if (activeCellResultIndex != cvf::UNDEFINED_SIZE_T)
{
valuesActiveCells[activeCellResultIndex] = valuesAllCells[gcIdx];
}
}
}
else
{
newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data());
}
}
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
@@ -197,9 +264,9 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData
//--------------------------------------------------------------------------------------------------
/// Read known properties from the input file
//--------------------------------------------------------------------------------------------------
std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData *reservoir)
std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData* caseData)
{
CVF_ASSERT(reservoir);
CVF_ASSERT(caseData);
std::set<QString> knownKeywordSet;
{
@@ -231,19 +298,18 @@ std::map<QString, QString> RifEclipseInputFileTools::readProperties(const QStri
if (knownKeywordSet.count(fileKeywords[i].keyword))
{
fseek(gridFilePointer, fileKeywords[i].filePos, SEEK_SET);
ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE);
if (eclKeyWordData)
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE);
if (eclipseKeywordData)
{
QString newResultName = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword);
QString newResultName = caseData->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword);
size_t resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword
size_t resultIndex = findOrCreateResult(newResultName, caseData);
if (resultIndex != cvf::UNDEFINED_SIZE_T)
{
readDoubleValues(caseData, resultIndex, eclipseKeywordData);
}
std::vector< std::vector<double> >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex);
newPropertyData.push_back(std::vector<double>());
newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data());
ecl_kw_free(eclKeyWordData);
ecl_kw_free(eclipseKeywordData);
newResults[newResultName] = fileKeywords[i].keyword;
}
}
@@ -300,30 +366,24 @@ void RifEclipseInputFileTools::findKeywordsOnFile(const QString &fileName, std::
/// Reads the property data requested into the \a reservoir, overwriting any previous
/// propeties with the same name.
//--------------------------------------------------------------------------------------------------
bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName)
bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* caseData, const QString& eclipseKeyWord, const QString& resultName)
{
CVF_ASSERT(eclipseCase);
CVF_ASSERT(caseData);
FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r");
if (!filePointer) return false;
ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_grdecl_dynamic__( filePointer , eclipseKeyWord.toLatin1().data() , false , ECL_FLOAT_TYPE);
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_grdecl_dynamic__( filePointer , eclipseKeyWord.toLatin1().data() , false , ECL_FLOAT_TYPE);
bool isOk = false;
if (eclKeyWordData)
if (eclipseKeywordData)
{
QString newResultName = resultName;
size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName);
if (resultIndex == cvf::UNDEFINED_SIZE_T)
size_t resultIndex = findOrCreateResult(resultName, caseData);
if (resultIndex != cvf::UNDEFINED_SIZE_T)
{
resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false);
isOk = readDoubleValues(caseData, resultIndex, eclipseKeywordData);
}
std::vector< std::vector<double> >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex);
newPropertyData.resize(1);
newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data());
isOk = true;
ecl_kw_free(eclKeyWordData);
ecl_kw_free(eclipseKeywordData);
}
util_fclose(filePointer);
@@ -535,31 +595,25 @@ void RifEclipseInputFileTools::findGridKeywordPositions(const std::vector< RifKe
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName)
bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* caseData, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName)
{
CVF_ASSERT(eclipseCase);
CVF_ASSERT(caseData);
FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r");
if (!filePointer) return false;
fseek(filePointer, filePos, SEEK_SET);
ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(filePointer, false , ECL_FLOAT_TYPE);
ecl_kw_type* eclipseKeywordData = ecl_kw_fscanf_alloc_current_grdecl__(filePointer, false , ECL_FLOAT_TYPE);
bool isOk = false;
if (eclKeyWordData)
if (eclipseKeywordData)
{
QString newResultName = resultName;
size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName);
if (resultIndex == cvf::UNDEFINED_SIZE_T)
size_t resultIndex = findOrCreateResult(resultName, caseData);
if (resultIndex != cvf::UNDEFINED_SIZE_T)
{
resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false);
isOk = readDoubleValues(caseData, resultIndex, eclipseKeywordData);
}
std::vector< std::vector<double> >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex);
newPropertyData.resize(1);
newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL);
ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data());
isOk = true;
ecl_kw_free(eclKeyWordData);
ecl_kw_free(eclipseKeywordData);
}
util_fclose(filePointer);
@@ -671,13 +725,13 @@ qint64 RifEclipseInputFileTools::findKeyword(const QString& keyword, QFile& file
do
{
line = file.readLine();
line = line.trimmed();
if (line.startsWith("--", Qt::CaseInsensitive))
{
continue;
}
line = line.trimmed();
if (line.startsWith(keyword, Qt::CaseInsensitive))
{
return file.pos();
@@ -706,6 +760,8 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF
do
{
line = file.readLine();
line = line.trimmed();
if (line.startsWith("--", Qt::CaseInsensitive))
{
continue;
@@ -720,14 +776,19 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF
return false;
}
line = line.trimmed();
if (line.startsWith(includeKeyword, Qt::CaseInsensitive))
{
QString nextLine = file.readLine();
line = file.readLine();
line = line.trimmed();
int firstQuote = nextLine.indexOf("'");
int lastQuote = nextLine.lastIndexOf("'");
while (line.startsWith("--", Qt::CaseInsensitive))
{
line = file.readLine();
line = line.trimmed();
}
int firstQuote = line.indexOf("'");
int lastQuote = line.lastIndexOf("'");
if (!(firstQuote < 0 || lastQuote < 0 || firstQuote == lastQuote))
{
@@ -738,7 +799,7 @@ bool RifEclipseInputFileTools::readFaultsAndParseIncludeStatementsRecursively(QF
}
// Read include file name, and both relative and absolute path is supported
QString includeFilename = nextLine.mid(firstQuote + 1, lastQuote - firstQuote - 1);
QString includeFilename = line.mid(firstQuote + 1, lastQuote - firstQuote - 1);
QFileInfo fi(currentFileFolder, includeFilename);
if (fi.exists())
{

View File

@@ -175,3 +175,11 @@ void RifReaderMockModel::populateReservoir(RigCaseData* eclipseCase)
m_reservoirBuilder.populateReservoir(eclipseCase);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderMockModel::enableWellData(bool enableWellData)
{
m_reservoirBuilder.enableWellData(enableWellData);
}

View File

@@ -30,6 +30,7 @@ public:
void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate);
void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions);
void setResultInfo(size_t resultCount, size_t timeStepCount);
void enableWellData(bool enableWellData);
void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors);

View File

@@ -11,6 +11,7 @@ ${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.h
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.h
${CEE_CURRENT_LIST_DIR}RivNNCGeometryGenerator.h
${CEE_CURRENT_LIST_DIR}RivGridPartMgr.h
${CEE_CURRENT_LIST_DIR}RivTernarySaturationOverlayItem.h
${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.h
${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.h
${CEE_CURRENT_LIST_DIR}RivPipeGeometryGenerator.h
@@ -27,9 +28,10 @@ set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RivCellEdgeEffectGenerator.cpp
${CEE_CURRENT_LIST_DIR}RivColorTableArray.cpp
${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.cpp
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp
${CEE_CURRENT_LIST_DIR}RivNNCGeometryGenerator.cpp
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp
${CEE_CURRENT_LIST_DIR}RivGridPartMgr.cpp
${CEE_CURRENT_LIST_DIR}RivTernarySaturationOverlayItem.cpp
${CEE_CURRENT_LIST_DIR}RivReservoirFaultsPartMgr.cpp
${CEE_CURRENT_LIST_DIR}RivReservoirPartMgr.cpp
${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.cpp

View File

@@ -105,6 +105,7 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
updateNNCColors(cellResultSlot);
size_t scalarSetIndex = cellResultSlot->gridScalarIndex();
const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper();
@@ -117,12 +118,19 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData();
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex);
if (dataAccessObject.isNull()) return;
// Faults
if (m_nativeFaultFaces.notNull())
{
if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
cvf::ref<cvf::Color3ubArray> surfaceFacesColorArray;
if (cellResultSlot->isTernarySaturationSelected())
{
surfaceFacesColorArray = new cvf::Color3ubArray;
const std::vector<size_t>& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices();
RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells);
}
else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
{
const std::vector<cvf::StructGridInterface::FaceType>& quadsToFaceTypes = m_nativeFaultGenerator->quadToFace();
const std::vector<size_t>& quadsToGridCells = m_nativeFaultGenerator->quadToGridCellIndices();
@@ -132,7 +140,12 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
}
else
{
if (dataAccessObject.isNull())
{
return;
}
m_nativeFaultGenerator->textureCoordinates(m_nativeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper);
}
if (m_opacityLevel < 1.0f )
@@ -159,16 +172,41 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
}
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_nativeFaultFaces->drawable());
if (dg) dg->setTextureCoordArray(m_nativeFaultFacesTextureCoords.p());
if (surfaceFacesColorArray.notNull())
{
if (dg)
{
dg->setColorArray(surfaceFacesColorArray.p());
}
cvf::ref<cvf::Effect> scalarEffect = cellResultEffect(mapper, caf::PO_1);
m_nativeFaultFaces->setEffect(scalarEffect.p());
cvf::ref<cvf::Effect> perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel);
m_nativeFaultFaces->setEffect(perVertexColorEffect.p());
m_nativeFaultFaces->setPriority(100);
}
else
{
if (dg) dg->setTextureCoordArray(m_nativeFaultFacesTextureCoords.p());
cvf::ref<cvf::Effect> scalarEffect = cellResultEffect(mapper, caf::PO_1);
m_nativeFaultFaces->setEffect(scalarEffect.p());
}
}
if (m_oppositeFaultFaces.notNull())
{
if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
cvf::ref<cvf::Color3ubArray> surfaceFacesColorArray;
if (cellResultSlot->isTernarySaturationSelected())
{
surfaceFacesColorArray = new cvf::Color3ubArray;
const std::vector<size_t>& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices();
RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells);
}
else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
{
const std::vector<cvf::StructGridInterface::FaceType>& quadsToFaceTypes = m_oppositeFaultGenerator->quadToFace();
const std::vector<size_t>& quadsToGridCells = m_oppositeFaultGenerator->quadToGridCellIndices();
@@ -178,6 +216,11 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
}
else
{
if (dataAccessObject.isNull())
{
return;
}
m_oppositeFaultGenerator->textureCoordinates(m_oppositeFaultFacesTextureCoords.p(), dataAccessObject.p(), mapper);
}
@@ -205,12 +248,27 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
}
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_oppositeFaultFaces->drawable());
if (dg) dg->setTextureCoordArray(m_oppositeFaultFacesTextureCoords.p());
if (surfaceFacesColorArray.notNull())
{
if (dg)
{
dg->setColorArray(surfaceFacesColorArray.p());
}
// Use a different offset than native fault faces to avoid z-fighting
cvf::ref<cvf::Effect> scalarEffect = cellResultEffect(mapper, caf::PO_2);
cvf::ref<cvf::Effect> perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel);
m_oppositeFaultFaces->setEffect(perVertexColorEffect.p());
m_oppositeFaultFaces->setEffect(scalarEffect.p());
m_oppositeFaultFaces->setPriority(100);
}
else
{
if (dg) dg->setTextureCoordArray(m_oppositeFaultFacesTextureCoords.p());
// Use a different offset than native fault faces to avoid z-fighting
cvf::ref<cvf::Effect> scalarEffect = cellResultEffect(mapper, caf::PO_2);
m_oppositeFaultFaces->setEffect(scalarEffect.p());
}
}
}
@@ -223,15 +281,15 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimResultS
}
const int priFaultGeo = 1;
const int priNncGeo = 2;
const int priMesh = 3;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivFaultPartMgr::generatePartGeometry()
{
const int priFaultGeo = 1;
const int priNncGeo = 2;
const int priMesh = 3;
bool useBufferObjects = true;
// Surface geometry
@@ -418,13 +476,20 @@ void RivFaultPartMgr::updatePartEffect()
if (m_opacityLevel < 1.0f)
{
// Must be fixed since currently fault drawing relies on internal priorities of the parts
CVF_FAIL_MSG("Not implemented");
// Set priority to make sure this transparent geometry are rendered last
if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(100);
if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(100);
if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(100);
if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(100 + priFaultGeo);
if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(100 + priFaultGeo);
if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(100 + priNncGeo);
if (m_nativeFaultGridLines.notNull())
{
m_nativeFaultGridLines->setPriority(100 + priMesh);
}
if (m_oppositeFaultGridLines.notNull())
{
m_oppositeFaultGridLines->setPriority(100 + priMesh);
}
}
}

View File

@@ -53,6 +53,7 @@ public:
void setCellVisibility(cvf::UByteArray* cellVisibilities);
void applySingleColorEffect();
void setOpacityLevel(float opacity) { m_opacityLevel = opacity; }
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot, RimCellEdgeResultSlot* cellEdgeResultSlot);

View File

@@ -18,33 +18,40 @@
#include "RivGridPartMgr.h"
#include "cvfPart.h"
#include "cafEffectGenerator.h"
#include "cvfStructGrid.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafProgressInfo.h"
#include "cvfDrawableGeo.h"
#include "cvfMath.h"
#include "cvfModelBasicList.h"
#include "RivCellEdgeEffectGenerator.h"
#include "RimReservoirView.h"
#include "RimResultSlot.h"
#include "RimCellEdgeResultSlot.h"
#include "RigCaseCellResultsData.h"
#include "RigCaseData.h"
#include "cvfPart.h"
#include "cvfRenderStateBlending.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfRenderState_FF.h"
#include "cvfShaderProgram.h"
#include "cvfShaderProgramGenerator.h"
#include "cvfShaderSourceProvider.h"
#include "cvfShaderSourceRepository.h"
#include "cvfStructGrid.h"
#include "cvfUniform.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RigCaseCellResultsData.h"
#include "RigCaseData.h"
#include "RimCase.h"
#include "RimWellCollection.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmFieldCvfColor.h"
#include "RimCellRangeFilterCollection.h"
#include "RimCellPropertyFilterCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCellEdgeResultSlot.h"
#include "RimReservoirCellResultsCacher.h"
#include "RimReservoirView.h"
#include "RimResultSlot.h"
#include "RimTernaryLegendConfig.h"
#include "RimWellCollection.h"
#include "RivCellEdgeEffectGenerator.h"
#include "RivSourceInfo.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -250,15 +257,23 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
{
CVF_ASSERT(cellResultSlot);
const cvf::ScalarMapper* mapper = cellResultSlot->legendConfig()->scalarMapper();
RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData();
cvf::ref<cvf::Color3ubArray> surfaceFacesColorArray;
// Outer surface
if (m_surfaceFaces.notNull())
{
if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
if (cellResultSlot->isTernarySaturationSelected())
{
surfaceFacesColorArray = new cvf::Color3ubArray;
const std::vector<size_t>& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices();
RivTransmissibilityColorMapper::updateTernarySaturationColorArray(timeStepIndex, cellResultSlot, m_grid.p(), surfaceFacesColorArray.p(), quadsToGridCells);
}
else if (cellResultSlot->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
{
const std::vector<cvf::StructGridInterface::FaceType>& quadsToFaceTypes = m_surfaceGenerator.quadToFace();
const std::vector<size_t>& quadsToGridCells = m_surfaceGenerator.quadToGridCellIndices();
@@ -309,16 +324,34 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot*
}
cvf::DrawableGeo* dg = dynamic_cast<cvf::DrawableGeo*>(m_surfaceFaces->drawable());
if (dg) dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p());
if (surfaceFacesColorArray.notNull())
{
if (dg)
{
dg->setColorArray(surfaceFacesColorArray.p());
}
caf::PolygonOffset polygonOffset = caf::PO_1;
caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset);
cvf::ref<cvf::Effect> perVertexColorEffect = RivGridPartMgr::createPerVertexColoringEffect(m_opacityLevel);
m_surfaceFaces->setEffect(perVertexColorEffect.p());
scalarEffgen.setOpacityLevel(m_opacityLevel);
m_surfaceFaces->setPriority(100);
}
else
{
if (dg)
{
dg->setTextureCoordArray(m_surfaceFacesTextureCoords.p());
}
cvf::ref<cvf::Effect> scalarEffect = scalarEffgen.generateEffect();
caf::PolygonOffset polygonOffset = caf::PO_1;
caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset);
m_surfaceFaces->setEffect(scalarEffect.p());
scalarEffgen.setOpacityLevel(m_opacityLevel);
cvf::ref<cvf::Effect> scalarEffect = scalarEffgen.generateEffect();
m_surfaceFaces->setEffect(scalarEffect.p());
}
}
// Faults
@@ -433,6 +466,53 @@ RivGridPartMgr::~RivGridPartMgr()
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Effect> RivGridPartMgr::createPerVertexColoringEffect(float opacity)
{
cvf::ref<cvf::Effect> colorArrayEffect = new cvf::Effect;
if (RiaApplication::instance()->useShaders())
{
cvf::ShaderProgramGenerator gen("PerVertexColor", cvf::ShaderSourceProvider::instance());
gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(cvf::ShaderSourceRepository::src_VaryingColorGlobalAlpha);
gen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse());
gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard);
cvf::ref<cvf::ShaderProgram> m_shaderProg = gen.generate();
m_shaderProg->setDefaultUniform(new cvf::UniformFloat("u_alpha", opacity));
colorArrayEffect->setShaderProgram(m_shaderProg.p());
}
else
{
cvf::ref<cvf::RenderStateMaterial_FF> mat = new cvf::RenderStateMaterial_FF(cvf::Color3::BLUE);
mat->setAlpha(opacity);
mat->enableColorMaterial(true);
colorArrayEffect->setRenderState(mat.p());
cvf::ref<cvf::RenderStateLighting_FF> lighting = new cvf::RenderStateLighting_FF;
lighting->enableTwoSided(true);
colorArrayEffect->setRenderState(lighting.p());
}
// Simple transparency
if (opacity < 1.0f)
{
cvf::ref<cvf::RenderStateBlending> blender = new cvf::RenderStateBlending;
blender->configureTransparencyBlending();
colorArrayEffect->setRenderState(blender.p());
}
caf::PolygonOffset polygonOffset = caf::PO_1;
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = caf::EffectGenerator::createAndConfigurePolygonOffsetRenderState(polygonOffset);
colorArrayEffect->setRenderState(polyOffset.p());
return colorArrayEffect;
}
//--------------------------------------------------------------------------------------------------
///
@@ -487,7 +567,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi
size_t i, j, k, neighborGridCellIdx;
grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k);
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_I, &neighborGridCellIdx))
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_I, &neighborGridCellIdx))
{
cellScalarValue = dataAccessObjectTranX->cellScalar(neighborGridCellIdx);
}
@@ -501,7 +581,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi
size_t i, j, k, neighborGridCellIdx;
grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k);
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_J, &neighborGridCellIdx))
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_J, &neighborGridCellIdx))
{
cellScalarValue = dataAccessObjectTranY->cellScalar(neighborGridCellIdx);
}
@@ -515,7 +595,7 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi
size_t i, j, k, neighborGridCellIdx;
grid->ijkFromCellIndex(quadsToGridCells[idx], &i, &j, &k);
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::POS_K, &neighborGridCellIdx))
if(grid->cellIJKNeighbor(i, j, k, cvf::StructGridInterface::NEG_K, &neighborGridCellIdx))
{
cellScalarValue = dataAccessObjectTranZ->cellScalar(neighborGridCellIdx);
}
@@ -535,3 +615,121 @@ void RivTransmissibilityColorMapper::updateCombinedTransmissibilityTextureCoordi
}
}
//--------------------------------------------------------------------------------------------------
/// Helper class used to provide zero for all cells
/// This way we can avoid to test if a StructGridScalarDataAccess object is valid before reading out the value.
//--------------------------------------------------------------------------------------------------
class ScalarDataAccessZeroForAllCells : public cvf::StructGridScalarDataAccess
{
public:
virtual double cellScalar(size_t cellIndex) const
{
return 0.0;
}
virtual void setCellScalar(size_t cellIndex, double value)
{
}
};
//--------------------------------------------------------------------------------------------------
/// Creates and assigns a ternary saturation color for all four vertices of a quad representing a cell face
///
/// Loads ternary saturation results SOIL, SWAT and SGAS
/// If any of these are not present, the values for a missing component is set to 0.0
//--------------------------------------------------------------------------------------------------
void RivTransmissibilityColorMapper::updateTernarySaturationColorArray(size_t timeStepIndex, RimResultSlot* cellResultSlot, const RigGridBase* grid, cvf::Color3ubArray* colorArray, const std::vector<size_t>& quadsToGridCells)
{
RimReservoirCellResultsStorage* gridCellResults = cellResultSlot->currentGridCellResults();
if (!gridCellResults) return;
RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData();
if (!eclipseCase) return;
size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL");
size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS");
size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT");
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel());
double soilMin = 0.0;
double soilMax = 1.0;
double sgasMin = 0.0;
double sgasMax = 1.0;
double swatMin = 0.0;
double swatMax = 1.0;
cellResultSlot->ternaryLegendConfig()->ternaryRanges(soilMin, soilMax, sgasMin, sgasMax, swatMin, swatMax);
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectSoil = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, soilScalarSetIndex);
if (dataAccessObjectSoil.isNull())
{
dataAccessObjectSoil = new ScalarDataAccessZeroForAllCells;
}
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectSgas = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, sgasScalarSetIndex);
if (dataAccessObjectSgas.isNull())
{
dataAccessObjectSgas = new ScalarDataAccessZeroForAllCells;
}
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectSwat = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, swatScalarSetIndex);
if (dataAccessObjectSwat.isNull())
{
dataAccessObjectSwat = new ScalarDataAccessZeroForAllCells;
}
double soilRange = soilMax - soilMin;
double soilFactor = 255.0 / soilRange;
double sgasRange = sgasMax - sgasMin;
double sgasFactor = 255.0 / sgasRange;
double swatRange = swatMax - swatMin;
double swatFactor = 255.0 / swatRange;
size_t numVertices = quadsToGridCells.size()*4;
colorArray->resize(numVertices);
cvf::Color3ub ternaryColorByte;
double v, vNormalized;
#pragma omp parallel for private(ternaryColorByte, v, vNormalized)
for (int idx = 0; idx < static_cast<int>(quadsToGridCells.size()); idx++)
{
size_t gridCellIndex = quadsToGridCells[idx];
{
v = dataAccessObjectSgas->cellScalar(gridCellIndex);
vNormalized = (v - sgasMin) * sgasFactor;
vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0);
ternaryColorByte.r() = vNormalized;
}
{
v = dataAccessObjectSoil->cellScalar(gridCellIndex);
vNormalized = (v - soilMin) * soilFactor;
vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0);
ternaryColorByte.g() = vNormalized;
}
{
v = dataAccessObjectSwat->cellScalar(gridCellIndex);
vNormalized = (v - swatMin) * swatFactor;
vNormalized = cvf::Math::clamp(vNormalized, 0.0, 255.0);
ternaryColorByte.b() = vNormalized;
}
size_t j;
for (j = 0; j < 4; j++)
{
colorArray->set(idx*4 + j, ternaryColorByte);
}
}
}

View File

@@ -29,6 +29,7 @@ namespace cvf
class ModelBasicList;
class Transform;
class Part;
class Effect;
}
class RimResultSlot;
@@ -50,6 +51,13 @@ public:
cvf::Vec2fArray* textureCoords,
const std::vector<cvf::StructGridInterface::FaceType>& quadsToFaceTypes,
const std::vector<size_t>& quadsToGridCells);
static void updateTernarySaturationColorArray(
size_t timeStepIndex,
RimResultSlot* cellResultSlot,
const RigGridBase* grid,
cvf::Color3ubArray* colorArray,
const std::vector<size_t>& quadsToGridCells);
};
@@ -73,15 +81,16 @@ public:
void updateCellColor(cvf::Color4f color);
void updateCellResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot);
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot,
RimCellEdgeResultSlot* cellEdgeResultSlot);
void appendPartsToModel(cvf::ModelBasicList* model);
static cvf::ref<cvf::Effect> createPerVertexColoringEffect(float opacity);
private:
void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry);
void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder, bool faultGeometry);
private:
size_t m_gridIdx;

View File

@@ -233,3 +233,14 @@ void RivReservoirFaultsPartMgr::setFaultForceVisibility(bool forceVisibility)
m_forceVisibility = forceVisibility;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::setOpacityLevel(float opacity)
{
for (size_t i = 0; i < m_faultParts.size(); i++)
{
m_faultParts[i]->setOpacityLevel(opacity);
}
}

View File

@@ -46,6 +46,7 @@ public:
void setCellVisibility(cvf::UByteArray* cellVisibilities);
void setFaultForceVisibility(bool isFilterGenerated);
void setOpacityLevel(float opacity);
void applySingleColorEffect();
void updateColors(size_t timeStepIndex, RimResultSlot* cellResultSlot);
void updateCellEdgeResultColor(size_t timeStepIndex, RimResultSlot* cellResultSlot,

View File

@@ -41,8 +41,11 @@ void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase, c
m_allGrids.push_back(new RivGridPartMgr(grids[i], i, faultCollection));
}
// Faults read from file are present only on main grid
m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), faultCollection);
if (eclipseCase->mainGrid())
{
// Faults read from file are present only on main grid
m_faultsPartMgr = new RivReservoirFaultsPartMgr(eclipseCase->mainGrid(), faultCollection);
}
}
}
@@ -98,6 +101,7 @@ void RivReservoirPartMgr::updateCellColor(cvf::Color4f color)
if (m_faultsPartMgr.notNull())
{
m_faultsPartMgr->setOpacityLevel(color.a());
m_faultsPartMgr->applySingleColorEffect();
}
}

View File

@@ -714,10 +714,12 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis
size_t scalarResultIndex = (*pfIt)->resultDefinition->gridScalarIndex();
size_t adjustedTimeStepIndex = timeStepIndex;
// Set time step to zero for static results
if ((*pfIt)->resultDefinition()->hasStaticResult())
{
timeStepIndex = 0;
adjustedTimeStepIndex = 0;
}
const RimCellFilter::FilterModeType filterType = (*pfIt)->filterMode();
@@ -725,7 +727,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel());
RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData();
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, scalarResultIndex);
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, adjustedTimeStepIndex, scalarResultIndex);
CVF_ASSERT(dataAccessObject.notNull());
//#pragma omp parallel for schedule(dynamic)

View File

@@ -0,0 +1,222 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA, Ceetron Solutions 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 "cvfBase.h"
#include "RivTernarySaturationOverlayItem.h"
#include "cvfOpenGL.h"
#include "cvfViewport.h"
#include "cvfCamera.h"
#include "cvfTextDrawer.h"
#include "cvfFont.h"
#include "cvfMatrixState.h"
#include "cvfRenderState_FF.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStatePolygonOffset.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font)
: m_textColor(cvf::Color3::BLACK),
m_font(font),
m_size(100, 120)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem()
{
// Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::setAxisLabelsColor(const cvf::Color3f& color)
{
m_textColor = color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui RivTernarySaturationOverlayItem::sizeHint()
{
return m_size;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::setSize(const cvf::Vec2ui& size)
{
m_size = size;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size)
{
render(oglContext, position, size, false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size)
{
render(oglContext, position, size, true);
}
//--------------------------------------------------------------------------------------------------
/// Set up camera/viewport and render
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software)
{
if (size.x() <= 0 || size.y() <= 0)
{
return;
}
cvf::Camera camera;
camera.setViewport(position.x(), position.y(), size.x(), size.y());
camera.setProjectionAsPixelExact2D();
camera.setViewMatrix(cvf::Mat4d::IDENTITY);
camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, cvf::Viewport::CLEAR_DEPTH);
cvf::TextDrawer textDrawer(m_font.p());
textDrawer.setTextColor(m_textColor);
textDrawer.addText("SWAT", cvf::Vec2f(0.0, 10.0));
textDrawer.addText(m_swatRange, cvf::Vec2f(0.0, 0.0));
textDrawer.addText("SOIL", cvf::Vec2f(static_cast<float>(size.x() - 25), 10.0));
float soilRangePos = static_cast<float>(size.x() - 40);
if (m_soilRange.size() < 6)
{
soilRangePos += 15;
}
textDrawer.addText(m_soilRange, cvf::Vec2f(soilRangePos, 0.0));
textDrawer.addText("SGAS", cvf::Vec2f(static_cast<float>( (size.x() / 2) - 17 ), static_cast<float>(size.y() - 10)));
textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast<float>( (size.x() / 2) - 17 ), static_cast<float>(size.y() - 20)));
textDrawer.renderSoftware(oglContext, camera);
renderAxisImmediateMode(oglContext);
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
/// Draw the axis using immediate mode OpenGL
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::renderAxisImmediateMode(cvf::OpenGLContext* oglContext)
{
#ifdef CVF_OPENGL_ES
CVF_UNUSED(layout);
CVF_FAIL_MSG("Not supported on OpenGL ES");
#else
cvf::RenderStateDepth depth(false);
depth.applyOpenGL(oglContext);
cvf::RenderStateLighting_FF lighting(false);
lighting.applyOpenGL(oglContext);
cvf::Color3ub colA(cvf::Color3::BLUE);
cvf::Color3ub colB(cvf::Color3::GREEN);
cvf::Color3ub colC(cvf::Color3::RED);
float lowerBoundY = 20;
float upperBoundY = static_cast<float>(m_size.y() - 20);
cvf::Vec3f a(0, lowerBoundY, 0);
cvf::Vec3f b(static_cast<float>(m_size.x()), lowerBoundY, 0);
cvf::Vec3f c(static_cast<float>(m_size.x() / 2), upperBoundY, 0);
// Draw filled rectangle elements
glBegin(GL_TRIANGLE_FAN);
glColor3ubv(colA.ptr());
glVertex3fv(a.ptr());
glColor3ubv(colB.ptr());
glVertex3fv(b.ptr());
glColor3ubv(colC.ptr());
glVertex3fv(c.ptr());
glVertex3fv(c.ptr());
glEnd();
// Lines
cvf::Color3ub linesColor(cvf::Color3::WHITE);
glColor3ubv(linesColor.ptr());
glBegin(GL_LINE_LOOP);
glVertex3fv(a.ptr());
glVertex3fv(b.ptr());
glVertex3fv(c.ptr());
glEnd();
cvf::RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
// Reset render states
cvf::RenderStateLighting_FF resetLighting;
resetLighting.applyOpenGL(oglContext);
CVF_CHECK_OGL(oglContext);
#endif // CVF_OPENGL_ES
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RivTernarySaturationOverlayItem::setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange)
{
m_soilRange = soilRange;
m_sgasRange = sgasRange;
m_swatRange = swatRange;
}

View File

@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA, Ceetron Solutions 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 "cvfOverlayItem.h"
#include "cvfMatrix4.h"
#include "cvfColor3.h"
#include "cvfString.h"
namespace cvf {
class Font;
}
//==================================================================================================
//
//
//
//==================================================================================================
class RivTernarySaturationOverlayItem : public cvf::OverlayItem
{
public:
RivTernarySaturationOverlayItem(cvf::Font* font);
~RivTernarySaturationOverlayItem();
void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange);
virtual cvf::Vec2ui sizeHint();
virtual void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size);
virtual void renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size);
void setSize(const cvf::Vec2ui& size);
void setAxisLabelsColor(const cvf::Color3f& color);
private:
void render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software);
void renderAxisImmediateMode(cvf::OpenGLContext* oglContext);
private:
cvf::Color3f m_textColor; // Text color
cvf::ref<cvf::Font> m_font;
cvf::String m_soilRange;
cvf::String m_sgasRange;
cvf::String m_swatRange;
cvf::Vec2ui m_size; // Pixel size of draw area
};

View File

@@ -46,6 +46,8 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.h
${CEE_CURRENT_LIST_DIR}RimTools.h
${CEE_CURRENT_LIST_DIR}RimFault.h
${CEE_CURRENT_LIST_DIR}RimFaultCollection.h
${CEE_CURRENT_LIST_DIR}RimMockModelSettings.h
${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.h
)
set (SOURCE_GROUP_SOURCE_FILES
@@ -90,6 +92,8 @@ ${CEE_CURRENT_LIST_DIR}RimCommandObject.cpp
${CEE_CURRENT_LIST_DIR}RimTools.cpp
${CEE_CURRENT_LIST_DIR}RimFault.cpp
${CEE_CURRENT_LIST_DIR}RimFaultCollection.cpp
${CEE_CURRENT_LIST_DIR}RimMockModelSettings.cpp
${CEE_CURRENT_LIST_DIR}RimTernaryLegendConfig.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -140,6 +140,11 @@ void Rim3dOverlayInfoConfig::update3DInfo()
"<b>Cell count. Total:</b> %2 <b>Active:</b> %3 <br>"
"<b>Main Grid I,J,K:</b> %4, %5, %6 <b>Z-Scale:</b> %7<br>").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale);
if (m_reservoirView->cellResult()->isTernarySaturationSelected())
{
infoText += QString("<b>Cell Property:</b> %1 ").arg(propName);
}
if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult())
{
infoText += QString("<b>Cell Property:</b> %1 ").arg(propName);
@@ -165,25 +170,29 @@ void Rim3dOverlayInfoConfig::update3DInfo()
{
if (m_reservoirView->faultCollection()->faultResult() == RimFaultCollection::FAULT_BACK_FACE_CULLING)
{
faultMapping = "Show values from cells behind fault";
faultMapping = "Cells behind fault";
}
else if (m_reservoirView->faultCollection()->faultResult() == RimFaultCollection::FAULT_FRONT_FACE_CULLING)
{
faultMapping = "Show values from cells in front of fault";
faultMapping = "Cells in front of fault";
}
else
{
faultMapping = "Show values from cells in front and behind fault";
faultMapping = "Cells in front and behind fault";
}
}
else
{
faultMapping = "Show values from cells in front and behind fault";
faultMapping = "Cells in front and behind fault";
}
infoText += QString("<b>Fault results: </b> %1<br>").arg(faultMapping);
}
}
else
{
infoText += "<br>";
}
if (m_reservoirView->animationMode() && m_reservoirView->cellEdgeResult()->hasResult())
@@ -196,7 +205,8 @@ void Rim3dOverlayInfoConfig::update3DInfo()
if ( m_reservoirView->cellResult()->hasDynamicResult()
|| m_reservoirView->propertyFilterCollection()->hasActiveDynamicFilters()
|| m_reservoirView->wellCollection()->hasVisibleWellPipes())
|| m_reservoirView->wellCollection()->hasVisibleWellPipes()
|| m_reservoirView->cellResult()->isTernarySaturationSelected())
{
int currentTimeStep = m_reservoirView->currentTimeStep();
QDateTime date = m_reservoirView->currentGridCellResults()->cellResults()->timeStepDate(0, currentTimeStep);

View File

@@ -124,7 +124,26 @@ void RimCellPropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedF
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimCellPropertyFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
{
return resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
QList<caf::PdmOptionItemInfo> optionItems = resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
// Remove ternary from list, as it is not supported to perform filtering on a ternary result
int ternaryIndex = -1;
for (int i = 0; i < optionItems.size(); i++)
{
QString text = optionItems[i].optionUiText;
if (text.compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0)
{
ternaryIndex = i;
}
}
if (ternaryIndex != -1)
{
optionItems.takeAt(ternaryIndex);
}
return optionItems;
}
//--------------------------------------------------------------------------------------------------

View File

@@ -41,7 +41,16 @@ public:
static QString undefinedResultName() { return "None"; }
static QString undefinedGridFaultName() { return "Undefined grid faults"; }
static QString combinedTransmissibilityResultName() { return "TRANSXYZ"; }
static QString ternarySaturationResultName() { return "TERNARY"; }
// Mock model text identifiers
static QString mockModelBasic() { return "Result Mock Debug Model Simple"; }
static QString mockModelBasicWithResults() { return "Result Mock Debug Model With Results"; }
static QString mockModelLargeWithResults() { return "Result Mock Debug Model Large With Results"; }
static QString mockModelCustomized() { return "Result Mock Debug Model Customized"; }
static QString mockModelBasicInputCase() { return "Input Mock Debug Model Simple"; }
};

View File

@@ -73,7 +73,7 @@ RimFaultCollection::RimFaultCollection()
CAF_PDM_InitField(&showFaultFaces, "ShowFaultFaces", true, "Show defined faces", "", "", "");
CAF_PDM_InitField(&showOppositeFaultFaces, "ShowOppositeFaultFaces", true, "Show opposite faces", "", "", "");
CAF_PDM_InitField(&showNNCs, "ShowNNCs", false, "Show NNCs", "", "", "");
CAF_PDM_InitField(&showResultsOnFaults, "ShowResultsOnFaults", false, "Show results on faults", "", "", "");
CAF_PDM_InitField(&showResultsOnFaults, "ShowResultsOnFaults", true, "Show results on faults", "", "", "");
CAF_PDM_InitField(&showFaultsOutsideFilters,"ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", "");
CAF_PDM_InitField(&faultResult, "FaultFaceCulling", caf::AppEnum<RimFaultCollection::FaultFaceCullingMode>(RimFaultCollection::FAULT_BACK_FACE_CULLING), "Dynamic Face Selection", "", "", "");
@@ -187,7 +187,7 @@ bool faultComparator(const cvf::ref<RigFault>& a, const cvf::ref<RigFault>& b)
//--------------------------------------------------------------------------------------------------
void RimFaultCollection::syncronizeFaults()
{
if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) ) return;
if (!(m_reservoirView && m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) ) return;
cvf::ref<cvf::Color3fArray> partColors = RivColorTableArray::colorTableArray();

View File

@@ -77,7 +77,7 @@ RimInputCase::~RimInputCase()
//--------------------------------------------------------------------------------------------------
void RimInputCase::openDataFileSet(const QStringList& fileNames)
{
if (fileNames.contains("Input Mock Debug Model Simple"))
if (fileNames.contains(RimDefines::mockModelBasicInputCase()))
{
cvf::ref<RifReaderInterface> readerInterface = this->createMockModel(fileNames[0]);
results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p());
@@ -184,7 +184,7 @@ bool RimInputCase::openEclipseGridFile()
{
cvf::ref<RifReaderInterface> readerInterface;
if (m_gridFileName().contains("Input Mock Debug Model Simple"))
if (m_gridFileName().contains(RimDefines::mockModelBasicInputCase()))
{
readerInterface = this->createMockModel(this->m_gridFileName());
}
@@ -377,7 +377,7 @@ cvf::ref<RifReaderInterface> RimInputCase::createMockModel(QString modelName)
cvf::ref<RigCaseData> reservoir = new RigCaseData;
cvf::ref<RifReaderMockModel> mockFileInterface = new RifReaderMockModel;
if (modelName == "Input Mock Debug Model Simple")
if (modelName == RimDefines::mockModelBasicInputCase())
{
m_gridFileName = modelName;

View File

@@ -18,27 +18,23 @@
#include "RimLegendConfig.h"
#include "RimReservoirView.h"
#include "cafFactory.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cvfScalarMapperDiscreteLog.h"
#include "cvfScalarMapperContinuousLog.h"
#include "cvfScalarMapperContinuousLinear.h"
#include "cvfOverlayScalarMapperLegend.h"
#include "cvfScalarMapperContinuousLinear.h"
#include "cvfScalarMapperContinuousLog.h"
#include "cvfScalarMapperDiscreteLinear.h"
#include "cvfScalarMapperDiscreteLog.h"
#include <cmath>
#include "RiaApplication.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmFieldCvfColor.h"
#include "RimResultSlot.h"
#include "RimCellEdgeResultSlot.h"
#include "RimCellRangeFilterCollection.h"
#include "RimCellPropertyFilterCollection.h"
#include "RimWellCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimReservoirView.h"
CAF_PDM_SOURCE_INIT(RimLegendConfig, "Legend");
@@ -112,7 +108,7 @@ RimLegendConfig::RimLegendConfig()
CAF_PDM_InitField(&m_colorRangeMode, "ColorRangeMode", ColorRangeEnum(NORMAL) , "Colors", "", "", "");
CAF_PDM_InitField(&m_mappingMode, "MappingMode", MappingEnum(LINEAR_CONTINUOUS) , "Mapping", "", "", "");
CAF_PDM_InitField(&m_rangeMode, "RangeType", caf::AppEnum<RimLegendConfig::RangeModeType>(AUTOMATIC_ALLTIMESTEPS), "Range type", "", "Switches between automatic and user defined range on the legend", "");
CAF_PDM_InitField(&m_rangeMode, "RangeType", RangeModeEnum(AUTOMATIC_ALLTIMESTEPS), "Range type", "", "Switches between automatic and user defined range on the legend", "");
CAF_PDM_InitField(&m_userDefinedMaxValue, "UserDefinedMax", 1.0, "Max", "", "Min value of the legend", "");
CAF_PDM_InitField(&m_userDefinedMinValue, "UserDefinedMin", 0.0, "Min", "", "Max value of the legend", "");
CAF_PDM_InitField(&resultVariableName, "ResultVariableUsage", QString(""), "", "", "", "");
@@ -635,16 +631,18 @@ void RimLegendConfig::setClosestToZeroValues(double globalPosClosestToZero, doub
//--------------------------------------------------------------------------------------------------
void RimLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Format");
formatGr->add(&m_numLevels);
formatGr->add(&m_precision);
formatGr->add(&m_tickNumberFormat);
formatGr->add(&m_colorRangeMode);
{
caf::PdmUiOrdering * formatGr = uiOrdering.addNewGroup("Format");
formatGr->add(&m_numLevels);
formatGr->add(&m_precision);
formatGr->add(&m_tickNumberFormat);
formatGr->add(&m_colorRangeMode);
caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping");
mappingGr->add(&m_mappingMode);
mappingGr->add(&m_rangeMode);
mappingGr->add(&m_userDefinedMaxValue);
mappingGr->add(&m_userDefinedMinValue);
caf::PdmUiOrdering * mappingGr = uiOrdering.addNewGroup("Mapping");
mappingGr->add(&m_mappingMode);
mappingGr->add(&m_rangeMode);
mappingGr->add(&m_userDefinedMaxValue);
mappingGr->add(&m_userDefinedMinValue);
}
}

View File

@@ -54,12 +54,14 @@ public:
caf::PdmField<QString> resultVariableName; // Used internally to describe the variable this legend setup is used for
enum RangeModeType
enum RangeModeType
{
AUTOMATIC_ALLTIMESTEPS,
AUTOMATIC_CURRENT_TIMESTEP,
USER_DEFINED
};
typedef caf::AppEnum<RangeModeType> RangeModeEnum;
enum ColorRangesType
{
@@ -94,6 +96,7 @@ public:
cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); }
cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); }
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void initAfterRead();
@@ -104,7 +107,6 @@ private:
cvf::ref<cvf::Color3ubArray> interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount);
double roundToNumSignificantDigits(double value, double precision);
private:
caf::PdmPointer<RimReservoirView> m_reservoirView;
@@ -133,7 +135,7 @@ private:
caf::PdmField<int> m_numLevels;
caf::PdmField<int> m_precision;
caf::PdmField<caf::AppEnum<NumberFormatType> > m_tickNumberFormat;
caf::PdmField<caf::AppEnum<RangeModeType> > m_rangeMode;
caf::PdmField<RangeModeEnum> m_rangeMode;
caf::PdmField<double> m_userDefinedMaxValue;
caf::PdmField<double> m_userDefinedMinValue;
caf::PdmField<caf::AppEnum<ColorRangesType> > m_colorRangeMode;

View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RiaStdInclude.h"
#include "RimMockModelSettings.h"
CAF_PDM_SOURCE_INIT(RimMockModelSettings, "MockModelSettings");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMockModelSettings::RimMockModelSettings()
{
CAF_PDM_InitObject("Mock Model Settings", "", "", "");
CAF_PDM_InitField(&cellCountX, "CellCountX", quint64(100), "Cell Count X", "", "", "");
CAF_PDM_InitField(&cellCountY, "CellCountY", quint64(100), "Cell Count Y", "", "", "");
CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(10), "Cell Count Z", "", "", "");
CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", "");
totalCellCount.setUiReadOnly(true);
CAF_PDM_InitField(&resultCount, "ResultCount", quint64(3), "Result Count", "", "", "");
CAF_PDM_InitField(&timeStepCount, "TimeStepCount", quint64(10), "Time Step Count", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMockModelSettings::~RimMockModelSettings()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMockModelSettings::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
totalCellCount = cellCountX * cellCountY * cellCountZ;
totalCellCount.updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimMockModelSettings::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* gridSizeGroup = uiOrdering.addNewGroup("Grid size");
gridSizeGroup->add(&cellCountX);
gridSizeGroup->add(&cellCountY);
gridSizeGroup->add(&cellCountZ);
gridSizeGroup->add(&totalCellCount);
caf::PdmUiGroup* resultGroup = uiOrdering.addNewGroup("Results");
resultGroup->add(&resultCount);
resultGroup->add(&timeStepCount);
}

View File

@@ -18,32 +18,35 @@
#pragma once
#include <QDialog>
namespace caf
{
class PdmObject;
class PdmUiPropertyView;
}
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
//==================================================================================================
//
//
//
///
///
//==================================================================================================
class RiuPreferencesDialog : public QDialog
class RimMockModelSettings : public caf::PdmObject
{
Q_OBJECT
CAF_PDM_HEADER_INIT;
public:
RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle);
private:
void setupUi();
RimMockModelSettings();
virtual ~RimMockModelSettings();
caf::PdmField<quint64> cellCountX;
caf::PdmField<quint64> cellCountY;
caf::PdmField<quint64> cellCountZ;
caf::PdmField<quint64> totalCellCount;
caf::PdmField<quint64> resultCount;
caf::PdmField<quint64> timeStepCount;
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering );
private:
QString m_windowTitle;
caf::PdmObject* m_pdmObject;
caf::PdmUiPropertyView* m_pdmUiPropertyView;
};

View File

@@ -56,7 +56,7 @@ CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage"
//--------------------------------------------------------------------------------------------------
RimReservoirCellResultsStorage::RimReservoirCellResultsStorage()
: m_cellResults(NULL),
m_ownerMainGrid(NULL)
m_ownerMainGrid(NULL)
{
CAF_PDM_InitObject("Cacher", "", "", "");
@@ -136,7 +136,7 @@ void RimReservoirCellResultsStorage::setupBeforeSave()
// If there is no data, we do not store anything for the current result variable
// (Even not the metadata, of cause)
size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size();
if (timestepCount && resInfo[rIdx].m_needsToBeStored)
{
progInfo.setProgressDescription(resInfo[rIdx].m_resultName);
@@ -251,7 +251,7 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefi
if (soilScalarResultIndex == cvf::UNDEFINED_SIZE_T)
{
computeSOILForTimeStep(timeStepIndex);
soilScalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName);
return soilScalarResultIndex;
}
@@ -419,32 +419,22 @@ void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex
size_t soilResultValueCount = 0;
size_t soilTimeStepCount = 0;
std::vector<double>* swatForTimeStep = NULL;
std::vector<double>* sgasForTimeStep = NULL;
if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T)
{
swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex));
if (swatForTimeStep->size() == 0)
std::vector<double>& swatForTimeStep = m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex);
if (swatForTimeStep.size() > 0)
{
swatForTimeStep = NULL;
}
else
{
soilResultValueCount = swatForTimeStep->size();
soilResultValueCount = swatForTimeStep.size();
soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size();
}
}
if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T)
{
sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex));
if (sgasForTimeStep->size() == 0)
std::vector<double>& sgasForTimeStep = m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex);
if (sgasForTimeStep.size() > 0)
{
sgasForTimeStep = NULL;
}
else
{
soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep->size());
soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep.size());
size_t sgasTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepDates.size();
soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount);
@@ -468,6 +458,28 @@ void RimReservoirCellResultsStorage::computeSOILForTimeStep(size_t timeStepIndex
}
}
std::vector<double>* swatForTimeStep = NULL;
std::vector<double>* sgasForTimeStep = NULL;
if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T)
{
swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex));
if (swatForTimeStep->size() == 0)
{
swatForTimeStep = NULL;
}
}
if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T)
{
sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex));
if (sgasForTimeStep->size() == 0)
{
sgasForTimeStep = NULL;
}
}
std::vector<double>& soilForTimeStep = m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIndex);
#pragma omp parallel for
@@ -514,7 +526,7 @@ void RimReservoirCellResultsStorage::computeDepthRelatedResults()
if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T)
{
depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount);
depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount);
computeDepth = true;
}
@@ -694,7 +706,7 @@ void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cell
for (size_t tsIdx = 0; tsIdx < resInfo->m_timeStepDates().size(); ++tsIdx)
{
std::vector<double>* data = NULL;
data = &(m_cellResults->cellScalarResults(rIdx, tsIdx));
quint64 cellCount = 0;
@@ -760,4 +772,4 @@ RimReservoirCellResultsStorageEntryInfo::RimReservoirCellResultsStorageEntryInfo
RimReservoirCellResultsStorageEntryInfo::~RimReservoirCellResultsStorageEntryInfo()
{
}
}

View File

@@ -45,6 +45,7 @@
#include "RimCaseCollection.h"
#include "RimOilField.h"
#include "RimAnalysisModels.h"
#include "RimTernaryLegendConfig.h"
#include "RiuMainWindow.h"
#include "RigGridBase.h"
@@ -74,6 +75,7 @@
#include <limits.h>
#include "cafCeetronPlusNavigation.h"
#include "RimFaultCollection.h"
#include "RivTernarySaturationOverlayItem.h"
namespace caf {
@@ -172,8 +174,8 @@ RimReservoirView::RimReservoirView()
this->cellResult()->setReservoirView(this);
this->cellResult()->legendConfig()->setReservoirView(this);
this->cellResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 120));
this->cellEdgeResult()->setReservoirView(this);
this->cellEdgeResult()->legendConfig()->setReservoirView(this);
this->cellEdgeResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 320));
@@ -231,6 +233,7 @@ void RimReservoirView::updateViewerWidget()
RiuMainWindow::instance()->addViewer(m_viewer);
m_viewer->setMinNearPlaneDistance(10);
this->cellResult()->legendConfig->recreateLegend();
this->cellResult()->ternaryLegendConfig->recreateLegend();
this->cellEdgeResult()->legendConfig->recreateLegend();
m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend());
m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend());
@@ -529,7 +532,8 @@ void RimReservoirView::createDisplayModel()
if (this->cellResult()->hasDynamicResult()
|| this->propertyFilterCollection()->hasActiveDynamicFilters()
|| this->wellCollection->hasVisibleWellPipes())
|| this->wellCollection->hasVisibleWellPipes()
|| this->cellResult()->isTernarySaturationSelected())
{
CVF_ASSERT(currentGridCellResults());
@@ -648,10 +652,7 @@ void RimReservoirView::createDisplayModel()
updateFaultForcedVisibility();
}
this->updateFaultColors();
// Compute triangle count, Debug only
if (false)
@@ -818,7 +819,7 @@ void RimReservoirView::updateCurrentTimeStep()
{
m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult());
}
else if (this->animationMode() && this->cellResult()->hasResult())
else if ((this->animationMode() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected())
{
m_reservoirGridPartManager->updateCellResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult());
}
@@ -928,10 +929,16 @@ void RimReservoirView::loadDataAndUpdate()
RiaApplication* app = RiaApplication::instance();
if (app->preferences()->autocomputeSOIL)
{
RimReservoirCellResultsStorage* results = currentGridCellResults();
CVF_ASSERT(results);
results->loadOrComputeSOIL();
results->createCombinedTransmissibilityResults();
{
RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::MATRIX_RESULTS);
results->loadOrComputeSOIL();
results->createCombinedTransmissibilityResults();
}
{
RimReservoirCellResultsStorage* results = m_reservoir->results(RifReaderInterface::FRACTURE_RESULTS);
results->loadOrComputeSOIL();
results->createCombinedTransmissibilityResults();
}
}
}
}
@@ -1107,7 +1114,38 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex,
RigCaseData* eclipseCase = m_reservoir->reservoirData();
RigGridBase* grid = eclipseCase->grid(gridIndex);
if (this->cellResult()->hasResult())
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel());
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject;
if (this->cellResult()->isTernarySaturationSelected())
{
RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults();
if (gridCellResults)
{
size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL");
size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS");
size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT");
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectX = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, soilScalarSetIndex);
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectY = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, sgasScalarSetIndex);
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObjectZ = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, swatScalarSetIndex);
double scalarValue = 0.0;
if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex);
else scalarValue = 0.0;
resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue));
if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex);
else scalarValue = 0.0;
resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue));
if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex);
else scalarValue = 0.0;
resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue));
}
}
else if (this->cellResult()->hasResult())
{
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel());
cvf::ref<cvf::StructGridScalarDataAccess> dataAccessObject;
@@ -1414,6 +1452,67 @@ void RimReservoirView::updateLegends()
this->cellEdgeResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0);
this->cellEdgeResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE);
}
viewer()->removeOverlayItem(this->cellResult()->ternaryLegendConfig->legend());
size_t maxTimeStepCount = results->maxTimeStepCount();
if (this->cellResult()->isTernarySaturationSelected() && maxTimeStepCount > 1)
{
RimReservoirCellResultsStorage* gridCellResults = this->cellResult()->currentGridCellResults();
{
double globalMin = 0.0;
double globalMax = 1.0;
double localMin = 0.0;
double localMax = 1.0;
size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL");
if (scalarSetIndex != cvf::UNDEFINED_SIZE_T)
{
results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax);
results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax);
this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SOIL_IDX, globalMin, globalMax, localMin, localMax);
}
}
{
double globalMin = 0.0;
double globalMax = 1.0;
double localMin = 0.0;
double localMax = 1.0;
size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS");
if (scalarSetIndex != cvf::UNDEFINED_SIZE_T)
{
results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax);
results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax);
this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SGAS_IDX, globalMin, globalMax, localMin, localMax);
}
}
{
double globalMin = 0.0;
double globalMax = 1.0;
double localMin = 0.0;
double localMax = 1.0;
size_t scalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT");
if (scalarSetIndex != cvf::UNDEFINED_SIZE_T)
{
results->minMaxCellScalarValues(scalarSetIndex, globalMin, globalMax);
results->minMaxCellScalarValues(scalarSetIndex, m_currentTimeStep, localMin, localMax);
this->cellResult()->ternaryLegendConfig()->setAutomaticRanges(RimTernaryLegendConfig::TERNARY_SWAT_IDX, globalMin, globalMax, localMin, localMax);
}
}
if (this->cellResult()->ternaryLegendConfig->legend())
{
viewer()->addOverlayItem(this->cellResult()->ternaryLegendConfig->legend());
}
}
}
//--------------------------------------------------------------------------------------------------

View File

@@ -57,6 +57,7 @@ namespace cvf
class Transform;
class ScalarMapperUniformLevels;
class ModelBasicList;
class OverlayItem;
}
enum PartRenderMaskEnum

View File

@@ -17,6 +17,13 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiaStdInclude.h"
#include "cafProgressInfo.h"
#include "cafPdmSettings.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmUiPropertyDialog.h"
#include "RimResultCase.h"
#include "RigCaseData.h"
#include "RifReaderEclipseOutput.h"
@@ -24,7 +31,7 @@
#include "RimReservoirView.h"
#include "RifReaderMockModel.h"
#include "RifReaderEclipseInput.h"
#include "cafProgressInfo.h"
#include "RimProject.h"
#include "RifEclipseOutputFileTools.h"
#include "RiaApplication.h"
@@ -34,8 +41,6 @@
#include "RimReservoirCellResultsCacher.h"
#include "RimWellPathCollection.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmFieldCvfColor.h"
#include "RimResultSlot.h"
#include "RimCellEdgeResultSlot.h"
#include "RimCellRangeFilterCollection.h"
@@ -45,6 +50,7 @@
#include "RimOilField.h"
#include "RimAnalysisModels.h"
#include "RiaPreferences.h"
#include "RimMockModelSettings.h"
CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase");
//--------------------------------------------------------------------------------------------------
@@ -199,29 +205,17 @@ cvf::ref<RifReaderInterface> RimResultCase::createMockModel(QString modelName)
cvf::ref<RifReaderMockModel> mockFileInterface = new RifReaderMockModel;
cvf::ref<RigCaseData> reservoir = new RigCaseData;
if (modelName == "Result Mock Debug Model Simple")
if (modelName == RimDefines::mockModelBasic())
{
// Create the mock file interface and and RigSerervoir and set them up.
mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(20, 20, 20));
mockFileInterface->setGridPointDimensions(cvf::Vec3st(4, 5, 6));
mockFileInterface->addLocalGridRefinement(cvf::Vec3st(0, 2, 2), cvf::Vec3st(0, 2, 2), cvf::Vec3st(3, 3, 3));
mockFileInterface->enableWellData(false);
mockFileInterface->open("", reservoir.p());
{
size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4);
//TODO: Rewrite active cell info in mock models
//reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T);
}
{
size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3);
//TODO: Rewrite active cell info in mock models
//reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T);
}
}
else if (modelName == "Result Mock Debug Model With Results")
else if (modelName == RimDefines::mockModelBasicWithResults())
{
mockFileInterface->setWorldCoordinates(cvf::Vec3d(10, 10, 10), cvf::Vec3d(-20, -20, -20));
mockFileInterface->setGridPointDimensions(cvf::Vec3st(5, 10, 20));
@@ -234,7 +228,7 @@ cvf::ref<RifReaderInterface> RimResultCase::createMockModel(QString modelName)
cvf::Vec3d& tmp = reservoir->mainGrid()->nodes()[1];
tmp += cvf::Vec3d(1, 0, 0);
}
else if (modelName =="Result Mock Debug Model Large With Results")
else if (modelName == RimDefines::mockModelLargeWithResults())
{
double startX = 0;
double startY = 0;
@@ -262,6 +256,45 @@ cvf::ref<RifReaderInterface> RimResultCase::createMockModel(QString modelName)
mockFileInterface->open("", reservoir.p());
}
else if (modelName == RimDefines::mockModelCustomized())
{
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
RimMockModelSettings rimMockModelSettings;
caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings);
caf::PdmUiPropertyDialog propertyDialog(NULL, &rimMockModelSettings, "Customize Mock Model");
if (propertyDialog.exec() == QDialog::Accepted)
{
QApplication::restoreOverrideCursor();
caf::Settings::writeFieldsToApplicationStore(&rimMockModelSettings);
double startX = 0;
double startY = 0;
double startZ = 0;
double widthX = 6000;
double widthY = 12000;
double widthZ = 500;
// Test code to simulate UTM coordinates
double offsetX = 400000;
double offsetY = 6000000;
double offsetZ = 0;
mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ));
mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX + 1, rimMockModelSettings.cellCountY + 1, rimMockModelSettings.cellCountZ + 1));
mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount);
mockFileInterface->enableWellData(false);
mockFileInterface->open("", reservoir.p());
}
else
{
QApplication::restoreOverrideCursor();
}
}
this->setReservoirData( reservoir.p() );

View File

@@ -160,10 +160,10 @@ QList<caf::PdmOptionItemInfo> RimResultDefinition::calculateValueOptions(const c
QStringList varList = getResultVariableListForCurrentUIFieldSettings();
bool hasCombinedTransmissibility = false;
QList<caf::PdmOptionItemInfo> optionList;
for (int i = 0; i < varList.size(); ++i)
{
if (varList[i].compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0)
{
hasCombinedTransmissibility = true;
@@ -171,7 +171,6 @@ QList<caf::PdmOptionItemInfo> RimResultDefinition::calculateValueOptions(const c
}
optionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i]));
}
if (hasCombinedTransmissibility)
@@ -179,6 +178,16 @@ QList<caf::PdmOptionItemInfo> RimResultDefinition::calculateValueOptions(const c
optionList.push_front(caf::PdmOptionItemInfo(RimDefines::combinedTransmissibilityResultName(), RimDefines::combinedTransmissibilityResultName()));
}
bool hasAtLeastOneTernaryComponent = false;
if (varList.contains("SOIL")) hasAtLeastOneTernaryComponent = true;
else if (varList.contains("SGAS")) hasAtLeastOneTernaryComponent = true;
else if (varList.contains("SWAT")) hasAtLeastOneTernaryComponent = true;
if (m_resultTypeUiField == RimDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent)
{
optionList.push_front(caf::PdmOptionItemInfo(RimDefines::ternarySaturationResultName(), RimDefines::ternarySaturationResultName()));
}
optionList.push_front(caf::PdmOptionItemInfo( RimDefines::undefinedResultName(), RimDefines::undefinedResultName() ));
if (useOptionsOnly) *useOptionsOnly = true;
@@ -223,7 +232,6 @@ void RimResultDefinition::loadResult()
gridCellResults->findOrLoadScalarResult(m_resultType(), m_resultVariable);
}
}
}
@@ -251,7 +259,6 @@ bool RimResultDefinition::hasStaticResult() const
//--------------------------------------------------------------------------------------------------
bool RimResultDefinition::hasResult() const
{
if (this->currentGridCellResults() && this->currentGridCellResults()->cellResults())
{
const RigCaseCellResultsData* gridCellResults = this->currentGridCellResults()->cellResults();
@@ -341,3 +348,14 @@ void RimResultDefinition::setPorosityModelUiFieldHidden(bool hide)
{
m_porosityModelUiField.setUiHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimResultDefinition::isTernarySaturationSelected() const
{
bool isTernary = (m_resultType() == RimDefines::DYNAMIC_NATIVE) &&
(m_resultVariable().compare(RimDefines::ternarySaturationResultName(), Qt::CaseInsensitive) == 0);
return isTernary;
}

View File

@@ -47,7 +47,7 @@ public:
RimDefines::PorosityModelType porosityModel() const { return m_porosityModel(); }
void setPorosityModel(RimDefines::PorosityModelType val);
QString resultVariable() const { return m_resultVariable(); }
void setResultVariable(const QString& val);
virtual void setResultVariable(const QString& val);
void setPorosityModelUiFieldHidden(bool hide);
void loadResult();
@@ -55,6 +55,8 @@ public:
bool hasStaticResult() const;
bool hasDynamicResult() const;
bool hasResult() const;
bool isTernarySaturationSelected() const;
RimReservoirCellResultsStorage* currentGridCellResults() const;

View File

@@ -19,23 +19,11 @@
#include "RiaStdInclude.h"
#include "RimResultSlot.h"
#include "RimLegendConfig.h"
#include "RimReservoirView.h"
#include "RimCase.h"
#include "RiuMainWindow.h"
#include "RimTernaryLegendConfig.h"
#include "RimUiTreeModelPdm.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmFieldCvfColor.h"
#include "RimResultSlot.h"
#include "RimCellEdgeResultSlot.h"
#include "RimCellRangeFilterCollection.h"
#include "RimCellPropertyFilterCollection.h"
#include "RimWellCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimReservoirCellResultsCacher.h"
#include "RiuMainWindow.h"
CAF_PDM_SOURCE_INIT(RimResultSlot, "ResultSlot");
@@ -47,11 +35,18 @@ RimResultSlot::RimResultSlot()
CAF_PDM_InitObject("Result Slot", "", "", "");
CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", "");
this->legendConfig = new RimLegendConfig();
this->legendConfig.setUiHidden(true);
this->legendConfig.setUiChildrenHidden(true);
CAF_PDM_InitFieldNoDefault(&m_legendConfigData, "ResultVarLegendDefinitionList", "", "", "", "");
m_legendConfigData.setUiHidden(true);
m_legendConfigData.setUiChildrenHidden(true);
legendConfig = new RimLegendConfig();
CAF_PDM_InitFieldNoDefault(&ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", "");
this->ternaryLegendConfig = new RimTernaryLegendConfig();
this->ternaryLegendConfig.setUiHidden(true);
this->ternaryLegendConfig.setUiChildrenHidden(true);
}
//--------------------------------------------------------------------------------------------------
@@ -60,6 +55,7 @@ RimResultSlot::RimResultSlot()
RimResultSlot::~RimResultSlot()
{
delete legendConfig();
delete ternaryLegendConfig();
}
//--------------------------------------------------------------------------------------------------
@@ -81,6 +77,8 @@ void RimResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, co
{
if (m_reservoirView) m_reservoirView->animationMode = true;
}
RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this);
}
if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw();
@@ -91,36 +89,51 @@ void RimResultSlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, co
//--------------------------------------------------------------------------------------------------
void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend)
{
if (this->legendConfig()->resultVariableName() == resultVarNameOfNewLegend) return;
std::list<caf::PdmPointer<RimLegendConfig> >::iterator it;
bool found = false;
for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it)
if (resultVarNameOfNewLegend == RimDefines::ternarySaturationResultName())
{
if ((*it)->resultVariableName() == resultVarNameOfNewLegend)
this->ternaryLegendConfig.setUiHidden(false);
this->ternaryLegendConfig.setUiChildrenHidden(false);
this->legendConfig.setUiHidden(true);
this->legendConfig.setUiChildrenHidden(true);
}
else
{
this->ternaryLegendConfig.setUiHidden(true);
this->ternaryLegendConfig.setUiChildrenHidden(true);
if (this->legendConfig()->resultVariableName() != resultVarNameOfNewLegend)
{
RimLegendConfig* newLegend = *it;
std::list<caf::PdmPointer<RimLegendConfig> >::iterator it;
bool found = false;
for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it)
{
if ((*it)->resultVariableName() == resultVarNameOfNewLegend)
{
RimLegendConfig* newLegend = *it;
m_legendConfigData.v().erase(it);
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this);
found = true;
break;
m_legendConfigData.v().erase(it);
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
found = true;
break;
}
}
// Not found ?
if (!found)
{
RimLegendConfig* newLegend = new RimLegendConfig;
newLegend->setReservoirView(m_reservoirView);
newLegend->resultVariableName = resultVarNameOfNewLegend;
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
}
}
this->legendConfig.setUiHidden(false);
this->legendConfig.setUiChildrenHidden(false);
}
// Not found ?
if (!found)
{
RimLegendConfig* newLegend = new RimLegendConfig;
newLegend->setReservoirView(m_reservoirView);
newLegend->resultVariableName = resultVarNameOfNewLegend;
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this);
}
}
//--------------------------------------------------------------------------------------------------
@@ -134,6 +147,8 @@ void RimResultSlot::initAfterRead()
{
this->legendConfig()->resultVariableName = this->resultVariable();
}
changeLegendConfig(this->resultVariable());
}
//--------------------------------------------------------------------------------------------------
@@ -148,4 +163,17 @@ void RimResultSlot::setReservoirView(RimReservoirView* ownerReservoirView)
{
(*it)->setReservoirView(ownerReservoirView);
}
this->ternaryLegendConfig()->setReservoirView(ownerReservoirView);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimResultSlot::setResultVariable(const QString& val)
{
RimResultDefinition::setResultVariable(val);
this->changeLegendConfig(val);
}

View File

@@ -18,12 +18,15 @@
#pragma once
#include "cafPdmObject.h"
#include "RimLegendConfig.h"
#include "cafAppEnum.h"
#include "cafPdmObject.h"
#include "RimDefines.h"
#include "RimLegendConfig.h"
#include "RimResultDefinition.h"
class RimTernaryLegendConfig;
//==================================================================================================
///
///
@@ -37,16 +40,18 @@ public:
virtual void setReservoirView(RimReservoirView* ownerReservoirView);
caf::PdmField<RimLegendConfig*> legendConfig;
caf::PdmField<RimTernaryLegendConfig*> ternaryLegendConfig;
// Overridden methods
virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue );
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void setResultVariable(const QString& resultName);
protected:
virtual void initAfterRead();
private:
void changeLegendConfig(QString resultVarNameOfNewLegend);
caf::PdmField<std::list<caf::PdmPointer<RimLegendConfig> > > m_legendConfigData;
caf::PdmField<std::list<caf::PdmPointer<RimLegendConfig> > > m_legendConfigData;
};

View File

@@ -0,0 +1,440 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimTernaryLegendConfig.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTextEditor.h"
#include "RiaApplication.h"
#include "RimReservoirView.h"
#include "RivTernarySaturationOverlayItem.h"
#include <cmath>
#include "cvfqtUtils.h"
CAF_PDM_SOURCE_INIT(RimTernaryLegendConfig, "RimTernaryLegendConfig");
namespace caf {
template<>
void AppEnum<RimTernaryLegendConfig::RangeModeType>::setUp()
{
addItem(RimTernaryLegendConfig::AUTOMATIC_ALLTIMESTEPS, "AUTOMATIC_ALLTIMESTEPS", "Global range");
addItem(RimTernaryLegendConfig::AUTOMATIC_CURRENT_TIMESTEP,"AUTOMATIC_CURRENT_TIMESTEP", "Local range");
addItem(RimTernaryLegendConfig::USER_DEFINED, "USER_DEFINED_MAX_MIN", "User defined range");
setDefault(RimTernaryLegendConfig::AUTOMATIC_ALLTIMESTEPS);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTernaryLegendConfig::RimTernaryLegendConfig()
{
CAF_PDM_InitObject("Ternary Legend Definition", ":/Legend.png", "", "");
CAF_PDM_InitField(&precision, "Precision", 2, "Significant digits", "", "The number of significant digits displayed in the legend numbers","");
CAF_PDM_InitField(&rangeMode, "RangeType", RangeModeEnum(USER_DEFINED), "Range type", "", "Switches between automatic and user defined range on the legend", "");
CAF_PDM_InitFieldNoDefault(&applyLocalMinMax, "m_applyLocalMinMax", "", "", "", "");
applyLocalMinMax.setIOWritable(false);
applyLocalMinMax.setIOReadable(false);
applyLocalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
applyLocalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
applyLocalMinMax = false;
CAF_PDM_InitFieldNoDefault(&applyGlobalMinMax, "m_applyGlobalMinMax", "", "", "", "");
applyGlobalMinMax.setIOWritable(false);
applyGlobalMinMax.setIOReadable(false);
applyGlobalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
applyGlobalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
applyGlobalMinMax = false;
CAF_PDM_InitFieldNoDefault(&applyFullRangeMinMax, "m_applyFullRangeMinMax", "", "", "", "");
applyFullRangeMinMax.setIOWritable(false);
applyFullRangeMinMax.setIOReadable(false);
applyFullRangeMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
applyFullRangeMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
applyFullRangeMinMax = false;
CAF_PDM_InitFieldNoDefault(&ternaryRangeSummary, "ternaryRangeSummary", "Range summary", "", "", "");
ternaryRangeSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
ternaryRangeSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP);
CAF_PDM_InitField(&userDefinedMaxValueSoil, "UserDefinedMaxSoil", 1.0, "Max", "", "Min value of the legend", "");
CAF_PDM_InitField(&userDefinedMinValueSoil, "UserDefinedMinSoil", 0.0, "Min", "", "Max value of the legend", "");
CAF_PDM_InitField(&userDefinedMaxValueSgas, "UserDefinedMaxSgas", 1.0, "Max", "", "Min value of the legend", "");
CAF_PDM_InitField(&userDefinedMinValueSgas, "UserDefinedMinSgas", 0.0, "Min", "", "Max value of the legend", "");
CAF_PDM_InitField(&userDefinedMaxValueSwat, "UserDefinedMaxSwat", 1.0, "Max", "", "Min value of the legend", "");
CAF_PDM_InitField(&userDefinedMinValueSwat, "UserDefinedMinSwat", 0.0, "Min", "", "Max value of the legend", "");
m_globalAutoMin.resize(3, 0.0);
m_globalAutoMax.resize(3, 1.0);
m_localAutoMin.resize(3, 0.0);
m_localAutoMax.resize(3, 1.0);
recreateLegend();
updateLegend();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimTernaryLegendConfig::~RimTernaryLegendConfig()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &applyLocalMinMax)
{
userDefinedMaxValueSoil = m_localAutoMax[TERNARY_SOIL_IDX];
userDefinedMinValueSoil = m_localAutoMin[TERNARY_SOIL_IDX];
userDefinedMaxValueSgas = m_localAutoMax[TERNARY_SGAS_IDX];
userDefinedMinValueSgas = m_localAutoMin[TERNARY_SGAS_IDX];
userDefinedMaxValueSwat = m_localAutoMax[TERNARY_SWAT_IDX];
userDefinedMinValueSwat = m_localAutoMin[TERNARY_SWAT_IDX];
applyLocalMinMax = false;
}
else if (changedField == &applyGlobalMinMax)
{
userDefinedMaxValueSoil = m_globalAutoMax[TERNARY_SOIL_IDX];
userDefinedMinValueSoil = m_globalAutoMin[TERNARY_SOIL_IDX];
userDefinedMaxValueSgas = m_globalAutoMax[TERNARY_SGAS_IDX];
userDefinedMinValueSgas = m_globalAutoMin[TERNARY_SGAS_IDX];
userDefinedMaxValueSwat = m_globalAutoMax[TERNARY_SWAT_IDX];
userDefinedMinValueSwat = m_globalAutoMin[TERNARY_SWAT_IDX];
applyGlobalMinMax = false;
}
else if (changedField == &applyFullRangeMinMax)
{
userDefinedMaxValueSoil = 1.0;
userDefinedMinValueSoil = 0.0;
userDefinedMaxValueSgas = 1.0;
userDefinedMinValueSgas = 0.0;
userDefinedMaxValueSwat = 1.0;
userDefinedMinValueSwat = 0.0;
applyFullRangeMinMax = false;
}
updateLabelText();
updateLegend();
if (m_reservoirView) m_reservoirView->updateCurrentTimeStepAndRedraw();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::updateLegend()
{
double soilLower = 0.0;
double soilUpper = 1.0;
double sgasLower = 0.0;
double sgasUpper = 1.0;
double swatLower = 0.0;
double swatUpper = 1.0;
ternaryRanges(soilLower, soilUpper, sgasLower, sgasUpper, swatLower, swatUpper);
cvf::String soilRange;
cvf::String sgasRange;
cvf::String swatRange;
int numberPrecision = 1;
{
QString tmpString = QString::number(soilLower, 'g', numberPrecision) + " - " + QString::number(soilUpper, 'g', numberPrecision);
soilRange = cvfqt::Utils::toString(tmpString);
}
{
QString tmpString = QString::number(sgasLower, 'g', numberPrecision) + " - " + QString::number(sgasUpper, 'g', numberPrecision);
sgasRange = cvfqt::Utils::toString(tmpString);
}
{
QString tmpString = QString::number(swatLower, 'g', numberPrecision) + " - " + QString::number(swatUpper, 'g', numberPrecision);
swatRange = cvfqt::Utils::toString(tmpString);
}
if (!m_legend.isNull())
{
m_legend->setRangeText(soilRange, sgasRange, swatRange);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::setAutomaticRanges(TernaryArrayIndex ternaryIndex, double globalMin, double globalMax, double localMin, double localMax)
{
double candidateGlobalAutoMin = roundToNumSignificantDigits(globalMin, precision);
double candidateGlobalAutoMax = roundToNumSignificantDigits(globalMax, precision);
double candidateLocalAutoMin = roundToNumSignificantDigits(localMin, precision);
double candidateLocalAutoMax = roundToNumSignificantDigits(localMax, precision);
m_globalAutoMin[ternaryIndex] = candidateGlobalAutoMin;
m_globalAutoMax[ternaryIndex] = candidateGlobalAutoMax;
m_localAutoMin[ternaryIndex] = candidateLocalAutoMin;
m_localAutoMax[ternaryIndex] = candidateLocalAutoMax;
updateLabelText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::recreateLegend()
{
// Due to possible visualization bug, we need to recreate the legend if the last viewer
// has been removed, (and thus the opengl resources has been deleted) The text in
// the legend disappeared because of this, so workaround: recreate the legend when needed:
cvf::Font* standardFont = RiaApplication::instance()->standardFont();
m_legend = new RivTernarySaturationOverlayItem(standardFont);
m_legend->setLayout(cvf::OverlayItem::VERTICAL, cvf::OverlayItem::BOTTOM_LEFT);
updateLegend();
}
//--------------------------------------------------------------------------------------------------
/// Rounding the double value to given number of significant digits
//--------------------------------------------------------------------------------------------------
double RimTernaryLegendConfig::roundToNumSignificantDigits(double domainValue, double numSignificantDigits)
{
double absDomainValue = cvf::Math::abs(domainValue);
if (absDomainValue == 0.0)
{
return 0.0;
}
double logDecValue = log10(absDomainValue);
logDecValue = cvf::Math::ceil(logDecValue);
double factor = pow(10.0, numSignificantDigits - logDecValue);
double tmp = domainValue * factor;
double integerPart;
double fraction = modf(tmp, &integerPart);
if (cvf::Math::abs(fraction)>= 0.5) (integerPart >= 0) ? integerPart++: integerPart-- ;
double newDomainValue = integerPart / factor;
return newDomainValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiOrdering* formatGr = uiOrdering.addNewGroup("Format");
formatGr->add(&precision);
formatGr->add(&rangeMode);
if (rangeMode == USER_DEFINED)
{
caf::PdmUiOrdering* ternaryGroupContainer = uiOrdering.addNewGroup("Ternary ");
{
caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SOIL");
ternaryGroup->add(&userDefinedMinValueSoil);
ternaryGroup->add(&userDefinedMaxValueSoil);
}
{
caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SGAS");
ternaryGroup->add(&userDefinedMinValueSgas);
ternaryGroup->add(&userDefinedMaxValueSgas);
}
{
caf::PdmUiOrdering* ternaryGroup = ternaryGroupContainer->addNewGroup("SWAT");
ternaryGroup->add(&userDefinedMinValueSwat);
ternaryGroup->add(&userDefinedMaxValueSwat);
}
ternaryGroupContainer->add(&applyLocalMinMax);
ternaryGroupContainer->add(&applyGlobalMinMax);
ternaryGroupContainer->add(&applyFullRangeMinMax);
}
else
{
caf::PdmUiOrdering* group = uiOrdering.addNewGroup("Summary");
group->add(&ternaryRangeSummary);
}
uiOrdering.setForgetRemainingFields(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::OverlayItem* RimTernaryLegendConfig::legend()
{
return m_legend.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (&applyLocalMinMax == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Apply local min/max values";
}
}
else if (&applyGlobalMinMax == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Apply global min/max values";
}
}
else if (&applyFullRangeMinMax == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = "Apply full range";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::ternaryRanges(double& soilLower, double& soilUpper, double& sgasLower, double& sgasUpper, double& swatLower, double& swatUpper) const
{
if (rangeMode() == AUTOMATIC_CURRENT_TIMESTEP)
{
soilLower = m_localAutoMin[TERNARY_SOIL_IDX];
soilUpper = m_localAutoMax[TERNARY_SOIL_IDX];
sgasLower = m_localAutoMin[TERNARY_SGAS_IDX];
sgasUpper = m_localAutoMax[TERNARY_SGAS_IDX];
swatLower = m_localAutoMin[TERNARY_SWAT_IDX];
swatUpper = m_localAutoMax[TERNARY_SWAT_IDX];
}
else if (rangeMode() == AUTOMATIC_ALLTIMESTEPS)
{
soilLower = m_globalAutoMin[TERNARY_SOIL_IDX];
soilUpper = m_globalAutoMax[TERNARY_SOIL_IDX];
sgasLower = m_globalAutoMin[TERNARY_SGAS_IDX];
sgasUpper = m_globalAutoMax[TERNARY_SGAS_IDX];
swatLower = m_globalAutoMin[TERNARY_SWAT_IDX];
swatUpper = m_globalAutoMax[TERNARY_SWAT_IDX];
}
else
{
soilLower = userDefinedMinValueSoil;
soilUpper = userDefinedMaxValueSoil;
sgasLower = userDefinedMinValueSgas;
sgasUpper = userDefinedMaxValueSgas;
swatLower = userDefinedMinValueSwat;
swatUpper = userDefinedMaxValueSwat;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTernaryLegendConfig::updateLabelText()
{
{
userDefinedMinValueSoil.setUiName("Min");
userDefinedMaxValueSoil.setUiName("Max");
if (m_globalAutoMin[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMinValueSoil.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + ")");
}
if (m_globalAutoMax[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMaxValueSoil.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + ")");
}
}
{
userDefinedMinValueSgas.setUiName("Min");
userDefinedMaxValueSgas.setUiName("Max");
if (m_globalAutoMin[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMinValueSgas.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + ")");
}
if (m_globalAutoMax[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMaxValueSgas.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + ")");
}
}
{
userDefinedMinValueSwat.setUiName("Min");
userDefinedMaxValueSwat.setUiName("Max");
if (m_globalAutoMin[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMinValueSwat.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + ")");
}
if (m_globalAutoMax[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE )
{
userDefinedMaxValueSwat.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + ")");
}
}
if (rangeMode == AUTOMATIC_ALLTIMESTEPS)
{
QString tmpString;
tmpString = QString("SOIL : ") + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + "\n";
tmpString += QString("SGAS : ") + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + "\n";
tmpString += QString("SWAT : ") + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + " - " + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + "\n";
ternaryRangeSummary = tmpString;
}
else if (rangeMode == AUTOMATIC_CURRENT_TIMESTEP)
{
QString tmpString;
tmpString = QString("SOIL : ") + QString::number(m_localAutoMin[TERNARY_SOIL_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SOIL_IDX], 'g', precision) + "\n";
tmpString += QString("SGAS : ") + QString::number(m_localAutoMin[TERNARY_SGAS_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SGAS_IDX], 'g', precision) + "\n";
tmpString += QString("SWAT : ") + QString::number(m_localAutoMin[TERNARY_SWAT_IDX], 'g', precision) + " - " + QString::number(m_localAutoMax[TERNARY_SWAT_IDX], 'g', precision) + "\n";
ternaryRangeSummary = tmpString;
}
}

View File

@@ -0,0 +1,108 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cvfBase.h"
#include "cvfObject.h"
#include "cafAppEnum.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
class RimReservoirView;
class RivTernarySaturationOverlayItem;
namespace cvf
{
class OverlayItem;
}
//==================================================================================================
///
///
//==================================================================================================
class RimTernaryLegendConfig : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
enum TernaryArrayIndex
{
TERNARY_SOIL_IDX = 0,
TERNARY_SGAS_IDX,
TERNARY_SWAT_IDX
};
enum RangeModeType
{
AUTOMATIC_ALLTIMESTEPS,
AUTOMATIC_CURRENT_TIMESTEP,
USER_DEFINED
};
typedef caf::AppEnum<RangeModeType> RangeModeEnum;
public:
RimTernaryLegendConfig();
virtual ~RimTernaryLegendConfig();
void setReservoirView(RimReservoirView* ownerReservoirView) {m_reservoirView = ownerReservoirView; }
void setAutomaticRanges(TernaryArrayIndex ternaryIndex, double globalMin, double globalMax, double localMin, double localMax);
void ternaryRanges(double& soilLower, double& soilUpper, double& sgasLower, double& sgasUpper, double& swatLower, double& swatUpper) const;
void recreateLegend();
cvf::OverlayItem* legend();
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering );
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute);
private:
void updateLegend();
void updateLabelText();
double roundToNumSignificantDigits(double value, double precision);
private:
caf::PdmField<int> precision;
caf::PdmField<RangeModeEnum> rangeMode;
caf::PdmField<double> userDefinedMaxValueSoil;
caf::PdmField<double> userDefinedMinValueSoil;
caf::PdmField<double> userDefinedMaxValueSgas;
caf::PdmField<double> userDefinedMinValueSgas;
caf::PdmField<double> userDefinedMaxValueSwat;
caf::PdmField<double> userDefinedMinValueSwat;
caf::PdmField<bool> applyLocalMinMax;
caf::PdmField<bool> applyGlobalMinMax;
caf::PdmField<bool> applyFullRangeMinMax;
caf::PdmField<QString> ternaryRangeSummary;
std::vector<double> m_globalAutoMax;
std::vector<double> m_globalAutoMin;
std::vector<double> m_localAutoMax;
std::vector<double> m_localAutoMin;
caf::PdmPointer<RimReservoirView> m_reservoirView;
cvf::ref<RivTernarySaturationOverlayItem> m_legend;
};

View File

@@ -19,6 +19,9 @@
//#include "RiaStdInclude.h"
#include "cafPdmDocument.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmUiPropertyDialog.h"
#include <QAction>
#include <QMenu>
@@ -37,7 +40,6 @@
#include "RimInputPropertyCollection.h"
#include "RimExportInputPropertySettings.h"
#include "RiaPreferences.h"
#include "RiuPreferencesDialog.h"
#include "RifEclipseInputFileTools.h"
#include "RimInputCase.h"
#include "RimBinaryExportSettings.h"
@@ -59,9 +61,6 @@
#include "RimWellPathCollection.h"
#include "RimReservoirCellResultsCacher.h"
#include "Rim3dOverlayInfoConfig.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "RimProject.h"
#include "RimOilField.h"
#include "RimAnalysisModels.h"
@@ -834,8 +833,8 @@ void RimUiTreeView::slotWriteInputProperty()
exportSettings.fileName = outputFileName;
}
RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File");
if (preferencesDialog.exec() == QDialog::Accepted)
caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Eclipse Property to Text File");
if (propertyDialog.exec() == QDialog::Accepted)
{
bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword);
if (isOk)
@@ -887,8 +886,8 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty()
exportSettings.fileName = outputFileName;
}
RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File");
if (preferencesDialog.exec() == QDialog::Accepted)
caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File");
if (propertyDialog.exec() == QDialog::Accepted)
{
size_t timeStep = resultSlot->reservoirView()->currentTimeStep();
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel());

View File

@@ -193,6 +193,14 @@ void RigActiveCellInfo::clear()
m_activeCellsBoundingBox.reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigActiveCellInfo::isCoarseningActive() const
{
return m_globalCellResultCount != m_globalActiveCellCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -36,6 +36,7 @@ public:
size_t globalCellCount() const;
size_t globalActiveCellCount() const;
size_t globalCellResultCount() const;
bool isCoarseningActive() const;
bool isActive(size_t globalCellIndex) const;
size_t cellResultIndex(size_t globalCellIndex) const;

View File

@@ -122,9 +122,20 @@ void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, si
size_t tranX, tranY, tranZ;
if (!findTransmissibilityResults(tranX, tranY, tranZ)) return;
minMaxCellScalarValues(tranX, timeStepIndex, min, max);
minMaxCellScalarValues(tranY, timeStepIndex, min, max);
minMaxCellScalarValues(tranZ, timeStepIndex, min, max);
double tranMin;
double tranMax;
minMaxCellScalarValues(tranX, timeStepIndex, tranMin, tranMax);
min = CVF_MIN(tranMin, min);
max = CVF_MAX(tranMax, max);
minMaxCellScalarValues(tranY, timeStepIndex, tranMin, tranMax);
min = CVF_MIN(tranMin, min);
max = CVF_MAX(tranMax, max);
minMaxCellScalarValues(tranZ, timeStepIndex, tranMin, tranMax);
min = CVF_MIN(tranMin, min);
max = CVF_MAX(tranMax, max);
return;
}
@@ -738,9 +749,16 @@ void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_
size_t tranX, tranY, tranZ;
if (findTransmissibilityResults(tranX, tranY, tranZ))
{
posNegClosestToZero(tranX, timeStepIndex, pos, neg);
posNegClosestToZero(tranY, timeStepIndex, pos, neg);
posNegClosestToZero(tranZ, timeStepIndex, pos, neg);
double traPos, traNeg;
posNegClosestToZero(tranX, timeStepIndex, traPos, traNeg);
if ( 0 < traPos && traPos < pos ) pos = traPos;
if ( neg < traNeg && traNeg < 0 ) neg = traNeg;
posNegClosestToZero(tranY, timeStepIndex, traPos, traNeg);
if ( 0 < traPos && traPos < pos ) pos = traPos;
if ( neg < traNeg && traNeg < 0 ) neg = traNeg;
posNegClosestToZero(tranZ, timeStepIndex, traPos, traNeg);
if ( 0 < traPos && traPos < pos ) pos = traPos;
if ( neg < traNeg && traNeg < 0 ) neg = traNeg;
}
return;

View File

@@ -119,7 +119,7 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid)
size_t ni, nj, nk;
mainGrid->neighborIJKAtCellFace(i, j, k, faceEnum, &ni, &nj, &nk);
if (ni != cvf::UNDEFINED_SIZE_T && nj != cvf::UNDEFINED_SIZE_T && nk != cvf::UNDEFINED_SIZE_T)
if (ni < mainGrid->cellCountI() && nj < mainGrid->cellCountJ() && nk < mainGrid->cellCountK())
{
size_t localCellIndex = mainGrid->cellIndexFromIJK(i, j, k);
size_t oppositeCellIndex = mainGrid->cellIndexFromIJK(ni, nj, nk);

View File

@@ -227,7 +227,7 @@ void RigMainGrid::calculateFaults()
RigFault * unNamedFault = new RigFault;
int unNamedFaultIdx = static_cast<int>(m_faults.size());
for (size_t gcIdx = 0 ; gcIdx < m_cells.size(); ++gcIdx)
for (int gcIdx = 0 ; gcIdx < static_cast<int>(m_cells.size()); ++gcIdx)
{
if ( m_cells[gcIdx].isInvalid())
{
@@ -298,8 +298,11 @@ void RigMainGrid::calculateFaults()
if (gcIdx < neighborGlobalCellIdx)
{
RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx);
unNamedFault->faultFaces().push_back(ff);
{
RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborGlobalCellIdx);
unNamedFault->faultFaces().push_back(ff);
}
}
else
{

View File

@@ -34,6 +34,7 @@ RigReservoirBuilderMock::RigReservoirBuilderMock()
m_resultCount = 0;
m_timeStepCount = 0;
m_gridPointDimensions = cvf::Vec3st::ZERO;
m_enableWellData = true;
}
//--------------------------------------------------------------------------------------------------
@@ -134,10 +135,15 @@ void RigReservoirBuilderMock::appendCubeNodes(const cvf::Vec3d& min, const cvf::
void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector<RigCell>& cells)
{
size_t activeCellIndex = 0;
size_t i;
for (i = 0; i < cellCount; i++)
long long i;
size_t cellIndexStart = cells.size();
cells.resize(cells.size() + cellCount);
#pragma omp parallel for
for (i = 0; i < static_cast<long long>(cellCount); i++)
{
RigCell riCell;
RigCell& riCell = cells[cellIndexStart + i];
riCell.setHostGrid(hostGrid);
riCell.setCellIndex(i);
@@ -152,20 +158,6 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun
riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7;
riCell.setParentCellIndex(0);
//TODO: Rewrite active cell info in mock models
/*
if (!(i % 5))
{
riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T);
}
else
{
riCell.setActiveIndexInMatrixModel(activeCellIndex++);
}
*/
cells.push_back(riCell);
}
}
@@ -246,7 +238,10 @@ void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase)
eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions);
addWellData(eclipseCase, eclipseCase->mainGrid());
if (m_enableWellData)
{
addWellData(eclipseCase, eclipseCase->mainGrid());
}
addFaults(eclipseCase);
@@ -317,13 +312,12 @@ bool RigReservoirBuilderMock::inputProperty(RigCaseData* eclipseCase, const QStr
//--------------------------------------------------------------------------------------------------
bool RigReservoirBuilderMock::staticResult(RigCaseData* eclipseCase, const QString& result, std::vector<double>* values)
{
size_t k;
values->resize(eclipseCase->mainGrid()->cells().size());
for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++)
#pragma omp parallel for
for (long long k = 0; k < static_cast<long long>(eclipseCase->mainGrid()->cells().size()); k++)
{
{
values->push_back((k * 2) % eclipseCase->mainGrid()->cells().size());
}
values->at(k) = (k * 2) % eclipseCase->mainGrid()->cells().size();
}
return false;
@@ -346,13 +340,15 @@ bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QStr
double scaleValue = 1.0 + resultIndex * 0.1;
double offsetValue = 100 * resultIndex;
size_t k;
for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++)
values->resize(eclipseCase->mainGrid()->cells().size());
#pragma omp parallel for
for (long long k = 0; k < static_cast<long long>(eclipseCase->mainGrid()->cells().size()); k++)
{
RigCell& cell = eclipseCase->mainGrid()->cells()[k];
{
double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() );
values->push_back(val);
values->at(k) = val;
}
}
@@ -521,3 +517,11 @@ void RigReservoirBuilderMock::addFaults(RigCaseData* eclipseCase)
grid->setFaults(faults);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigReservoirBuilderMock::enableWellData(bool enableWellData)
{
m_enableWellData = false;
}

View File

@@ -48,6 +48,7 @@ public:
void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate);
void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions);
void setResultInfo(size_t resultCount, size_t timeStepCount);
void enableWellData(bool enableWellData);
size_t resultCount() const { return m_resultCount; }
size_t timeStepCount() const { return m_timeStepCount; }
@@ -91,6 +92,7 @@ private:
cvf::Vec3st m_gridPointDimensions;
size_t m_resultCount;
size_t m_timeStepCount;
bool m_enableWellData;
std::vector<LocalGridRefinement> m_localGridRefinements;
};

View File

@@ -16,9 +16,12 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiaStdInclude.h"
#include "RiaSocketCommand.h"
#include "RiaSocketServer.h"
#include "RiaSocketTools.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RimReservoirView.h"
#include "RimResultSlot.h"
@@ -28,8 +31,8 @@
#include "RimWellCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimReservoirCellResultsCacher.h"
#include "RimCase.h"
#include "RigCaseData.h"
#include "RigCaseCellResultsData.h"
@@ -37,6 +40,7 @@
//--------------------------------------------------------------------------------------------------
/// OBSOLETE, to be deleted
//--------------------------------------------------------------------------------------------------
@@ -128,18 +132,9 @@ public:
quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(qint32));
socketStream << timestepByteCount;
// Then write the data.
for (size_t tIdx = 0; tIdx < columnCount; ++tIdx)
{
#if 1 // Write data as raw bytes, fast but does not handle byteswapping
server->currentClient()->write((const char *)activeCellInfo[tIdx].data(), timestepByteCount);
#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well
for (size_t cIdx = 0; cIdx < activeCellInfo[tIdx].size(); ++cIdx)
{
socketStream << activeCellInfo[tIdx][cIdx];
}
#endif
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)activeCellInfo[tIdx].data(), timestepByteCount);
}
return true;

View File

@@ -34,6 +34,9 @@
#include "RigCaseCellResultsData.h"
#include <QTcpSocket>
#include "RiaApplication.h"
#include "RiaPreferences.h"
//--------------------------------------------------------------------------------------------------
@@ -84,11 +87,14 @@ public:
// dv(2) = cellCountK;
// dv(3) = 3;
std::vector<double> cellCenterValues(doubleValueCount);
cvf::Vec3d cornerVerts[8];
quint64 coordCount = 0;
size_t blockByteCount = cellCount * sizeof(double);
std::vector<double> doubleValues(blockByteCount);
for (int coordIdx = 0; coordIdx < 3; coordIdx++)
{
quint64 valueIndex = 0;
for (size_t k = 0; k < cellCountK; k++)
{
for (size_t j = 0; j < cellCountJ; j++)
@@ -98,16 +104,16 @@ public:
size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k);
cvf::Vec3d center = rigGrid->cell(localCellIdx).center();
cellCenterValues[coordCount++] = center[coordIdx];
doubleValues[valueIndex++] = center[coordIdx];
}
}
}
CVF_ASSERT(valueIndex == cellCount);
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount);
}
CVF_ASSERT(coordCount == doubleValueCount);
server->currentClient()->write((const char *)cellCenterValues.data(), byteCount);
return true;
}
};
@@ -149,6 +155,11 @@ public:
size_t activeCellCount = actCellInfo->globalActiveCellCount();
size_t doubleValueCount = activeCellCount * 3;
socketStream << (quint64)activeCellCount;
quint64 byteCount = doubleValueCount * sizeof(double);
socketStream << byteCount;
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
// defined by the ordering of the receiving NDArray
//
@@ -159,28 +170,26 @@ public:
// dv(0) = coordCount;
// dv(1) = 3;
std::vector<double> cellCenterValues(doubleValueCount);
quint64 coordCount = 0;
size_t blockByteCount = activeCellCount * sizeof(double);
std::vector<double> doubleValues(blockByteCount);
for (int coordIdx = 0; coordIdx < 3; coordIdx++)
{
quint64 valueIndex = 0;
for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++)
{
if (!actCellInfo->isActive(globalCellIdx)) continue;
cvf::Vec3d center = mainGrid->cells()[globalCellIdx].center();
cellCenterValues[coordCount++] = center[coordIdx];
doubleValues[valueIndex++] = center[coordIdx];
}
CVF_ASSERT(valueIndex == activeCellCount);
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount);
}
CVF_ASSERT(coordCount == doubleValueCount);
socketStream << (quint64)activeCellCount;
quint64 byteCount = doubleValueCount * sizeof(double);
socketStream << byteCount;
server->currentClient()->write((const char *)cellCenterValues.data(), byteCount);
return true;
}
@@ -241,15 +250,18 @@ public:
// dv(3) = 8;
// dv(4) = 3;
std::vector<double> cellCornerValues(doubleValueCount);
cvf::Vec3d cornerVerts[8];
quint64 coordCount = 0;
size_t blockByteCount = cellCount * sizeof(double);
std::vector<double> doubleValues(blockByteCount);
for (int coordIdx = 0; coordIdx < 3; coordIdx++)
{
for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++)
{
size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx];
quint64 valueIndex = 0;
for (size_t k = 0; k < cellCountK; k++)
{
for (size_t j = 0; j < cellCountJ; j++)
@@ -259,15 +271,17 @@ public:
size_t localCellIdx = rigGrid->cellIndexFromIJK(i, j, k);
rigGrid->cellCornerVertices(localCellIdx, cornerVerts);
cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx];
doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx];
}
}
}
CVF_ASSERT(valueIndex == cellCount);
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount);
}
}
server->currentClient()->write((const char *)cellCornerValues.data(), byteCount);
return true;
}
};
@@ -310,6 +324,10 @@ public:
size_t activeCellCount = actCellInfo->globalActiveCellCount();
size_t doubleValueCount = activeCellCount * 3 * 8;
socketStream << (quint64)activeCellCount;
quint64 byteCount = doubleValueCount * sizeof(double);
socketStream << byteCount;
// This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
// defined by the ordering of the receiving NDArray
//
@@ -321,32 +339,33 @@ public:
// dv(1) = 8;
// dv(2) = 3;
std::vector<double> cellCornerValues(doubleValueCount);
cvf::Vec3d cornerVerts[8];
quint64 coordCount = 0;
size_t blockByteCount = activeCellCount * sizeof(double);
std::vector<double> doubleValues(blockByteCount);
for (int coordIdx = 0; coordIdx < 3; coordIdx++)
{
for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++)
{
size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx];
quint64 valueIndex = 0;
for (size_t globalCellIdx = 0; globalCellIdx < mainGrid->cells().size(); globalCellIdx++)
{
if (!actCellInfo->isActive(globalCellIdx)) continue;
mainGrid->cellCornerVertices(globalCellIdx, cornerVerts);
cellCornerValues[coordCount++] = cornerVerts[cornerIndexMapping][coordIdx];
doubleValues[valueIndex++] = cornerVerts[cornerIndexMapping][coordIdx];
}
CVF_ASSERT(valueIndex == activeCellCount);
RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount);
}
}
socketStream << (quint64)activeCellCount;
quint64 byteCount = doubleValueCount * sizeof(double);
socketStream << byteCount;
server->currentClient()->write((const char *)cellCornerValues.data(), byteCount);
return true;
}

View File

@@ -40,6 +40,9 @@
#include "Rim3dOverlayInfoConfig.h"
#include <QTcpSocket>
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaSocketDataTransfer.h"
//--------------------------------------------------------------------------------------------------
@@ -143,48 +146,60 @@ public:
socketStream << timestepByteCount ;
// Then write the data.
size_t valueCount = RiaSocketDataTransfer::maximumValueCountInBlock();
std::vector<double> values(valueCount);
size_t valueIndex = 0;
size_t globalCellCount = activeInfo->globalCellCount();
for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx)
{
std::vector<double>& doubleValues = scalarResultFrames->at(requestedTimesteps[tIdx]);
for (size_t gcIdx = 0; gcIdx < globalCellCount; ++gcIdx)
{
size_t resultIdx = activeInfo->cellResultIndex(gcIdx);
if (resultIdx != cvf::UNDEFINED_SIZE_T)
if (resultIdx == cvf::UNDEFINED_SIZE_T) continue;
if (resultIdx < doubleValues.size())
{
if (resultIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size())
if (doubleValues.size() == activeInfo->globalCellCount())
{
socketStream << scalarResultFrames->at(requestedTimesteps[tIdx])[resultIdx];
// When reading data from input text files, result data is read for all grid cells
// Read out values from data vector using global cell index instead of active cell result index
// When data is written back to ResInsight using RiaSetActiveCellProperty, the resulting
// data vector will have activeCellCount data values, which is potentially smaller
// than total number of cells
values[valueIndex] = doubleValues[gcIdx];
}
else
{
socketStream << HUGE_VAL;
values[valueIndex] = doubleValues[resultIdx];
}
}
else
{
values[valueIndex] = HUGE_VAL;
}
valueIndex++;
if (valueIndex >= valueCount)
{
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
return false;
}
valueIndex = 0;
}
}
}
#if 0
// This aproach is faster but does not handle coarsening
size_t timestepResultCount = scalarResultFrames->front().size();
quint64 timestepByteCount = (quint64)(timestepResultCount*sizeof(double));
socketStream << timestepByteCount ;
// Then write the data.
for (size_t tIdx = 0; tIdx < requestedTimesteps.size(); ++tIdx)
// Write remaining data
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
#if 1 // Write data as raw bytes, fast but does not handle byteswapping
server->currentClient()->write((const char *)scalarResultFrames->at(requestedTimesteps[tIdx]).data(), timestepByteCount); // Raw print of data. Fast but no platform conversion
#else // Write data using QDataStream, does byteswapping for us. Must use QDataStream on client as well
for (size_t cIdx = 0; cIdx < scalarResultFrames->at(requestedTimesteps[tIdx]).size(); ++cIdx)
{
socketStream << scalarResultFrames->at(tIdx)[cIdx];
}
#endif
return false;
}
#endif
}
}
return true;
}
};
@@ -304,10 +319,6 @@ public:
quint64 timestepCount = (quint64)requestedTimesteps.size();
socketStream << timestepCount;
size_t doubleValueCount = cellCountI * cellCountJ * cellCountK * timestepCount * sizeof(double);
std::vector<double> values(doubleValueCount);
size_t valueIdx = 0;
for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++)
{
cvf::ref<cvf::StructGridScalarDataAccess> cellCenterDataAccessObject = rimCase->reservoirData()->dataAccessObject(rigGrid, porosityModelEnum, requestedTimesteps[tsIdx], scalarResultIndex);
@@ -316,6 +327,9 @@ public:
continue;
}
size_t valueCount = RiaSocketDataTransfer::maximumValueCountInBlock();
std::vector<double> values(valueCount);
size_t valueIndex = 0;
for (size_t cellIdx = 0; cellIdx < rigGrid->cellCount(); cellIdx++)
{
double cellValue = cellCenterDataAccessObject->cellScalar(cellIdx);
@@ -323,12 +337,26 @@ public:
{
cellValue = 0.0;
}
values[valueIdx++] = cellValue;
values[valueIndex++] = cellValue;
if (valueIndex >= valueCount)
{
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
return false;
}
valueIndex = 0;
}
}
// Write remaining data
if (!RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)values.data(), valueIndex * sizeof(double)))
{
return false;
}
}
server->currentClient()->write((const char *)values.data(), doubleValueCount);
return true;
}
};
@@ -553,16 +581,18 @@ public:
internalMatrixData = m_scalarResultsToAdd->at(m_requestedTimesteps[m_currentTimeStepNumberToRead]).data();
}
#if 1 // Use raw data transfer. Faster.
bytesRead = currentClient->read((char*)(internalMatrixData), m_bytesPerTimeStepToRead);
#else
for (size_t cIdx = 0; cIdx < cellCountFromOctave; ++cIdx)
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(internalMatrixData), m_bytesPerTimeStepToRead, errorMessages))
{
socketStream >> internalMatrixData[cIdx];
for (int i = 0; i < errorMessages.size(); i++)
{
server->errorMessageDialog()->showMessage(errorMessages[i]);
}
if (socketStream.status() == QDataStream::Ok) bytesRead += sizeof(double);
currentClient->abort();
return true;
}
#endif
// Map data from active to result index based container ( Coarsening is active)
if (isCoarseningActive)
{
@@ -577,12 +607,6 @@ public:
}
}
if ((int)m_bytesPerTimeStepToRead != bytesRead)
{
server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") +
RiaSocketServer::tr("Could not read binary double data properly from socket"));
}
++m_currentTimeStepNumberToRead;
}
@@ -897,8 +921,17 @@ public:
std::vector<double> doubleValues(cellCountFromOctave);
qint64 bytesRead = currentClient->read((char*)(doubleValues.data()), m_bytesPerTimeStepToRead);
size_t doubleValueIndex = 0;
QStringList errorMessages;
if (!RiaSocketDataTransfer::readBlockDataFromSocket(currentClient, (char*)(doubleValues.data()), m_bytesPerTimeStepToRead, errorMessages))
{
for (int i = 0; i < errorMessages.size(); i++)
{
server->errorMessageDialog()->showMessage(errorMessages[i]);
}
currentClient->abort();
return true;
}
cvf::ref<cvf::StructGridScalarDataAccess> cellCenterDataAccessObject =
m_currentReservoir->reservoirData()->dataAccessObject(grid, m_porosityModelEnum, m_requestedTimesteps[m_currentTimeStepNumberToRead], m_currentScalarIndex);

View File

@@ -0,0 +1,113 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA, Ceetron Solutions 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 "RiaSocketDataTransfer.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaSocketDataTransfer::writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages)
{
quint64 bytesWritten = 0;
int blockCount = 0;
quint64 maxBlockSize = maximumValueCountInBlock() * sizeof(double);
while (bytesWritten < bytesToWrite)
{
quint64 byteCountToWrite = qMin(bytesToWrite - bytesWritten, maxBlockSize);
qint64 actuallyBytesWritten = socket->write(data + bytesWritten, byteCountToWrite);
if (actuallyBytesWritten < 0)
{
errorMessages.push_back("Error detected when writing data, error string from socket");
errorMessages.push_back(socket->errorString());
return false;
}
bytesWritten += actuallyBytesWritten;
blockCount++;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaSocketDataTransfer::readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages)
{
quint64 bytesRead = 0;
quint64 maxBlockSize = maximumValueCountInBlock() * sizeof(double);
while (bytesRead < bytesToRead)
{
if (socket->bytesAvailable())
{
quint64 byteCountToRead = bytesToRead - bytesRead;
byteCountToRead = qMin(byteCountToRead, maxBlockSize);
qint64 actuallyBytesRead = socket->read(data + bytesRead, byteCountToRead);
if (actuallyBytesRead < 0)
{
errorMessages.push_back("Error detected when reading data, error string from socket");
errorMessages.push_back(socket->errorString());
return false;
}
bytesRead += actuallyBytesRead;
#ifdef octave_oct_h
//octave_stdout << "Byte read " << bytesRead << " of a total of "<< bytesToRead << "\n";
#endif
}
else
{
if (!socket->waitForReadyRead())
{
errorMessages.push_back("Waited for data for %1 milli seconds.");
errorMessages.push_back(socket->errorString());
return false;
}
}
// Allow Octave process to end a long running Octave function
#ifdef octave_oct_h
OCTAVE_QUIT;
#endif
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RiaSocketDataTransfer::maximumValueCountInBlock()
{
return 20000;
}

View File

@@ -0,0 +1,36 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA, Ceetron Solutions 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 <QTcpSocket>
#include <QStringList>
//==================================================================================================
/// Utility class used for transfer of data using QTcpSocket
///
/// As the compile configuration for octave plugins is quite complex,
// the octave plugins includes the cpp-file to be able to compile only one file per plugin
//==================================================================================================
class RiaSocketDataTransfer
{
public:
static size_t maximumValueCountInBlock();
public:
static bool writeBlockDataToSocket(QTcpSocket* socket, const char* data, quint64 bytesToWrite, QStringList& errorMessages);
static bool readBlockDataFromSocket(QTcpSocket* socket, char* data, quint64 bytesToRead, QStringList& errorMessages);
};

View File

@@ -16,6 +16,10 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiaStdInclude.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaSocketTools.h"
#include "RiaSocketServer.h"
#include "RimCase.h"
@@ -34,6 +38,9 @@
#include "RimInputPropertyCollection.h"
#include "RiaSocketDataTransfer.h"
#include <QTcpSocket>
//--------------------------------------------------------------------------------------------------
///
@@ -98,4 +105,28 @@ void RiaSocketTools::getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QStri
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaSocketTools::writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite)
{
cvf::Timer timer;
QStringList errorMessages;
bool writeSucceded = RiaSocketDataTransfer::writeBlockDataToSocket(socket, data, bytesToWrite, errorMessages);
if (server)
{
for (int i = 0; i < errorMessages.size(); i++)
{
server->errorMessageDialog()->showMessage(errorMessages[i]);
}
// double totalTimeMS = timer.time() * 1000.0;
// QString resultInfo = QString("Total time '%1 ms'").arg(totalTimeMS);
//
// server->errorMessageDialog()->showMessage(resultInfo);
}
return writeSucceded;
}

View File

@@ -17,6 +17,7 @@
class RimCase;
class RiaSocketServer;
class QTcpSocket;
#define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString );
@@ -25,4 +26,6 @@ class RiaSocketTools
public:
static RimCase* findCaseFromArgs(RiaSocketServer* server, const QList<QByteArray>& args);
static void getCaseInfoFromCase(RimCase* rimCase, qint64& caseId, QString& caseName, QString& caseType, qint64& caseGroupId);
static bool writeBlockData(RiaSocketServer* server, QTcpSocket* socket, const char* data, quint64 bytesToWrite);
};

View File

@@ -43,7 +43,6 @@
#include "RiuMultiCaseImportDialog.h"
#include "RiaPreferences.h"
#include "RiuPreferencesDialog.h"
#include "RigCaseCellResultsData.h"
@@ -63,6 +62,7 @@
#include "RimCalcScript.h"
#include "RimTools.h"
#include "RiaRegressionTest.h"
#include "cafPdmUiPropertyDialog.h"
@@ -199,6 +199,7 @@ void RiuMainWindow::createActions()
m_mockModelAction = new QAction("&Mock Model", this);
m_mockResultsModelAction = new QAction("Mock Model With &Results", this);
m_mockLargeResultsModelAction = new QAction("Large Mock Model", this);
m_mockModelCustomizedAction = new QAction("Customized Mock Model", this);
m_mockInputModelAction = new QAction("Input Mock Model", this);
m_snapshotToFile = new QAction(QIcon(":/SnapShotSave.png"), "Snapshot To File", this);
@@ -226,6 +227,7 @@ void RiuMainWindow::createActions()
connect(m_mockModelAction, SIGNAL(triggered()), SLOT(slotMockModel()));
connect(m_mockResultsModelAction, SIGNAL(triggered()), SLOT(slotMockResultsModel()));
connect(m_mockLargeResultsModelAction, SIGNAL(triggered()), SLOT(slotMockLargeResultsModel()));
connect(m_mockModelCustomizedAction, SIGNAL(triggered()), SLOT(slotMockModelCustomized()));
connect(m_mockInputModelAction, SIGNAL(triggered()), SLOT(slotInputMockModel()));
connect(m_snapshotToFile, SIGNAL(triggered()), SLOT(slotSnapshotToFile()));
@@ -386,6 +388,7 @@ void RiuMainWindow::createMenus()
testMenu->addAction(m_mockModelAction);
testMenu->addAction(m_mockResultsModelAction);
testMenu->addAction(m_mockLargeResultsModelAction);
testMenu->addAction(m_mockModelCustomizedAction);
testMenu->addAction(m_mockInputModelAction);
testMenu->addSeparator();
testMenu->addAction(m_createCommandObject);
@@ -660,7 +663,8 @@ void RiuMainWindow::refreshAnimationActions()
{
if (app->activeReservoirView()->cellResult()->hasDynamicResult()
|| app->activeReservoirView()->propertyFilterCollection()->hasActiveDynamicFilters()
|| app->activeReservoirView()->wellCollection()->hasVisibleWellPipes())
|| app->activeReservoirView()->wellCollection()->hasVisibleWellPipes()
|| app->activeReservoirView()->cellResult()->isTernarySaturationSelected())
{
std::vector<QDateTime> timeStepDates = app->activeReservoirView()->currentGridCellResults()->cellResults()->timeStepDates(0);
bool showHoursAndMinutes = false;
@@ -845,8 +849,6 @@ void RiuMainWindow::slotMockModel()
{
RiaApplication* app = RiaApplication::instance();
app->createMockModel();
//m_mainViewer->setDefaultView();
}
//--------------------------------------------------------------------------------------------------
@@ -856,8 +858,6 @@ void RiuMainWindow::slotMockResultsModel()
{
RiaApplication* app = RiaApplication::instance();
app->createResultsMockModel();
//m_mainViewer->setDefaultView();
}
@@ -870,6 +870,14 @@ void RiuMainWindow::slotMockLargeResultsModel()
app->createLargeResultsMockModel();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuMainWindow::slotMockModelCustomized()
{
RiaApplication* app = RiaApplication::instance();
app->createMockModelCustomized();
}
//--------------------------------------------------------------------------------------------------
///
@@ -1216,8 +1224,8 @@ void RiuMainWindow::slotShowPerformanceInfo(bool enable)
void RiuMainWindow::slotEditPreferences()
{
RiaApplication* app = RiaApplication::instance();
RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences");
if (preferencesDialog.exec() == QDialog::Accepted)
caf::PdmUiPropertyDialog propertyDialog(this, app->preferences(), "Preferences");
if (propertyDialog.exec() == QDialog::Accepted)
{
// Write preferences using QSettings and apply them to the application
app->writeFieldsToApplicationStore(app->preferences());
@@ -1446,9 +1454,9 @@ void RiuMainWindow::slotOpenMultipleCases()
if (1)
{
gridFileNames += "Result Mock Debug Model With Results";
gridFileNames += "Result Mock Debug Model With Results";
gridFileNames += "Result Mock Debug Model With Results";
gridFileNames += RimDefines::mockModelBasicWithResults();
gridFileNames += RimDefines::mockModelBasicWithResults();
gridFileNames += RimDefines::mockModelBasicWithResults();
}
else
{
@@ -1765,7 +1773,7 @@ void RiuMainWindow::slotShowRegressionTestDialog()
RiaApplication* app = RiaApplication::instance();
app->readFieldsFromApplicationStore(&regTestConfig);
RiuPreferencesDialog regressionTestDialog(this, &regTestConfig, "Regression Test");
caf::PdmUiPropertyDialog regressionTestDialog(this, &regTestConfig, "Regression Test");
if (regressionTestDialog.exec() == QDialog::Accepted)
{
// Write preferences using QSettings and apply them to the application

View File

@@ -154,6 +154,7 @@ private:
QAction* m_mockModelAction;
QAction* m_mockResultsModelAction;
QAction* m_mockLargeResultsModelAction;
QAction* m_mockModelCustomizedAction;
QAction* m_mockInputModelAction;
QAction* m_snapshotToFile;
@@ -243,6 +244,7 @@ private slots:
void slotMockModel();
void slotMockResultsModel();
void slotMockLargeResultsModel();
void slotMockModelCustomized();
void slotInputMockModel();
// Windows slots

View File

@@ -1,67 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RiaStdInclude.h"
#include "RiuPreferencesDialog.h"
#include "cafAppEnum.h"
#include "cafPdmObject.h"
#include "RimUiTreeModelPdm.h"
#include "cafPdmUiPropertyView.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle)
: QDialog(parent)
{
CVF_ASSERT(object);
m_pdmObject = object;
m_windowTitle = windowTitle;
setupUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuPreferencesDialog::setupUi()
{
setWindowTitle(m_windowTitle);
m_pdmUiPropertyView = new caf::PdmUiPropertyView(this);
QVBoxLayout* dialogLayout = new QVBoxLayout;
setLayout(dialogLayout);
dialogLayout->addWidget(m_pdmUiPropertyView);
m_pdmUiPropertyView->showProperties(m_pdmObject);
// Buttons
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
dialogLayout->addWidget(buttonBox);
this->resize(400, 200);
}

View File

@@ -742,3 +742,19 @@ void RiuViewer::mousePressEvent(QMouseEvent* event)
m_lastMousePressPosition = event->pos();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuViewer::addOverlayItem(cvf::OverlayItem* overlayItem)
{
m_renderingSequence->firstRendering()->addOverlayItem(overlayItem);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuViewer::removeOverlayItem(cvf::OverlayItem* overlayItem)
{
m_renderingSequence->firstRendering()->removeOverlayItem(overlayItem);
}

View File

@@ -34,6 +34,7 @@ class QCDEStyle;
namespace cvf
{
class Part;
class OverlayItem;
}
//==================================================================================================
@@ -64,6 +65,10 @@ public:
void setHistogramPercentiles(double pmin, double pmax, double mean);
void showAnimationProgress(bool enable);
void addOverlayItem(cvf::OverlayItem* overlayItem);
void removeOverlayItem(cvf::OverlayItem* overlayItem);
public slots:
virtual void slotSetCurrentFrame(int frameIndex);

View File

@@ -93,8 +93,30 @@ include (${QT_USE_FILE})
find_package( OpenGL )
################################################################################
# CeeViz
# Vizualization Framework
################################################################################
# Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support
if (CMAKE_COMPILER_IS_GNUCC)
if (NOT DEFINED HAVE_GCC_SYNC_FUNCTIONS)
check_c_source_compiles("int main(int argc, char **argv) {
int a;
__sync_add_and_fetch(&a, 1);
__sync_fetch_and_add(&a, 1);
__sync_sub_and_fetch(&a, 1);
__sync_fetch_and_sub(&a, 1); }" HAVE_GCC_SYNC_FUNCTIONS)
endif()
if (HAVE_GCC_SYNC_FUNCTIONS)
message("GCC synchronization functions detected")
else()
message("GCC synchronization functions NOT detected, fallback to non threadsafe reference counting")
add_definitions(-DCVF_USE_NON_THREADSAFE_REFERENCE_COUNT)
endif()
endif()
add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibCore)
add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibGeometry)
add_subdirectory(${VIZ_MODULES_FOLDER_NAME}/LibRender)
@@ -111,7 +133,7 @@ include_directories(
################################################################################
# Ceetron Application Framework
# Application Framework
################################################################################
add_subdirectory(Fwk/AppFwk/cafProjectDataModel)

View File

@@ -3,40 +3,84 @@
-----
## Faults
ResInsight can import faults from `*.DATA` files, and is available in the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**. The imported faults are ordered in ascending order based on name.
ResInsight will detect all the cell faces with no geometrically matching neighbors, and display them as *Faults*.
This means that the are drawn in special ways, and that their visual appearance can be controlled separately from the rest of the grid.
As import of faults can be time consuming, reading of faults can be disabled from **Preferences -> Read fault data**
### Fault Names and NNC
A fault is defined as a set of cell faces. When clicking on a fault, the fault name is displayed in **Result Info**. Results can be mapped onto a fault, and **Dynamic Face Selection** controls the cell result mapping onto faults. Faults are given a color on import, and this color can be controlled by activating the fault and select **Fault color**.
#### Import of Fault info from `*.DATA`-files
If enabled, ResInsight will also import fault information from the `*.DATA` files and use this information to group the detected faces into named items which is available in the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**. The imported faults are ordered in ascending order based on their name.
When clicking on a NNC, the relevant data for this NNC is displayed in the **Result Info**. The static result **TRANSXYZ** can be mapped onto NNC geometry.
>
***Note:*** As import of faults can be time consuming, reading of faults can be disabled from **Preferences -> Read fault data**
ResInsight will detect all cell faces with no matching neighbor. All detected cell faces are compared to faults imported from disk, and if no fault face is defined for a cell face, the cell face is added to a fault called **Undefined grid faults**.
#### Undefined grid faults
All the detected cell faces are compared to the faults imported from the `*.DATA` file in order to group them. If a particular face is *not* found among the fault faces defined in the `*.DATA` file or it's opposite face, the cell face is added to a fault called **Undefined grid faults**. This particular Fault will always be present, even if reading of the `*.DATA` file is disabled.
### Toolbar control
#### Fault color
Each named Fault is given a color on import. This color can be controlled by selecting the fault and edit its **Fault color** in the **Property Editor.**
#### NNC visualization
ResInsight will read Non Neighbor Connections from the Eclipse output file (`*.INIT`), and create explicit visualizations of those witch have a common surface area. These NNC's are then sorted onto the Fault's and their visibility is controlled from the **Property Editor** of the **Faults** Item in the **Project Tree**.
The color of the NNC faces are set to be a bit lighter than their corresponding named fault, and can not be controlled directly.
Currently the only result property that is mapped onto the NNC is the static TRANSXYZ property which displays the transmissibility associated to each face.
### Picking info
When clicking on a cell face that is member of a fault, the fault name is displayed in the **Result Info** window, along with cell, and result property info.
When clicking on a NNC, the relevant data for this NNC is displayed.
### Fault visualization options
#### Toolbar control
Visualization mode and mesh lines can be controlled from the toolbar.
- ![](images/draw_style_faults_24x24.png) Toggle button to control faults only visualization mode
- ![](images/draw_style_surface_24x24.png) Shows surface visualization
- ![](images/draw_style_surface_w_fault_mesh_24x24.png) Shows mesh lines on faults
- ![](images/draw_style_faults_24x24.png) **Faults-Only** visualization mode.
<br>When turned on, this option hides all the grid cells, and shows only the fault faces in the reservoir limited by the applied range and property filters. (Unless **Show faults outside filters** are turned on. See below.)
- ![](images/draw_style_surface_24x24.png) Turns faces on and mesh off
- ![](images/draw_style_surface_w_fault_mesh_24x24.png) Turns on all faces, and shows meshlines on faults only.
<br> This is a useful method to highlight the faults in your reservoir, because the faults stands out with black outlining.
- ![](images/draw_style_faults_label_24x24.png) Shows labels for faults
### Common Fault Options
By clicking the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**, the following options are displayed:
#### Common Fault Options
By clicking the ![](images/draw_style_faults_24x24.png) **Faults** item in the **Project Tree**, the following options common to all the faults are displayed:
![](images/FaultProperties.png)
- **Show labels**: Displays one label per fault with fault name
##### Fault labels
- **Show labels**: Displays one label per fault with the name defined in the `*.DATA`-file
- **Label color**: Defines the label color
- **Show faults outside filters**: Default behavior is to hide faults outside filters. Turning this option on, will display faults outside filter region.
- **Show results on faults**: Map currently selected result onto fault. **Dynamic Face Selection** controls which cell results to map onto faults.
- **Show NNCs**: Displays non neighborhood connections (see details below)
##### Fault options
- **Show faults outside filters**: Turning this option on, will display faults outside the filter region, making the fault visualization completely ignore the Range and Property filters in action.
- **Show results on faults**: This toggle controls whether to show the selected result property on the faults or not. This should normally be left on.
- **Show NNCs**: Toggles whether to display the Non Neighbor Connections, or not.
##### Fault Face Visibility
This group of options controls the visibility of the fault faces. Since they work together, and in some cases are overridden by the system, they can be a bit confusing.
First of all. These options are only available in **Faults-only** visualization mode. ( See *Toolbar Control* above) When not in **Faults-Only** mode, ResInsight overrides the options, and the controls are inactive.
Secondly: The option you would normally want to adjust is **Dynamic Face Selection** (See below).
- **Show defined faces**: Displays the fault cell faces that are defined on the Eclipse input file (`*.DATA`)
- **Show opposite faces**: Displays the opposite fault cell faces from what is defined on the input file, based on IJK neighbors.
<br> *These two options should normally be left **On***. <br>They are useful when investigating the exact faults information provided on the `*.DATA` file.
<br>If you need to use them, it is normally wise to set the **Dynamic Face Selection** to "Show Both"
######Dynamic Face Selection:
At one particular position on a fault there are usually two cells competing for your attention: The cell closer to you as the viewer, or the one further from you. When showing results, this becomes important because these two cell faces have different result property values, and thus color.
This option controls which of the two cell faces you actually can see: The one behind the fault, or the one in front of the fault. There is also an option of showing both, which will give you an undefined mixture, making it hard to be certain what you see.
This means that ResInsight turns on or off the faces based on your view position and this option to make sure that you always see the faces (and thus the result property) you request.
- **Show defined faces**: Displays the defined fault cell faces
- **Show opposite faces**: Displays the opposite fault cell faces based on IJK neighbor data
- **Dynamic Face Selection**: Controls mapping of cell results onto a fault, either from cell in front of fault, from cell behind fault or both.
------
[ Contents ](UsersGuide.md#contents)

View File

@@ -13,6 +13,11 @@ Below is a description of the most important View settings and their properties.
The **Cell Result** item defines which Eclipse property the 3D View uses for the main cell color. The property can be chosen in the property panel of the **Cell Result** item. The mapping between cell values and color is defined by the **Legend Definition** ![](images/Legend.png) along with some appearance settings on the Legend itself. (Number format etc.)
#### TRANSXYZ
Normally the Cell Result setting gives one cell color based on the legend and the selected Result Property. This is *not* the case for the special static TRANXYZ property. This property gives each face the correct color based on the TRANS value that is associated with that particular face.
The Positive I-face of the cell gets the cell TRANX value, while the J-face gets the TRANY-value etc. The negative faces, however, get the value from the neighbor cell in that direction. The negative I-face gets the TRANX value of the IJK-neighbor in negative I direction, and so on for the -J and -K faces.
### Cell Edge Results ![](images/EdgeResult_1.png)
The **Cell Edge Result** visualization mode is one of ResInsight's special features. Its main use is to show the MULT(X, Y, Z) properties at the same time.

View File

@@ -1,4 +1,4 @@
# ![](images/AppLogo48x48.png) ResInsight 1.1 Users Guide
# ![](images/AppLogo48x48.png) ResInsight 1.2 Users Guide
## Introduction

View File

@@ -107,7 +107,7 @@ cvf::String CommonShaderSources::light_AmbientDiffuse()
//--------------------------------------------------------------------------------------------------
/// Static helper to configure polygon offset render state from enum
//--------------------------------------------------------------------------------------------------
static cvf::ref<cvf::RenderStatePolygonOffset> CreateAngConfigurePolygonOffsetRenderState(PolygonOffset polygonOffset)
cvf::ref<cvf::RenderStatePolygonOffset> EffectGenerator::createAndConfigurePolygonOffsetRenderState(PolygonOffset polygonOffset)
{
cvf::ref<cvf::RenderStatePolygonOffset> rs = new cvf::RenderStatePolygonOffset;
if (polygonOffset == PO_NONE)
@@ -301,7 +301,7 @@ void SurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
{
if (m_polygonOffset != PO_NONE)
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = CreateAngConfigurePolygonOffsetRenderState(m_polygonOffset);
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset);
effect->setRenderState(polyOffset.p());
}
@@ -479,7 +479,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
if (m_polygonOffset != PO_NONE)
{
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = CreateAngConfigurePolygonOffsetRenderState(m_polygonOffset);
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset);
effect->setRenderState(polyOffset.p());
}

View File

@@ -44,6 +44,7 @@
#include "cvfTextureImage.h"
#include "cvfCollection.h"
#include "cvfString.h"
#include "cvfRenderStatePolygonOffset.h"
namespace caf {
@@ -96,6 +97,8 @@ public:
static void clearEffectCache();
static void releaseUnreferencedEffects();
static cvf::ref<cvf::RenderStatePolygonOffset> createAndConfigurePolygonOffsetRenderState(caf::PolygonOffset polygonOffset);
protected:
// Interface that must be implemented in base classes

View File

@@ -31,5 +31,6 @@ add_library( ${PROJECT_NAME}
cafPdmUiOrdering.h
cafPdmUiTreeOrdering.cpp
cafPdmUiTreeOrdering.h
cafPdmUiTreeEditorHandle.h
cafPdmUiTreeEditorHandle.cpp
)

View File

@@ -171,7 +171,7 @@ class PdmField <DataType*> : public PdmFieldHandle
{
typedef DataType* DataTypePtr;
public:
PdmField() : PdmFieldHandle() { m_fieldValue = NULL; }
PdmField() : PdmFieldHandle() { }
PdmField(const PdmField& other);
PdmField(const DataTypePtr& fieldValue);
virtual ~PdmField();

View File

@@ -292,7 +292,7 @@ void caf::PdmField<DataType*>::readFieldData(QXmlStreamReader& xmlStream)
}
else
{
if (dynamic_cast<DataType *>(obj) == NULL)
if (obj->classKeyword() != className)
{
assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword
@@ -341,7 +341,7 @@ void caf::PdmField<DataType*>::readFieldData(QXmlStreamReader& xmlStream)
template<typename DataType >
void caf::PdmField<DataType*>::writeFieldData(QXmlStreamWriter& xmlStream)
{
if (m_fieldValue == NULL) return;
if (m_fieldValue.rawPtr() == NULL) return;
QString className = m_fieldValue.rawPtr()->classKeyword();
@@ -397,7 +397,7 @@ template<typename DataType >
caf::PdmField<DataType*>::~PdmField()
{
if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this);
m_fieldValue = NULL;
m_fieldValue.setRawPtr(NULL);
}
//--------------------------------------------------------------------------------------------------
@@ -553,7 +553,6 @@ size_t PdmPointersField<DataType*>::count(const DataType* pointer) const
template<typename DataType>
void PdmPointersField<DataType*>::clear()
{
this->removeThisAsParentField();
m_pointers.clear();
}
@@ -567,7 +566,7 @@ void PdmPointersField<DataType*>::deleteAllChildObjects()
size_t index;
for (index = 0; index < m_pointers.size(); ++index)
{
delete(m_pointers[index]);
delete(m_pointers[index].rawPtr());
}
m_pointers.clear();
@@ -579,7 +578,11 @@ void PdmPointersField<DataType*>::deleteAllChildObjects()
template<typename DataType>
void PdmPointersField<DataType*>::erase(size_t index)
{
if (m_pointers[index]) m_pointers[index]->removeParentField(this);
if (m_pointers[index])
{
m_pointers[index]->removeParentField(this);
}
m_pointers.erase(m_pointers.begin() + index);
}
@@ -589,21 +592,23 @@ void PdmPointersField<DataType*>::erase(size_t index)
template<typename DataType>
void PdmPointersField<DataType*>::removeChildObject(PdmObject* object)
{
DataType* pointer = dynamic_cast<DataType*>(object);
size_t index;
std::vector< PdmPointer<DataType> > tempPointers;
tempPointers = m_pointers;
m_pointers.clear();
for (index = 0; index < tempPointers.size(); ++index)
for (size_t index = 0; index < tempPointers.size(); ++index)
{
if (tempPointers[index] != pointer)
if (tempPointers[index].rawPtr() != object)
{
m_pointers.push_back(tempPointers[index]);
}
else
{
if (tempPointers[index]) tempPointers[index]->removeParentField(this);
if (tempPointers[index].rawPtr())
{
tempPointers[index].rawPtr()->removeParentField(this);
}
}
}
}
@@ -618,12 +623,12 @@ template<typename DataType>
typename std::vector< PdmPointer<DataType> >::iterator it;
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
{
if (*it == NULL) continue;
if (it->rawPtr() == NULL) continue;
QString className = (*it)->classKeyword();
QString className = it->rawPtr()->classKeyword();
xmlStream.writeStartElement("", className);
(*it)->writeFields(xmlStream);
it->rawPtr()->writeFields(xmlStream);
xmlStream.writeEndElement();
}
}
@@ -661,9 +666,7 @@ template<typename DataType>
continue;
}
currentObject = dynamic_cast<DataType *> (obj);
if (currentObject == NULL)
if (obj->classKeyword() != className)
{
assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword
@@ -678,8 +681,11 @@ template<typename DataType>
continue;
}
currentObject->readFields(xmlStream);
this->push_back(currentObject);
obj->readFields(xmlStream);
m_pointers.push_back(PdmPointer<DataType>());
m_pointers.back().setRawPtr(obj);
obj->addParentField(this);
// Jump off the end element, and head for next start element (or the final EndElement of the field)
// Qt reports a character token between EndElements and StartElements so skip it
@@ -700,7 +706,7 @@ void PdmPointersField<DataType*>::childObjects(std::vector<PdmObject*>* objects)
size_t i;
for (i = 0; i < m_pointers.size(); ++i)
{
objects->push_back(m_pointers[i]);
objects->push_back(m_pointers[i].rawPtr());
}
}
@@ -715,7 +721,7 @@ void PdmPointersField<DataType*>::removeThisAsParentField()
{
if (!it->isNull())
{
(*it)->removeParentField(this);
it->rawPtr()->removeParentField(this);
}
}
}

View File

@@ -421,7 +421,7 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/)
}
}
expandUiTree(uiTreeOrdering, uiConfigName);
addUiTreeChildren(uiTreeOrdering, uiConfigName);
return uiTreeOrdering;
}
@@ -429,13 +429,13 @@ PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
{
if (!root) return;
if ( root->childCount() == 0)
if ( root->childCount() == 0) // This means that no one has tried to expand it.
{
if (!root->isSubTreeDefined() && root->dataObject())
if (!root->ignoreSubTree() && root->dataObject())
{
if (root->m_field && !root->m_field->isUiChildrenHidden(uiConfigName))
@@ -449,7 +449,7 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "
}
else
{
root->dataObject()->defineUiTreeOrdering(*root, uiConfigName);
root->object()->defineUiTreeOrdering(*root, uiConfigName);
}
}
}
@@ -457,9 +457,9 @@ void PdmObject::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "
for (int cIdx = 0; cIdx < root->childCount(); ++cIdx)
{
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(root->child(cIdx));
if (!child->isSubTreeDefined())
if (!child->ignoreSubTree())
{
expandUiTree(child);
addUiTreeChildren(child);
}
}
}

View File

@@ -255,7 +255,7 @@ private:
private:
/// Recursive function to traverse and create a Ui tree representation of the object hierarchy
static void expandUiTree( PdmUiTreeOrdering* root, QString uiConfigName = "" );
static void addUiTreeChildren( PdmUiTreeOrdering* root, QString uiConfigName = "" );
private:
std::multiset<PdmFieldHandle*> m_parentFields;

View File

@@ -59,6 +59,8 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent)
//--------------------------------------------------------------------------------------------------
void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object)
{
cleanupBeforeSettingPdmObject();
this->bindToPdmItem(object);
}

View File

@@ -66,6 +66,7 @@ public:
protected:
virtual QWidget* createWidget(QWidget* parent) = 0;
virtual void cleanupBeforeSettingPdmObject() {};
protected:
QPointer<QWidget> m_widget;

View File

@@ -0,0 +1,76 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiTreeEditorHandle.h"
#include "cafPdmObject.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* PdmUiTreeEditorHandle::getOrCreateWidget(QWidget* parent)
{
if (m_widget.isNull())
{
m_widget = this->createWidget(parent);
}
return m_widget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeEditorHandle::setPdmItemRoot(PdmUiItem* root)
{
cleanupBeforeSettingPdmObject();
this->bindToPdmItem(root);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiItem* PdmUiTreeEditorHandle::pdmItemRoot()
{
return this->pdmItem();
}
} //End of namespace caf

View File

@@ -0,0 +1,78 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <vector>
#include <QString>
#include <QWidget>
#include <QPointer>
#include "cafPdmUiEditorHandle.h"
#include "cafPdmPointer.h"
namespace caf
{
class PdmObject;
//==================================================================================================
/// Abstract class to handle editors for complete PdmObjects
//==================================================================================================
class PdmUiTreeEditorHandle: public PdmUiEditorHandle
{
public:
PdmUiTreeEditorHandle() {}
~PdmUiTreeEditorHandle() {}
QWidget* getOrCreateWidget(QWidget* parent);
QWidget* widget() { return m_widget; }
void setPdmItemRoot(PdmUiItem* root);
PdmUiItem* pdmItemRoot();
protected:
virtual QWidget* createWidget(QWidget* parent) = 0;
virtual void cleanupBeforeSettingPdmObject() {};
protected:
QPointer<QWidget> m_widget;
};
} // End of namespace caf

View File

@@ -65,7 +65,11 @@ namespace caf
PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName)
{
PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL);
to->m_uiInfo = new PdmUiItemInfo(title, QIcon(iconResourceName));
to->m_uiItem = new PdmUiItem();
to->m_uiItem->setUiName(title);
to->m_uiItem->setUiIcon(QIcon(iconResourceName));
return to;
}
@@ -98,7 +102,7 @@ namespace caf
{
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx));
if (child->dataObject() == object)
if (child->object() == object)
{
return true;
}
@@ -112,15 +116,27 @@ namespace caf
/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added
/// at the end of parents existing child list.
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : UiTreeItem< PdmPointer<PdmObject> >(parent, position, dataObject),
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : PdmUiTreeItem(parent, position, this),
m_field(NULL),
m_uiInfo(NULL),
m_forgetRemainingFields(false),
m_isSubTreeDefined(false)
m_isToIgnoreSubTree(false),
m_uiItem(NULL),
m_object(dataObject)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeOrdering::~PdmUiTreeOrdering()
{
if (m_uiItem)
{
delete m_uiItem;
}
}
} //End of namespace caf

View File

@@ -49,16 +49,19 @@ namespace caf
class PdmObject;
class PdmFieldHandle;
//typedef UiTreeItem<PdmPointer<PdmObject> > PdmUiTreeItem;
class PdmUiTreeOrdering;
typedef UiTreeItem<PdmUiTreeOrdering* > PdmUiTreeItem;
//==================================================================================================
/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui
//==================================================================================================
class PdmUiTreeOrdering : public UiTreeItem< PdmPointer<PdmObject> >
class PdmUiTreeOrdering : public UiTreeItem< PdmUiTreeOrdering* >
{
public:
PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL);
~PdmUiTreeOrdering();
void add(PdmFieldHandle * field);
void add(PdmObject* object);
@@ -67,23 +70,26 @@ public:
/// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true.
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
/// To stop the tree generation at this level, setSubTreeDefined to true
void setSubTreeDefined(bool isSubTreeDefined ) { m_isSubTreeDefined = isSubTreeDefined; }
void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; }
PdmObject* object() const { return m_object; }
PdmFieldHandle* field() const { return m_field; }
PdmUiItem* uiItem() const { return m_uiItem; }
private:
friend class PdmObject;
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
bool isSubTreeDefined() const { return m_isSubTreeDefined; }
bool ignoreSubTree() const { return m_isToIgnoreSubTree; }
bool containsField(const PdmFieldHandle* field);
bool containsObject(const PdmObject* object);
private:
PdmPointer<PdmObject> m_object;
PdmFieldHandle* m_field;
PdmUiItemInfo* m_uiInfo;
PdmUiItem* m_uiItem;
bool m_forgetRemainingFields;
bool m_isSubTreeDefined;
bool m_isToIgnoreSubTree;
};

View File

@@ -14,6 +14,9 @@ include_directories (
add_executable (${PROJECT_NAME}
cafPdmBasicTest.cpp
cafProjectDataModel_UnitTests.cpp
Child.cpp
Parent.cpp
TestObj.cpp
${CMAKE_SOURCE_DIR}/cafTests/gtest/gtest-all.cpp
)

View File

@@ -0,0 +1,13 @@
#include "Child.h"
#include "TestObj.h"
CAF_PDM_SOURCE_INIT(Child, "Child");
Child::Child()
{
CAF_PDM_InitFieldNoDefault(&m_testObj, "Numbers", "Important Numbers", "", "", "");
}
Child::~Child()
{
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class TestObj;
class Child: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Child();
~Child();
caf::PdmField<TestObj*> m_testObj;
};

View File

@@ -0,0 +1,32 @@
#include "Parent.h"
//#include "Child.h"
CAF_PDM_SOURCE_INIT(Parent, "Parent");
Parent::Parent()
{
CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_simpleObjectF, "SimpleObject", "A child object", "", "", "");
}
Parent::~Parent()
{
}
void Parent::doSome()
{
size_t i = m_simpleObjectsField.size();
if (i){
//Child* c = m_simpleObjectsField[0];
//TestObj* to = c->m_testObj();
}
}
#include <gtest/gtest.h>
TEST(IncludeTest, Basic)
{
Parent* p = new Parent;
delete(p);
}

View File

@@ -0,0 +1,52 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#if 0
class PdmPointerTarget
{
public:
PdmPointerTarget() {}
PdmPointerTarget(const PdmPointerTarget& ) {}
PdmPointerTarget& operator=(const PdmPointerTarget& ) {}
virtual ~PdmPointerTarget()
{
// Set all guarded pointers pointing to this to NULL
std::set<PdmObject**>::iterator it;
for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it)
{
(**it) = NULL;
}
}
private:
// Support system for PdmPointer
friend class PdmPointerImpl;
std::set<PdmPointerTarget**> m_pointersReferencingMe;
};
#endif
class Child;
class Parent: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Parent();
~Parent();
void doSome();
caf::PdmPointersField<Child*> m_simpleObjectsField;
caf::PdmField<Child*> m_simpleObjectF;
};

View File

@@ -0,0 +1,11 @@
#include "TestObj.h"
CAF_PDM_SOURCE_INIT(TestObj, "TestObj");
TestObj::TestObj()
{
CAF_PDM_InitObject("TestObj", "", "", "");
CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", "");
}
TestObj::~TestObj() {}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
class TestObj: public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
TestObj();
~TestObj();
caf::PdmField<double> m_position;
};

View File

@@ -11,6 +11,7 @@ set( QOBJECT_HEADERS
cafUiTreeModelPdm.h
cafUiProcess.h
cafPdmSettings.h
cafPdmUiLineEditor.h
cafPdmUiCheckBoxEditor.h
cafPdmUiComboBoxEditor.h
@@ -24,7 +25,9 @@ set( QOBJECT_HEADERS
cafPdmUiColorEditor.h
cafPdmUiPropertyView.h
cafPdmUiPropertyDialog.h
cafPdmUiTreeView.h
cafPdmUiTreeViewModel.h
cafPdmUiListView.h
cafPdmUiListViewEditor.h
)
@@ -37,6 +40,7 @@ endif()
add_library( ${PROJECT_NAME}
cafAboutDialog.cpp
cafAboutDialog.h
cafPdmSettings.cpp
cafPdmUiCheckBoxEditor.cpp
cafPdmUiCheckBoxEditor.h
cafPdmUiColorEditor.cpp
@@ -56,6 +60,8 @@ add_library( ${PROJECT_NAME}
cafPdmUiListViewEditor.cpp
cafPdmUiListViewEditor.h
cafPdmUiListView.cpp
cafPdmUiPropertyDialog.cpp
cafPdmUiPropertyDialog.h
cafPdmUiPropertyView.cpp
cafPdmUiPropertyView.h
cafPdmUiPushButtonEditor.cpp
@@ -66,6 +72,8 @@ add_library( ${PROJECT_NAME}
cafPdmUiTextEditor.h
cafPdmUiTreeViewEditor.cpp
cafPdmUiTreeViewEditor.h
cafPdmUiTreeViewModel.cpp
cafPdmUiTreeViewModel.h
cafPdmUiTreeView.cpp
cafProgressInfo.cpp
cafProgressInfo.h

View File

@@ -0,0 +1,116 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmSettings.h"
#include "cafPdmField.h"
#include <assert.h>
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Settings::readFieldsFromApplicationStore(caf::PdmObject* object)
{
// Qt doc :
//
// Constructs a QSettings object for accessing settings of the application and organization
// set previously with a call to QCoreApplication::setOrganizationName(),
// QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName().
QSettings settings;
QString prefix = object->classKeyword();
if (!prefix.isEmpty())
{
prefix += "/";
}
std::vector<caf::PdmFieldHandle*> fields;
object->fields(fields);
size_t i;
for (i = 0; i < fields.size(); i++)
{
caf::PdmFieldHandle* fieldHandle = fields[i];
QString keywordWithPrefix = prefix + fieldHandle->keyword();
if (settings.contains(keywordWithPrefix))
{
QVariant val = settings.value(keywordWithPrefix);
fieldHandle->setValueFromUi(val);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Settings::writeFieldsToApplicationStore(caf::PdmObject* object)
{
assert(object);
// Qt doc :
//
// Constructs a QSettings object for accessing settings of the application and organization
// set previously with a call to QCoreApplication::setOrganizationName(),
// QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName().
QSettings settings;
QString prefix = object->classKeyword();
if (!prefix.isEmpty())
{
prefix += "/";
}
std::vector<caf::PdmFieldHandle*> fields;
object->fields(fields);
size_t i;
for (i = 0; i < fields.size(); i++)
{
caf::PdmFieldHandle* fieldHandle = fields[i];
QString keywordWithPrefix = prefix + fieldHandle->keyword();
settings.setValue(keywordWithPrefix, fieldHandle->uiValue());
}
}
} // namespace caf

View File

@@ -0,0 +1,55 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <QSettings>
namespace caf
{
class PdmObject;
class Settings
{
public:
static void readFieldsFromApplicationStore(caf::PdmObject* object);
static void writeFieldsToApplicationStore(caf::PdmObject* object);
};
} // end namespace caf

View File

@@ -65,10 +65,11 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, QString);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, quint64);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<QString>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<int>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<unsigned int>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<float>);

View File

@@ -0,0 +1,92 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiPropertyDialog.h"
#include "cafPdmObject.h"
#include "cafPdmUiPropertyView.h"
#include <QVBoxLayout>
#include <QDialogButtonBox>
#include <assert.h>
namespace caf {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiPropertyDialog::PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle)
: QDialog(parent)
{
assert(object);
m_pdmObject = object;
m_windowTitle = windowTitle;
setupUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiPropertyDialog::setupUi()
{
setWindowTitle(m_windowTitle);
m_pdmUiPropertyView = new caf::PdmUiPropertyView(this);
QVBoxLayout* dialogLayout = new QVBoxLayout;
setLayout(dialogLayout);
dialogLayout->addWidget(m_pdmUiPropertyView);
m_pdmUiPropertyView->showProperties(m_pdmObject);
// Buttons
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
dialogLayout->addWidget(buttonBox);
this->resize(400, 200);
}
} // end namespace caf

View File

@@ -0,0 +1,70 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <QDialog>
namespace caf
{
class PdmObject;
class PdmUiPropertyView;
//==================================================================================================
//
//
//
//==================================================================================================
class PdmUiPropertyDialog : public QDialog
{
Q_OBJECT
public:
PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle);
private:
void setupUi();
private:
QString m_windowTitle;
caf::PdmObject* m_pdmObject;
caf::PdmUiPropertyView* m_pdmUiPropertyView;
};
} // end namespace caf

View File

@@ -0,0 +1,567 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmUiTreeViewModel.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmUiTreeOrdering.h"
namespace caf
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeViewModel::PdmUiTreeViewModel(QObject* parent)
{
m_treeItemRoot = NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::setTreeItemRoot(PdmUiTreeItem* root)
{
beginResetModel();
if (m_treeItemRoot)
{
delete m_treeItemRoot;
}
m_treeItemRoot = root;
endResetModel();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
// if (!m_treeItemRoot)
// return QModelIndex();
if (!hasIndex(row, column, parentIndex))
return QModelIndex();
PdmUiTreeItem* parentItem = NULL;
if (!parentIndex.isValid())
parentItem = m_treeItemRoot;
else
parentItem = static_cast<PdmUiTreeItem*>(parentIndex.internalPointer());
PdmUiTreeItem* childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const
{
// if (!m_treeItemRoot) return QModelIndex();
if (!childIndex.isValid()) return QModelIndex();
PdmUiTreeItem* childItem = static_cast<PdmUiTreeItem*>(childIndex.internalPointer());
if (!childItem) return QModelIndex();
PdmUiTreeItem* parentItem = childItem->parent();
if (!parentItem) return QModelIndex();
if (parentItem == m_treeItemRoot) return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
if (!m_treeItemRoot)
return 0;
if (parentIndex.column() > 0)
return 0;
PdmUiTreeItem* parentItem;
if (!parentIndex.isValid())
parentItem = m_treeItemRoot;
else
parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex);
return parentItem->childCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const
{
if (!m_treeItemRoot)
return 0;
if (parentIndex.isValid())
{
PdmUiTreeItem* parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex);
if (parentItem)
{
return parentItem->columnCount();
}
else
{
return 0;
}
}
else
return m_treeItemRoot->columnCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const
{
if (!index.isValid())
return QVariant();
PdmUiTreeOrdering* uitreeOrdering = static_cast<PdmUiTreeOrdering*>(index.internalPointer());
if (!uitreeOrdering)
{
return QVariant();
}
PdmFieldHandle* pdmField = uitreeOrdering->field();
PdmObject* pdmObj = uitreeOrdering->object();
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
if (pdmField && !pdmField->uiName().isEmpty())
{
return pdmField->uiName();
}
else if (pdmObj)
{
if (pdmObj->userDescriptionField())
return pdmObj->userDescriptionField()->uiValue();
else
return pdmObj->uiName();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiName();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::DecorationRole)
{
if (pdmField && !pdmField->uiIcon().isNull())
{
return pdmField->uiIcon();
}
else if (pdmObj)
{
return pdmObj->uiIcon();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiIcon();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::ToolTipRole)
{
if (pdmField && !pdmField->uiToolTip().isEmpty())
return pdmField->uiToolTip();
else if (pdmObj)
{
return pdmObj->uiToolTip();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiToolTip();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::WhatsThisRole)
{
if (pdmField && !pdmField->uiWhatsThis().isEmpty())
return pdmField->uiWhatsThis();
else if (pdmObj)
{
return pdmObj->uiWhatsThis();
}
else if (uitreeOrdering->uiItem())
{
return uitreeOrdering->uiItem()->uiWhatsThis();
}
else
{
// Should not get here
assert(0);
}
}
else if (role == Qt::CheckStateRole)
{
if (pdmObj && pdmObj->objectToggleField())
{
bool isToggledOn = pdmObj->objectToggleField()->uiValue().toBool();
if (isToggledOn)
{
return Qt::Checked;
}
else
{
return Qt::Unchecked;
}
}
}
return QVariant();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index)
{
emit dataChanged(index, index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/)
{
if (!index.isValid())
{
return false;
}
PdmUiTreeItem* treeItem = PdmUiTreeViewModel::getTreeItemFromIndex(index);
assert(treeItem);
PdmObject* obj = treeItem->dataObject()->object();
if (!obj)
{
return false;
}
if (role == Qt::EditRole && obj->userDescriptionField())
{
obj->userDescriptionField()->setValueFromUi(value);
emitDataChanged(index);
return true;
}
else if (role == Qt::CheckStateRole && obj->objectToggleField())
{
bool toggleOn = (value == Qt::Checked);
obj->objectToggleField()->setValueFromUi(toggleOn);
emitDataChanged(index);
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Enable edit of this item if we have a editable user description field for a pdmObject
/// Disable edit for other items
//--------------------------------------------------------------------------------------------------
Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
Qt::ItemFlags flagMask = QAbstractItemModel::flags(index);
PdmUiTreeItem* treeItem = getTreeItemFromIndex(index);
if (treeItem)
{
PdmObject* pdmObject = treeItem->dataObject()->object();
if (pdmObject)
{
if (pdmObject->userDescriptionField() && !pdmObject->userDescriptionField()->isUiReadOnly())
{
flagMask = flagMask | Qt::ItemIsEditable;
}
if (pdmObject->objectToggleField())
{
flagMask = flagMask | Qt::ItemIsUserCheckable;
}
if (pdmObject->isUiReadOnly())
{
flagMask = flagMask & (~Qt::ItemIsEnabled);
}
}
}
else
{
flagMask = flagMask & (~Qt::ItemIsEditable);
}
return flagMask;
}
//--------------------------------------------------------------------------------------------------
/// Refreshes the UI-tree below the supplied root PdmObject
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::updateUiSubTree(PdmObject* pdmRoot)
{
// Build the new "Correct" Tree
PdmUiTreeOrdering* tempUpdatedPdmTree = pdmRoot->uiTreeOrdering();
// Find the corresponding entry for "root" in the existing Ui tree
QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot);
PdmUiTreeItem* uiModelSubTreeRoot = NULL;
if (uiSubTreeRootModelIdx.isValid())
{
uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx);
}
else
{
uiModelSubTreeRoot = m_treeItemRoot;
}
updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree);
delete tempUpdatedPdmTree;
}
//--------------------------------------------------------------------------------------------------
/// Makes the destinationSubTreeRoot tree become identical to the tree in sourceSubTreeRoot,
/// calling begin..() end..() to make the UI update accordingly.
/// This assumes that all the items have a pointer an unique PdmObject
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::updateModelSubTree(const QModelIndex& modelIdxOfDestinationSubTreeRoot, PdmUiTreeItem* destinationSubTreeRoot, PdmUiTreeItem* sourceSubTreeRoot)
{
// First loop over children in the old ui tree, deleting the ones not present in
// the newUiTree
for (int resultChildIdx = 0; resultChildIdx < destinationSubTreeRoot->childCount() ; ++resultChildIdx)
{
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(resultChildIdx);
int childIndex = sourceSubTreeRoot->findChildItemIndex(oldChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginRemoveRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx);
destinationSubTreeRoot->removeChildren(resultChildIdx, 1);
this->endRemoveRows();
resultChildIdx--;
}
}
// Then loop over the children in the new ui tree, finding the corresponding items in the old tree.
// If they are found, we move them to the correct position.
// If not found, we pulls the item out of the old ui tree, inserting it into the new tree to avoid the default delete operation in ~UiTreeItem()
int sourceChildCount = sourceSubTreeRoot->childCount();
int sourceChildIdx = 0;
for (int resultChildIdx = 0; resultChildIdx < sourceChildCount; ++resultChildIdx, ++sourceChildIdx)
{
PdmUiTreeItem* newChild = sourceSubTreeRoot->child(sourceChildIdx);
int childIndex = destinationSubTreeRoot->findChildItemIndex(newChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginInsertRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx);
destinationSubTreeRoot->insertChild(resultChildIdx, newChild);
this->endInsertRows();
sourceSubTreeRoot->removeChildrenNoDelete(sourceChildIdx, 1);
sourceChildIdx--;
}
else if (childIndex != resultChildIdx) // Found, but must be moved
{
assert(childIndex > resultChildIdx);
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex);
this->beginMoveRows(modelIdxOfDestinationSubTreeRoot, childIndex, childIndex, modelIdxOfDestinationSubTreeRoot, resultChildIdx);
destinationSubTreeRoot->removeChildrenNoDelete(childIndex, 1);
destinationSubTreeRoot->insertChild(resultChildIdx, oldChild);
this->endMoveRows();
updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild);
}
else // Found the corresponding item in the right place.
{
PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex);
updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeItem* PdmUiTreeViewModel::treeItemRoot()
{
return m_treeItemRoot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::notifyModelChanged()
{
QModelIndex startModelIdx = index(0,0);
QModelIndex endModelIdx = index(rowCount(startModelIdx), 0);
emit dataChanged(startModelIdx, endModelIdx);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (section < m_columnHeaders.size())
{
return m_columnHeaders[section];
}
return QVariant();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders)
{
m_columnHeaders = columnHeaders;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiTreeItem* caf::PdmUiTreeViewModel::getTreeItemFromIndex(const QModelIndex& index)
{
if (index.isValid())
{
assert(index.internalPointer());
PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(index.internalPointer());
return treeItem;
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const
{
if (currentIndex.internalPointer())
{
PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(currentIndex.internalPointer());
if (treeItem->dataObject()->object() == object) return currentIndex;
}
int row;
for (row = 0; row < rowCount(currentIndex); ++row)
{
QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object);
if (foundIndex.isValid()) return foundIndex;
}
return QModelIndex();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObject( const PdmObject * object) const
{
QModelIndex foundIndex;
int numRows = rowCount(QModelIndex());
int r = 0;
while (r < numRows && !foundIndex.isValid())
{
foundIndex = getModelIndexFromPdmObjectRecursive(index(r, 0, QModelIndex()), object);
++r;
}
return foundIndex;
}
} // end namespace caf

View File

@@ -0,0 +1,114 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafUiTreeItem.h"
#include <QAbstractItemModel>
#include <QStringList>
#include <assert.h>
#include "cafPdmPointer.h"
namespace caf
{
class PdmObject;
//typedef UiTreeItem<PdmPointer<PdmObject> > PdmUiTreeItem;
class PdmUiTreeOrdering;
typedef UiTreeItem<PdmUiTreeOrdering* > PdmUiTreeItem;
//==================================================================================================
//
// This class is intended to replace UiTreeModelPdm (cafUiTreeModelPdm)
//
//==================================================================================================
class PdmUiTreeViewModel : public QAbstractItemModel
{
Q_OBJECT
public:
PdmUiTreeViewModel(QObject* parent);
void setTreeItemRoot(PdmUiTreeItem* root);
PdmUiTreeItem* treeItemRoot();
void emitDataChanged(const QModelIndex& index);
static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index);
QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const;
void updateUiSubTree(PdmObject* root);
void notifyModelChanged();
void setColumnHeaders(const QStringList& columnHeaders);
public:
// Overrides from QAbstractItemModel
virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const;
virtual QModelIndex parent(const QModelIndex &index) const;
virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const;
virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
protected:
QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const;
private:
void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot);
PdmUiTreeItem* m_treeItemRoot;
QStringList m_columnHeaders;
};
//==================================================================================================
///
//==================================================================================================
class UiTreeItemBuilderPdm
{
public:
static PdmUiTreeItem* buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object);
};
} // End of namespace caf

View File

@@ -76,7 +76,10 @@ ProgressInfo::ProgressInfo(size_t maxProgressValue, const QString& title)
{
ProgressInfoStatic::start(maxProgressValue, title);
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
if (qApp)
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}
}
//--------------------------------------------------------------------------------------------------
@@ -86,7 +89,10 @@ ProgressInfo::~ProgressInfo()
{
ProgressInfoStatic::finished();
QApplication::restoreOverrideCursor();
if (qApp)
{
QApplication::restoreOverrideCursor();
}
}
//--------------------------------------------------------------------------------------------------

View File

@@ -69,7 +69,11 @@ if (MSVC)
# Setup the our STRICT compile flags
# These are the flags we would like to use on all of our own libraries
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall")
if (${MSVC_VERSION} LESS 1600)
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W4")
elseif()
set(CEE_STRICT_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /Wall")
endif()
# Must add base warning level after setting up strict
set(CEE_BASE_CXX_FLAGS "${CEE_BASE_CXX_FLAGS} /W3")

View File

@@ -23,6 +23,13 @@ if (CEE_STAND_ALONE)
endif()
# Allow use of non-threadsafe reference counter in cvf::Object on systems with no atomics support
option(CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS "Allow use of non-threadsafe reference counter on systems with no atomics support" OFF)
if (CEE_WORKAROUND_ON_SYSTEMS_WITHOUT_ATOMICS)
add_definitions(-DCVF_WORKAROUND_TO_COMPILE_ON_SYSTEMS_WITHOUT_ATOMICS)
endif()
add_subdirectory(LibCore)
add_subdirectory(LibIo)
add_subdirectory(LibGeometry)

View File

@@ -6,13 +6,13 @@ project(LibCore)
# Use our strict compile flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CEE_STRICT_CXX_FLAGS}")
set(CEE_HEADER_FILES
cvfArray.h
cvfArray.inl
cvfArrayWrapperConst.h
cvfArrayWrapperToEdit.h
cvfAssert.h
cvfAtomicCounter.h
cvfBase.h
cvfBase64.h
cvfCharArray.h
@@ -68,6 +68,7 @@ cvfVersion.h
set(CEE_SOURCE_FILES
cvfAssert.cpp
cvfAtomicCounter.cpp
cvfBase64.cpp
cvfCharArray.cpp
cvfCodeLocation.cpp

View File

@@ -232,6 +232,7 @@
<ClInclude Include="cvfArrayWrapperConst.h" />
<ClInclude Include="cvfArrayWrapperToEdit.h" />
<ClInclude Include="cvfAssert.h" />
<ClInclude Include="cvfAtomicCounter.h" />
<ClInclude Include="cvfBase.h" />
<ClInclude Include="cvfBase64.h" />
<ClInclude Include="cvfCharArray.h" />
@@ -290,6 +291,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="cvfAssert.cpp" />
<ClCompile Include="cvfAtomicCounter.cpp" />
<ClCompile Include="cvfBase64.cpp" />
<ClCompile Include="cvfCharArray.cpp" />
<ClCompile Include="cvfCodeLocation.cpp" />

View File

@@ -45,6 +45,7 @@
<ClInclude Include="cvfArrayWrapperConst.h" />
<ClInclude Include="cvfArrayWrapperToEdit.h" />
<ClInclude Include="cvfProgramOptions.h" />
<ClInclude Include="cvfAtomicCounter.h" />
</ItemGroup>
<ItemGroup>
<None Include="cvfArray.inl" />
@@ -90,5 +91,6 @@
<ClCompile Include="cvfLogDestinationConsole.cpp" />
<ClCompile Include="cvfLogDestinationFile.cpp" />
<ClCompile Include="cvfProgramOptions.cpp" />
<ClCompile Include="cvfAtomicCounter.cpp" />
</ItemGroup>
</Project>
</Project>

View File

@@ -151,3 +151,4 @@ inline const ArrayWrapperConst< const ElmType*, ElmType > wrapArrayConst( ElmTy
}
}

View File

@@ -130,3 +130,4 @@ inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, s
}
}

View File

@@ -113,9 +113,11 @@ Assert::FailAction AssertHandlerConsole::handleAssert(const char* fileName, int
// Does the job on both Windows and Linux (creates a console on Windows if one doesn't exist)
reportToConsole(fileName, lineNumber, expr, msg);
#ifdef WIN32
if (::IsDebuggerPresent())
{
#ifdef _MSC_VER
#if (_MSC_VER >= 1600)
if (::IsDebuggerPresent())
#endif
{
__debugbreak();
}
#endif

View File

@@ -0,0 +1,193 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfAtomicCounter.h"
// Some older GCC version do not support atomics, we have seen this for RHEL5
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS)
namespace cvf {
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return InterlockedIncrement(&m_counter);
}
int AtomicCounter::operator ++ (int) // postfix
{
int result = InterlockedIncrement(&m_counter);
return --result;
}
int AtomicCounter::operator -- () // prefix
{
return InterlockedDecrement(&m_counter);
}
int AtomicCounter::operator -- (int) // postfix
{
int result = InterlockedDecrement(&m_counter);
return ++result;
}
#elif defined(CVF_IOS) || defined(CVF_OSX)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::AtomicCounter(const AtomicCounter& counter)
: m_counter(counter.value())
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return OSAtomicIncrement32(&m_counter);
}
int AtomicCounter::operator ++ (int) // postfix
{
int result = OSAtomicIncrement32(&m_counter);
return --result;
}
int AtomicCounter::operator -- () // prefix
{
return OSAtomicDecrement32(&m_counter);
}
int AtomicCounter::operator -- (int) // postfix
{
int result = OSAtomicDecrement32(&m_counter);
return ++result;
}
#elif defined(CVF_GCC_DEFINED)
AtomicCounter::AtomicCounter(int initialValue)
: m_counter(initialValue)
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter::operator int () const
{
return m_counter;
}
int AtomicCounter::operator ++ () // prefix
{
return __sync_add_and_fetch(&m_counter, 1);
}
int AtomicCounter::operator ++ (int) // postfix
{
return __sync_fetch_and_add(&m_counter, 1);
}
int AtomicCounter::operator -- () // prefix
{
return __sync_sub_and_fetch(&m_counter, 1);
}
int AtomicCounter::operator -- (int) // postfix
{
return __sync_fetch_and_sub(&m_counter, 1);
}
#endif
} // namespace cvf
#endif // CVF_ATOMICS_COMPILED

View File

@@ -0,0 +1,91 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2014 Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfBase.h"
#ifdef WIN32
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#elif defined(CVF_IOS) || defined(CVF_OSX)
#include <libkern/OSAtomic.h>
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#elif defined __GNUC__
#define CVF_GCC_DEFINED
#define CVF_ATOMIC_COUNTER_CLASS_EXISTS
#endif
#if defined(CVF_ATOMIC_COUNTER_CLASS_EXISTS)
namespace cvf {
// Inspired by Poco
class AtomicCounter
{
public:
explicit AtomicCounter(int initialValue);
~AtomicCounter();
operator int () const;
int operator ++ (); // prefix
int operator ++ (int); // postfix
int operator -- (); // prefix
int operator -- (int); // postfix
private:
CVF_DISABLE_COPY_AND_ASSIGN(AtomicCounter);
#ifdef WIN32
typedef volatile long ImplType;
#elif defined(CVF_IOS) || defined(CVF_OSX)
typedef int32_t ImplType;
#else
typedef int ImplType;
#endif
ImplType m_counter;
};
} // namespace cvf
#endif

Some files were not shown because too many files have changed in this diff Show More