Merge remote-tracking branch 'refs/remotes/origin/dev'

Conflicts:
	ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp
	ApplicationCode/Resources/ResInsight.qrc
This commit is contained in:
Magne Sjaastad 2017-02-16 10:18:39 +01:00
commit f9d8ab8bad
128 changed files with 7589 additions and 3420 deletions

View File

@ -70,6 +70,7 @@
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
#include "RimWellPath.h"
#include "RimFlowPlotCollection.h"
#include "RimWellPathCollection.h"
#include "RiuMainPlotWindow.h"
@ -80,6 +81,7 @@
#include "RiuSummaryQwtPlot.h"
#include "RiuViewer.h"
#include "RiuWellLogPlot.h"
#include "RiuWellAllocationPlot.h"
#include "RicImportSummaryCaseFeature.h"
#include "RicSnapshotViewToClipboardFeature.h"
@ -114,7 +116,6 @@
#ifdef WIN32
#include <fcntl.h>
#endif
#include "RimFlowPlotCollection.h"
namespace caf
{
@ -574,7 +575,7 @@ void RiaApplication::loadAndUpdatePlotData()
size_t plotCount = 0;
plotCount += wlpColl ? wlpColl->wellLogPlots().size() : 0;
plotCount += spColl ? spColl->summaryPlots().size() : 0;
plotCount += flowColl ? flowColl->flowPlots().size() : 0;
plotCount += flowColl ? flowColl->plotCount() : 0;
caf::ProgressInfo plotProgress(plotCount, "Loading Plot Data");
if (wlpColl)
@ -594,17 +595,15 @@ void RiaApplication::loadAndUpdatePlotData()
plotProgress.incrementProgress();
}
}
plotProgress.setNextProgressIncrement(flowColl->plotCount());
if (flowColl)
{
flowColl->defaultPlot->loadDataAndUpdate();
for (RimWellAllocationPlot* p : flowColl->flowPlots())
{
p->loadDataAndUpdate();
plotProgress.incrementProgress();
}
flowColl->loadDataAndUpdate();
}
plotProgress.incrementProgress();
}
//--------------------------------------------------------------------------------------------------
@ -813,16 +812,19 @@ QString RiaApplication::createAbsolutePathFromProjectRelativePath(QString projec
return projectRelativePath;
}
QString absolutePath;
if (m_project && !m_project->fileName().isEmpty())
{
QString absoluteProjectPath = QFileInfo(m_project->fileName()).absolutePath();
QDir projectDir(absoluteProjectPath);
return projectDir.absoluteFilePath(projectRelativePath);
absolutePath = QFileInfo(m_project->fileName()).absolutePath();
}
else
{
return projectRelativePath;
absolutePath = this->lastUsedDialogDirectory("BINARY_GRID");
}
QDir projectDir(absolutePath);
return projectDir.absoluteFilePath(projectRelativePath);
}
@ -868,8 +870,6 @@ bool RiaApplication::openEclipseCase(const QString& caseName, const QString& cas
riv->loadDataAndUpdate();
riv->wellCollection()->assignDefaultWellColors();
// Add a corresponding summary case if it exists
{
RimSummaryCaseCollection* sumCaseColl = m_project->activeOilField() ? m_project->activeOilField()->summaryCaseCollection() : NULL;
@ -1634,6 +1634,12 @@ RimViewWindow* RiaApplication::activeViewWindow()
{
viewWindow = wellLogPlot->ownerPlotDefinition();
}
RiuWellAllocationPlot* wellAllocationPlot = dynamic_cast<RiuWellAllocationPlot*>(subwindows.back()->widget());
if (wellAllocationPlot)
{
viewWindow = wellAllocationPlot->ownerPlotDefinition();
}
}
}
@ -2279,7 +2285,7 @@ void RiaApplication::runRegressionTest(const QString& testRootPath)
QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName);
saveSnapshotForAllViews(fullPathGeneratedFolder);
RicSnapshotAllPlotsToFileFeature::createSnapshotOfAllPlotsInFolder(fullPathGeneratedFolder);
RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder);
QDir baseDir(testCaseFolder.filePath(baseFolderName));
QDir genDir(testCaseFolder.filePath(generatedFolderName));

View File

@ -0,0 +1,404 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RiaColorTables.h"
#include <QColor>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::normalPaletteColors()
{
static std::vector<cvf::Color3ub> colors {
cvf::Color3ub( 0, 0, 255),
cvf::Color3ub( 0, 127, 255),
cvf::Color3ub( 0, 255, 255),
cvf::Color3ub( 0, 255, 0),
cvf::Color3ub(255, 255, 0),
cvf::Color3ub(255, 127, 0),
cvf::Color3ub(255, 0, 0)
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::normalPaletteOppositeOrderingColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(255, 0, 0),
cvf::Color3ub(255, 127, 0),
cvf::Color3ub(255, 255, 0),
cvf::Color3ub( 0, 255, 0),
cvf::Color3ub( 0, 255, 255),
cvf::Color3ub( 0, 127, 255),
cvf::Color3ub( 0, 0, 255)
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::blackWhitePaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::BLACK,
cvf::Color3ub::WHITE
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::whiteBlackPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::WHITE,
cvf::Color3ub::BLACK
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::pinkWhitePaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::DEEP_PINK,
cvf::Color3ub::WHITE
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::whitePinkPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::WHITE,
cvf::Color3ub::DEEP_PINK
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::blueWhiteRedPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::BLUE,
cvf::Color3ub::WHITE,
cvf::Color3ub::RED
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::redWhiteBluePaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub::RED,
cvf::Color3ub::WHITE,
cvf::Color3ub::BLUE
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::categoryPaletteColors()
{
// Based on http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors
// and Kelly Colors and sorted by hue
// See also http://www.w3schools.com/colors/ for palettes etc.
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(128, 62, 117), // hwb(310, 24%, 50%) strong_purple
cvf::Color3ub(212, 28, 132), // hwb(326, 11%, 17%) strong_purplish_red
cvf::Color3ub(246, 118, 142), // hwb(349, 46%, 4%) strong_purplish_pink
cvf::Color3ub(193, 0, 32), // hwb(350, 0%, 24%) vivid_red
cvf::Color3ub(127, 24, 13), // hwb( 6, 5%, 50%) strong_reddish_brown
cvf::Color3ub(241, 58, 19), // hwb( 11, 7%, 5%) vivid_reddish_orange
cvf::Color3ub(255, 122, 92), // hwb( 11, 36%, 0%) strong_yellowish_pink
cvf::Color3ub(129, 112, 102), // hwb( 22, 40%, 49%) medium_gray
cvf::Color3ub(255, 104, 0), // hwb( 24, 0%, 0%) vivid_orange
cvf::Color3ub( 89, 51, 21), // hwb( 26, 8%, 65%) deep_yellowish_brown
cvf::Color3ub(255, 142, 0), // hwb( 33, 0%, 0%) vivid_orange_yellow
cvf::Color3ub(206, 162, 98), // hwb( 36, 38%, 19%) grayish_yellow
cvf::Color3ub(244, 200, 0), // hwb( 49, 0%, 4%) vivid_greenish_yellow
cvf::Color3ub(147, 170, 0), // hwb( 68, 0%, 33%) vivid_yellowish_green
cvf::Color3ub( 59, 84, 23), // hwb( 85, 9%, 67%) dark_olive_green
cvf::Color3ub( 0, 125, 52), // hwb(145, 0%, 51%) vivid_green
cvf::Color3ub( 54, 125, 123), // hwb(178, 21%, 51%) vivid_blueish_green
cvf::Color3ub( 0, 83, 138), // hwb(204, 0%, 46%) strong_blue
cvf::Color3ub(166, 189, 215), // hwb(212, 65%, 16%) very_light_blue
cvf::Color3ub( 46, 76, 224) // hwb(230, 18%, 12%) medium_blue
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::angularPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(255, 0, 255),
cvf::Color3ub(0, 0, 255),
cvf::Color3ub(0, 127, 255),
cvf::Color3ub(0, 255, 255),
cvf::Color3ub(0, 255, 0),
cvf::Color3ub(255, 255, 0),
cvf::Color3ub(255, 127, 0),
cvf::Color3ub(255, 0, 0),
cvf::Color3ub(255, 0, 255)
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::faultsPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(101, 132, 96), // Dark green
cvf::Color3ub(255, 131, 140), // Old pink
cvf::Color3ub(210, 176, 112), // Light Brown
cvf::Color3ub(140, 171, 238), // Light gray blue
cvf::Color3ub(255, 205, 131), // Peach
cvf::Color3ub(220, 212, 166), // Dark off white
cvf::Color3ub(130, 255, 120), // Light green
cvf::Color3ub(166, 220, 215), // Light gray torquise
cvf::Color3ub(168, 220, 166), // Light gray green
cvf::Color3ub(255, 64, 236) // Magneta
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::wellsPaletteColors()
{
return categoryPaletteColors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveDefaultPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub( 0, 112, 136), // Dark Green-Blue
cvf::Color3ub(202, 0, 0), // Red
cvf::Color3ub( 78, 204, 0), // Clear Green
cvf::Color3ub(236, 118, 0), // Orange
cvf::Color3ub( 0, 0, 0), // Black
cvf::Color3ub( 56, 56, 255), // Vivid Blue
cvf::Color3ub(248, 0, 170), // Magenta
cvf::Color3ub(169, 2, 240), // Purple
cvf::Color3ub( 0, 221, 221), // Turquoise
cvf::Color3ub(201, 168, 206), // Light Violet
cvf::Color3ub( 0, 205, 68), // Bluish Green
cvf::Color3ub(236, 188, 0), // Mid Yellow
cvf::Color3ub( 51, 204, 255), // Bluer Turquoise
cvf::Color3ub(164, 193, 0), // Mid Yellowish Green
cvf::Color3ub( 0, 143, 239) // Dark Light Blue
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveRedPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(202, 0, 0), // Off Red
cvf::Color3ub(255, 51, 51), // Bright Red
cvf::Color3ub(255, 102, 102) // Light Red
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveGreenPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub( 78, 204, 0), // Clear Green
cvf::Color3ub(164, 193, 0), // Mid Yellowish Green
cvf::Color3ub( 0, 205, 68) // Bluish Green
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveBluePaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub( 56, 56, 255), // Vivid Blue
cvf::Color3ub( 0, 143, 239), // Dark Light Blue
cvf::Color3ub(153, 153, 255) // Off Light Blue
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveBrownPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(186, 101, 44),
cvf::Color3ub( 99, 53, 23), // Highway Brown
cvf::Color3ub(103, 56, 24), // Dark Brown
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::summaryCurveNoneRedGreenBlueBrownPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
cvf::Color3ub(236, 118, 0), // Orange
cvf::Color3ub( 0, 0, 0), // Black
cvf::Color3ub(248, 0, 170), // Magenta
cvf::Color3ub(236, 188, 0), // Mid Yellow
cvf::Color3ub(169, 2, 240), // Purple
cvf::Color3ub( 0, 221, 221), // Turquoise
cvf::Color3ub(201, 168, 206) // Light Violet
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::wellLogPlotPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::black)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkBlue)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkRed)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkGreen)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkYellow)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkMagenta)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkCyan)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::darkGray)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::blue)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::red)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::green)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::yellow)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::magenta)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::cyan)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::gray))
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const caf::ColorTable& RiaColorTables::selectionPaletteColors()
{
static std::vector<cvf::Color3ub> colors{
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::magenta)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::cyan)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::blue)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::red)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::green)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::yellow)),
caf::ColorTable::fromQColor(Qt::GlobalColor(Qt::gray))
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
return colorTable;
}

View File

@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "cafColorTable.h"
//==================================================================================================
///
///
//==================================================================================================
class RiaColorTables
{
public:
static const caf::ColorTable& normalPaletteColors();
static const caf::ColorTable& normalPaletteOppositeOrderingColors();
static const caf::ColorTable& blackWhitePaletteColors();
static const caf::ColorTable& whiteBlackPaletteColors();
static const caf::ColorTable& pinkWhitePaletteColors();
static const caf::ColorTable& whitePinkPaletteColors();
static const caf::ColorTable& blueWhiteRedPaletteColors();
static const caf::ColorTable& redWhiteBluePaletteColors();
static const caf::ColorTable& categoryPaletteColors();
static const caf::ColorTable& angularPaletteColors();
static const caf::ColorTable& faultsPaletteColors();
static const caf::ColorTable& wellsPaletteColors();
static const caf::ColorTable& summaryCurveDefaultPaletteColors();
static const caf::ColorTable& summaryCurveRedPaletteColors();
static const caf::ColorTable& summaryCurveGreenPaletteColors();
static const caf::ColorTable& summaryCurveBluePaletteColors();
static const caf::ColorTable& summaryCurveBrownPaletteColors();
static const caf::ColorTable& summaryCurveNoneRedGreenBlueBrownPaletteColors();
static const caf::ColorTable& wellLogPlotPaletteColors();
static const caf::ColorTable& selectionPaletteColors();
};

View File

@ -79,6 +79,7 @@ set( APPLICATION_FILES
Application/RiaImageCompareReporter.cpp
Application/RiaProjectModifier.cpp
Application/RiaRegressionTest.cpp
Application/RiaColorTables.cpp
)
set( SOCKET_INTERFACE_FILES

View File

@ -6,12 +6,14 @@ endif()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature
${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.h
${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFeature.h
)
set (SOURCE_GROUP_SOURCE_FILES
${CEE_CURRENT_LIST_DIR}RicShowWellAllocationPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicAddStoredWellAllocationPlotFeature.cpp
${CEE_CURRENT_LIST_DIR}RicShowContributingWellsFeature.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -67,12 +67,14 @@ void RicAddStoredWellAllocationPlotFeature::onActionTriggered(bool isChecked)
{
RimWellAllocationPlot* sourceObject = dynamic_cast<RimWellAllocationPlot*>(caf::SelectionManager::instance()->selectedItem());
RimWellAllocationPlot* newObject = dynamic_cast<RimWellAllocationPlot*>(sourceObject->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance()));
CVF_ASSERT(newObject);
RimWellAllocationPlot* wellAllocationPlot = dynamic_cast<RimWellAllocationPlot*>(sourceObject->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance()));
CVF_ASSERT(wellAllocationPlot);
flowPlotColl->flowPlots.push_back(newObject);
newObject->resolveReferencesRecursively();
flowPlotColl->addPlot(wellAllocationPlot);
wellAllocationPlot->resolveReferencesRecursively();
wellAllocationPlot->loadDataAndUpdate();
flowPlotColl->updateConnectedEditors();
}
}

View File

@ -0,0 +1,117 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RicShowContributingWellsFeature.h"
#include "RiaApplication.h"
#include "RimDefines.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h"
#include "RimWellAllocationPlot.h"
#include "RiuMainWindow.h"
#include <QAction>
CAF_CMD_SOURCE_INIT(RicShowContributingWellsFeature, "RicShowContributingWellsFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicShowContributingWellsFeature::isCommandEnabled()
{
RimWellAllocationPlot* wellAllocationPlot = RiaApplication::instance()->activeWellAllocationPlot();
if (!wellAllocationPlot) return false;
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
if (!activeView) return false;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowContributingWellsFeature::onActionTriggered(bool isChecked)
{
RimWellAllocationPlot* wellAllocationPlot = RiaApplication::instance()->activeWellAllocationPlot();
if (!wellAllocationPlot) return;
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
if (activeView)
{
activeView->cellResult()->setResultType(RimDefines::FLOW_DIAGNOSTICS);
activeView->cellResult()->setResultVariable("MaxFractionTracer");
activeView->cellResult()->loadDataAndUpdate();
activeView->cellResult()->updateConnectedEditors();
const std::vector<QString> contributingTracers = wellAllocationPlot->contributingTracerNames();
for (RimEclipseWell* well : activeView->wellCollection()->wells())
{
if (std::find(contributingTracers.begin(), contributingTracers.end(), well->name()) != contributingTracers.end()
|| wellAllocationPlot->wellName() == well->name())
{
well->showWell = true;
}
else
{
well->showWell = false;
}
}
// Disable all existing property filters, and
// create a new property filter based on TOF for current well
RimEclipsePropertyFilterCollection* propertyFilterCollection = activeView->eclipsePropertyFilterCollection();
for (RimEclipsePropertyFilter* f : propertyFilterCollection->propertyFilters())
{
f->isActive = false;
}
RimEclipsePropertyFilter* propertyFilter = new RimEclipsePropertyFilter();
propertyFilterCollection->propertyFilters().push_back(propertyFilter);
propertyFilter->resultDefinition()->setEclipseCase(activeView->eclipseCase());
propertyFilter->resultDefinition()->setTofAndSelectTracer(wellAllocationPlot->wellName());
propertyFilter->resultDefinition()->loadDataAndUpdate();
propertyFilterCollection->updateConnectedEditors();
RiuMainWindow::instance()->setExpanded(propertyFilterCollection, true);
activeView->scheduleCreateDisplayModelAndRedraw();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowContributingWellsFeature::setupActionLook(QAction* actionToSetup)
{
//actionToSetup->setIcon(QIcon(":/new_icon16x16.png"));
actionToSetup->setText("Show Contributing Wells");
}

View File

@ -1,7 +1,6 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
// Copyright (C) 2017 Statoil ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -19,15 +18,21 @@
#pragma once
#include "cvfBase.h"
#include "cvfColor3.h"
#include "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RiuSelectionColors
class RicShowContributingWellsFeature : public caf::CmdFeature
{
public:
static cvf::Color3f curveColorFromTable();
static cvf::Color3f singleCurveColor();
CAF_CMD_HEADER_INIT;
protected:
// Overrides
virtual bool isCommandEnabled() override;
virtual void onActionTriggered( bool isChecked ) override;
virtual void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -59,13 +59,12 @@ void RicShowWellAllocationPlotFeature::onActionTriggered(bool isChecked)
RimFlowPlotCollection* flowPlotColl = RiaApplication::instance()->project()->mainPlotCollection->flowPlotCollection();
if (flowPlotColl)
{
flowPlotColl->defaultPlot->setFromSimulationWell(eclWell);
flowPlotColl->defaultPlot->updateConnectedEditors();
flowPlotColl->defaultPlot()->setFromSimulationWell(eclWell);
flowPlotColl->defaultPlot()->updateConnectedEditors();
// Make sure the summary plot window is created and visible
RiuMainPlotWindow* plotwindow = RiaApplication::instance()->getOrCreateAndShowMainPlotWindow();
//RiaApplication::instance()->project()->updateConnectedEditors();
plotwindow->selectAsCurrentItem(flowPlotColl->defaultPlot);
plotwindow->selectAsCurrentItem(flowPlotColl->defaultPlot());
}
}
}

View File

@ -40,6 +40,7 @@
#include "RimSummaryCurveFilter.h"
#include "RimSummaryPlot.h"
#include "RimViewController.h"
#include "RimWellAllocationPlot.h"
#include "RimWellFlowRateCurve.h"
#include "RimWellLogCurve.h"
#include "RimWellLogPlot.h"
@ -62,7 +63,17 @@ namespace caf
bool isDeletable(PdmUiItem * uiItem)
{
if (dynamic_cast<RimWellFlowRateCurve*>(uiItem)) return false;
caf::PdmObjectHandle* destinationObject = dynamic_cast<caf::PdmObjectHandle*>(uiItem);
if (destinationObject)
{
RimWellAllocationPlot* wellAllocationPlot = nullptr;
destinationObject->firstAncestorOrThisOfType(wellAllocationPlot);
if (wellAllocationPlot)
{
return false;
}
}
if (dynamic_cast<RimGeoMechView*>(uiItem)) return true;
if (dynamic_cast<RimEclipseView*>(uiItem)) return true;

View File

@ -20,12 +20,10 @@
#include "RiaApplication.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimSummaryPlot.h"
#include "RimViewWindow.h"
#include "RimWellLogPlot.h"
#include "RiuMainPlotWindow.h"
#include "RiuWellLogPlot.h"
#include "cafUtils.h"
@ -35,6 +33,7 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QMdiSubWindow>
#include <QMessageBox>
CAF_CMD_SOURCE_INIT(RicSnapshotViewToClipboardFeature, "RicSnapshotViewToClipboardFeature");
@ -178,13 +177,16 @@ void RicSnapshotAllPlotsToFileFeature::saveAllPlots()
// Save images in snapshot catalog relative to project directory
QString snapshotFolderName = app->createAbsolutePathFromProjectRelativePath("snapshots");
createSnapshotOfAllPlotsInFolder(snapshotFolderName);
exportSnapshotOfAllPlotsIntoFolder(snapshotFolderName);
QString text = QString("Exported snapshots to folder : \n%1").arg(snapshotFolderName);
QMessageBox::information(nullptr, "Export Snapshots To Folder", text);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSnapshotAllPlotsToFileFeature::createSnapshotOfAllPlotsInFolder(QString snapshotFolderName)
void RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(QString snapshotFolderName)
{
RiaApplication* app = RiaApplication::instance();
@ -199,41 +201,20 @@ void RicSnapshotAllPlotsToFileFeature::createSnapshotOfAllPlotsInFolder(QString
const QString absSnapshotPath = snapshotPath.absolutePath();
// Well log plots
std::vector<RimViewWindow*> viewWindows;
proj->mainPlotCollection()->descendantsIncludingThisOfType(viewWindows);
for (auto viewWindow : viewWindows)
{
std::vector<RimWellLogPlot*> wellLogPlots;
proj->descendantsIncludingThisOfType(wellLogPlots);
for (RimWellLogPlot* wellLogPlot : wellLogPlots)
if (viewWindow->isMdiWindow() && viewWindow->viewWidget())
{
if (wellLogPlot && wellLogPlot->viewWidget())
{
QString fileName = wellLogPlot->description();
fileName = caf::Utils::makeValidFileBasename(fileName);
QString fileName = viewWindow->userDescriptionField()->uiCapability()->uiValue().toString();
fileName = caf::Utils::makeValidFileBasename(fileName);
QString absoluteFileName = caf::Utils::constructFullFileName(absSnapshotPath, fileName, ".png");
absoluteFileName.replace(" ", "_");
QString absoluteFileName = caf::Utils::constructFullFileName(absSnapshotPath, fileName, ".png");
absoluteFileName.replace(" ", "_");
RicSnapshotViewToFileFeature::saveSnapshotAs(absoluteFileName, wellLogPlot);
}
}
}
// Summary plots
{
std::vector<RimSummaryPlot*> summaryPlots;
proj->descendantsIncludingThisOfType(summaryPlots);
for (RimSummaryPlot* summaryPlot : summaryPlots)
{
if (summaryPlot && summaryPlot->viewWidget())
{
QString fileName = summaryPlot->description();
fileName = caf::Utils::makeValidFileBasename(fileName);
QString absoluteFileName = caf::Utils::constructFullFileName(absSnapshotPath, fileName, ".png");
absoluteFileName.replace(" ", "_");
RicSnapshotViewToFileFeature::saveSnapshotAs(absoluteFileName, summaryPlot);
}
RicSnapshotViewToFileFeature::saveSnapshotAs(absoluteFileName, viewWindow);
}
}
}

View File

@ -66,7 +66,7 @@ class RicSnapshotAllPlotsToFileFeature : public caf::CmdFeature
public:
static void saveAllPlots();
static void createSnapshotOfAllPlotsInFolder(QString snapshotFolderName);
static void exportSnapshotOfAllPlotsIntoFolder(QString snapshotFolderName);
protected:
// Overrides

View File

@ -67,11 +67,11 @@ void RicNewSummaryCurveFeature::onActionTriggered(bool isChecked)
if (plot)
{
RimSummaryCurve* newCurve = new RimSummaryCurve();
plot->addCurve(newCurve);
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable();
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(plot->curveCount());
newCurve->setColor(curveColor);
plot->addCurve(newCurve);
RimSummaryCase* defaultCase = nullptr;
if (project->activeOilField()->summaryCaseCollection()->summaryCaseCount() > 0)
{

View File

@ -85,6 +85,9 @@ void RicAddWellLogToPlotFeature::onActionTriggered(bool isChecked)
if (wellLogFile)
{
RimWellLogFileCurve* curve = new RimWellLogFileCurve;
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(plotTrack->curveCount());
curve->setColor(curveColor);
plotTrack->addCurve(curve);
RigWellLogFile* wellLogDataFile = wellLogFile->wellLogFile();
@ -96,8 +99,6 @@ void RicAddWellLogToPlotFeature::onActionTriggered(bool isChecked)
plot->setDepthUnit(wellLogDataFile->depthUnit());
}
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable();
curve->setColor(curveColor);
curve->setWellPath(wellPath);
curve->setWellLogChannelName(wellLog->name());

View File

@ -19,6 +19,8 @@
#include "RicDeleteWellLogPlotTrackFeature.h"
#include "RicWellLogPlotCurveFeatureImpl.h"
#include "RimWellLogTrack.h"
#include "RimWellLogPlot.h"
@ -34,6 +36,8 @@ CAF_CMD_SOURCE_INIT(RicDeleteWellLogPlotTrackFeature, "RicDeleteWellLogPlotTrack
//--------------------------------------------------------------------------------------------------
bool RicDeleteWellLogPlotTrackFeature::isCommandEnabled()
{
if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return false;
std::vector<RimWellLogTrack*> selection;
caf::SelectionManager::instance()->objectsByType(&selection);
@ -55,6 +59,8 @@ bool RicDeleteWellLogPlotTrackFeature::isCommandEnabled()
//--------------------------------------------------------------------------------------------------
void RicDeleteWellLogPlotTrackFeature::onActionTriggered(bool isChecked)
{
if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return;
std::vector<RimWellLogTrack*> selection;
caf::SelectionManager::instance()->objectsByType(&selection);

View File

@ -134,10 +134,11 @@ RimWellLogExtractionCurve* RicNewWellLogCurveExtractionFeature::addCurve(RimWell
CVF_ASSERT(plotTrack);
RimWellLogExtractionCurve* curve = new RimWellLogExtractionCurve();
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable();
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(plotTrack->curveCount());
curve->setColor(curveColor);
curve->setWellPath(wellPath);
curve->setPropertiesFromView(view);
plotTrack->addCurve(curve);
plotTrack->updateConnectedEditors();

View File

@ -145,11 +145,12 @@ RimWellLogFileCurve* RicNewWellLogFileCurveFeature::addCurve(RimWellLogTrack* pl
CVF_ASSERT(plotTrack);
RimWellLogFileCurve* curve = new RimWellLogFileCurve();
plotTrack->addCurve(curve);
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable();
cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(plotTrack->curveCount());
curve->setColor(curveColor);
plotTrack->addCurve(curve);
plotTrack->updateConnectedEditors();
RiuMainPlotWindow* plotwindow = RiaApplication::instance()->getOrCreateAndShowMainPlotWindow();

View File

@ -82,6 +82,8 @@ void RicPasteWellLogTrackFeature::onActionTriggered(bool isChecked)
wellLogPlot->addTrack(newObject);
newObject->setDescription(QString("Track %1").arg(wellLogPlot->trackCount()));
// Resolve references after object has been inserted into the project data model
newObject->resolveReferencesRecursively();
newObject->initAfterReadRecursively();

View File

@ -19,6 +19,8 @@
#include "RicWellLogPlotCurveFeatureImpl.h"
#include "RiaColorTables.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogCurve.h"
@ -26,36 +28,13 @@
#include <QColor>
static const int RI_LOGPLOT_CURVECOLORSCOUNT = 15;
static const int RI_LOGPLOT_CURVECOLORS[] =
{
Qt::black,
Qt::darkBlue,
Qt::darkRed,
Qt::darkGreen,
Qt::darkYellow,
Qt::darkMagenta,
Qt::darkCyan,
Qt::darkGray,
Qt::blue,
Qt::red,
Qt::green,
Qt::yellow,
Qt::magenta,
Qt::cyan,
Qt::gray
};
//--------------------------------------------------------------------------------------------------
/// Pick default curve color from an index based palette
//--------------------------------------------------------------------------------------------------
cvf::Color3f RicWellLogPlotCurveFeatureImpl::curveColorFromTable()
cvf::Color3f RicWellLogPlotCurveFeatureImpl::curveColorFromTable(size_t index)
{
static int colorIndex = 0;
QColor color = QColor(Qt::GlobalColor(RI_LOGPLOT_CURVECOLORS[colorIndex % RI_LOGPLOT_CURVECOLORSCOUNT]));
++colorIndex;
cvf::Color3f cvfColor(color.redF(), color.greenF(), color.blueF());
return cvfColor;
return RiaColorTables::wellLogPlotPaletteColors().cycledColor3f(index);
}
//--------------------------------------------------------------------------------------------------

View File

@ -30,7 +30,7 @@ class RimWellAllocationPlot;
class RicWellLogPlotCurveFeatureImpl
{
public:
static cvf::Color3f curveColorFromTable();
static cvf::Color3f curveColorFromTable(size_t index);
static std::vector<RimWellLogCurve*> selectedWellLogCurves();
static RimWellAllocationPlot* parentWellAllocationPlot();
};

View File

@ -6,7 +6,6 @@ endif()
set (SOURCE_GROUP_HEADER_FILES
${CEE_CURRENT_LIST_DIR}RivCellEdgeEffectGenerator.h
${CEE_CURRENT_LIST_DIR}RivColorTableArray.h
${CEE_CURRENT_LIST_DIR}RivFaultPartMgr.h
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.h
${CEE_CURRENT_LIST_DIR}RivNNCGeometryGenerator.h
@ -41,7 +40,6 @@ ${CEE_CURRENT_LIST_DIR}RivWellFracturePartMgr.h
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}RivNNCGeometryGenerator.cpp
${CEE_CURRENT_LIST_DIR}RivFaultGeometryGenerator.cpp

View File

@ -1,44 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA
// Copyright (C) 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 "RivColorTableArray.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Color3fArray> RivColorTableArray::colorTableArray()
{
cvf::ref<cvf::Color3fArray> partColors = new cvf::Color3fArray();
partColors->reserve(10);
partColors->add(cvf::Color3f(101.0f/255, 132.0f/255, 96.0f/255)); // Dark green
partColors->add(cvf::Color3f(255.0f/255, 131.0f/255, 140.0f/255)); // Old pink
partColors->add(cvf::Color3f(210.0f/255, 176.0f/255, 112.0f/255)); // Light Brown
partColors->add(cvf::Color3f(140.0f/255, 171.0f/255, 238.0f/255)); // Light gray blue
partColors->add(cvf::Color3f(255.0f/255, 205.0f/255, 131.0f/255)); // Peach
partColors->add(cvf::Color3f(220.0f/255, 212.0f/255, 166.0f/255)); // Dark off white
partColors->add(cvf::Color3f(130.0f/255, 255.0f/255, 120.0f/255)); // Light green
partColors->add(cvf::Color3f(166.0f/255, 220.0f/255, 215.0f/255)); // Light gray torquise
partColors->add(cvf::Color3f(168.0f/255, 220.0f/255, 166.0f/255)); // Light gray green
partColors->add(cvf::Color3f(255.0f/255, 64.0f/255, 236.0f/255)); // Magneta
return partColors;
}

View File

@ -1,30 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA
// Copyright (C) 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 "cvfBase.h"
#include "cvfObject.h"
#include "cvfArray.h"
class RivColorTableArray
{
public:
static cvf::ref<cvf::Color3fArray> colorTableArray();
};

View File

@ -33,6 +33,7 @@
#include "RimCellRangeFilterCollection.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseResultDefinition.h"
#include "RimEclipseView.h"

View File

@ -144,6 +144,13 @@ void RivSimWellPipesPartMgr::buildWellPipeParts()
pbd.m_centerLinePart->setEffect(eff.p());
}
// Create slightly larger geometry for active (open) wells
// This will avoid visual artifacts when two wells are located at the same position
{
pbd.m_pipeGeomGenerator->setRadius(pipeRadius * 1.1);
pbd.m_largeSurfaceDrawable = pbd.m_pipeGeomGenerator->createPipeSurface();
}
}
m_needsTransformUpdate = false;
@ -182,6 +189,8 @@ void RivSimWellPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicLi
if (m_needsTransformUpdate) buildWellPipeParts();
const RigWellResultFrame& wellResultFrame = m_rimWell->wellResults()->wellResultFrame(frameIndex);
std::list<RivPipeBranchData>::iterator it;
for (it = m_wellBranches.begin(); it != m_wellBranches.end(); ++it)
{
@ -189,6 +198,7 @@ void RivSimWellPipesPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicLi
{
model->addPart(it->m_surfacePart.p());
}
if (it->m_centerLinePart.notNull())
{
model->addPart(it->m_centerLinePart.p());
@ -230,6 +240,12 @@ void RivSimWellPipesPartMgr::updatePipeResultColor(size_t frameIndex)
}
caf::ScalarMapperEffectGenerator surfEffGen(scalarMapper.p(), caf::PO_1);
if (m_rimReservoirView && m_rimReservoirView->isLightingDisabled())
{
surfEffGen.disableLighting(true);
}
cvf::ref<cvf::Effect> scalarMapperSurfaceEffect = surfEffGen.generateUnCachedEffect();
caf::ScalarMapperMeshEffectGenerator meshEffGen(scalarMapper.p());
@ -300,15 +316,27 @@ void RivSimWellPipesPartMgr::updatePipeResultColor(size_t frameIndex)
if (brIt->m_surfaceDrawable.notNull())
{
cvf::ref<cvf::Vec2fArray> surfTexCoords = const_cast<cvf::Vec2fArray*>(brIt->m_surfaceDrawable->textureCoordArray());
if (surfTexCoords.isNull())
{
surfTexCoords = new cvf::Vec2fArray;
}
brIt->m_pipeGeomGenerator->pipeSurfaceTextureCoords( surfTexCoords.p(), wellCellStates, scalarMapper.p());
brIt->m_surfaceDrawable->setTextureCoordArray( surfTexCoords.p());
brIt->m_pipeGeomGenerator->pipeSurfaceTextureCoords(surfTexCoords.p(), wellCellStates, scalarMapper.p());
brIt->m_surfaceDrawable->setTextureCoordArray(surfTexCoords.p());
brIt->m_largeSurfaceDrawable->setTextureCoordArray(surfTexCoords.p());
if (wResFrame.m_isOpen)
{
// Use slightly larger geometry for open wells to avoid z-fighting when two wells are located at the same position
brIt->m_surfacePart->setDrawable(brIt->m_largeSurfaceDrawable.p());
}
else
{
brIt->m_surfacePart->setDrawable(brIt->m_surfaceDrawable.p());
}
brIt->m_surfacePart->setEffect(scalarMapperSurfaceEffect.p());
}

View File

@ -72,6 +72,7 @@ private:
cvf::ref<cvf::Part> m_surfacePart;
cvf::ref<cvf::DrawableGeo> m_surfaceDrawable;
cvf::ref<cvf::DrawableGeo> m_largeSurfaceDrawable;
cvf::ref<cvf::Part> m_centerLinePart;
cvf::ref<cvf::DrawableGeo> m_centerLineDrawable;

View File

@ -161,6 +161,12 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
pipeGeomGenerator->setCrossSectionVertexCount(m_rimReservoirView->wellCollection()->pipeCrossSectionVertexCount());
double pipeRadius = m_rimReservoirView->wellCollection()->pipeScaleFactor() * m_rimWell->pipeScaleFactor() * characteristicCellSize;
if (wellResultFrame.m_isOpen)
{
// Use slightly larger well head arrow when well is open
pipeRadius *= 1.1;
}
pipeGeomGenerator->setRadius(pipeRadius);
cvf::ref<cvf::DrawableGeo> pipeSurface = pipeGeomGenerator->createPipeSurface();
@ -173,6 +179,11 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
part->setDrawable(pipeSurface.p());
caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(well->wellPipeColor()), caf::PO_1);
if (m_rimReservoirView && m_rimReservoirView->isLightingDisabled())
{
surfaceGen.enableLighting(false);
}
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
part->setEffect(eff.p());
@ -198,6 +209,13 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
}
double arrowLength = characteristicCellSize * m_rimReservoirView->wellCollection()->wellHeadScaleFactor() * m_rimWell->wellHeadScaleFactor();
if (wellResultFrame.m_isOpen)
{
// Use slightly larger well head arrow when well is open
arrowLength = 1.1 * arrowLength;
}
cvf::Vec3d textPosition = arrowPosition;
textPosition.z() += 1.2 * arrowLength;
@ -208,6 +226,10 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
}
double ijScaleFactor = arrowLength / 6;
if (wellResultFrame.m_isOpen)
{
ijScaleFactor *= 1.1;
}
matr(0, 0) *= ijScaleFactor;
matr(1, 1) *= ijScaleFactor;
matr(2, 2) *= arrowLength;
@ -285,6 +307,10 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex)
}
caf::SurfaceEffectGenerator surfaceGen(headColor, caf::PO_1);
if (m_rimReservoirView && m_rimReservoirView->isLightingDisabled())
{
surfaceGen.enableLighting(false);
}
cvf::ref<cvf::Effect> eff = surfaceGen.generateCachedEffect();
part->setEffect(eff.p());

View File

@ -110,7 +110,7 @@ void RivWellSpheresPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicLis
}
}
cvf::ref<cvf::Part> part = createPart(centerColorPairs);
cvf::ref<cvf::Part> part = createPart(centerColorPairs, wellResultFrame.m_isOpen);
model->addPart(part.p());
}
@ -118,7 +118,7 @@ void RivWellSpheresPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicLis
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellSpheresPartMgr::createPart(std::vector<std::pair<cvf::Vec3f, cvf::Color3f> >& centerColorPairs)
cvf::ref<cvf::Part> RivWellSpheresPartMgr::createPart(std::vector<std::pair<cvf::Vec3f, cvf::Color3f> >& centerColorPairs, bool isWellOpen)
{
cvf::ref<cvf::Vec3fArray> vertices = new cvf::Vec3fArray;
cvf::ref<cvf::Vec3fArray> vecRes = new cvf::Vec3fArray;
@ -154,6 +154,13 @@ cvf::ref<cvf::Part> RivWellSpheresPartMgr::createPart(std::vector<std::pair<cvf:
cvf::GeometryBuilderTriangles builder;
double characteristicCellSize = m_rimReservoirView->mainGrid()->characteristicIJCellSize();
double cellRadius = m_rimReservoirView->wellCollection()->spheresScaleFactor() * characteristicCellSize;
if (isWellOpen)
{
// Increase radius to make sure open connection are slightly larger than closed connections
cellRadius = 1.1 * cellRadius;
}
cvf::GeometryUtils::createSphere(cellRadius, 15, 15, &builder);
vectorDrawable->setGlyph(builder.trianglesUShort().p(), builder.vertices().p());
@ -186,7 +193,7 @@ cvf::Color3f RivWellSpheresPartMgr::wellCellColor(const RigWellResultFrame& well
{
// Colours should be synchronized with RivWellPipesPartMgr::updatePipeResultColor
cvf::Color3f cellColor(m_rimWell->wellPipeColor());
cvf::Color3f cellColor(cvf::Color3f::GRAY);
RimEclipseWellCollection* wellColl = nullptr;
if (m_rimWell)
@ -212,16 +219,9 @@ cvf::Color3f RivWellSpheresPartMgr::wellCellColor(const RigWellResultFrame& well
case RigWellResultFrame::WATER_INJECTOR:
cellColor = cvf::Color3f::BLUE;
break;
case RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE:
cellColor = cvf::Color3f::GRAY;
break;
}
}
}
else
{
cellColor = m_rimWell->wellPipeColor();
}
return cellColor;
}

View File

@ -56,7 +56,7 @@ public:
private:
cvf::Color3f wellCellColor(const RigWellResultFrame& wellResultFrame, const RigWellResultPoint& wellResultPoint);
cvf::ref<cvf::Part> createPart(std::vector<std::pair<cvf::Vec3f, cvf::Color3f> >& centerColorPairs);
cvf::ref<cvf::Part> createPart(std::vector<std::pair<cvf::Vec3f, cvf::Color3f> >& centerColorPairs, bool isWellOpen);
private:
caf::PdmPointer<RimEclipseView> m_rimReservoirView;

View File

@ -10,6 +10,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.h
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.h
${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.h
${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.h
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -18,6 +19,7 @@ ${CEE_CURRENT_LIST_DIR}RimFlowPlotCollection.cpp
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlot.cpp
${CEE_CURRENT_LIST_DIR}RimTotalWellAllocationPlot.cpp
${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.cpp
${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -18,7 +18,8 @@
#include "RimFlowDiagSolution.h"
#include "RimEclipseResultCase.h"
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
@ -26,6 +27,9 @@
#include "RigFlowDiagResults.h"
#include "RigMainGrid.h"
#include "RigSingleWellResultsData.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h"
CAF_PDM_SOURCE_INIT(RimFlowDiagSolution, "FlowDiagSolution");
@ -281,14 +285,29 @@ cvf::Color3f RimFlowDiagSolution::tracerColor(QString tracerName)
if ( eclCase )
{
const cvf::Collection<RigSingleWellResultsData>& wellResults = eclCase->reservoirData()->wellResults();
RimEclipseView* activeView = dynamic_cast<RimEclipseView*>(RiaApplication::instance()->activeReservoirView());
for ( size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx )
if (activeView)
{
if ( wellResults[wIdx]->m_wellName == tracerName )
RimEclipseWell* well = activeView->wellCollection->findWell(tracerName);
if (well)
{
return well->wellPipeColor();
}
}
else
{
// If we do not find a well color, use index in well result data to be able to get variation of tracer colors
// This can be the case if we do not have any views at all
return RimEclipseWellCollection::cycledPaletteColor(wIdx);
const cvf::Collection<RigSingleWellResultsData>& wellResults = eclCase->reservoirData()->wellResults();
for ( size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx )
{
if ( wellResults[wIdx]->m_wellName == tracerName )
{
return RiaColorTables::wellsPaletteColors().cycledColor3f(wIdx);
}
}
}
}

View File

@ -22,6 +22,7 @@
#include "cvfAssert.h"
#include "cafProgressInfo.h"
CAF_PDM_SOURCE_INIT(RimFlowPlotCollection, "FlowPlotCollection");
@ -30,14 +31,12 @@ CAF_PDM_SOURCE_INIT(RimFlowPlotCollection, "FlowPlotCollection");
//--------------------------------------------------------------------------------------------------
RimFlowPlotCollection::RimFlowPlotCollection()
{
CAF_PDM_InitObject("Flow Diagnostics Plots", ":/newIcon16x16.png", "", "");
CAF_PDM_InitObject("Flow Diagnostics Plots", ":/WellAllocPlots16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&defaultPlot, "DefaultFlowPlot", "", "", "", "");
defaultPlot = new RimWellAllocationPlot;
defaultPlot->setDescription("Default Flow Diagnostics Plot");
defaultPlot.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_defaultPlot, "DefaultFlowPlot", "", "", "", "");
m_defaultPlot.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&flowPlots, "FlowPlots", "Stored Plots", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_flowPlots, "FlowPlots", "Stored Plots", "", "", "");
}
//--------------------------------------------------------------------------------------------------
@ -45,9 +44,9 @@ RimFlowPlotCollection::RimFlowPlotCollection()
//--------------------------------------------------------------------------------------------------
RimFlowPlotCollection::~RimFlowPlotCollection()
{
delete defaultPlot();
delete m_defaultPlot();
flowPlots.deleteAllChildObjects();
m_flowPlots.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
@ -55,7 +54,59 @@ RimFlowPlotCollection::~RimFlowPlotCollection()
//--------------------------------------------------------------------------------------------------
void RimFlowPlotCollection::closeDefaultPlotWindowAndDeletePlots()
{
defaultPlot->removeFromMdiAreaAndDeleteViewWidget();
flowPlots.deleteAllChildObjects();
if ( m_defaultPlot )
{
m_defaultPlot->removeFromMdiAreaAndDeleteViewWidget();
delete m_defaultPlot();
}
m_flowPlots.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowPlotCollection::loadDataAndUpdate()
{
caf::ProgressInfo plotProgress(m_flowPlots.size() + 1, "");
if (m_defaultPlot) m_defaultPlot->loadDataAndUpdate();
plotProgress.incrementProgress();
for (RimWellAllocationPlot* p : m_flowPlots)
{
p->loadDataAndUpdate();
plotProgress.incrementProgress();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimFlowPlotCollection::plotCount() const
{
return m_flowPlots.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFlowPlotCollection::addPlot(RimWellAllocationPlot* plot)
{
m_flowPlots.push_back(plot);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlot* RimFlowPlotCollection::defaultPlot()
{
if ( !m_defaultPlot() )
{
m_defaultPlot = new RimWellAllocationPlot;
m_defaultPlot->setDescription("Default Flow Diagnostics Plot");
}
this->updateConnectedEditors();
return m_defaultPlot();
}

View File

@ -36,7 +36,13 @@ public:
virtual ~RimFlowPlotCollection();
void closeDefaultPlotWindowAndDeletePlots();
void loadDataAndUpdate();
size_t plotCount() const;
caf::PdmChildField<RimWellAllocationPlot*> defaultPlot;
caf::PdmChildArrayField<RimWellAllocationPlot*> flowPlots;
void addPlot(RimWellAllocationPlot* plot);
RimWellAllocationPlot* defaultPlot();
private:
caf::PdmChildField<RimWellAllocationPlot*> m_defaultPlot;
caf::PdmChildArrayField<RimWellAllocationPlot*> m_flowPlots;
};

View File

@ -44,7 +44,7 @@ CAF_PDM_SOURCE_INIT(RimTotalWellAllocationPlot, "TotalWellAllocationPlot");
//--------------------------------------------------------------------------------------------------
RimTotalWellAllocationPlot::RimTotalWellAllocationPlot()
{
CAF_PDM_InitObject("Total Well Allocation Plot", ":/newIcon16x16.png", "", "");
CAF_PDM_InitObject("Total Well Allocation Plot", ":/WellAllocPie16x16.png", "", "");
CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Total Well Allocation Plot"), "Name", "", "", "");
m_userName.uiCapability()->setUiReadOnly(true);
@ -180,6 +180,7 @@ void RimTotalWellAllocationPlot::loadDataAndUpdate()
QWidget* RimTotalWellAllocationPlot::createViewWidget(QWidget* mainWindowParent)
{
m_wellTotalAllocationPlotWidget = new RiuNightchartsWidget(mainWindowParent);
m_wellTotalAllocationPlotWidget->showLegend(false);
return m_wellTotalAllocationPlotWidget;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,110 +1,126 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimViewWindow.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include <QPointer>
class RimEclipseResultCase;
class RimEclipseWell;
class RimFlowDiagSolution;
class RimTotalWellAllocationPlot;
class RimWellLogPlot;
class RiuWellAllocationPlot;
class RimWellLogTrack;
namespace caf {
class PdmOptionItemInfo;
}
//==================================================================================================
///
///
//==================================================================================================
class RimWellAllocationPlot : public RimViewWindow
{
CAF_PDM_HEADER_INIT;
public:
RimWellAllocationPlot();
virtual ~RimWellAllocationPlot();
void setFromSimulationWell(RimEclipseWell* simWell);
void setDescription(const QString& description);
QString description() const;
void loadDataAndUpdate();
virtual QWidget* viewWidget() override;
virtual void zoomAll() override;
RimWellLogPlot* accumulatedWellFlowPlot();
RimTotalWellAllocationPlot* totalWellFlowPlot();
QString wellName() const;
void removeFromMdiAreaAndDeleteViewWidget();
protected:
// Overridden PDM methods
virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; }
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
virtual QImage snapshotWindowContent() override;
private:
void updateFromWell();
void addStackedCurve(const QString& tracerName,
const std::vector<double>& connNumbers,
const std::vector<double>& accFlow,
RimWellLogTrack* plotTrack);
void updateWidgetTitleWindowTitle();
static QString wellStatusTextForTimeStep(const QString& wellName, const RimEclipseResultCase* eclipseResultCase, size_t timeStep);
// RimViewWindow overrides
virtual QWidget* createViewWidget(QWidget* mainWindowParent) override;
virtual void deleteViewWidget() override;
private:
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<QString> m_userName;
caf::PdmPtrField<RimEclipseResultCase*> m_case;
caf::PdmField<QString> m_wellName;
caf::PdmField<int> m_timeStep;
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
QPointer<RiuWellAllocationPlot> m_wellAllocationPlotWidget;
caf::PdmChildField<RimWellLogPlot*> m_accumulatedWellFlowPlot;
caf::PdmChildField<RimTotalWellAllocationPlot*> m_totalWellAllocationPlot;
};
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimViewWindow.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include <QPointer>
class RimEclipseResultCase;
class RimEclipseWell;
class RimFlowDiagSolution;
class RimTotalWellAllocationPlot;
class RimWellAllocationPlotLegend;
class RimWellLogPlot;
class RiuWellAllocationPlot;
class RimWellLogTrack;
class RigSingleWellResultsData;
namespace caf {
class PdmOptionItemInfo;
}
//==================================================================================================
///
///
//==================================================================================================
class RimWellAllocationPlot : public RimViewWindow
{
CAF_PDM_HEADER_INIT;
public:
RimWellAllocationPlot();
virtual ~RimWellAllocationPlot();
void setFromSimulationWell(RimEclipseWell* simWell);
void setDescription(const QString& description);
QString description() const;
void loadDataAndUpdate();
virtual QWidget* viewWidget() override;
virtual void zoomAll() override;
RimWellLogPlot* accumulatedWellFlowPlot();
RimTotalWellAllocationPlot* totalWellFlowPlot();
QString wellName() const;
const std::vector<QString> contributingTracerNames() const;
void removeFromMdiAreaAndDeleteViewWidget();
void showPlotLegend(bool doShow);
protected:
// Overridden PDM methods
virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; }
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
virtual QImage snapshotWindowContent() override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
private:
void updateFromWell();
std::map<QString, const std::vector<double> *> findRelevantTracerCellFractions(const RigSingleWellResultsData* wellResults);
void updateWellFlowPlotXAxisTitle(RimWellLogTrack* plotTrack);
void addStackedCurve(const QString& tracerName,
const std::vector<double>& connNumbers,
const std::vector<double>& accFlow,
RimWellLogTrack* plotTrack);
void updateWidgetTitleWindowTitle();
static QString wellStatusTextForTimeStep(const QString& wellName, const RimEclipseResultCase* eclipseResultCase, size_t timeStep);
// RimViewWindow overrides
virtual QWidget* createViewWidget(QWidget* mainWindowParent) override;
virtual void deleteViewWidget() override;
private:
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<QString> m_userName;
caf::PdmPtrField<RimEclipseResultCase*> m_case;
caf::PdmField<QString> m_wellName;
caf::PdmField<int> m_timeStep;
caf::PdmPtrField<RimFlowDiagSolution*> m_flowDiagSolution;
caf::PdmField<bool> m_groupSmallContributions;
caf::PdmField<double> m_smallContributionsThreshold;
QPointer<RiuWellAllocationPlot> m_wellAllocationPlotWidget;
caf::PdmChildField<RimWellLogPlot*> m_accumulatedWellFlowPlot;
caf::PdmChildField<RimTotalWellAllocationPlot*> m_totalWellAllocationPlot;
caf::PdmChildField<RimWellAllocationPlotLegend*> m_wellAllocationPlotLegend;
std::vector<QString> m_contributingTracerNames;
};

View File

@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimWellAllocationPlotLegend.h"
#include "RimWellAllocationPlot.h"
CAF_PDM_SOURCE_INIT(RimWellAllocationPlotLegend, "WellAllocationPlotLegend");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlotLegend::RimWellAllocationPlotLegend()
{
CAF_PDM_InitObject("Well Allocation Plot Legend", ":/WellAllocLegend16x16.png", "", "");
CAF_PDM_InitField(&m_showLegend, "ShowPlotLegend", true, "Show Plot Legend", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlotLegend::~RimWellAllocationPlotLegend()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellAllocationPlotLegend::objectToggleField()
{
return &m_showLegend;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellAllocationPlotLegend::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_showLegend)
{
RimWellAllocationPlot* walp;
firstAncestorOrThisOfType(walp);
if (walp) walp->showPlotLegend(m_showLegend());
}
}

View File

@ -0,0 +1,47 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "cafPdmField.h"
#include "cafPdmObject.h"
//==================================================================================================
///
///
//==================================================================================================
class RimWellAllocationPlotLegend : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimWellAllocationPlotLegend();
virtual ~RimWellAllocationPlotLegend();
bool isShowingLegend() { return m_showLegend();}
protected:
virtual caf::PdmFieldHandle* objectToggleField() override;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
private:
caf::PdmField<bool> m_showLegend;
};

View File

@ -42,7 +42,6 @@ CAF_PDM_SOURCE_INIT(RimWellFlowRateCurve, "RimWellFlowRateCurve");
RimWellFlowRateCurve::RimWellFlowRateCurve()
{
CAF_PDM_InitObject("Flow Rate Curve", "", "", "");
m_curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable();
}
//--------------------------------------------------------------------------------------------------
@ -142,7 +141,7 @@ void RimWellFlowRateCurve::updateStackedPlotData()
bool isFirstTrack = (wellLogTrack == wellLogPlot->trackByIndex(0));
RimDefines::DepthUnitType displayUnit = RimDefines::UNIT_METER;
RimDefines::DepthUnitType displayUnit = RimDefines::UNIT_NONE;
std::vector<double> depthValues = m_curveData->measuredDepthPlotValues(displayUnit);
if (depthValues.size()) depthValues.insert(depthValues.begin(), depthValues[0]); // Insert the first depth position again, to make room for a real 0 value
@ -192,10 +191,10 @@ RimWellAllocationPlot* RimWellFlowRateCurve::wellAllocationPlot() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellFlowRateCurve::setFlowValues(const QString& tracerName, const std::vector<double>& measuredDepths, const std::vector<double>& flowRates)
void RimWellFlowRateCurve::setFlowValuesPrConnection(const QString& tracerName, const std::vector<double>& connectionNumbers, const std::vector<double>& flowRates)
{
m_curveData = new RigWellLogCurveData;
m_curveData->setValuesAndMD(flowRates, measuredDepths, RimDefines::UNIT_METER, false);
m_curveData->setValuesAndMD(flowRates, connectionNumbers, RimDefines::UNIT_NONE, false);
m_tracerName = tracerName;
}

View File

@ -38,7 +38,7 @@ public:
RimWellFlowRateCurve();
virtual ~RimWellFlowRateCurve();
void setFlowValues(const QString& tracerName , const std::vector<double>& measuredDepths, const std::vector<double>& flowRates);
void setFlowValuesPrConnection(const QString& tracerName , const std::vector<double>& connectionNumbers, const std::vector<double>& flowRates);
void updateStackedPlotData();
virtual QString wellName() const override;

View File

@ -50,6 +50,8 @@ namespace caf
{
addItem(RimDefines::UNIT_METER, "UNIT_METER", "Meter");
addItem(RimDefines::UNIT_FEET, "UNIT_FEET", "Feet");
addItem(RimDefines::UNIT_NONE, "UNIT_NONE", "None");
setDefault(RimDefines::UNIT_METER);
}

View File

@ -77,7 +77,8 @@ public:
enum DepthUnitType
{
UNIT_METER,
UNIT_FEET
UNIT_FEET,
UNIT_NONE
};
static double feetPerMeter() { return 3.2808399; }

View File

@ -29,6 +29,8 @@
#include "RimEclipseCase.h"
#include "RimEclipseFaultColors.h"
#include "RimEclipseView.h"
#include "RimEclipseWell.h"
#include "RimEclipseWellCollection.h"
#include "RimLegendConfig.h"
#include "RimTernaryLegendConfig.h"
#include "RimViewController.h"
@ -281,7 +283,32 @@ void RimEclipseCellColors::updateLegendData(size_t currentTimeStep)
if (this->hasCategoryResult())
{
this->legendConfig()->setNamedCategories(this->flowDiagSolution()->tracerNames());
std::vector<std::tuple<QString, int, cvf::Color3ub>> categories;
std::vector<QString> tracerNames = this->flowDiagSolution()->tracerNames();
// Loop through the wells to get same ordering as the wells in tree view
for (size_t i = 0; i < m_reservoirView->wellCollection()->wells().size(); i++)
{
size_t reverseIndex = m_reservoirView->wellCollection()->wells().size() - i - 1;
RimEclipseWell* well = m_reservoirView->wellCollection()->wells()[reverseIndex];
QString wellName = well->name();
auto tracer = std::find(begin(tracerNames), end(tracerNames), wellName);
if (tracer != end(tracerNames))
{
// The category value is defined as the index of the tracer name in the tracer name vector
size_t categoryValue = std::distance(begin(tracerNames), tracer);
cvf::Color3ub color(cvf::Color3::SEA_GREEN);
color = cvf::Color3ub(well->wellPipeColor());
categories.push_back(std::make_tuple(wellName, static_cast<int>(categoryValue), color));
}
}
this->legendConfig()->setCategoryItems(categories);
}
}
else

View File

@ -121,7 +121,7 @@ void RimEclipseInputProperty::fieldChangedByUi(const caf::PdmFieldHandle* change
it->setResultVariable(newName);
}
it->updateResultNameHasChanged();
it->loadDataAndUpdate();
it->updateAnyFieldHasChanged();
}
}

View File

@ -401,8 +401,6 @@ void RimEclipsePropertyFilter::initAfterRead()
resultDefinition->initAfterRead();
resultDefinition->setEclipseCase(parentContainer()->reservoirView()->eclipseCase());
resultDefinition->loadResult();
updateIconState();
computeResultValueRange();
}

View File

@ -21,6 +21,7 @@
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipseResultDefinition.h"
#include "RimEclipseView.h"
#include "RimViewController.h"

View File

@ -20,11 +20,12 @@
#pragma once
#include "RimEclipsePropertyFilter.h"
#include "cafPdmChildArrayField.h"
#include "RimPropertyFilterCollection.h"
#include "cafPdmChildArrayField.h"
class RimEclipsePropertyFilter;
class RimEclipseView;
//==================================================================================================
///

View File

@ -125,6 +125,7 @@ void RimEclipseResultDefinition::simpleCopy(const RimEclipseResultDefinition* ot
this->setResultType(other->resultType());
this->setFlowSolution(other->m_flowSolution());
this->setSelectedTracers(other->m_selectedTracers());
m_flowTracerSelectionMode = other->m_flowTracerSelectionMode();
}
//--------------------------------------------------------------------------------------------------
@ -195,14 +196,14 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha
m_flowSolution = m_flowSolutionUiField();
m_selectedTracers = m_selectedTracersUiField();
}
updateResultNameHasChanged();
loadDataAndUpdate();
}
if ( &m_selectedTracersUiField == changedField )
{
m_flowSolution = m_flowSolutionUiField();
m_selectedTracers = m_selectedTracersUiField();
updateResultNameHasChanged();
loadDataAndUpdate();
}
updateAnyFieldHasChanged();
@ -252,7 +253,44 @@ void RimEclipseResultDefinition::updateAnyFieldHasChanged()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultDefinition::updateResultNameHasChanged()
void RimEclipseResultDefinition::setTofAndSelectTracer(const QString& tracerName)
{
setResultType(RimDefines::FLOW_DIAGNOSTICS);
setResultVariable("TOF");
m_flowTracerSelectionMode = FLOW_TR_BY_SELECTION;
std::vector<QString> tracers;
tracers.push_back(tracerName);
setSelectedTracers(tracers);
if (m_flowSolution() == nullptr)
{
assignFlowSolutionFromCase();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultDefinition::assignFlowSolutionFromCase()
{
RimEclipseResultCase* eclCase = nullptr;
this->firstAncestorOrThisOfType(eclCase);
if (eclCase)
{
std::vector<RimFlowDiagSolution*> flowSols = eclCase->flowDiagSolutions();
if (flowSols.size() > 0)
{
this->setFlowSolution(flowSols[0]);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseResultDefinition::loadDataAndUpdate()
{
RimView* view = nullptr;
this->firstAncestorOrThisOfType(view);
@ -890,13 +928,7 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm
if ( m_flowSolution() == nullptr )
{
RimEclipseResultCase* eclCase;
this->firstAncestorOrThisOfType(eclCase);
if ( eclCase )
{
std::vector<RimFlowDiagSolution*> flowSols = eclCase->flowDiagSolutions();
if (flowSols.size()){ this->setFlowSolution(flowSols[0]); }
}
assignFlowSolutionFromCase();
}
}
uiOrdering.add(&m_resultVariableUiField);

View File

@ -27,13 +27,13 @@
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include "cafPdmPtrField.h"
#include "RigFlowDiagResultAddress.h"
class RigCaseCellResultsData;
class RimEclipseCase;
class RimEclipseView;
class RimReservoirCellResultsStorage;
class RimFlowDiagSolution;
class RigFlowDiagResultAddress;
//==================================================================================================
@ -84,9 +84,11 @@ public:
RimReservoirCellResultsStorage* currentGridCellResults() const;
void updateResultNameHasChanged();
void loadDataAndUpdate();
void updateAnyFieldHasChanged();
void setTofAndSelectTracer(const QString& tracerName);
protected:
virtual void updateLegendCategorySettings() {};
@ -123,6 +125,7 @@ protected:
private:
void setFlowSolution(RimFlowDiagSolution* flowSol);
void setSelectedTracers(const std::vector<QString>& selectedTracers);
void assignFlowSolutionFromCase();
bool hasDualPorFractureResult();

View File

@ -1121,6 +1121,8 @@ void RimEclipseView::syncronizeWellsWithResults()
well->setWellResults(NULL, -1);
}
bool isAnyWellCreated = false;
// Find corresponding well from well result, or create a new
for (size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx)
@ -1131,6 +1133,8 @@ void RimEclipseView::syncronizeWellsWithResults()
{
well = new RimEclipseWell;
well->name = wellResults[wIdx]->m_wellName;
isAnyWellCreated = true;
}
newWells.push_back(well);
@ -1153,10 +1157,16 @@ void RimEclipseView::syncronizeWellsWithResults()
// Set the new wells into the field.
this->wellCollection()->wells().insert(0, newWells);
// Make sure all the wells have their reservoirView ptr setup correctly
this->wellCollection()->setReservoirView(this);
// Sort wells before assigning colors, as the colors are distributed based on sorting
this->wellCollection()->sortWellsByName();
if (isAnyWellCreated)
{
this->wellCollection()->assignDefaultWellColors();
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -47,13 +47,13 @@ RimEclipseWell::RimEclipseWell()
CAF_PDM_InitField(&showWell, "ShowWell", true, "Show well ", "", "", "");
CAF_PDM_InitField(&showWellLabel, "ShowWellLabel", true, "Label", "", "", "");
CAF_PDM_InitField(&showWellHead, "ShowWellHead", true, "Well head", "", "", "");
CAF_PDM_InitField(&showWellHead, "ShowWellHead", true, "Well Head", "", "", "");
CAF_PDM_InitField(&showWellPipe, "ShowWellPipe", true, "Pipe", "", "", "");
CAF_PDM_InitField(&showWellSpheres, "ShowWellSpheres", false, "Spheres", "", "", "");
CAF_PDM_InitField(&wellHeadScaleFactor, "WellHeadScaleFactor", 1.0, "Well Head Scale Factor", "", "", "");
CAF_PDM_InitField(&pipeScaleFactor, "WellPipeRadiusScale", 1.0, "Pipe Scale Factor", "", "", "");
CAF_PDM_InitField(&wellPipeColor, "WellPipeColor", cvf::Color3f(0.588f, 0.588f, 0.804f), "Pipe color", "", "", "");
CAF_PDM_InitField(&wellPipeColor, "WellPipeColor", cvf::Color3f(0.588f, 0.588f, 0.804f), "Pipe Color", "", "", "");
CAF_PDM_InitField(&showWellCells, "ShowWellCells", false, "Well Cells", "", "", "");
CAF_PDM_InitField(&showWellCellFence, "ShowWellCellFence", false, "Well Cell Fence", "", "", "");
@ -128,6 +128,11 @@ void RimEclipseWell::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c
RiuMainWindow::instance()->refreshDrawStyleActions();
}
if (changedField == &wellPipeColor)
{
RimEclipseWellCollection::updateWellAllocationPlots();
}
}
//--------------------------------------------------------------------------------------------------
@ -334,7 +339,8 @@ bool RimEclipseWell::isWellCellsVisible() const
if (reservoirView->crossSectionCollection()->hasActiveIntersectionForSimulationWell(this))
return true;
if (reservoirView->wellCollection()->showWellsIntersectingVisibleCells())
if (reservoirView->wellCollection()->showWellsIntersectingVisibleCells()
&& reservoirView->rangeFilterCollection()->hasActiveFilters())
{
return intersectsStaticWellCellsFilteredCells();
}

View File

@ -21,14 +21,16 @@
#include "RimEclipseWellCollection.h"
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RiaPreferences.h"
#include "RigEclipseCaseData.h"
#include "RigSingleWellResultsData.h"
#include "RimEclipseCase.h"
#include "RimEclipseView.h"
#include "RimEclipseWell.h"
#include "RimProject.h"
#include "RimWellAllocationPlot.h"
#include "RimSimWellFracture.h"
#include "RimSimWellFractureCollection.h"
@ -115,10 +117,10 @@ RimEclipseWellCollection::RimEclipseWellCollection()
CAF_PDM_InitField(&showWellsIntersectingVisibleCells, "ShowWellsIntersectingVisibleCells", false, "Hide Wells Not Intersecting Filtered Cells", "", "", "");
// Appearance
CAF_PDM_InitFieldNoDefault(&m_showWellHead, "ShowWellHeadTristate", "Show Well Head", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellLabel, "ShowWellLabelTristate", "Show Well Label", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellPipe, "ShowWellPipe", "Show Well Pipe", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellSpheres, "ShowWellSpheres", "Show Well Spheres", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellHead, "ShowWellHeadTristate", "Well Head", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellLabel, "ShowWellLabelTristate", "Label", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellPipe, "ShowWellPipe", "Pipe", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_showWellSpheres, "ShowWellSpheres", "Spheres", "", "", "");
m_showWellHead.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName());
m_showWellHead.xmlCapability()->setIOReadable(false);
@ -148,7 +150,7 @@ RimEclipseWellCollection::RimEclipseWellCollection()
CAF_PDM_InitField(&showConnectionStatusColors, "ShowConnectionStatusColors", true, "Show Connection Status Colors Along Well", "", "", "");
cvf::Color3f defaultApplyColor = cvf::Color3f::YELLOW;
CAF_PDM_InitField(&m_wellColorForApply, "WellColorForApply", defaultApplyColor, "Single Well Color", "", "", "");
CAF_PDM_InitField(&m_wellColorForApply, "WellColorForApply", defaultApplyColor, "Well Color", "", "", "");
CAF_PDM_InitField(&m_applySingleColorToWells, "ApplySingleColorToWells", false, "", "", "", "");
m_applySingleColorToWells.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
@ -436,6 +438,8 @@ void RimEclipseWellCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang
if (m_reservoirView) m_reservoirView->scheduleCreateDisplayModelAndRedraw();
RimEclipseWellCollection::updateWellAllocationPlots();
m_applySingleColorToWells = false;
}
@ -461,27 +465,39 @@ void RimEclipseWellCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang
//--------------------------------------------------------------------------------------------------
void RimEclipseWellCollection::assignDefaultWellColors()
{
// The wells are sorted, use ordering of single well results data to assign colors
const caf::ColorTable& colorTable = RiaColorTables::wellsPaletteColors();
cvf::Color3ubArray catColors = colorTable.color3ubArray();
cvf::Color3ubArray interpolatedCatColors = caf::ColorTable::interpolateColorArray(catColors, wells.size());
RimEclipseCase* rimEclipseCase = nullptr;
this->firstAncestorOrThisOfType(rimEclipseCase);
if (!rimEclipseCase) return;
if (!rimEclipseCase->reservoirData()) return;
cvf::Collection<RigSingleWellResultsData> wellResults = rimEclipseCase->reservoirData()->wellResults();
for (size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx)
for (size_t wIdx = 0; wIdx < wells.size(); ++wIdx)
{
RimEclipseWell* well = this->findWell(wellResults[wIdx]->m_wellName);
RimEclipseWell* well = wells[wIdx];
if (well)
{
cvf::Color3f col = cycledPaletteColor(wIdx);
cvf::Color3f col = cvf::Color3f(interpolatedCatColors[wIdx]);
well->wellPipeColor = col;
well->updateConnectedEditors();
}
}
RimEclipseWellCollection::updateWellAllocationPlots();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseWellCollection::updateWellAllocationPlots()
{
RimProject* proj = RiaApplication::instance()->project();
std::vector<RimWellAllocationPlot*> wellAllocationPlots;
proj->descendantsIncludingThisOfType(wellAllocationPlots);
for (auto wap : wellAllocationPlots)
{
wap->loadDataAndUpdate();
}
}
//--------------------------------------------------------------------------------------------------
@ -516,14 +532,14 @@ void RimEclipseWellCollection::defineUiOrdering(QString uiConfigName, caf::PdmUi
colorGroup->add(&wellLabelColor);
colorGroup->add(&m_applyIndividualColorsToWells);
colorGroup->add(&m_wellColorForApply);
colorGroup->add(&m_applySingleColorToWells);
colorGroup->add(&showConnectionStatusColors);
caf::PdmUiGroup* singleWellColorGroup = colorGroup->addNewGroup("Uniform Well Coloring");
singleWellColorGroup->add(&m_wellColorForApply);
singleWellColorGroup->add(&m_applySingleColorToWells);
caf::PdmUiGroup* wellPipeGroup = uiOrdering.addNewGroup("Well Pipe Geometry");
wellPipeGroup->add(&wellPipeCoordType);
wellPipeGroup->add(&isAutoDetectingBranches);
wellPipeGroup->add(&showConnectionStatusColors);
caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup("Advanced");
advancedGroup->add(&wellCellTransparencyLevel);
@ -679,7 +695,7 @@ void RimEclipseWellCollection::defineEditorAttribute(const caf::PdmFieldHandle*
caf::PdmUiPushButtonEditorAttribute* editorAttr = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
if (editorAttr)
{
editorAttr->m_buttonText = "Apply Individual Well Colors";
editorAttr->m_buttonText = "Apply Default Well Colors";
}
}
@ -697,7 +713,7 @@ void RimEclipseWellCollection::defineEditorAttribute(const caf::PdmFieldHandle*
QIcon colorIcon(pixmap);
editorAttr->m_buttonIcon = colorIcon;
editorAttr->m_buttonText = "Apply Single Well Color";
editorAttr->m_buttonText = "Apply Uniform Well Color";
}
}
}
@ -741,39 +757,6 @@ void RimEclipseWellCollection::calculateWellGeometryVisibility(size_t frameIndex
}
}
//--------------------------------------------------------------------------------------------------
/// TODO: Consider creating a factory for colors, see also RimSummaryCurveAppearanceCalculator
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimEclipseWellCollection::cycledPaletteColor(size_t colorIndex)
{
static const size_t colorCount = 15;
static const cvf::ubyte colorData[][3] =
{
{ 0, 112, 136 }, // Dark Green-Blue
{ 202, 0, 0 }, // Red
{ 78, 204, 0 }, // Clear Green
{ 236, 118, 0 }, // Orange
{ 0 , 0, 0 }, // Black
{ 56, 56, 255 }, // Vivid Blue
{ 248, 0, 170 }, // Magenta
{ 169, 2, 240 }, // Purple
{ 0, 221, 221 }, // Turquoise
{ 201, 168, 206 }, // Light Violet
{ 0, 205, 68 }, // Bluish Green
{ 236, 188, 0 }, // Mid Yellow
{ 51, 204, 255 }, // Bluer Turquoise
{ 164, 193, 0 }, // Mid Yellowish Green
{ 0, 143, 239 }, // Dark Light Blue
};
size_t paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
}
bool lessEclipseWell(const caf::PdmPointer<RimEclipseWell>& w1, const caf::PdmPointer<RimEclipseWell>& w2)
{
if (w1.notNull() && w2.notNull())

View File

@ -120,9 +120,10 @@ public:
void updateStateForVisibilityCheckboxes();
static cvf::Color3f cycledPaletteColor(size_t colorIndex);
void assignDefaultWellColors();
static void updateWellAllocationPlots();
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;

View File

@ -21,6 +21,7 @@
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaColorTables.h"
#include "RigMainGrid.h"
@ -32,8 +33,6 @@
#include "RiuMainWindow.h"
#include "RivColorTableArray.h"
#include "cafAppEnum.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
@ -187,7 +186,7 @@ void RimFaultCollection::syncronizeFaults()
{
if (!(m_reservoirView && m_reservoirView->mainGrid()) ) return;
cvf::ref<cvf::Color3fArray> partColors = RivColorTableArray::colorTableArray();
const caf::ColorTable& colorTable = RiaColorTables::faultsPaletteColors();
const cvf::Collection<RigFault> constRigFaults = m_reservoirView->mainGrid()->faults();
@ -246,7 +245,7 @@ void RimFaultCollection::syncronizeFaults()
if (!rimFault)
{
rimFault = new RimFault();
rimFault->faultColor = partColors->get(fIdx % partColors->size());
rimFault->faultColor = colorTable.cycledColor3f(fIdx);
QString faultName = rigFaults[fIdx]->name();
if (faultName.startsWith(RimDefines::undefinedGridFaultName(), Qt::CaseInsensitive)

View File

@ -21,6 +21,7 @@
#include "RimLegendConfig.h"
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RimCellEdgeColors.h"
#include "RimEclipseCellColors.h"
@ -278,129 +279,7 @@ void RimLegendConfig::updateLegend()
m_logDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
m_logSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
cvf::Color3ubArray legendColors;
switch (m_colorRangeMode())
{
case NORMAL:
{
legendColors.reserve(7);
legendColors.add(cvf::Color3ub( 0, 0, 255));
legendColors.add(cvf::Color3ub( 0, 127, 255));
legendColors.add(cvf::Color3ub( 0, 255, 255));
legendColors.add(cvf::Color3ub( 0, 255, 0));
legendColors.add(cvf::Color3ub(255, 255, 0));
legendColors.add(cvf::Color3ub(255, 127, 0));
legendColors.add(cvf::Color3ub(255, 0, 0));
}
break;
case OPPOSITE_NORMAL:
{
legendColors.reserve(7);
legendColors.add(cvf::Color3ub(255, 0, 0));
legendColors.add(cvf::Color3ub(255, 127, 0));
legendColors.add(cvf::Color3ub(255, 255, 0));
legendColors.add(cvf::Color3ub( 0, 255, 0));
legendColors.add(cvf::Color3ub( 0, 255, 255));
legendColors.add(cvf::Color3ub( 0, 127, 255));
legendColors.add(cvf::Color3ub( 0, 0, 255));
}
break;
case BLACK_WHITE:
case WHITE_BLACK:
{
legendColors.reserve(2);
if (m_colorRangeMode() == BLACK_WHITE)
{
legendColors.add(cvf::Color3ub::BLACK);
legendColors.add(cvf::Color3ub::WHITE);
}
else
{
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::BLACK);
}
}
break;
case PINK_WHITE:
case WHITE_PINK:
{
legendColors.reserve(2);
if (m_colorRangeMode() == PINK_WHITE)
{
legendColors.add(cvf::Color3ub::DEEP_PINK);
legendColors.add(cvf::Color3ub::WHITE);
}
else
{
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::DEEP_PINK);
}
}
break;
case BLUE_WHITE_RED:
case RED_WHITE_BLUE:
{
legendColors.reserve(3);
if (m_colorRangeMode() == BLUE_WHITE_RED)
{
legendColors.add(cvf::Color3ub::BLUE);
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::RED);
}
else
{
legendColors.add(cvf::Color3ub::RED);
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::BLUE);
}
}
break;
case CATEGORY:
{
// Based on http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors
// and Kelly Colors and sorted by hue
// See also http://www.w3schools.com/colors/ for palettes etc.
legendColors.reserve(20);
legendColors.add(cvf::Color3ub(128, 62, 117)); // hwb(310, 24%, 50%) strong_purple
legendColors.add(cvf::Color3ub(212, 28, 132)); // hwb(326, 11%, 17%) strong_purplish_red
legendColors.add(cvf::Color3ub(246, 118, 142)); // hwb(349, 46%, 4%) strong_purplish_pink
legendColors.add(cvf::Color3ub(193, 0, 32)); // hwb(350, 0%, 24%) vivid_red
legendColors.add(cvf::Color3ub(127, 24, 13)); // hwb( 6, 5%, 50%) strong_reddish_brown
legendColors.add(cvf::Color3ub(241, 58, 19)); // hwb( 11, 7%, 5%) vivid_reddish_orange
legendColors.add(cvf::Color3ub(255, 122, 92)); // hwb( 11, 36%, 0%) strong_yellowish_pink
legendColors.add(cvf::Color3ub(129, 112, 102)); // hwb( 22, 40%, 49%) medium_gray
legendColors.add(cvf::Color3ub(255, 104, 0)); // hwb( 24, 0%, 0%) vivid_orange
legendColors.add(cvf::Color3ub( 89, 51, 21)); // hwb( 26, 8%, 65%) deep_yellowish_brown
legendColors.add(cvf::Color3ub(255, 142, 0)); // hwb( 33, 0%, 0%) vivid_orange_yellow
legendColors.add(cvf::Color3ub(206, 162, 98)); // hwb( 36, 38%, 19%) grayish_yellow
legendColors.add(cvf::Color3ub(244, 200, 0)); // hwb( 49, 0%, 4%) vivid_greenish_yellow
legendColors.add(cvf::Color3ub(147, 170, 0)); // hwb( 68, 0%, 33%) vivid_yellowish_green
legendColors.add(cvf::Color3ub( 59, 84, 23)); // hwb( 85, 9%, 67%) dark_olive_green
legendColors.add(cvf::Color3ub( 0, 125, 52)); // hwb(145, 0%, 51%) vivid_green
legendColors.add(cvf::Color3ub( 54, 125, 123)); // hwb(178, 21%, 51%) vivid_blueish_green
legendColors.add(cvf::Color3ub( 0, 83, 138)); // hwb(204, 0%, 46%) strong_blue
legendColors.add(cvf::Color3ub(166, 189, 215)); // hwb(212, 65%, 16%) very_light_blue
legendColors.add(cvf::Color3ub( 46, 76, 224)); // hwb(230, 18%, 12%) medium_blue
}
break;
case ANGULAR:
{
legendColors.reserve(9);
legendColors.add(cvf::Color3ub(255, 0, 255));
legendColors.add(cvf::Color3ub(0, 0, 255));
legendColors.add(cvf::Color3ub(0, 127, 255));
legendColors.add(cvf::Color3ub(0, 255, 255));
legendColors.add(cvf::Color3ub(0, 255, 0));
legendColors.add(cvf::Color3ub(255, 255, 0));
legendColors.add(cvf::Color3ub(255, 127, 0));
legendColors.add(cvf::Color3ub(255, 0, 0));
legendColors.add(cvf::Color3ub(255, 0, 255));
}
break;
}
cvf::Color3ubArray legendColors = colorArrayFromColorType(m_colorRangeMode());
m_linDiscreteScalarMapper->setColors(legendColors);
m_logDiscreteScalarMapper->setColors(legendColors);
@ -429,7 +308,15 @@ void RimLegendConfig::updateLegend()
break;
case CATEGORY_INTEGER:
m_categoryMapper->setCategoriesWithNames(m_categories, m_categoryNames);
m_categoryMapper->setInterpolateColors(legendColors);
if (m_categoryColors.size() > 0)
{
m_categoryMapper->setCycleColors(m_categoryColors);
}
else
{
m_categoryMapper->setInterpolateColors(legendColors);
}
m_currentScalarMapper = m_categoryMapper.p();
break;
default:
@ -600,55 +487,6 @@ void RimLegendConfig::setMappingMode(MappingType mappingType)
updateLegend();
}
/*
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Color3ubArray> RimLegendConfig::interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount)
{
uint inputColorCount = static_cast<uint>(colorArray.size());
CVF_ASSERT(inputColorCount > 1);
CVF_ASSERT(targetColorCount > 1);
cvf::ref<cvf::Color3ubArray> colors = new cvf::Color3ubArray;
colors->reserve(targetColorCount);
const uint inputLevelCount = inputColorCount - 1;
const uint outputLevelCount = targetColorCount - 1;
uint outputLevelIdx;
for (outputLevelIdx = 0; outputLevelIdx < outputLevelCount; outputLevelIdx++)
{
double dblInputLevelIndex = inputLevelCount * (outputLevelIdx / static_cast<double>(outputLevelCount));
const uint inputLevelIndex = static_cast<uint>(dblInputLevelIndex);
CVF_ASSERT(inputLevelIndex < inputLevelCount);
double t = dblInputLevelIndex - inputLevelIndex;
CVF_ASSERT(t >= 0 && t <= 1.0);
cvf::Color3ub c1 = colorArray[inputLevelIndex];
cvf::Color3ub c2 = colorArray[inputLevelIndex + 1];
int r = static_cast<int>(c1.r() + t*(c2.r() - c1.r()) + 0.5);
int g = static_cast<int>(c1.g() + t*(c2.g() - c1.g()) + 0.5);
int b = static_cast<int>(c1.b() + t*(c2.b() - c1.b()) + 0.5);
r = cvf::Math::clamp(r, 0, 255);
g = cvf::Math::clamp(g, 0, 255);
b = cvf::Math::clamp(b, 0, 255);
cvf::Color3ub col((cvf::ubyte)r, (cvf::ubyte)g, (cvf::ubyte)b);
colors->add(col);
}
colors->add(colorArray[colorArray.size() - 1]);
return colors;
}
*/
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -740,6 +578,7 @@ void RimLegendConfig::setIntegerCategories(const std::vector<int>& categories)
{
m_categories = categories;
m_categoryNames.clear();
m_categoryColors.clear();
updateLegend();
}
@ -759,6 +598,7 @@ void RimLegendConfig::setNamedCategoriesInverse(const std::vector<QString>& cate
m_categories = nameIndices;
m_categoryNames = names;
m_categoryColors.clear();
updateLegend();
}
@ -766,23 +606,42 @@ void RimLegendConfig::setNamedCategoriesInverse(const std::vector<QString>& cate
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimLegendConfig::setNamedCategories(const std::vector<QString>& categoryNames)
void RimLegendConfig::setCategoryItems(const std::vector< std::tuple<QString, int, cvf::Color3ub> >& categories)
{
std::vector<int> nameIndices;
std::vector<cvf::String> names;
m_categories.clear();
m_categoryNames.clear();
m_categoryColors.clear();
m_categoryColors.reserve(categories.size());
for ( size_t i = 0; i < categoryNames.size(); ++i )
for (auto item : categories)
{
nameIndices.push_back(static_cast<int>(i));
names.push_back(cvfqt::Utils::toString(categoryNames[i]));
m_categoryNames.push_back(cvfqt::Utils::toString(std::get<0>(item)));
m_categories.push_back(std::get<1>(item));
m_categoryColors.add(std::get<2>(item));
}
m_categories = nameIndices;
m_categoryNames = names;
updateLegend();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimLegendConfig::categoryNameFromCategoryValue(int categoryValue) const
{
if (m_categoryNames.size() > 0)
{
for (size_t categoryIndex = 0; categoryIndex < m_categories.size(); categoryIndex++)
{
if (categoryValue == m_categories[categoryIndex])
{
return cvfqt::Utils::toQString(m_categoryNames[categoryIndex]);
}
}
}
return QString("%1").arg(categoryValue);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -816,6 +675,50 @@ void RimLegendConfig::setUiValuesFromLegendConfig(const RimLegendConfig* otherLe
this->readObjectFromXmlString(serializedObjectString, caf::PdmDefaultObjectFactory::instance());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3ubArray RimLegendConfig::colorArrayFromColorType(ColorRangesType colorType)
{
switch (colorType)
{
case RimLegendConfig::NORMAL:
return RiaColorTables::normalPaletteColors().color3ubArray();
break;
case RimLegendConfig::OPPOSITE_NORMAL:
return RiaColorTables::normalPaletteOppositeOrderingColors().color3ubArray();
break;
case RimLegendConfig::WHITE_PINK:
return RiaColorTables::whitePinkPaletteColors().color3ubArray();
break;
case RimLegendConfig::PINK_WHITE:
return RiaColorTables::pinkWhitePaletteColors().color3ubArray();
break;
case RimLegendConfig::WHITE_BLACK:
return RiaColorTables::whiteBlackPaletteColors().color3ubArray();
break;
case RimLegendConfig::BLACK_WHITE:
return RiaColorTables::blackWhitePaletteColors().color3ubArray();
break;
case RimLegendConfig::BLUE_WHITE_RED:
return RiaColorTables::blueWhiteRedPaletteColors().color3ubArray();
break;
case RimLegendConfig::RED_WHITE_BLUE:
return RiaColorTables::redWhiteBluePaletteColors().color3ubArray();
break;
case RimLegendConfig::CATEGORY:
return RiaColorTables::categoryPaletteColors().color3ubArray();
break;
case RimLegendConfig::ANGULAR:
return RiaColorTables::angularPaletteColors().color3ubArray();
break;
default:
break;
}
return RiaColorTables::normalPaletteColors().color3ubArray();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -26,6 +26,8 @@
#include "cafPdmObject.h"
#include "cafPdmField.h"
#include <tuple>
namespace cvf
{
class ScalarMapperContinuousLog;
@ -105,9 +107,11 @@ public:
void setAutomaticRanges(double globalMin, double globalMax, double localMin, double localMax);
void setClosestToZeroValues(double globalPosClosestToZero, double globalNegClosestToZero, double localPosClosestToZero, double localNegClosestToZero);
void setIntegerCategories(const std::vector<int>& categories);
void setNamedCategoriesInverse(const std::vector<QString>& categoryNames);
void setNamedCategories(const std::vector<QString>& categoryNames);
void setCategoryItems(const std::vector<std::tuple<QString, int, cvf::Color3ub>>& categories);
QString categoryNameFromCategoryValue(int categoryValue) const;
void setTitle(const cvf::String& title);
@ -123,11 +127,12 @@ protected:
private:
void updateLegend();
void updateFieldVisibility();
cvf::ref<cvf::Color3ubArray> interpolateColorArray(const cvf::Color3ubArray& colorArray, cvf::uint targetColorCount);
double roundToNumSignificantDigits(double value, double precision);
friend class RimViewLinker;
void setUiValuesFromLegendConfig(const RimLegendConfig* otherLegendConfig);
static cvf::Color3ubArray colorArrayFromColorType(ColorRangesType colorType);
private:
cvf::ref<cvf::ScalarMapperDiscreteLinear> m_linDiscreteScalarMapper;
@ -155,6 +160,7 @@ private:
std::vector<int> m_categories;
std::vector<cvf::String> m_categoryNames;
cvf::Color3ubArray m_categoryColors;
// Fields
caf::PdmField<int> m_numLevels;

View File

@ -90,6 +90,19 @@ void RimViewWindow::updateMdiWindowVisibility()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimViewWindow::isMdiWindow() const
{
if (m_windowController())
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -51,6 +51,7 @@ public:
void setAs3DViewMdiWindow() { setAsMdiWindow(0); }
void setAsPlotMdiWindow() { setAsMdiWindow(1); }
bool isMdiWindow() const;
void setMdiWindowGeometry(const RimMdiWindowGeometry& windowGeometry);
RimMdiWindowGeometry mdiWindowGeometry();

View File

@ -304,7 +304,7 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate()
{
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->trueDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
}
else
else if (wellLogPlot->depthType() == RimWellLogPlot::MEASURED_DEPTH)
{
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->measuredDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
}

View File

@ -30,6 +30,7 @@
#include "cvfAssert.h"
#include <math.h>
#include "RimWellAllocationPlot.h"
#define RI_LOGPLOT_MINDEPTH_DEFAULT 0.0
#define RI_LOGPLOT_MAXDEPTH_DEFAULT 1000.0
@ -41,6 +42,8 @@ namespace caf {
{
addItem(RimWellLogPlot::MEASURED_DEPTH, "MEASURED_DEPTH", "Measured Depth");
addItem(RimWellLogPlot::TRUE_VERTICAL_DEPTH, "TRUE_VERTICAL_DEPTH", "True Vertical Depth");
addItem(RimWellLogPlot::PSEUDO_LENGTH, "PSEUDO_LENGTH", "Pseudo Length");
addItem(RimWellLogPlot::CONNECTION_NUMBER, "CONNECTION_NUMBER", "Connection Number");
setDefault(RimWellLogPlot::MEASURED_DEPTH);
}
@ -70,6 +73,7 @@ RimWellLogPlot::RimWellLogPlot()
CAF_PDM_InitField(&m_minVisibleDepth, "MinimumDepth", 0.0, "Min", "", "", "");
CAF_PDM_InitField(&m_maxVisibleDepth, "MaximumDepth", 1000.0, "Max", "", "", "");
CAF_PDM_InitField(&m_isAutoScaleDepthEnabled, "AutoScaleDepthEnabled", true, "Auto Scale", "", "", "");
CAF_PDM_InitField(&m_showTrackLegends, "ShowTrackLegends", true, "Show Legends", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_tracks, "Tracks", "", "", "", "");
m_tracks.uiCapability()->setUiHidden(true);
@ -111,11 +115,49 @@ void RimWellLogPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c
{
updateMdiWindowTitle();
}
if (changedField == &m_depthType ||
changedField == &m_depthUnit)
if ( changedField == &m_depthType
|| changedField == &m_depthUnit)
{
updateTracks();
}
if ( changedField == &m_showTrackLegends)
{
updateTracks();
if (m_viewer) m_viewer->updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellLogPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (fieldNeedingOptions == &m_depthType )
{
using DepthAppEnum = caf::AppEnum< DepthTypeEnum >;
for (size_t i = 0; i < DepthAppEnum::size(); ++i)
{
DepthTypeEnum enumVal = DepthAppEnum::fromIndex(i);
if (m_disabledDepthTypes.count( enumVal) == 0)
{
options.push_back(caf::PdmOptionItemInfo(DepthAppEnum::uiText(enumVal), enumVal));
}
}
}
else if ( fieldNeedingOptions == &m_depthUnit)
{
using UnitAppEnum = caf::AppEnum< RimDefines::DepthUnitType >;
options.push_back(caf::PdmOptionItemInfo(UnitAppEnum::uiText(RimDefines::UNIT_METER), RimDefines::UNIT_METER));
options.push_back(caf::PdmOptionItemInfo(UnitAppEnum::uiText(RimDefines::UNIT_FEET), RimDefines::UNIT_FEET));
}
(*useOptionsOnly) = true;
return options;
}
//--------------------------------------------------------------------------------------------------
@ -145,8 +187,6 @@ void RimWellLogPlot::addTrack(RimWellLogTrack* track)
track->recreateViewer();
m_viewer->addTrackPlot(track->viewer());
}
updateTrackNames();
}
//--------------------------------------------------------------------------------------------------
@ -354,12 +394,19 @@ void RimWellLogPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
{
uiOrdering.add(&m_userName);
uiOrdering.add(&m_depthType);
uiOrdering.add(&m_depthUnit);
if ( m_depthType() != CONNECTION_NUMBER )
{
uiOrdering.add(&m_depthUnit);
}
caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible Depth Range");
gridGroup->add(&m_isAutoScaleDepthEnabled);
gridGroup->add(&m_minVisibleDepth);
gridGroup->add(&m_maxVisibleDepth);
uiOrdering.add(&m_showTrackLegends);
uiOrdering.setForgetRemainingFields(true);
}
@ -379,6 +426,8 @@ void RimWellLogPlot::updateTracks()
{
if (m_showWindow)
{
updateDisabledDepthTypes();
for (size_t tIdx = 0; tIdx < m_tracks.size(); ++tIdx)
{
m_tracks[tIdx]->loadDataAndUpdate();
@ -520,6 +569,14 @@ RimWellLogPlot::DepthTypeEnum RimWellLogPlot::depthType() const
return m_depthType.value();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogPlot::setDepthType(DepthTypeEnum depthType)
{
m_depthType = depthType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -538,14 +595,24 @@ QString RimWellLogPlot::depthPlotTitle() const
switch (m_depthType.value())
{
case MEASURED_DEPTH:
depthTitle = "MD";
break;
depthTitle = "MD";
break;
case TRUE_VERTICAL_DEPTH:
depthTitle = "TVD";
break;
depthTitle = "TVD";
break;
case PSEUDO_LENGTH:
depthTitle = "PL";
break;
case CONNECTION_NUMBER:
depthTitle = "Connection";
break;
}
if (m_depthType() == CONNECTION_NUMBER) return depthTitle;
if (m_depthUnit == RimDefines::UNIT_METER)
{
depthTitle += " [m]";
@ -554,10 +621,30 @@ QString RimWellLogPlot::depthPlotTitle() const
{
depthTitle += " [ft]";
}
else if (m_depthUnit == RimDefines::UNIT_NONE)
{
depthTitle += "";
}
return depthTitle;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellLogPlot::isTrackLegendsVisible() const
{
return m_showTrackLegends();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogPlot::setTrackLegendsVisible(bool doShow)
{
m_showTrackLegends = doShow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -576,3 +663,24 @@ void RimWellLogPlot::setDepthUnit(RimDefines::DepthUnitType depthUnit)
updateTracks();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogPlot::updateDisabledDepthTypes()
{
m_disabledDepthTypes.clear();
RimWellAllocationPlot* wap;
firstAncestorOrThisOfType(wap);
if (wap)
{
m_disabledDepthTypes.insert(MEASURED_DEPTH);
m_disabledDepthTypes.insert(TRUE_VERTICAL_DEPTH);
m_disabledDepthTypes.insert(PSEUDO_LENGTH);
}
else
{
m_disabledDepthTypes.insert(PSEUDO_LENGTH);
m_disabledDepthTypes.insert(CONNECTION_NUMBER);
}
}

View File

@ -45,10 +45,14 @@ public:
enum DepthTypeEnum
{
MEASURED_DEPTH,
TRUE_VERTICAL_DEPTH
TRUE_VERTICAL_DEPTH,
PSEUDO_LENGTH,
CONNECTION_NUMBER
};
public:
RimWellLogPlot();
virtual ~RimWellLogPlot();
@ -57,11 +61,15 @@ public:
QString description() const;
DepthTypeEnum depthType() const;
void setDepthType(DepthTypeEnum depthType);
RimDefines::DepthUnitType depthUnit() const;
void setDepthUnit(RimDefines::DepthUnitType depthUnit);
QString depthPlotTitle() const;
bool isTrackLegendsVisible() const;
void setTrackLegendsVisible(bool doShow);
void addTrack(RimWellLogTrack* track);
void insertTrack(RimWellLogTrack* track, size_t index);
@ -97,6 +105,7 @@ protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering);
virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; }
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
virtual QImage snapshotWindowContent() override;
@ -107,6 +116,8 @@ private:
void recreateTrackPlots();
void detachAllCurves();
void updateDisabledDepthTypes();
public: // Needed by RiuWellAllocation Plot
// RimViewWindow overrides
@ -118,12 +129,14 @@ private:
caf::PdmField< caf::AppEnum< DepthTypeEnum > > m_depthType;
caf::PdmField< caf::AppEnum< RimDefines::DepthUnitType > > m_depthUnit;
std::set<DepthTypeEnum> m_disabledDepthTypes;
caf::PdmChildArrayField<RimWellLogTrack*> m_tracks;
caf::PdmField<double> m_minVisibleDepth;
caf::PdmField<double> m_maxVisibleDepth;
caf::PdmField<bool> m_isAutoScaleDepthEnabled;
caf::PdmField<bool> m_showTrackLegends;
double m_minAvailableDepth;
double m_maxAvailableDepth;

View File

@ -1,483 +1,492 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RimWellLogTrack.h"
#include "RigStatisticsCalculator.h"
#include "RimWellLogPlot.h"
#include "RimWellLogCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuWellLogPlot.h"
#include "RiuMainWindow.h"
#include "cvfAssert.h"
#include "cvfMath.h"
#include "qwt_scale_engine.h"
#include <math.h>
#include "RimWellFlowRateCurve.h"
#define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0
#define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0
CAF_PDM_SOURCE_INIT(RimWellLogTrack, "WellLogPlotTrack");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack::RimWellLogTrack()
{
CAF_PDM_InitObject("Track", ":/WellLogTrack16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_userName, "TrackDescription", "Name", "", "", "");
m_userName.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitField(&m_show, "Show", true, "Show track", "", "", "");
m_show.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&curves, "Curves", "", "", "", "");
curves.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_visibleXRangeMin, "VisibleXRangeMin", RI_LOGPLOTTRACK_MINX_DEFAULT, "Min", "", "", "");
CAF_PDM_InitField(&m_visibleXRangeMax, "VisibleXRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max", "", "", "");
CAF_PDM_InitField(&m_isAutoScaleXEnabled, "AutoScaleX", true, "Auto Scale", "", "", "");
CAF_PDM_InitField(&m_isLogarithmicScaleEnabled, "LogarithmicScaleX", false, "Logarithmic Scale", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack::~RimWellLogTrack()
{
curves.deleteAllChildObjects();
if (m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->deleteLater();
m_wellLogTrackPlotWidget = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setDescription(const QString& description)
{
m_userName = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_show)
{
if (m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->setVisible(m_show());
}
RimWellLogPlot* wellLogPlot;
this->firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot)
{
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
RiuWellLogPlot* wellLogPlotViewer = dynamic_cast<RiuWellLogPlot*>(wellLogPlot->viewWidget());
if (wellLogPlotViewer)
{
wellLogPlotViewer->updateChildrenLayout();
}
}
}
else if (changedField == &m_visibleXRangeMin || changedField == &m_visibleXRangeMax)
{
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
m_isAutoScaleXEnabled = false;
}
else if (changedField == &m_isAutoScaleXEnabled)
{
if (m_isAutoScaleXEnabled())
{
this->updateXZoom();
computeAndSetXRangeMinForLogarithmicScale();
if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->replot();
}
}
else if (changedField == &m_isLogarithmicScaleEnabled)
{
updateAxisScaleEngine();
this->updateXZoom();
computeAndSetXRangeMinForLogarithmicScale();
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellLogTrack::objectToggleField()
{
return &m_show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellLogTrack::userDescriptionField()
{
return &m_userName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::addCurve(RimWellLogCurve* curve)
{
curves.push_back(curve);
if (m_wellLogTrackPlotWidget)
{
curve->setParentQwtPlot(m_wellLogTrackPlotWidget);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::insertCurve(RimWellLogCurve* curve, size_t index)
{
curves.insert(index, curve);
// Todo: Mark curve data to use either TVD or MD
if (m_wellLogTrackPlotWidget)
{
curve->setParentQwtPlot(m_wellLogTrackPlotWidget);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::removeCurve(RimWellLogCurve* curve)
{
size_t index = curves.index(curve);
if ( index < curves.size())
{
curves[index]->detachQwtCurve();
curves.removeChildObject(curve);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack* RimWellLogTrack::viewer()
{
return m_wellLogTrackPlotWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::availableDepthRange(double* minimumDepth, double* maximumDepth)
{
double minDepth = HUGE_VAL;
double maxDepth = -HUGE_VAL;
size_t curveCount = curves.size();
for (size_t cIdx = 0; cIdx < curveCount; cIdx++)
{
double minCurveDepth = HUGE_VAL;
double maxCurveDepth = -HUGE_VAL;
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->depthRange(&minCurveDepth, &maxCurveDepth))
{
if (minCurveDepth < minDepth)
{
minDepth = minCurveDepth;
}
if (maxCurveDepth > maxDepth)
{
maxDepth = maxCurveDepth;
}
}
}
*minimumDepth = minDepth;
*maximumDepth = maxDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::loadDataAndUpdate()
{
RimWellLogPlot* wellLogPlot;
firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot && m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->setDepthTitle(wellLogPlot->depthPlotTitle());
}
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->loadDataAndUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::recreateViewer()
{
if (m_wellLogTrackPlotWidget == NULL)
{
m_wellLogTrackPlotWidget = new RiuWellLogTrack(this);
updateAxisScaleEngine();
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->setParentQwtPlot(this->m_wellLogTrackPlotWidget);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::detachAllCurves()
{
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->detachQwtCurve();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateXZoomAndParentPlotDepthZoom()
{
if (m_wellLogTrackPlotWidget)
{
RimWellLogPlot* wellLogPlot;
firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot)
{
wellLogPlot->updateDepthZoom();
}
updateXZoom();
m_wellLogTrackPlotWidget->replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateXZoom()
{
std::vector<RimWellFlowRateCurve*> stackCurves = visibleStackedCurves();
for (RimWellFlowRateCurve* stCurve: stackCurves) stCurve->updateStackedPlotData();
if (!m_isAutoScaleXEnabled())
{
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
return;
}
double minValue = HUGE_VAL;
double maxValue = -HUGE_VAL;
for (size_t cIdx = 0; cIdx < curves.size(); cIdx++)
{
double minCurveValue = HUGE_VAL;
double maxCurveValue = -HUGE_VAL;
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->valueRange(&minCurveValue, &maxCurveValue))
{
if (minCurveValue < minValue)
{
minValue = minCurveValue;
}
if (maxCurveValue > maxValue)
{
maxValue = maxCurveValue;
}
}
}
if (minValue == HUGE_VAL)
{
minValue = RI_LOGPLOTTRACK_MINX_DEFAULT;
maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT;
}
m_visibleXRangeMin = minValue;
m_visibleXRangeMax = maxValue;
computeAndSetXRangeMinForLogarithmicScale();
if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogCurve* RimWellLogTrack::curveDefinitionFromCurve(const QwtPlotCurve* curve) const
{
for (size_t idx = 0; idx < curves.size(); idx++)
{
if (curves[idx]->qwtPlotCurve() == curve)
{
return curves[idx];
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&m_userName);
caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible X Axis Range");
gridGroup->add(&m_isAutoScaleXEnabled);
gridGroup->add(&m_visibleXRangeMin);
gridGroup->add(&m_visibleXRangeMax);
gridGroup->add(&m_isLogarithmicScaleEnabled);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimWellLogTrack::curveIndex(RimWellLogCurve* curve)
{
return curves.index(curve);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellLogTrack::isVisible()
{
return m_show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateAxisScaleEngine()
{
if (m_isLogarithmicScaleEnabled)
{
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine);
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLogScaleEngine);
}
else
{
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLinearScaleEngine);
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::computeAndSetXRangeMinForLogarithmicScale()
{
if (m_isAutoScaleXEnabled && m_isLogarithmicScaleEnabled)
{
double pos = HUGE_VAL;
double neg = -HUGE_VAL;
for (size_t cIdx = 0; cIdx < curves.size(); cIdx++)
{
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->curveData())
{
RigStatisticsCalculator::posNegClosestToZero(curves[cIdx]->curveData()->xPlotValues(), pos, neg);
}
}
if (pos != HUGE_VAL)
{
m_visibleXRangeMin = pos;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setLogarithmicScale(bool enable)
{
m_isLogarithmicScaleEnabled = enable;
updateAxisScaleEngine();
computeAndSetXRangeMinForLogarithmicScale();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellFlowRateCurve*> RimWellLogTrack::visibleStackedCurves()
{
std::vector<RimWellFlowRateCurve*> stackedCurves;
for (RimWellLogCurve* curve: curves)
{
if (curve && curve->isCurveVisible() )
{
RimWellFlowRateCurve* wfrCurve = dynamic_cast<RimWellFlowRateCurve*>(curve);
if (wfrCurve) stackedCurves.push_back(wfrCurve);
}
}
return stackedCurves;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RimWellLogTrack.h"
#include "RigStatisticsCalculator.h"
#include "RimWellLogPlot.h"
#include "RimWellLogCurve.h"
#include "RiuWellLogTrack.h"
#include "RiuWellLogPlot.h"
#include "RiuMainWindow.h"
#include "cvfAssert.h"
#include "cvfMath.h"
#include "qwt_scale_engine.h"
#include <math.h>
#include "RimWellFlowRateCurve.h"
#define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0
#define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0
CAF_PDM_SOURCE_INIT(RimWellLogTrack, "WellLogPlotTrack");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack::RimWellLogTrack()
{
CAF_PDM_InitObject("Track", ":/WellLogTrack16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_userName, "TrackDescription", "Name", "", "", "");
m_userName.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitField(&m_show, "Show", true, "Show track", "", "", "");
m_show.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&curves, "Curves", "", "", "", "");
curves.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_visibleXRangeMin, "VisibleXRangeMin", RI_LOGPLOTTRACK_MINX_DEFAULT, "Min", "", "", "");
CAF_PDM_InitField(&m_visibleXRangeMax, "VisibleXRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max", "", "", "");
CAF_PDM_InitField(&m_isAutoScaleXEnabled, "AutoScaleX", true, "Auto Scale", "", "", "");
CAF_PDM_InitField(&m_isLogarithmicScaleEnabled, "LogarithmicScaleX", false, "Logarithmic Scale", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack::~RimWellLogTrack()
{
curves.deleteAllChildObjects();
if (m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->deleteLater();
m_wellLogTrackPlotWidget = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setDescription(const QString& description)
{
m_userName = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_show)
{
if (m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->setVisible(m_show());
}
RimWellLogPlot* wellLogPlot;
this->firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot)
{
wellLogPlot->calculateAvailableDepthRange();
wellLogPlot->updateDepthZoom();
RiuWellLogPlot* wellLogPlotViewer = dynamic_cast<RiuWellLogPlot*>(wellLogPlot->viewWidget());
if (wellLogPlotViewer)
{
wellLogPlotViewer->updateChildrenLayout();
}
}
}
else if (changedField == &m_visibleXRangeMin || changedField == &m_visibleXRangeMax)
{
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
m_isAutoScaleXEnabled = false;
}
else if (changedField == &m_isAutoScaleXEnabled)
{
if (m_isAutoScaleXEnabled())
{
this->updateXZoom();
computeAndSetXRangeMinForLogarithmicScale();
if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->replot();
}
}
else if (changedField == &m_isLogarithmicScaleEnabled)
{
updateAxisScaleEngine();
this->updateXZoom();
computeAndSetXRangeMinForLogarithmicScale();
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellLogTrack::objectToggleField()
{
return &m_show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimWellLogTrack::userDescriptionField()
{
return &m_userName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::addCurve(RimWellLogCurve* curve)
{
curves.push_back(curve);
if (m_wellLogTrackPlotWidget)
{
curve->setParentQwtPlot(m_wellLogTrackPlotWidget);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::insertCurve(RimWellLogCurve* curve, size_t index)
{
curves.insert(index, curve);
// Todo: Mark curve data to use either TVD or MD
if (m_wellLogTrackPlotWidget)
{
curve->setParentQwtPlot(m_wellLogTrackPlotWidget);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::removeCurve(RimWellLogCurve* curve)
{
size_t index = curves.index(curve);
if ( index < curves.size())
{
curves[index]->detachQwtCurve();
curves.removeChildObject(curve);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack* RimWellLogTrack::viewer()
{
return m_wellLogTrackPlotWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::availableDepthRange(double* minimumDepth, double* maximumDepth)
{
double minDepth = HUGE_VAL;
double maxDepth = -HUGE_VAL;
size_t curveCount = curves.size();
for (size_t cIdx = 0; cIdx < curveCount; cIdx++)
{
double minCurveDepth = HUGE_VAL;
double maxCurveDepth = -HUGE_VAL;
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->depthRange(&minCurveDepth, &maxCurveDepth))
{
if (minCurveDepth < minDepth)
{
minDepth = minCurveDepth;
}
if (maxCurveDepth > maxDepth)
{
maxDepth = maxCurveDepth;
}
}
}
*minimumDepth = minDepth;
*maximumDepth = maxDepth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::loadDataAndUpdate()
{
RimWellLogPlot* wellLogPlot;
firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot && m_wellLogTrackPlotWidget)
{
m_wellLogTrackPlotWidget->setDepthTitle(wellLogPlot->depthPlotTitle());
m_wellLogTrackPlotWidget->setXTitle(m_xAxisTitle);
}
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->loadDataAndUpdate();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setXAxisTitle(const QString& text)
{
m_xAxisTitle = text;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::recreateViewer()
{
if (m_wellLogTrackPlotWidget == NULL)
{
m_wellLogTrackPlotWidget = new RiuWellLogTrack(this);
updateAxisScaleEngine();
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->setParentQwtPlot(this->m_wellLogTrackPlotWidget);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::detachAllCurves()
{
for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx)
{
curves[cIdx]->detachQwtCurve();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateXZoomAndParentPlotDepthZoom()
{
if (m_wellLogTrackPlotWidget)
{
RimWellLogPlot* wellLogPlot;
firstAncestorOrThisOfType(wellLogPlot);
if (wellLogPlot)
{
wellLogPlot->updateDepthZoom();
}
updateXZoom();
m_wellLogTrackPlotWidget->replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateXZoom()
{
std::vector<RimWellFlowRateCurve*> stackCurves = visibleStackedCurves();
for (RimWellFlowRateCurve* stCurve: stackCurves) stCurve->updateStackedPlotData();
if (!m_isAutoScaleXEnabled())
{
m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
m_wellLogTrackPlotWidget->replot();
return;
}
double minValue = HUGE_VAL;
double maxValue = -HUGE_VAL;
for (size_t cIdx = 0; cIdx < curves.size(); cIdx++)
{
double minCurveValue = HUGE_VAL;
double maxCurveValue = -HUGE_VAL;
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->valueRange(&minCurveValue, &maxCurveValue))
{
if (minCurveValue < minValue)
{
minValue = minCurveValue;
}
if (maxCurveValue > maxValue)
{
maxValue = maxCurveValue;
}
}
}
if (minValue == HUGE_VAL)
{
minValue = RI_LOGPLOTTRACK_MINX_DEFAULT;
maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT;
}
m_visibleXRangeMin = minValue;
m_visibleXRangeMax = maxValue;
computeAndSetXRangeMinForLogarithmicScale();
if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax);
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogCurve* RimWellLogTrack::curveDefinitionFromCurve(const QwtPlotCurve* curve) const
{
for (size_t idx = 0; idx < curves.size(); idx++)
{
if (curves[idx]->qwtPlotCurve() == curve)
{
return curves[idx];
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&m_userName);
caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible X Axis Range");
gridGroup->add(&m_isAutoScaleXEnabled);
gridGroup->add(&m_visibleXRangeMin);
gridGroup->add(&m_visibleXRangeMax);
gridGroup->add(&m_isLogarithmicScaleEnabled);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimWellLogTrack::curveIndex(RimWellLogCurve* curve)
{
return curves.index(curve);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellLogTrack::isVisible()
{
return m_show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::updateAxisScaleEngine()
{
if (m_isLogarithmicScaleEnabled)
{
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLogScaleEngine);
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLogScaleEngine);
}
else
{
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLinearScaleEngine);
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::computeAndSetXRangeMinForLogarithmicScale()
{
if (m_isAutoScaleXEnabled && m_isLogarithmicScaleEnabled)
{
double pos = HUGE_VAL;
double neg = -HUGE_VAL;
for (size_t cIdx = 0; cIdx < curves.size(); cIdx++)
{
if (curves[cIdx]->isCurveVisible() && curves[cIdx]->curveData())
{
RigStatisticsCalculator::posNegClosestToZero(curves[cIdx]->curveData()->xPlotValues(), pos, neg);
}
}
if (pos != HUGE_VAL)
{
m_visibleXRangeMin = pos;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack::setLogarithmicScale(bool enable)
{
m_isLogarithmicScaleEnabled = enable;
updateAxisScaleEngine();
computeAndSetXRangeMinForLogarithmicScale();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellFlowRateCurve*> RimWellLogTrack::visibleStackedCurves()
{
std::vector<RimWellFlowRateCurve*> stackedCurves;
for (RimWellLogCurve* curve: curves)
{
if (curve && curve->isCurveVisible() )
{
RimWellFlowRateCurve* wfrCurve = dynamic_cast<RimWellFlowRateCurve*>(curve);
if (wfrCurve) stackedCurves.push_back(wfrCurve);
}
}
return stackedCurves;
}

View File

@ -51,6 +51,7 @@ public:
void removeCurve(RimWellLogCurve* curve);
size_t curveIndex(RimWellLogCurve* curve);
size_t curveCount() { return curves.size(); }
void setXAxisTitle(const QString& text);
void recreateViewer();
void detachAllCurves();
@ -82,6 +83,10 @@ private:
void updateAxisScaleEngine();
private:
QString m_xAxisTitle;
// Fields
caf::PdmField<bool> m_show;
caf::PdmField<QString> m_userName;
caf::PdmChildArrayField<RimWellLogCurve*> curves;

View File

@ -17,7 +17,11 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RimSummaryCurveAppearanceCalculator.h"
#include "RiaColorTables.h"
#include "RimSummaryCurve.h"
#include "cvfVector3.h"
#include <cmath>
@ -253,31 +257,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledPaletteColor(int colorIn
{
if (colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 15;
static const cvf::ubyte colorData[][3] =
{
{ 0, 112, 136 }, // Dark Green-Blue
{ 202, 0, 0 }, // Red
{ 78, 204, 0 }, // Clear Green
{ 236, 118, 0 }, // Orange
{ 0 , 0, 0 }, // Black
{ 56, 56, 255 }, // Vivid Blue
{ 248, 0, 170 }, // Magenta
{ 169, 2, 240 }, // Purple
{ 0, 221, 221 }, // Turquoise
{ 201, 168, 206 }, // Light Violet
{ 0, 205, 68 }, // Bluish Green
{ 236, 188, 0 }, // Mid Yellow
{ 51, 204, 255 }, // Bluer Turquoise
{ 164, 193, 0 }, // Mid Yellowish Green
{ 0, 143, 239 }, // Dark Light Blue
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(colorIndex);
}
//--------------------------------------------------------------------------------------------------
@ -287,23 +267,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledNoneRGBBrColor(int color
{
if(colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 7;
static const cvf::ubyte colorData[][3] =
{
{ 236, 118, 0 }, // Orange
{ 0 , 0, 0 }, // Black
{ 248, 0, 170 }, // Magenta
{ 236, 188, 0 }, // Mid Yellow
{ 169, 2, 240 }, // Purple
{ 0, 221, 221 }, // Turquoise
{ 201, 168, 206 }, // Light Violet
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveNoneRedGreenBlueBrownPaletteColors().cycledColor3f(colorIndex);
}
//--------------------------------------------------------------------------------------------------
@ -313,19 +277,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledGreenColor(int colorInde
{
if(colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 3;
static const cvf::ubyte colorData[][3] =
{
{ 78, 204, 0 }, // Clear Green
{ 164, 193, 0 }, // Mid Yellowish Green
{ 0, 205, 68 } // Bluish Green
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveGreenPaletteColors().cycledColor3f(colorIndex);
}
@ -336,19 +288,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledBlueColor(int colorIndex
{
if(colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 3;
static const cvf::ubyte colorData[][3] =
{
{ 56, 56, 255 }, // Vivid Blue
{ 0, 143, 239 }, // Dark Light Blue
{ 153, 153, 255 }, // Off Light Blue
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveBluePaletteColors().cycledColor3f(colorIndex);
}
@ -359,19 +299,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledRedColor(int colorIndex)
{
if(colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 3;
static const cvf::ubyte colorData[][3] =
{
{ 202, 0, 0 }, // Off Red
{ 255, 51, 51}, // Bright Red
{ 255, 102, 102 } // Light Red
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveRedPaletteColors().cycledColor3f(colorIndex);
}
@ -382,19 +310,7 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledBrownColor(int colorInde
{
if(colorIndex < 0) return cvf::Color3f::BLACK;
static const int colorCount = 3;
static const cvf::ubyte colorData[][3] =
{
{186, 101, 44},
{ 99, 53, 23 }, // Highway Brown
{ 103, 56, 24} // Dark Brown
};
int paletteIdx = colorIndex % colorCount;
cvf::Color3ub ubColor(colorData[paletteIdx][0], colorData[paletteIdx][1], colorData[paletteIdx][2]);
cvf::Color3f cvfColor(ubColor);
return cvfColor;
return RiaColorTables::summaryCurveBrownPaletteColors().cycledColor3f(colorIndex);
}
//--------------------------------------------------------------------------------------------------

View File

@ -28,7 +28,6 @@
#include "RimSummaryYAxisProperties.h"
#include "RiuMainPlotWindow.h"
#include "RiuSelectionColors.h"
#include "RiuSummaryQwtPlot.h"
#include "cvfBase.h"
@ -50,7 +49,7 @@ CAF_PDM_SOURCE_INIT(RimSummaryPlot, "SummaryPlot");
//--------------------------------------------------------------------------------------------------
RimSummaryPlot::RimSummaryPlot()
{
CAF_PDM_InitObject("Summary Plot", ":/SummaryPlot16x16.png", "", "");
CAF_PDM_InitObject("Summary Plot", ":/SummaryPlotLight16x16.png", "", "");
CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Summary Plot"), "Name", "", "", "");
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
@ -708,3 +707,11 @@ RimSummaryCurve* RimSummaryPlot::findRimCurveFromQwtCurve(const QwtPlotCurve* qw
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimSummaryPlot::curveCount() const
{
return m_curves.size();
}

View File

@ -61,6 +61,7 @@ public:
void addCurveFilter(RimSummaryCurveFilter* curveFilter);
RimSummaryCurve* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const;
size_t curveCount() const;
void loadDataAndUpdate();

View File

@ -27,38 +27,64 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords, const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds, const std::map<QString, const std::vector<double>* >& tracerCellFractionValues, const RigEclCellIndexCalculator cellIndexCalculator):
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
const RigEclCellIndexCalculator cellIndexCalculator,
double smallContribThreshold,
bool isProducer):
m_pipeBranchesCLCoords(pipeBranchesCLCoords),
m_pipeBranchesCellIds(pipeBranchesCellIds),
m_tracerCellFractionValues(&tracerCellFractionValues),
m_cellIndexCalculator(cellIndexCalculator)
m_cellIndexCalculator(cellIndexCalculator),
m_smallContributionsThreshold(smallContribThreshold)
{
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
for ( const auto& it: (*m_tracerCellFractionValues) ) m_tracerNames.push_back(it.first);
m_tracerNames.push_back(RIG_RESERVOIR_TRACER_NAME);
calculateAccumulatedFlowPrConnection(0, 1);
if (isWellFlowConsistent(isProducer))
{
for ( const auto& it: (*m_tracerCellFractionValues) ) m_tracerNames.push_back(it.first);
m_tracerNames.push_back(RIG_RESERVOIR_TRACER_NAME);
calculateAccumulatedFlowPrConnection(0, 1);
sortTracers();
groupSmallContributions();
}
else
{
m_tracerCellFractionValues = nullptr;
m_cellIndexCalculator = RigEclCellIndexCalculator(nullptr, nullptr);
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
calculateAccumulatedFlowPrConnection(0, 1);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords, const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds):
RigAccWellFlowCalculator::RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
double smallContribThreshold ):
m_pipeBranchesCLCoords(pipeBranchesCLCoords),
m_pipeBranchesCellIds(pipeBranchesCellIds),
m_tracerCellFractionValues(nullptr),
m_cellIndexCalculator(RigEclCellIndexCalculator(nullptr, nullptr))
m_cellIndexCalculator(RigEclCellIndexCalculator(nullptr, nullptr)),
m_smallContributionsThreshold(smallContribThreshold)
{
m_accConnectionFlowPrBranch.resize(m_pipeBranchesCellIds.size());
m_tracerNames.push_back(RIG_FLOW_TOTAL_NAME);
calculateAccumulatedFlowPrConnection(0, 1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTotalFlowPrConnection(size_t branchIdx)
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTotalFlowPrConnection(size_t branchIdx)
{
CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.find(RIG_FLOW_TOTAL_NAME) != m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.end());
@ -68,7 +94,7 @@ const std::vector<double>& RigAccWellFlowCalculator::accumulatedTotalFlowPrConne
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx)
const std::vector<double>& RigAccWellFlowCalculator::accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx)
{
CVF_ASSERT(m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.find(tracerName) != m_accConnectionFlowPrBranch[branchIdx].accConnFlowFractionsPrTracer.end());
@ -78,11 +104,71 @@ const std::vector<double>& RigAccWellFlowCalculator::accumulatedTracerFlowPrConn
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<size_t>& RigAccWellFlowCalculator::connectionNumbersFromTop(size_t branchIdx)
const std::vector<size_t>& RigAccWellFlowCalculator::connectionNumbersFromTop(size_t branchIdx) const
{
return m_accConnectionFlowPrBranch[branchIdx].connectionNumbersFromTop;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalWellFlowPrTracer()
{
std::vector<QString> tracerNames = this->tracerNames();
std::vector<std::pair<QString, double> > tracerWithValues;
for (const QString& tracerName: tracerNames)
{
const std::vector<double>& accFlow = this->accumulatedTracerFlowPrConnection(tracerName, 0);
tracerWithValues.push_back(std::make_pair(tracerName, accFlow.back()));
}
return tracerWithValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::pair<QString, double> > RigAccWellFlowCalculator::totalTracerFractions()
{
std::vector<std::pair<QString, double> > totalFlows = totalWellFlowPrTracer();
float sumTracerFlows = 0.0f;
for ( const auto& tracerVal : totalFlows)
{
sumTracerFlows += tracerVal.second;
}
if (sumTracerFlows == 0.0) totalFlows.clear();
for (auto& tracerPair : totalFlows)
{
tracerPair.second = tracerPair.second/sumTracerFlows;
}
return totalFlows;
}
bool RigAccWellFlowCalculator::isWellFlowConsistent( bool isProducer)
{
bool isConsistent = true;
for (const std::vector <RigWellResultPoint> & branch : m_pipeBranchesCellIds)
{
for (const RigWellResultPoint& wrp : branch)
{
if (isProducer)
isConsistent = (wrp.flowRate() >= 0.0) ;
else
isConsistent = (wrp.flowRate() <= 0.0) ;
if (!isConsistent) break;
}
if (!isConsistent) break;
}
return isConsistent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -250,3 +336,84 @@ std::vector<size_t> RigAccWellFlowCalculator::findDownstreamBranchIdxs(const Rig
return downStreamBranchIdxs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigAccWellFlowCalculator::sortTracers()
{
std::multimap<double, QString> sortedTracers;
for (const QString& tracerName: m_tracerNames)
{
const std::vector<double>& mainBranchAccFlow = accumulatedTracerFlowPrConnection(tracerName, 0);
double totalFlow = 0.0;
if (mainBranchAccFlow.size()) totalFlow = - abs( mainBranchAccFlow.back() ); // Based on size in reverse order (biggest to least)
sortedTracers.insert({totalFlow, tracerName});
}
m_tracerNames.clear();
for (const auto& tracerPair : sortedTracers)
{
m_tracerNames.push_back(tracerPair.second);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigAccWellFlowCalculator::groupSmallContributions()
{
// Concatenate small tracers into an "Other" group
if ( m_smallContributionsThreshold > 0.0 )
{
std::vector<std::pair<QString, double> > totalTracerFractions = this->totalTracerFractions();
if ( totalTracerFractions.size() < 5 ) return; // No grouping for few legend items
std::vector<QString> tracersToGroup;
for ( const auto& tracerPair : totalTracerFractions )
{
if ( abs(tracerPair.second) <= m_smallContributionsThreshold ) tracersToGroup.push_back(tracerPair.first);
}
if ( tracersToGroup.size() < 2 ) return; // Must at least group two ...
for ( BranchResult& brRes : m_accConnectionFlowPrBranch )
{
std::vector<double> groupedConnectionValues(brRes.connectionNumbersFromTop.size(), 0.0);
for ( const QString& tracername:tracersToGroup )
{
auto it = brRes.accConnFlowFractionsPrTracer.find(tracername);
if ( it != brRes.accConnFlowFractionsPrTracer.end() )
{
const std::vector<double>& tracerVals = it->second;
for ( size_t cIdx = 0; cIdx < groupedConnectionValues.size(); ++cIdx )
{
groupedConnectionValues[cIdx] += tracerVals[cIdx];
}
}
brRes.accConnFlowFractionsPrTracer.erase(it);
}
brRes.accConnFlowFractionsPrTracer[RIG_TINY_TRACER_GROUP_NAME] = groupedConnectionValues;
}
std::vector<QString> filteredTracernames;
for ( const QString& tracerName: m_tracerNames )
{
bool isDeleted = false;
for ( const QString& deletedTracerName: tracersToGroup )
{
if ( tracerName == deletedTracerName ) { isDeleted = true; break; }
}
if ( !isDeleted ) filteredTracernames.push_back(tracerName);
}
m_tracerNames.swap(filteredTracernames);
m_tracerNames.push_back(RIG_TINY_TRACER_GROUP_NAME);
}
}

View File

@ -57,31 +57,42 @@ class RigAccWellFlowCalculator
{
public:
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
const RigEclCellIndexCalculator cellIndexCalculator);
const std::map<QString, const std::vector<double>* >& tracerCellFractionValues,
const RigEclCellIndexCalculator cellIndexCalculator,
double smallContribThreshold,
bool isProducer);
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds);
RigAccWellFlowCalculator(const std::vector< std::vector <cvf::Vec3d> >& pipeBranchesCLCoords,
const std::vector< std::vector <RigWellResultPoint> >& pipeBranchesCellIds,
double smallContribThreshold);
const std::vector<double>& accumulatedTotalFlowPrConnection( size_t branchIdx);
const std::vector<double>& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx);
const std::vector<size_t>& connectionNumbersFromTop(size_t branchIdx);
const std::vector<QString>& tracerNames() { return m_tracerNames;}
const std::vector<double>& accumulatedTotalFlowPrConnection( size_t branchIdx);// const;
const std::vector<double>& accumulatedTracerFlowPrConnection(const QString& tracerName, size_t branchIdx);// const;
const std::vector<size_t>& connectionNumbersFromTop(size_t branchIdx) const;
const std::vector<QString>& tracerNames() const { return m_tracerNames;}
std::vector<std::pair<QString, double> > totalTracerFractions();
private:
bool isWellFlowConsistent(bool isProducer);
void calculateAccumulatedFlowPrConnection( size_t branchIdx, size_t startConnectionNumberFromTop);
std::vector<size_t> wrpToConnectionIndexFromBottom( const std::vector<RigWellResultPoint> &branchCells);
static size_t connectionIndexFromTop( const std::vector<size_t>& resPointToConnectionIndexFromBottom, size_t clSegIdx);
std::vector<size_t> findDownstreamBranchIdxs( const RigWellResultPoint& connectionPoint);
std::vector<std::pair<QString, double> > totalWellFlowPrTracer() ;
void sortTracers();
void groupSmallContributions();
const std::vector< std::vector <cvf::Vec3d> >& m_pipeBranchesCLCoords;
const std::vector< std::vector <RigWellResultPoint> >& m_pipeBranchesCellIds;
const std::map<QString, const std::vector<double>* >* m_tracerCellFractionValues;
RigEclCellIndexCalculator m_cellIndexCalculator;
std::vector<QString> m_tracerNames;
double m_smallContributionsThreshold;
struct BranchResult
{

View File

@ -6,6 +6,7 @@
#include <opm/flowdiagnostics/ConnectionValues.hpp>
#include <opm/flowdiagnostics/Toolbox.hpp>
#include <opm/utility/ECLFluxCalc.hpp>
#include <opm/utility/ECLGraph.hpp>
#include <opm/utility/ECLWellSolution.hpp>
@ -17,43 +18,37 @@
namespace RigFlowDiagInterfaceTools {
inline Opm::FlowDiagnostics::ConnectionValues
extractFluxField(const Opm::ECLGraph& G)
extractFluxField(const Opm::ECLGraph& G, const bool compute_fluxes)
{
using ConnVals = Opm::FlowDiagnostics::ConnectionValues;
using NConn = ConnVals::NumConnections;
using NPhas = ConnVals::NumPhases;
const auto nconn = NConn{G.numConnections()};
const auto nphas = NPhas{3};
auto flux = ConnVals(nconn, nphas);
auto phas = ConnVals::PhaseID{0};
for (const auto& p : { Opm::ECLGraph::PhaseIndex::Aqua ,
Opm::ECLGraph::PhaseIndex::Liquid ,
Opm::ECLGraph::PhaseIndex::Vapour })
auto flux = ConnVals(ConnVals::NumConnections{ G.numConnections() },
ConnVals::NumPhases{ 3 });
auto phas = ConnVals::PhaseID{ 0 };
Opm::ECLFluxCalc calc(G);
const auto phases = { Opm::ECLGraph::PhaseIndex::Aqua ,
Opm::ECLGraph::PhaseIndex::Liquid ,
Opm::ECLGraph::PhaseIndex::Vapour };
for ( const auto& p : phases )
{
const std::vector<double> pflux = G.flux(p);
if (! pflux.empty()) {
assert (pflux.size() == nconn.total);
auto conn = ConnVals::ConnID{0};
for (const auto& v : pflux) {
const auto pflux = compute_fluxes ? calc.flux(p) : G.flux(p);
if ( ! pflux.empty() )
{
assert (pflux.size() == flux.numConnections());
auto conn = ConnVals::ConnID{ 0 };
for ( const auto& v : pflux )
{
flux(conn, phas) = v;
conn.id += 1;
}
}
phas.id += 1;
}
return flux;
}
@ -77,53 +72,6 @@ namespace RigFlowDiagInterfaceTools {
return inflow;
}
namespace Hack {
inline Opm::FlowDiagnostics::ConnectionValues
convert_flux_to_SI(Opm::FlowDiagnostics::ConnectionValues&& fl)
{
using Co = Opm::FlowDiagnostics::ConnectionValues::ConnID;
using Ph = Opm::FlowDiagnostics::ConnectionValues::PhaseID;
const auto nconn = fl.numConnections();
const auto nphas = fl.numPhases();
for (auto phas = Ph{0}; phas.id < nphas; ++phas.id) {
for (auto conn = Co{0}; conn.id < nconn; ++conn.id) {
fl(conn, phas) /= 86400;
}
}
return fl;
}
}
inline Opm::FlowDiagnostics::Toolbox
initialiseFlowDiagnostics(const Opm::ECLGraph& G)
{
const Opm::FlowDiagnostics::ConnectivityGraph connGraph =
Opm::FlowDiagnostics::ConnectivityGraph{ static_cast<int>(G.numCells()),
G.neighbours() };
// Create the Toolbox.
Opm::FlowDiagnostics::Toolbox tool = Opm::FlowDiagnostics::Toolbox{ connGraph };
tool.assignPoreVolume(G.poreVolume());
Opm::FlowDiagnostics::ConnectionValues connectionsVals = Hack::convert_flux_to_SI(extractFluxField(G));
tool.assignConnectionFlux(connectionsVals);
Opm::ECLWellSolution wsol = Opm::ECLWellSolution{};
const std::vector<Opm::ECLWellSolution::WellData> well_fluxes =
wsol.solution(G.rawResultData(), G.numGrids());
tool.assignInflowFlux(extractWellFlows(G, well_fluxes));
return tool;
}
}

View File

@ -214,7 +214,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI
// Set up flow Toolbox with timestep data
{
Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::Hack::convert_flux_to_SI( RigFlowDiagInterfaceTools::extractFluxField(m_opmFldData->eclGraph));
Opm::FlowDiagnostics::ConnectionValues connectionsVals = RigFlowDiagInterfaceTools::extractFluxField(m_opmFldData->eclGraph, false);
m_opmFldData->fldToolbox->assignConnectionFlux(connectionsVals);

View File

@ -203,6 +203,11 @@ public:
{
lasFile->AddLog("DEPTH", "FT", "Depth in feet", firstCurveData->measuredDepths());
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile->AddLog("DEPTH", "", "Depth in Connection number", firstCurveData->measuredDepths());
}
if (firstCurveData->tvDepths().size())
{
@ -225,6 +230,12 @@ public:
{
lasFile->AddLog("TVDRKB", "FT", "True vertical depth (Rotary Kelly Bushing)", tvdrkbValues);
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile->AddLog("TVDRKB", "", "", tvdrkbValues);
}
}
}
@ -243,6 +254,10 @@ public:
{
lasFile->setDepthUnit("FT");
}
else if ( firstCurveData->depthUnit() == RimDefines::UNIT_NONE )
{
CVF_ASSERT(false);
}
double absentValue = SingleLasFileMetaData::createAbsentValue(m_minimumCurveValue);
lasFile->SetMissing(absentValue);

View File

@ -262,6 +262,38 @@ bool RigSingleWellResultsData::isMultiSegmentWell() const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigWellResultFrame::WellProductionType RigSingleWellResultsData::wellProductionType(size_t resultTimeStepIndex) const
{
if (hasWellResult(resultTimeStepIndex))
{
const RigWellResultFrame& wResFrame = wellResultFrame(resultTimeStepIndex);
return wResFrame.m_productionType;
}
else
{
return RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigSingleWellResultsData::isOpen(size_t resultTimeStepIndex) const
{
if (hasWellResult(resultTimeStepIndex))
{
const RigWellResultFrame& wResFrame = wellResultFrame(resultTimeStepIndex);
return wResFrame.m_isOpen;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -131,23 +131,25 @@ class RigSingleWellResultsData : public cvf::Object
public:
RigSingleWellResultsData() { m_isMultiSegmentWell = false; }
void setMultiSegmentWell(bool isMultiSegmentWell);
bool isMultiSegmentWell() const;
void setMultiSegmentWell(bool isMultiSegmentWell);
bool isMultiSegmentWell() const;
bool hasWellResult(size_t resultTimeStepIndex) const;
bool hasWellResult(size_t resultTimeStepIndex) const;
const RigWellResultFrame& wellResultFrame(size_t resultTimeStepIndex) const;
bool isOpen(size_t resultTimeStepIndex) const;
RigWellResultFrame::WellProductionType wellProductionType(size_t resultTimeStepIndex) const;
const RigWellResultFrame& wellResultFrame(size_t resultTimeStepIndex) const;
void computeStaticWellCellPath() const ;
void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes);
public: // Todo: Clean up this regarding public members and constness etc.
QString m_wellName;
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;
mutable RigWellResultFrame m_staticWellCells;
void computeStaticWellCellPath() const ;
void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector<QDateTime>& resultTimes);
public:
QString m_wellName;
bool m_isMultiSegmentWell;
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;
mutable RigWellResultFrame m_staticWellCells;
private:
bool m_isMultiSegmentWell;
};

View File

@ -228,6 +228,11 @@ QString RigWellLogFile::wellLogChannelUnitString(const QString& wellLogChannelNa
{
return "FT";
}
else if (displayDepthUnit == RimDefines::UNIT_NONE)
{
CVF_ASSERT(false);
return "";
}
}
}
@ -279,7 +284,11 @@ bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString
else if (curveData->depthUnit() == RimDefines::UNIT_FEET)
{
lasFile.AddLog("DEPTH", "FT", "Depth in feet", curveData->measuredDepths());
}
else if (curveData->depthUnit() == RimDefines::UNIT_NONE)
{
CVF_ASSERT(false);
lasFile.AddLog("DEPTH", "", "Depth in connection number", curveData->measuredDepths());
}
if(curveData->tvDepths().size())
@ -305,6 +314,11 @@ bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString
{
lasFile.setDepthUnit("FT");
}
else if ( curveData->depthUnit() == RimDefines::UNIT_NONE )
{
CVF_ASSERT(false);
lasFile.setDepthUnit("");
}
lasFile.setVersionInfo("2.0");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -80,6 +80,12 @@
<file>RightAxis16x16.png</file>
<file>BottomAxis16x16.png</file>
<file>Axes16x16.png</file>
<file>WellAllocPlots16x16.png</file>
<file>WellAllocPlot16x16.png</file>
<file>WellFlowPlot16x16.png</file>
<file>WellAllocPie16x16.png</file>
<file>WellAllocLegend16x16.png</file>
<file>SummaryPlotLight16x16.png</file>
<file>FractureLayout16x16.png</file>
<file>FractureSymbol16x16.png</file>
<file>FractureTemplate16x16.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 879 B

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 889 B

View File

@ -26,7 +26,6 @@ ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.h
${CEE_CURRENT_LIST_DIR}RiuResultTextBuilder.h
${CEE_CURRENT_LIST_DIR}RiuRmsNavigation.h
${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.h
${CEE_CURRENT_LIST_DIR}RiuSelectionColors.h
${CEE_CURRENT_LIST_DIR}RiuSelectionManager.h
${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.h
${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.h
@ -65,7 +64,6 @@ ${CEE_CURRENT_LIST_DIR}RiuResultQwtPlot.cpp
${CEE_CURRENT_LIST_DIR}RiuResultTextBuilder.cpp
${CEE_CURRENT_LIST_DIR}RiuRmsNavigation.cpp
${CEE_CURRENT_LIST_DIR}RiuSelectionChangedHandler.cpp
${CEE_CURRENT_LIST_DIR}RiuSelectionColors.cpp
${CEE_CURRENT_LIST_DIR}RiuSelectionManager.cpp
${CEE_CURRENT_LIST_DIR}RiuSimpleHistogramWidget.cpp
${CEE_CURRENT_LIST_DIR}RiuSummaryQwtPlot.cpp

View File

@ -25,6 +25,9 @@
RiuNightchartsWidget::RiuNightchartsWidget(QWidget* parent) :
QWidget(parent)
{
m_showLegend = true;
m_showPie = true;
updateSizePolicy();
clear();
}
@ -36,6 +39,51 @@ void RiuNightchartsWidget::setType(Nightcharts::type t)
m_chart.setType(t);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuNightchartsWidget::showLegend(bool doShow)
{
m_showLegend = doShow;
updateSizePolicy();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuNightchartsWidget::showPie(bool doShow)
{
m_showPie = doShow;
updateSizePolicy();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuNightchartsWidget::updateSizePolicy()
{
if (m_showPie && m_showLegend)
{
this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
else if (m_showPie && !m_showLegend )
{
this->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
}
else if (!m_showPie && m_showLegend )
{
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
}
else
{
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -45,8 +93,49 @@ void RiuNightchartsWidget::clear()
m_chart.setType(Nightcharts::Pie);
m_chart.setLegendType(Nightcharts::Vertical);
m_marginLeft = 16;
m_marginTop = 16;
m_marginLeft = 10;
m_marginTop = 10;
m_maxNameWidth = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuNightchartsWidget::sizeHint() const
{
int widthHint = 0;
int heightHint = 0;
int maxPieSize = 180;
if ( m_showLegend )
{
QPainter painter;
int lineHeight = painter.fontMetrics().height();
int lineCount = m_chart.pieceCount();
int exactLegendHeight = (lineCount + lineCount-1) * lineHeight;
widthHint = m_maxNameWidth + 5 + lineHeight;
heightHint = exactLegendHeight;
}
if (m_showPie)
{
widthHint = widthHint + maxPieSize;
heightHint = heightHint > maxPieSize ? heightHint : maxPieSize;
}
if ( m_showPie || m_showLegend )
{
widthHint += 2*m_marginLeft;
heightHint += 2*m_marginTop;
return QSize(widthHint, heightHint);
}
else
{
return QSize();
}
}
//--------------------------------------------------------------------------------------------------
@ -59,21 +148,45 @@ void RiuNightchartsWidget::paintEvent(QPaintEvent* e)
if(!m_chart.pieceCount()) return ;
QPainter painter;
QFont font;
painter.begin(this);
int w = (this->width() - m_marginLeft - 150);
int h = (this->height() - m_marginTop - 100);
int size = (w<h)?w:h;
m_chart.setCords(m_marginLeft, m_marginTop,size, size);
int legendWidth = 170;
int legendMargin = 20;
m_chart.draw(&painter);
m_chart.drawLegend(&painter);
if (!m_showLegend)
{
legendWidth = 0;
legendMargin = 0;
}
int w = (this->width() - 2* m_marginLeft - legendWidth - legendMargin);
int h = (this->height() - 2* m_marginTop );
int size = ( w < h ) ? w : h;
if ( m_showPie )
{
m_chart.setCords(m_marginLeft, m_marginTop, size, size);
m_chart.setLegendCords(m_marginLeft + size + legendMargin, m_marginTop);
}
else
{
m_chart.setLegendCords(m_marginLeft, m_marginTop);
}
if (m_showPie) m_chart.draw(&painter);
if ( m_showLegend) m_chart.drawLegend(&painter);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuNightchartsWidget::addItem(QString name, QColor color, float value)
void RiuNightchartsWidget::addItem(const QString& name, const QColor& color, float value)
{
m_chart.addPiece(name,color,value);
m_chart.addPiece(name, color, value);
QPainter painter;
int textWidth = painter.fontMetrics().width(name + " (00 %)");
m_maxNameWidth = textWidth > m_maxNameWidth ? textWidth: m_maxNameWidth;
}

View File

@ -33,16 +33,27 @@ class RiuNightchartsWidget : public QWidget
public:
explicit RiuNightchartsWidget(QWidget* parent = 0);
void addItem(QString name, QColor color, float value);
void addItem(const QString& name, const QColor& color, float value);
void setType(Nightcharts::type type);
void showLegend(bool doShow);
void showPie(bool doShow);
void clear();
virtual QSize sizeHint() const override;
protected:
virtual void paintEvent(QPaintEvent* e);
private:
void updateSizePolicy();
Nightcharts m_chart;
int m_marginLeft;
int m_marginTop;
int m_marginLeft;
int m_marginTop;
bool m_showLegend;
bool m_showPie;
int m_maxNameWidth;
};

View File

@ -33,6 +33,7 @@
#include "RimEclipseFaultColors.h"
#include "RimEclipseView.h"
#include "RimFormationNames.h"
#include "RimLegendConfig.h"
#include "RimReservoirCellResultsStorage.h"
#include "cafDisplayCoordTransform.h"
@ -401,11 +402,12 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
else scalarValue = 0.0;
resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue));
}
return;
}
else if (resultColors->hasResult())
{
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel());
cvf::ref<RigResultAccessor> resultAccessor;
if (resultColors->hasStaticResult())
{
@ -422,6 +424,8 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K);
resultInfoText->append(QString("Tran Z : %1\n").arg(scalarValue));
}
return;
}
else if (resultColors->resultVariable().compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0)
{
@ -444,6 +448,8 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_K);
resultInfoText->append(QString("MULTZ- : %1\n").arg(scalarValue));
}
return;
}
else if (resultColors->resultVariable().compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0)
{
@ -458,6 +464,8 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K);
resultInfoText->append(QString("riTran Z : %1\n").arg(scalarValue));
}
return;
}
else if (resultColors->resultVariable().compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0)
{
@ -472,6 +480,8 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K);
resultInfoText->append(QString("riMult Z : %1\n").arg(scalarValue));
}
return;
}
else if (resultColors->resultVariable().compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0)
{
@ -486,25 +496,13 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigEclipseCaseData* eclips
scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K);
resultInfoText->append(QString("riTransByArea Z : %1\n").arg(scalarValue));
}
}
else
{
resultAccessor = RigResultAccessorFactory::createFromResultIdx(eclipseCase, gridIndex, porosityModel, 0, resultColors->scalarResultIndex());
}
}
else
{
resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, gridIndex, timeStepIndex, resultColors);
}
if (resultAccessor.notNull())
{
double scalarValue = resultAccessor->cellScalar(cellIndex);
resultInfoText->append("Cell result : ");
resultInfoText->append(resultColors->resultVariableUiName());
resultInfoText->append(QString(" : %1\n").arg(scalarValue));
return;
}
}
}
resultInfoText->append(cellResultText(resultColors));
}
//--------------------------------------------------------------------------------------------------
@ -661,9 +659,6 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors)
RigEclipseCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData();
RigGridBase* grid = eclipseCaseData->grid(m_gridIndex);
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel());
if (resultColors->isTernarySaturationSelected())
{
RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->cellResult()->currentGridCellResults();
@ -673,6 +668,8 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors)
size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS");
size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT");
RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel());
cvf::ref<RigResultAccessor> dataAccessObjectX = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, soilScalarSetIndex);
cvf::ref<RigResultAccessor> dataAccessObjectY = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, sgasScalarSetIndex);
cvf::ref<RigResultAccessor> dataAccessObjectZ = RigResultAccessorFactory::createFromResultIdx(eclipseCaseData, m_gridIndex, porosityModel, m_timeStepIndex, swatScalarSetIndex);
@ -706,7 +703,19 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors)
double scalarValue = resultAccessor->cellFaceScalar(m_cellIndex, m_face);
QString resultVar = resultColors->resultVariableUiName();
text = QString("%1 : %2").arg(resultVar).arg(scalarValue);
QString resultValueText;
if (resultColors->hasCategoryResult())
{
RimLegendConfig* legendConfig = resultColors->legendConfig();
resultValueText += legendConfig->categoryNameFromCategoryValue(scalarValue);
}
else
{
resultValueText = QString("%1").arg(scalarValue);
}
text = QString("%1 : %2").arg(resultVar).arg(resultValueText);
}
}
}

View File

@ -1,57 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RiuSelectionColors.h"
#include <QColor>
static const int RI_SELECTION_COLOR_COUNT = 7;
static const int RI_SELECTION_COLOR[] =
{
Qt::magenta,
Qt::cyan,
Qt::blue,
Qt::red,
Qt::green,
Qt::yellow,
Qt::gray
};
static int riuSelectionColorIndex = 0;
//--------------------------------------------------------------------------------------------------
/// Pick default curve color from an index based palette
//--------------------------------------------------------------------------------------------------
cvf::Color3f RiuSelectionColors::curveColorFromTable()
{
QColor color = QColor(Qt::GlobalColor(RI_SELECTION_COLOR[riuSelectionColorIndex % RI_SELECTION_COLOR_COUNT]));
++riuSelectionColorIndex;
cvf::Color3f cvfColor(color.redF(), color.greenF(), color.blueF());
return cvfColor;
}
//--------------------------------------------------------------------------------------------------
/// Color rarely present in result value colors
//--------------------------------------------------------------------------------------------------
cvf::Color3f RiuSelectionColors::singleCurveColor()
{
riuSelectionColorIndex = 0;
return curveColorFromTable();
}

View File

@ -258,7 +258,14 @@ QPointF RiuSummaryQwtPlot::closestCurvePoint(const QPoint& cursorPosition, QStri
if (timeString)
{
const QwtScaleDraw* timeAxisScaleDraw = axisScaleDraw(QwtPlot::xBottom);
if (timeAxisScaleDraw)
auto dateScaleDraw = dynamic_cast<const QwtDateScaleDraw*>(timeAxisScaleDraw) ;
if (dateScaleDraw)
{
QDateTime date = dateScaleDraw->toDateTime(samplePoint.x());
*timeString = date.toString("hh:mm dd.MMMM.yyyy");
}
else if (timeAxisScaleDraw)
{
*timeString = timeAxisScaleDraw->label(samplePoint.x()).text();
}

View File

@ -20,6 +20,7 @@
#include "RiuViewerCommands.h"
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RicViewerEventInterface.h"
#include "RicEclipsePropertyFilterNewExec.h"
@ -55,7 +56,6 @@
#include "RimWellPath.h"
#include "RiuMainWindow.h"
#include "RiuSelectionColors.h"
#include "RiuSelectionManager.h"
#include "RiuViewer.h"
@ -595,10 +595,16 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM
appendToSelection = true;
}
cvf::Color3f curveColor = RiuSelectionColors::curveColorFromTable();
if (RiuSelectionManager::instance()->isEmpty() || !appendToSelection)
std::vector<RiuSelectionItem*> items;
RiuSelectionManager::instance()->selectedItems(items);
const caf::ColorTable& colorTable = RiaColorTables::selectionPaletteColors();
cvf::Color3f curveColor = colorTable.cycledColor3f(items.size());
if (!appendToSelection)
{
curveColor = RiuSelectionColors::singleCurveColor();
curveColor = colorTable.cycledColor3f(0);
}
RiuSelectionItem* selItem = NULL;

View File

@ -1,125 +1,198 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RiuWellAllocationPlot.h"
#include "RiaApplication.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimTotalWellAllocationPlot.h"
#include <QBoxLayout>
#include <QLabel>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellAllocationPlot::RiuWellAllocationPlot(RimWellAllocationPlot* plotDefinition, QWidget* parent)
: m_plotDefinition(plotDefinition),
QFrame(parent)
{
Q_ASSERT(m_plotDefinition);
QVBoxLayout* mainLayout = new QVBoxLayout();
this->setLayout(mainLayout);
this->layout()->setMargin(0);
this->layout()->setSpacing(2);
m_titleLabel = new QLabel(this);
QFont font = m_titleLabel->font();
font.setPointSize(14);
font.setBold(true);
m_titleLabel->setFont(font);
mainLayout->addWidget(m_titleLabel, 0, Qt::AlignCenter);
QHBoxLayout* plotWidgetsLayout = new QHBoxLayout();
mainLayout->addLayout(plotWidgetsLayout, 10);
QWidget* totalFlowAllocationWidget = m_plotDefinition->totalWellFlowPlot()->createViewWidget(this);
plotWidgetsLayout->addWidget(totalFlowAllocationWidget);
QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createViewWidget(this);
plotWidgetsLayout->addWidget(wellFlowWidget);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellAllocationPlot::~RiuWellAllocationPlot()
{
if (m_plotDefinition)
{
m_plotDefinition->handleMdiWindowClosed();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlot* RiuWellAllocationPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::showTitle(const QString& title)
{
m_titleLabel->show();
m_titleLabel->setText(title);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::hideTitle()
{
m_titleLabel->hide();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellAllocationPlot::minimumSizeHint() const
{
return QSize(0, 100);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellAllocationPlot::sizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::setDefaults()
{
}
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RiuWellAllocationPlot.h"
#include "RiaApplication.h"
#include "RimContextCommandBuilder.h"
#include "RimTotalWellAllocationPlot.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuNightchartsWidget.h"
#include "cvfColor3.h"
#include <QBoxLayout>
#include <QContextMenuEvent>
#include <QLabel>
#include <QMenu>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellAllocationPlot::RiuWellAllocationPlot(RimWellAllocationPlot* plotDefinition, QWidget* parent)
: m_plotDefinition(plotDefinition),
QFrame(parent)
{
Q_ASSERT(m_plotDefinition);
QVBoxLayout* mainLayout = new QVBoxLayout();
this->setLayout(mainLayout);
this->layout()->setMargin(0);
this->layout()->setSpacing(2);
m_titleLabel = new QLabel(this);
QFont font = m_titleLabel->font();
font.setPointSize(14);
font.setBold(true);
m_titleLabel->setFont(font);
// White background
QPalette pal = this->palette();
pal.setColor(QPalette::Background, Qt::white);
this->setAutoFillBackground(true);
this->setPalette(pal);
mainLayout->addWidget(m_titleLabel, 0, Qt::AlignCenter);
auto plotWidgetsLayout = new QHBoxLayout();
auto rightColumnLayout = new QVBoxLayout();
mainLayout->addLayout(plotWidgetsLayout);
plotWidgetsLayout->addLayout(rightColumnLayout);
m_legendWidget = new RiuNightchartsWidget(this);
rightColumnLayout->addWidget(m_legendWidget);
m_legendWidget->showPie(false);
QWidget* totalFlowAllocationWidget = m_plotDefinition->totalWellFlowPlot()->createViewWidget(this);
rightColumnLayout->addWidget(totalFlowAllocationWidget);
rightColumnLayout->addStretch();
QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createViewWidget(this);
plotWidgetsLayout->addWidget(wellFlowWidget);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellAllocationPlot::~RiuWellAllocationPlot()
{
if (m_plotDefinition)
{
m_plotDefinition->handleMdiWindowClosed();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellAllocationPlot* RiuWellAllocationPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::showTitle(const QString& title)
{
m_titleLabel->show();
m_titleLabel->setText(title);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::hideTitle()
{
m_titleLabel->hide();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::showLegend(bool doShow)
{
if (doShow)
m_legendWidget->show();
else
m_legendWidget->hide();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::addLegendItem(const QString& name, const cvf::Color3f& color, float value)
{
QColor sliceColor(color.rByte(), color.gByte(), color.bByte());
m_legendWidget->addItem(name, sliceColor, value);
m_legendWidget->updateGeometry();
m_legendWidget->update();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::clearLegend()
{
m_legendWidget->clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellAllocationPlot::minimumSizeHint() const
{
return QSize(0, 100);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::contextMenuEvent(QContextMenuEvent* event)
{
QMenu menu;
QStringList commandIds;
commandIds << "RicShowContributingWellsFeature";
RimContextCommandBuilder::appendCommandsToMenu(commandIds, &menu);
if (menu.actions().size() > 0)
{
menu.exec(event->globalPos());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellAllocationPlot::sizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellAllocationPlot::setDefaults()
{
}

View File

@ -26,9 +26,14 @@
#include <QFrame>
class RimWellAllocationPlot;
class RiuNightchartsWidget;
class QLabel;
namespace cvf {
class Color3f;
}
//==================================================================================================
//
//
@ -45,16 +50,21 @@ public:
void showTitle(const QString& title);
void hideTitle();
void showLegend(bool doShow);
void addLegendItem(const QString& name, const cvf::Color3f& color, float value);
void clearLegend();
protected:
virtual QSize sizeHint() const override;
virtual QSize minimumSizeHint() const override;
virtual void contextMenuEvent(QContextMenuEvent *) override;
private:
void setDefaults();
private:
caf::PdmPointer<RimWellAllocationPlot> m_plotDefinition;
QPointer<RiuNightchartsWidget> m_legendWidget;
QPointer<QLabel> m_titleLabel;
};

View File

@ -1,364 +1,381 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RiuWellLogPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuMainWindow.h"
#include "RiuWellLogTrack.h"
#include "qwt_legend.h"
#include "cvfAssert.h"
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QMdiSubWindow>
#include <QScrollBar>
#include <QTimer>
#include <math.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent)
: QWidget(parent), m_scheduleUpdateChildrenLayoutTimer(NULL)
{
Q_ASSERT(plotDefinition);
m_plotDefinition = plotDefinition;
QPalette newPalette(palette());
newPalette.setColor(QPalette::Background, Qt::white);
setPalette(newPalette);
setAutoFillBackground(true);
m_scrollBar = new QScrollBar(this);
m_scrollBar->setOrientation(Qt::Vertical);
m_scrollBar->setVisible(true);
connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotSetMinDepth(int)));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::~RiuWellLogPlot()
{
if (m_plotDefinition)
{
m_plotDefinition->detachAllCurves();
m_plotDefinition->handleMdiWindowClosed();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::addTrackPlot(RiuWellLogTrack* trackPlot)
{
// Insert the plot to the left of the scroll bar
insertTrackPlot(trackPlot, m_trackPlots.size());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index)
{
trackPlot->setParent(this);
m_trackPlots.insert(static_cast<int>(index), trackPlot);
QwtLegend* legend = new QwtLegend(this);
legend->setMaxColumns(1);
legend->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(updateLegend(const QVariant &, const QList< QwtLegendData > &)));
legend->contentsWidget()->layout()->setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
m_legends.insert(static_cast<int>(index), legend);
this->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(scheduleUpdateChildrenLayout()));
trackPlot->updateLegend();
if (trackPlot->isRimTrackVisible())
{
trackPlot->show();
}
else
{
trackPlot->hide();
}
modifyWidthOfContainingMdiWindow(trackPlot->width());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::removeTrackPlot(RiuWellLogTrack* trackPlot)
{
if (!trackPlot) return;
int windowWidthChange = - trackPlot->width();
int trackIdx = m_trackPlots.indexOf(trackPlot);
CVF_ASSERT(trackIdx >= 0);
m_trackPlots.removeAt(trackIdx);
trackPlot->setParent(NULL);
QwtLegend* legend = m_legends[trackIdx];
m_legends.removeAt(trackIdx);
delete legend;
modifyWidthOfContainingMdiWindow(windowWidthChange);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::modifyWidthOfContainingMdiWindow(int widthChange)
{
QMdiSubWindow* mdiWindow = RiuMainWindow::instance()->findMdiSubWindow(this);
if (mdiWindow)
{
if (m_trackPlots.size() == 0 && widthChange <= 0) return; // Last track removed. Leave be
QSize subWindowSize = mdiWindow->size();
int newWidth = 0;
if (m_trackPlots.size() == 1 && widthChange > 0) // First track added
{
newWidth = widthChange;
}
else
{
newWidth = subWindowSize.width() + widthChange;
}
if (newWidth < 0) newWidth = 100;
subWindowSize.setWidth(newWidth);
mdiWindow->resize(subWindowSize);
if (mdiWindow->isMaximized())
{
// Set window temporarily to normal state and back to maximized
// to redo layout so the whole window canvas is filled
// Tried to activate layout, did not work as expected
// Tested code:
// m_layout->activate();
// mdiWindow->layout()->activate();
mdiWindow->showNormal();
mdiWindow->showMaximized();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setDepthZoomAndReplot(double minDepth, double maxDepth)
{
for (int tpIdx = 0; tpIdx < m_trackPlots.count(); tpIdx++)
{
m_trackPlots[tpIdx]->setDepthZoom(minDepth, maxDepth);
m_trackPlots[tpIdx]->replot();
}
updateScrollBar(minDepth, maxDepth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateScrollBar(double minDepth, double maxDepth)
{
double availableMinDepth;
double availableMaxDepth;
m_plotDefinition->availableDepthRange(&availableMinDepth, &availableMaxDepth);
availableMaxDepth += 0.01*(availableMaxDepth-availableMinDepth);
double visibleDepth = maxDepth - minDepth;
m_scrollBar->blockSignals(true);
{
m_scrollBar->setRange((int) availableMinDepth, (int) ((availableMaxDepth - visibleDepth)));
m_scrollBar->setPageStep((int) visibleDepth);
m_scrollBar->setValue((int) minDepth);
m_scrollBar->setVisible(true);
}
m_scrollBar->blockSignals(false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::slotSetMinDepth(int value)
{
double minimumDepth;
double maximumDepth;
m_plotDefinition->depthZoomMinMax(&minimumDepth, &maximumDepth);
double delta = value - minimumDepth;
m_plotDefinition->setDepthZoomMinMax(minimumDepth + delta, maximumDepth + delta);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogPlot* RiuWellLogPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::resizeEvent(QResizeEvent *event)
{
int height = event->size().height();
int width = event->size().width();
placeChildWidgets(height, width);
QWidget::resizeEvent(event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::placeChildWidgets(int height, int width)
{
int trackCount = m_trackPlots.size();
CVF_ASSERT(m_legends.size() == trackCount);
int visibleTrackCount = 0;
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible()) ++visibleTrackCount;
}
int scrollBarWidth = 0;
if (m_scrollBar->isVisible()) scrollBarWidth = m_scrollBar->sizeHint().width();
int maxLegendHeight = 0;
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible())
{
int legendHeight = m_legends[tIdx]->sizeHint().height();
if (legendHeight > maxLegendHeight) maxLegendHeight = legendHeight;
}
}
int trackHeight = height - maxLegendHeight;
int trackX = 0;
if (visibleTrackCount)
{
int trackWidth = (width - scrollBarWidth)/visibleTrackCount;
int trackWidthExtra = (width-scrollBarWidth)%visibleTrackCount;
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible())
{
int realTrackWidth = trackWidth;
if (trackWidthExtra > 0)
{
realTrackWidth += 1;
--trackWidthExtra;
}
int realLegendWidth = std::max(realTrackWidth, m_legends[tIdx]->sizeHint().width());
m_legends[tIdx]->setGeometry(trackX, 0, realLegendWidth, maxLegendHeight);
m_trackPlots[tIdx]->setGeometry(trackX, maxLegendHeight, realTrackWidth, trackHeight);
trackX += realTrackWidth;
}
}
}
if (m_scrollBar->isVisible()) m_scrollBar->setGeometry(trackX, maxLegendHeight, scrollBarWidth, trackHeight);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateChildrenLayout()
{
int trackCount = m_trackPlots.size();
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible())
{
m_legends[tIdx]->show();
}
else
{
m_legends[tIdx]->hide();
}
}
placeChildWidgets(this->height(), this->width());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::showEvent(QShowEvent *)
{
updateChildrenLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::changeEvent(QEvent *event)
{
if (event->type() == QEvent::WindowStateChange)
{
updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
/// Schedule an update of the widget positions
/// Will happen just a bit after the event loop is entered
/// Used to delay the positioning to after the legend widgets is actually updated.
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::scheduleUpdateChildrenLayout()
{
if (!m_scheduleUpdateChildrenLayoutTimer)
{
m_scheduleUpdateChildrenLayoutTimer = new QTimer(this);
connect(m_scheduleUpdateChildrenLayoutTimer, SIGNAL(timeout()), this, SLOT(updateChildrenLayout()));
}
if (!m_scheduleUpdateChildrenLayoutTimer->isActive())
{
m_scheduleUpdateChildrenLayoutTimer->setSingleShot(true);
m_scheduleUpdateChildrenLayoutTimer->start(10);
}
}
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RiuWellLogPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RiuMainWindow.h"
#include "RiuWellLogTrack.h"
#include "qwt_legend.h"
#include "cvfAssert.h"
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QMdiSubWindow>
#include <QScrollBar>
#include <QTimer>
#include <math.h>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent)
: QWidget(parent), m_scheduleUpdateChildrenLayoutTimer(NULL)
{
Q_ASSERT(plotDefinition);
m_plotDefinition = plotDefinition;
QPalette newPalette(palette());
newPalette.setColor(QPalette::Background, Qt::white);
setPalette(newPalette);
setAutoFillBackground(true);
m_scrollBar = new QScrollBar(this);
m_scrollBar->setOrientation(Qt::Vertical);
m_scrollBar->setVisible(true);
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotSetMinDepth(int)));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogPlot::~RiuWellLogPlot()
{
if (m_plotDefinition)
{
m_plotDefinition->detachAllCurves();
m_plotDefinition->handleMdiWindowClosed();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::addTrackPlot(RiuWellLogTrack* trackPlot)
{
// Insert the plot to the left of the scroll bar
insertTrackPlot(trackPlot, m_trackPlots.size());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index)
{
trackPlot->setParent(this);
m_trackPlots.insert(static_cast<int>(index), trackPlot);
QwtLegend* legend = new QwtLegend(this);
legend->setMaxColumns(1);
legend->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(updateLegend(const QVariant &, const QList< QwtLegendData > &)));
legend->contentsWidget()->layout()->setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
m_legends.insert(static_cast<int>(index), legend);
this->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(scheduleUpdateChildrenLayout()));
if (!m_plotDefinition->isTrackLegendsVisible())
{
legend->hide();
}
trackPlot->updateLegend();
if (trackPlot->isRimTrackVisible())
{
trackPlot->show();
}
else
{
trackPlot->hide();
}
modifyWidthOfContainingMdiWindow(trackPlot->width());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::removeTrackPlot(RiuWellLogTrack* trackPlot)
{
if (!trackPlot) return;
int windowWidthChange = - trackPlot->width();
int trackIdx = m_trackPlots.indexOf(trackPlot);
CVF_ASSERT(trackIdx >= 0);
m_trackPlots.removeAt(trackIdx);
trackPlot->setParent(NULL);
QwtLegend* legend = m_legends[trackIdx];
m_legends.removeAt(trackIdx);
delete legend;
modifyWidthOfContainingMdiWindow(windowWidthChange);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::modifyWidthOfContainingMdiWindow(int widthChange)
{
QMdiSubWindow* mdiWindow = RiuMainWindow::instance()->findMdiSubWindow(this);
if (mdiWindow)
{
if (m_trackPlots.size() == 0 && widthChange <= 0) return; // Last track removed. Leave be
QSize subWindowSize = mdiWindow->size();
int newWidth = 0;
if (m_trackPlots.size() == 1 && widthChange > 0) // First track added
{
newWidth = widthChange;
}
else
{
newWidth = subWindowSize.width() + widthChange;
}
if (newWidth < 0) newWidth = 100;
subWindowSize.setWidth(newWidth);
mdiWindow->resize(subWindowSize);
if (mdiWindow->isMaximized())
{
// Set window temporarily to normal state and back to maximized
// to redo layout so the whole window canvas is filled
// Tried to activate layout, did not work as expected
// Tested code:
// m_layout->activate();
// mdiWindow->layout()->activate();
mdiWindow->showNormal();
mdiWindow->showMaximized();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::setDepthZoomAndReplot(double minDepth, double maxDepth)
{
for (int tpIdx = 0; tpIdx < m_trackPlots.count(); tpIdx++)
{
m_trackPlots[tpIdx]->setDepthZoom(minDepth, maxDepth);
m_trackPlots[tpIdx]->replot();
}
updateScrollBar(minDepth, maxDepth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogPlot::sizeHint() const
{
return QSize(1,1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateScrollBar(double minDepth, double maxDepth)
{
double availableMinDepth;
double availableMaxDepth;
m_plotDefinition->availableDepthRange(&availableMinDepth, &availableMaxDepth);
availableMaxDepth += 0.01*(availableMaxDepth-availableMinDepth);
double visibleDepth = maxDepth - minDepth;
m_scrollBar->blockSignals(true);
{
m_scrollBar->setRange((int) availableMinDepth, (int) ((availableMaxDepth - visibleDepth)));
m_scrollBar->setPageStep((int) visibleDepth);
m_scrollBar->setValue((int) minDepth);
m_scrollBar->setVisible(true);
}
m_scrollBar->blockSignals(false);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::slotSetMinDepth(int value)
{
double minimumDepth;
double maximumDepth;
m_plotDefinition->depthZoomMinMax(&minimumDepth, &maximumDepth);
double delta = value - minimumDepth;
m_plotDefinition->setDepthZoomMinMax(minimumDepth + delta, maximumDepth + delta);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogPlot* RiuWellLogPlot::ownerPlotDefinition()
{
return m_plotDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::resizeEvent(QResizeEvent *event)
{
int height = event->size().height();
int width = event->size().width();
placeChildWidgets(height, width);
QWidget::resizeEvent(event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::placeChildWidgets(int height, int width)
{
int trackCount = m_trackPlots.size();
CVF_ASSERT(m_legends.size() == trackCount);
int visibleTrackCount = 0;
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible()) ++visibleTrackCount;
}
int scrollBarWidth = 0;
if (m_scrollBar->isVisible()) scrollBarWidth = m_scrollBar->sizeHint().width();
int maxLegendHeight = 0;
if (m_plotDefinition && m_plotDefinition->isTrackLegendsVisible())
{
for ( int tIdx = 0; tIdx < trackCount; ++tIdx )
{
if ( m_trackPlots[tIdx]->isVisible() )
{
int legendHeight = m_legends[tIdx]->sizeHint().height();
if ( legendHeight > maxLegendHeight ) maxLegendHeight = legendHeight;
}
}
}
int trackHeight = height - maxLegendHeight;
int trackX = 0;
if (visibleTrackCount)
{
int trackWidth = (width - scrollBarWidth)/visibleTrackCount;
int trackWidthExtra = (width-scrollBarWidth)%visibleTrackCount;
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible())
{
int realTrackWidth = trackWidth;
if (trackWidthExtra > 0)
{
realTrackWidth += 1;
--trackWidthExtra;
}
int realLegendWidth = std::max(realTrackWidth, m_legends[tIdx]->sizeHint().width());
m_legends[tIdx]->setGeometry(trackX, 0, realLegendWidth, maxLegendHeight);
m_trackPlots[tIdx]->setGeometry(trackX, maxLegendHeight, realTrackWidth, trackHeight);
trackX += realTrackWidth;
}
}
}
if (m_scrollBar->isVisible()) m_scrollBar->setGeometry(trackX, maxLegendHeight, scrollBarWidth, trackHeight);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::updateChildrenLayout()
{
int trackCount = m_trackPlots.size();
for (int tIdx = 0; tIdx < trackCount; ++tIdx)
{
if (m_trackPlots[tIdx]->isVisible())
{
m_legends[tIdx]->show();
}
else
{
m_legends[tIdx]->hide();
}
}
placeChildWidgets(this->height(), this->width());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::showEvent(QShowEvent *)
{
updateChildrenLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::changeEvent(QEvent *event)
{
if (event->type() == QEvent::WindowStateChange)
{
updateChildrenLayout();
}
}
//--------------------------------------------------------------------------------------------------
/// Schedule an update of the widget positions
/// Will happen just a bit after the event loop is entered
/// Used to delay the positioning to after the legend widgets is actually updated.
//--------------------------------------------------------------------------------------------------
void RiuWellLogPlot::scheduleUpdateChildrenLayout()
{
if (!m_scheduleUpdateChildrenLayoutTimer)
{
m_scheduleUpdateChildrenLayoutTimer = new QTimer(this);
connect(m_scheduleUpdateChildrenLayoutTimer, SIGNAL(timeout()), this, SLOT(updateChildrenLayout()));
}
if (!m_scheduleUpdateChildrenLayoutTimer->isActive())
{
m_scheduleUpdateChildrenLayoutTimer->setSingleShot(true);
m_scheduleUpdateChildrenLayoutTimer->start(10);
}
}

View File

@ -1,82 +1,83 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "cafPdmPointer.h"
#include <QList>
#include <QPointer>
#include <QWidget>
class RimWellLogPlot;
class RiuWellLogTrack;
class QHBoxLayout;
class QScrollBar;
class QFocusEvent;
class QwtLegend;
//==================================================================================================
//
// RiuWellLogPlot
//
//==================================================================================================
class RiuWellLogPlot : public QWidget
{
Q_OBJECT
public:
RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent = NULL);
virtual ~RiuWellLogPlot();
RimWellLogPlot* ownerPlotDefinition();
void addTrackPlot(RiuWellLogTrack* trackPlot);
void insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index);
void removeTrackPlot(RiuWellLogTrack* trackPlot);
void setDepthZoomAndReplot(double minDepth, double maxDepth);
public slots:
void updateChildrenLayout();
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void showEvent(QShowEvent *);
virtual void changeEvent(QEvent *);
private:
void updateScrollBar(double minDepth, double maxDepth);
void modifyWidthOfContainingMdiWindow(int widthChange);
void placeChildWidgets(int height, int width);
private slots:
void slotSetMinDepth(int value);
void scheduleUpdateChildrenLayout();
private:
QHBoxLayout* m_layout;
QScrollBar* m_scrollBar;
QList<QPointer<QwtLegend> > m_legends;
QList<QPointer<RiuWellLogTrack> > m_trackPlots;
caf::PdmPointer<RimWellLogPlot> m_plotDefinition;
QTimer* m_scheduleUpdateChildrenLayoutTimer;
};
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "cafPdmPointer.h"
#include <QList>
#include <QPointer>
#include <QWidget>
class RimWellLogPlot;
class RiuWellLogTrack;
class QHBoxLayout;
class QScrollBar;
class QFocusEvent;
class QwtLegend;
//==================================================================================================
//
// RiuWellLogPlot
//
//==================================================================================================
class RiuWellLogPlot : public QWidget
{
Q_OBJECT
public:
RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent = NULL);
virtual ~RiuWellLogPlot();
RimWellLogPlot* ownerPlotDefinition();
void addTrackPlot(RiuWellLogTrack* trackPlot);
void insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index);
void removeTrackPlot(RiuWellLogTrack* trackPlot);
void setDepthZoomAndReplot(double minDepth, double maxDepth);
public slots:
void updateChildrenLayout();
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void showEvent(QShowEvent *);
virtual void changeEvent(QEvent *);
virtual QSize sizeHint() const override;
private:
void updateScrollBar(double minDepth, double maxDepth);
void modifyWidthOfContainingMdiWindow(int widthChange);
void placeChildWidgets(int height, int width);
private slots:
void slotSetMinDepth(int value);
void scheduleUpdateChildrenLayout();
private:
QHBoxLayout* m_layout;
QScrollBar* m_scrollBar;
QList<QPointer<QwtLegend> > m_legends;
QList<QPointer<RiuWellLogTrack> > m_trackPlots;
caf::PdmPointer<RimWellLogPlot> m_plotDefinition;
QTimer* m_scheduleUpdateChildrenLayoutTimer;
};

View File

@ -1,458 +1,475 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RiuWellLogTrack.h"
#include "RiaApplication.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimWellLogCurve.h"
#include "RiuMainPlotWindow.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_picker.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_engine.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include <QFont>
#include <QMouseEvent>
#include <QScrollArea>
#include <QWheelEvent>
#include <float.h>
#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1
#define RIU_SCROLLWHEEL_PANFACTOR 0.1
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuWellLogTrackQwtPicker : public QwtPlotPicker
{
public:
RiuWellLogTrackQwtPicker(QWidget *canvas)
: QwtPlotPicker(canvas)
{
}
protected:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
virtual QwtText trackerText(const QPoint& pos) const override
{
QwtText txt;
const RiuWellLogTrack* wellLogTrack = dynamic_cast<const RiuWellLogTrack*>(this->plot());
if (wellLogTrack)
{
QString depthString;
QString valueString;
QPointF closestPoint = wellLogTrack->closestCurvePoint(pos, &valueString, &depthString);
if (!closestPoint.isNull())
{
QString str = valueString;
if (!depthString.isEmpty())
{
str += QString(" (%1)").arg(depthString);
}
txt.setText(str);
}
RiuWellLogTrack* nonConstPlot = const_cast<RiuWellLogTrack*>(wellLogTrack);
nonConstPlot->updateClosestCurvePointMarker(closestPoint);
}
return txt;
}
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* parent)
: QwtPlot(parent)
{
Q_ASSERT(plotTrackDefinition);
m_plotTrackDefinition = plotTrackDefinition;
m_grid = new QwtPlotGrid();
m_grid->attach(this);
setFocusPolicy(Qt::ClickFocus);
setDefaults();
// Create a plot picker to display values next to mouse cursor
m_plotPicker = new RiuWellLogTrackQwtPicker(this->canvas());
m_plotPicker->setTrackerMode(QwtPicker::AlwaysOn);
m_plotMarker = new QwtPlotMarker;
// QwtPlotMarker takes ownership of the symbol, it is deleted in destructor of QwtPlotMarker
QwtSymbol* mySymbol = new QwtSymbol(QwtSymbol::Ellipse, Qt::NoBrush, QPen(Qt::black, 2.0), QSize(12, 12));
m_plotMarker->setSymbol(mySymbol);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::~RiuWellLogTrack()
{
m_grid->detach();
delete m_grid;
m_plotMarker->detach();
delete m_plotMarker;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPointF RiuWellLogTrack::closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const
{
QPointF samplePoint;
QwtPlotCurve* closestCurve = nullptr;
double distMin = DBL_MAX;
int closestPointSampleIndex = -1;
const QwtPlotItemList& itmList = itemList();
for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++)
{
if ((*it)->rtti() == QwtPlotItem::Rtti_PlotCurve)
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>(*it);
double dist = DBL_MAX;
int candidateSampleIndex = candidateCurve->closestPoint(pos, &dist);
if (dist < distMin)
{
closestCurve = candidateCurve;
distMin = dist;
closestPointSampleIndex = candidateSampleIndex;
}
}
}
if (closestCurve && distMin < 50)
{
samplePoint = closestCurve->sample(closestPointSampleIndex);
}
if (depthString)
{
const QwtScaleDraw* depthAxisScaleDraw = axisScaleDraw(QwtPlot::yLeft);
if (depthAxisScaleDraw)
{
*depthString = depthAxisScaleDraw->label(samplePoint.y()).text();
}
}
if (valueString && closestCurve)
{
const QwtScaleDraw* xAxisScaleDraw = axisScaleDraw(closestCurve->xAxis());
if (xAxisScaleDraw)
{
*valueString = xAxisScaleDraw->label(samplePoint.x()).text();
}
}
return samplePoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::updateClosestCurvePointMarker(const QPointF& pos)
{
bool replotRequired = false;
if (!pos.isNull())
{
if (!m_plotMarker->plot())
{
m_plotMarker->attach(this);
replotRequired = true;
}
if (m_plotMarker->value() != pos)
{
m_plotMarker->setValue(pos.x(), pos.y());
replotRequired = true;
}
}
else
{
if (m_plotMarker->plot())
{
m_plotMarker->detach();
replotRequired = true;
}
}
if (replotRequired) this->replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDefaults()
{
QPalette newPalette(palette());
newPalette.setColor(QPalette::Background, Qt::white);
setPalette(newPalette);
setAutoFillBackground(true);
setCanvasBackground(Qt::white);
QFrame* canvasFrame = dynamic_cast<QFrame*>(canvas());
if (canvasFrame)
{
canvasFrame->setFrameShape(QFrame::NoFrame);
}
canvas()->setMouseTracking(true);
canvas()->installEventFilter(this);
QPen gridPen(Qt::SolidLine);
gridPen.setColor(Qt::lightGray);
m_grid->setPen(gridPen);
enableAxis(QwtPlot::xTop, true);
enableAxis(QwtPlot::yLeft, true);
enableAxis(QwtPlot::xBottom, false);
enableAxis(QwtPlot::yRight, false);
plotLayout()->setAlignCanvasToScales(true);
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Inverted, true);
// Align the canvas with the actual min and max values of the curves
axisScaleEngine(QwtPlot::xTop)->setAttribute(QwtScaleEngine::Floating, true);
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating, true);
setAxisScale(QwtPlot::yLeft, 1000, 0);
setAxisScale(QwtPlot::xTop, -10, 100);
QFont xAxisFont = axisFont(QwtPlot::xTop);
xAxisFont.setPixelSize(9);
setAxisFont(QwtPlot::xTop, xAxisFont);
QFont yAxisFont = axisFont(QwtPlot::yLeft);
yAxisFont.setPixelSize(9);
setAxisFont(QwtPlot::yLeft, yAxisFont);
QwtText axisTitleY = axisTitle(QwtPlot::yLeft);
QFont yAxisTitleFont = axisTitleY.font();
yAxisTitleFont.setPixelSize(9);
yAxisTitleFont.setBold(false);
axisTitleY.setFont(yAxisTitleFont);
axisTitleY.setRenderFlags(Qt::AlignRight);
setAxisTitle(QwtPlot::yLeft, axisTitleY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthZoom(double minDepth, double maxDepth)
{
// Note: Y-axis is inverted
setAxisScale(QwtPlot::yLeft, maxDepth, minDepth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setXRange(double min, double max)
{
setAxisScale(QwtPlot::xTop, min, max);
setAxisScale(QwtPlot::xBottom, min, max);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthTitle(const QString& title)
{
QwtText axisTitleY = axisTitle(QwtPlot::yLeft);
axisTitleY.setText(title);
setAxisTitle(QwtPlot::yLeft, axisTitleY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::eventFilter(QObject* watched, QEvent* event)
{
if (watched == canvas())
{
QWheelEvent* wheelEvent = dynamic_cast<QWheelEvent*>(event);
if (wheelEvent)
{
if (!m_plotTrackDefinition)
{
return QwtPlot::eventFilter(watched, event);
}
RimWellLogPlot* plotDefinition;
m_plotTrackDefinition->firstAncestorOrThisOfType(plotDefinition);
if (!plotDefinition)
{
return QwtPlot::eventFilter(watched, event);
}
if (wheelEvent->modifiers() & Qt::ControlModifier)
{
QwtScaleMap scaleMap = canvasMap(QwtPlot::yLeft);
double zoomCenter = scaleMap.invTransform(wheelEvent->pos().y());
if (wheelEvent->delta() > 0)
{
plotDefinition->setDepthZoomByFactorAndCenter(RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter);
}
else
{
plotDefinition->setDepthZoomByFactorAndCenter(1.0/RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter);
}
}
else
{
plotDefinition->panDepth(wheelEvent->delta() < 0 ? RIU_SCROLLWHEEL_PANFACTOR : -RIU_SCROLLWHEEL_PANFACTOR);
}
event->accept();
return true;
}
else
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (mouseEvent)
{
if (mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonRelease)
{
selectClosestCurve(mouseEvent->pos());
}
}
}
}
return QwtPlot::eventFilter(watched, event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::focusInEvent(QFocusEvent* event)
{
if (m_plotTrackDefinition)
{
RiaApplication::instance()->getOrCreateAndShowMainPlotWindow()->selectAsCurrentItem(m_plotTrackDefinition);
clearFocus();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::selectClosestCurve(const QPoint& pos)
{
QwtPlotCurve* closestCurve = NULL;
double distMin = DBL_MAX;
const QwtPlotItemList& itmList = itemList();
for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++)
{
if ((*it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>(*it);
double dist = DBL_MAX;
candidateCurve->closestPoint(pos, &dist);
if (dist < distMin)
{
closestCurve = candidateCurve;
distMin = dist;
}
}
}
if (closestCurve && distMin < 20)
{
RimWellLogCurve* selectedCurve = m_plotTrackDefinition->curveDefinitionFromCurve(closestCurve);
if (selectedCurve)
{
RiaApplication::instance()->getOrCreateAndShowMainPlotWindow()->selectAsCurrentItem(selectedCurve);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::sizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::minimumSizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::leaveEvent(QEvent *)
{
if (m_plotMarker->plot())
{
m_plotMarker->detach();
replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::isRimTrackVisible()
{
if (m_plotTrackDefinition)
{
return m_plotTrackDefinition->isVisible();
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "RiuWellLogTrack.h"
#include "RiaApplication.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimWellLogCurve.h"
#include "RiuMainPlotWindow.h"
#include "qwt_legend.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_picker.h"
#include "qwt_scale_draw.h"
#include "qwt_scale_engine.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include <QFont>
#include <QMouseEvent>
#include <QScrollArea>
#include <QWheelEvent>
#include <float.h>
#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1
#define RIU_SCROLLWHEEL_PANFACTOR 0.1
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RiuWellLogTrackQwtPicker : public QwtPlotPicker
{
public:
RiuWellLogTrackQwtPicker(QWidget *canvas)
: QwtPlotPicker(canvas)
{
}
protected:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
virtual QwtText trackerText(const QPoint& pos) const override
{
QwtText txt;
const RiuWellLogTrack* wellLogTrack = dynamic_cast<const RiuWellLogTrack*>(this->plot());
if (wellLogTrack)
{
QString depthString;
QString valueString;
QPointF closestPoint = wellLogTrack->closestCurvePoint(pos, &valueString, &depthString);
if (!closestPoint.isNull())
{
QString str = valueString;
if (!depthString.isEmpty())
{
str += QString(" (%1)").arg(depthString);
}
txt.setText(str);
}
RiuWellLogTrack* nonConstPlot = const_cast<RiuWellLogTrack*>(wellLogTrack);
nonConstPlot->updateClosestCurvePointMarker(closestPoint);
}
return txt;
}
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* parent)
: QwtPlot(parent)
{
Q_ASSERT(plotTrackDefinition);
m_plotTrackDefinition = plotTrackDefinition;
m_grid = new QwtPlotGrid();
m_grid->attach(this);
setFocusPolicy(Qt::ClickFocus);
setDefaults();
// Create a plot picker to display values next to mouse cursor
m_plotPicker = new RiuWellLogTrackQwtPicker(this->canvas());
m_plotPicker->setTrackerMode(QwtPicker::AlwaysOn);
m_plotMarker = new QwtPlotMarker;
// QwtPlotMarker takes ownership of the symbol, it is deleted in destructor of QwtPlotMarker
QwtSymbol* mySymbol = new QwtSymbol(QwtSymbol::Ellipse, Qt::NoBrush, QPen(Qt::black, 2.0), QSize(12, 12));
m_plotMarker->setSymbol(mySymbol);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack::~RiuWellLogTrack()
{
m_grid->detach();
delete m_grid;
m_plotMarker->detach();
delete m_plotMarker;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QPointF RiuWellLogTrack::closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const
{
QPointF samplePoint;
QwtPlotCurve* closestCurve = nullptr;
double distMin = DBL_MAX;
int closestPointSampleIndex = -1;
const QwtPlotItemList& itmList = itemList();
for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++)
{
if ((*it)->rtti() == QwtPlotItem::Rtti_PlotCurve)
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>(*it);
double dist = DBL_MAX;
int candidateSampleIndex = candidateCurve->closestPoint(pos, &dist);
if (dist < distMin)
{
closestCurve = candidateCurve;
distMin = dist;
closestPointSampleIndex = candidateSampleIndex;
}
}
}
if (closestCurve && distMin < 50)
{
samplePoint = closestCurve->sample(closestPointSampleIndex);
}
if (depthString)
{
const QwtScaleDraw* depthAxisScaleDraw = axisScaleDraw(QwtPlot::yLeft);
if (depthAxisScaleDraw)
{
*depthString = depthAxisScaleDraw->label(samplePoint.y()).text();
}
}
if (valueString && closestCurve)
{
const QwtScaleDraw* xAxisScaleDraw = axisScaleDraw(closestCurve->xAxis());
if (xAxisScaleDraw)
{
*valueString = xAxisScaleDraw->label(samplePoint.x()).text();
}
}
return samplePoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::updateClosestCurvePointMarker(const QPointF& pos)
{
bool replotRequired = false;
if (!pos.isNull())
{
if (!m_plotMarker->plot())
{
m_plotMarker->attach(this);
replotRequired = true;
}
if (m_plotMarker->value() != pos)
{
m_plotMarker->setValue(pos.x(), pos.y());
replotRequired = true;
}
}
else
{
if (m_plotMarker->plot())
{
m_plotMarker->detach();
replotRequired = true;
}
}
if (replotRequired) this->replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDefaults()
{
QPalette newPalette(palette());
newPalette.setColor(QPalette::Background, Qt::white);
setPalette(newPalette);
setAutoFillBackground(true);
setCanvasBackground(Qt::white);
QFrame* canvasFrame = dynamic_cast<QFrame*>(canvas());
if (canvasFrame)
{
canvasFrame->setFrameShape(QFrame::NoFrame);
}
canvas()->setMouseTracking(true);
canvas()->installEventFilter(this);
QPen gridPen(Qt::SolidLine);
gridPen.setColor(Qt::lightGray);
m_grid->setPen(gridPen);
enableAxis(QwtPlot::xTop, true);
enableAxis(QwtPlot::yLeft, true);
enableAxis(QwtPlot::xBottom, false);
enableAxis(QwtPlot::yRight, false);
plotLayout()->setAlignCanvasToScales(true);
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Inverted, true);
// Align the canvas with the actual min and max values of the curves
axisScaleEngine(QwtPlot::xTop)->setAttribute(QwtScaleEngine::Floating, true);
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating, true);
setAxisScale(QwtPlot::yLeft, 1000, 0);
setAxisScale(QwtPlot::xTop, -10, 100);
QFont xAxisFont = axisFont(QwtPlot::xTop);
xAxisFont.setPixelSize(9);
setAxisFont(QwtPlot::xTop, xAxisFont);
QwtText axisTitleX = axisTitle(QwtPlot::yLeft);
QFont xAxisTitleFont = axisTitleX.font();
xAxisTitleFont.setPixelSize(9);
xAxisTitleFont.setBold(false);
axisTitleX.setFont(xAxisTitleFont);
axisTitleX.setRenderFlags(Qt::AlignRight);
setAxisTitle(QwtPlot::xTop, axisTitleX);
QFont yAxisFont = axisFont(QwtPlot::yLeft);
yAxisFont.setPixelSize(9);
setAxisFont(QwtPlot::yLeft, yAxisFont);
QwtText axisTitleY = axisTitle(QwtPlot::yLeft);
QFont yAxisTitleFont = axisTitleY.font();
yAxisTitleFont.setPixelSize(9);
yAxisTitleFont.setBold(false);
axisTitleY.setFont(yAxisTitleFont);
axisTitleY.setRenderFlags(Qt::AlignRight);
setAxisTitle(QwtPlot::yLeft, axisTitleY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthZoom(double minDepth, double maxDepth)
{
// Note: Y-axis is inverted
setAxisScale(QwtPlot::yLeft, maxDepth, minDepth);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setXRange(double min, double max)
{
setAxisScale(QwtPlot::xTop, min, max);
setAxisScale(QwtPlot::xBottom, min, max);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setDepthTitle(const QString& title)
{
QwtText axisTitleY = axisTitle(QwtPlot::yLeft);
axisTitleY.setText(title);
setAxisTitle(QwtPlot::yLeft, axisTitleY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::setXTitle(const QString& title)
{
QwtText axisTitleX = axisTitle(QwtPlot::xTop);
axisTitleX.setText(title);
setAxisTitle(QwtPlot::xTop, axisTitleX);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::eventFilter(QObject* watched, QEvent* event)
{
if (watched == canvas())
{
QWheelEvent* wheelEvent = dynamic_cast<QWheelEvent*>(event);
if (wheelEvent)
{
if (!m_plotTrackDefinition)
{
return QwtPlot::eventFilter(watched, event);
}
RimWellLogPlot* plotDefinition;
m_plotTrackDefinition->firstAncestorOrThisOfType(plotDefinition);
if (!plotDefinition)
{
return QwtPlot::eventFilter(watched, event);
}
if (wheelEvent->modifiers() & Qt::ControlModifier)
{
QwtScaleMap scaleMap = canvasMap(QwtPlot::yLeft);
double zoomCenter = scaleMap.invTransform(wheelEvent->pos().y());
if (wheelEvent->delta() > 0)
{
plotDefinition->setDepthZoomByFactorAndCenter(RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter);
}
else
{
plotDefinition->setDepthZoomByFactorAndCenter(1.0/RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter);
}
}
else
{
plotDefinition->panDepth(wheelEvent->delta() < 0 ? RIU_SCROLLWHEEL_PANFACTOR : -RIU_SCROLLWHEEL_PANFACTOR);
}
event->accept();
return true;
}
else
{
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
if (mouseEvent)
{
if (mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonRelease)
{
selectClosestCurve(mouseEvent->pos());
}
}
}
}
return QwtPlot::eventFilter(watched, event);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::focusInEvent(QFocusEvent* event)
{
if (m_plotTrackDefinition)
{
RiaApplication::instance()->getOrCreateAndShowMainPlotWindow()->selectAsCurrentItem(m_plotTrackDefinition);
clearFocus();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::selectClosestCurve(const QPoint& pos)
{
QwtPlotCurve* closestCurve = NULL;
double distMin = DBL_MAX;
const QwtPlotItemList& itmList = itemList();
for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++)
{
if ((*it )->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
QwtPlotCurve* candidateCurve = static_cast<QwtPlotCurve*>(*it);
double dist = DBL_MAX;
candidateCurve->closestPoint(pos, &dist);
if (dist < distMin)
{
closestCurve = candidateCurve;
distMin = dist;
}
}
}
if (closestCurve && distMin < 20)
{
RimWellLogCurve* selectedCurve = m_plotTrackDefinition->curveDefinitionFromCurve(closestCurve);
if (selectedCurve)
{
RiaApplication::instance()->getOrCreateAndShowMainPlotWindow()->selectAsCurrentItem(selectedCurve);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::sizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiuWellLogTrack::minimumSizeHint() const
{
return QSize(0, 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuWellLogTrack::leaveEvent(QEvent *)
{
if (m_plotMarker->plot())
{
m_plotMarker->detach();
replot();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuWellLogTrack::isRimTrackVisible()
{
if (m_plotTrackDefinition)
{
return m_plotTrackDefinition->isVisible();
}
return false;
}

View File

@ -1,76 +1,77 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "qwt_plot.h"
#include "cafPdmPointer.h"
class RimWellLogTrack;
class QwtLegend;
class QwtPicker;
class QwtPlotGrid;
class QwtPlotMarker;
class QEvent;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuWellLogTrack : public QwtPlot
{
Q_OBJECT
public:
RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* parent = NULL);
virtual ~RiuWellLogTrack();
void setDepthZoom(double minDepth, double maxDepth);
void setDepthTitle(const QString& title);
void setXRange(double min, double max);
bool isRimTrackVisible();
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
virtual void focusInEvent(QFocusEvent* event);
virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
virtual void leaveEvent(QEvent *) override;
private:
friend class RiuWellLogTrackQwtPicker;
QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const;
void updateClosestCurvePointMarker(const QPointF& pos);
void setDefaults();
void selectClosestCurve(const QPoint& pos);
private:
caf::PdmPointer<RimWellLogTrack> m_plotTrackDefinition;
QwtPlotGrid* m_grid;
QwtPicker* m_plotPicker;
QwtPlotMarker* m_plotMarker;
};
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- 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 "qwt_plot.h"
#include "cafPdmPointer.h"
class RimWellLogTrack;
class QwtLegend;
class QwtPicker;
class QwtPlotGrid;
class QwtPlotMarker;
class QEvent;
//==================================================================================================
//
//
//
//==================================================================================================
class RiuWellLogTrack : public QwtPlot
{
Q_OBJECT
public:
RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* parent = NULL);
virtual ~RiuWellLogTrack();
void setDepthZoom(double minDepth, double maxDepth);
void setDepthTitle(const QString& title);
void setXTitle(const QString& title);
void setXRange(double min, double max);
bool isRimTrackVisible();
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
virtual void focusInEvent(QFocusEvent* event);
virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
virtual void leaveEvent(QEvent *) override;
private:
friend class RiuWellLogTrackQwtPicker;
QPointF closestCurvePoint(const QPoint& pos, QString* valueString, QString* depthString) const;
void updateClosestCurvePointMarker(const QPointF& pos);
void setDefaults();
void selectClosestCurve(const QPoint& pos);
private:
caf::PdmPointer<RimWellLogTrack> m_plotTrackDefinition;
QwtPlotGrid* m_grid;
QwtPicker* m_plotPicker;
QwtPlotMarker* m_plotMarker;
};

View File

@ -43,7 +43,8 @@ add_library( ${PROJECT_NAME}
cvfStructGrid.h
cvfCellRange.cpp
cvfCellRange.h
cafColorTable.cpp
cafColorTable.h
cvfStructGridGeometryGenerator.cpp
cvfStructGridGeometryGenerator.h

View File

@ -0,0 +1,161 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2017 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 "cafColorTable.h"
#include <QColor>
namespace caf {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ColorTable::ColorTable(const std::vector<cvf::Color3ub>& colors)
: m_colors(colors)
{
CVF_ASSERT(m_colors.size() > 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f ColorTable::cycledColor3f(size_t itemIndex) const
{
return cvf::Color3f(cycledColor3ub(itemIndex));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3ub ColorTable::cycledColor3ub(size_t itemIndex) const
{
size_t modIndex = itemIndex % m_colors.size();
return m_colors[modIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QColor ColorTable::cycledQColor(size_t itemIndex) const
{
cvf::Color3ub col = cycledColor3ub(itemIndex);
return QColor(col.r(), col.g(), col.b());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3ubArray ColorTable::color3ubArray() const
{
return cvf::Color3ubArray(m_colors);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3fArray ColorTable::color3fArray() const
{
cvf::Color3fArray col3fArr;
col3fArr.resize(m_colors.size());
for (const auto& c : m_colors)
{
col3fArr.add(cvf::Color3f(c));
}
return col3fArr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3ub ColorTable::fromQColor(const QColor& color)
{
return cvf::Color3ub(color.red(), color.green(), color.blue());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3ubArray ColorTable::interpolateColorArray(const cvf::Color3ubArray& colorArray, size_t targetColorCount)
{
size_t inputColorCount = colorArray.size();
CVF_ASSERT(inputColorCount > 1);
CVF_ASSERT(targetColorCount > 1);
cvf::Color3ubArray colors;
colors.reserve(targetColorCount);
const size_t inputColorsMaxIdx = inputColorCount - 1;
const size_t outputColorsMaxIdx = targetColorCount - 1;
for (size_t outputLevelIdx = 0; outputLevelIdx < outputColorsMaxIdx; outputLevelIdx++)
{
double dblInputLevelIndex = inputColorsMaxIdx * (outputLevelIdx / static_cast<double>(outputColorsMaxIdx));
const size_t inputLevelIndex = static_cast<size_t>(dblInputLevelIndex);
CVF_ASSERT(inputLevelIndex < inputColorsMaxIdx);
double t = dblInputLevelIndex - inputLevelIndex;
CVF_ASSERT(t >= 0 && t <= 1.0);
cvf::Color3ub c1 = colorArray[inputLevelIndex];
cvf::Color3ub c2 = colorArray[inputLevelIndex + 1];
int r = static_cast<int>(c1.r() + t*(c2.r() - c1.r()) + 0.5);
int g = static_cast<int>(c1.g() + t*(c2.g() - c1.g()) + 0.5);
int b = static_cast<int>(c1.b() + t*(c2.b() - c1.b()) + 0.5);
r = cvf::Math::clamp(r, 0, 255);
g = cvf::Math::clamp(g, 0, 255);
b = cvf::Math::clamp(b, 0, 255);
cvf::Color3ub col((cvf::ubyte)r, (cvf::ubyte)g, (cvf::ubyte)b);
colors.add(col);
}
colors.add(colorArray[colorArray.size() - 1]);
return colors;
}
} // namespace caf

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