Merge remote-tracking branch 'refs/remotes/origin/dev'
Conflicts: ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp ApplicationCode/Resources/ResInsight.qrc
@ -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));
|
||||
|
404
ApplicationCode/Application/RiaColorTables.cpp
Normal 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;
|
||||
}
|
51
ApplicationCode/Application/RiaColorTables.h
Normal 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();
|
||||
};
|
@ -79,6 +79,7 @@ set( APPLICATION_FILES
|
||||
Application/RiaImageCompareReporter.cpp
|
||||
Application/RiaProjectModifier.cpp
|
||||
Application/RiaRegressionTest.cpp
|
||||
Application/RiaColorTables.cpp
|
||||
)
|
||||
|
||||
set( SOCKET_INTERFACE_FILES
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
@ -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"
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ public:
|
||||
enum DepthUnitType
|
||||
{
|
||||
UNIT_METER,
|
||||
UNIT_FEET
|
||||
UNIT_FEET,
|
||||
UNIT_NONE
|
||||
};
|
||||
|
||||
static double feetPerMeter() { return 3.2808399; }
|
||||
|
@ -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
|
||||
|
@ -121,7 +121,7 @@ void RimEclipseInputProperty::fieldChangedByUi(const caf::PdmFieldHandle* change
|
||||
it->setResultVariable(newName);
|
||||
}
|
||||
|
||||
it->updateResultNameHasChanged();
|
||||
it->loadDataAndUpdate();
|
||||
it->updateAnyFieldHasChanged();
|
||||
}
|
||||
}
|
||||
|
@ -401,8 +401,6 @@ void RimEclipsePropertyFilter::initAfterRead()
|
||||
resultDefinition->initAfterRead();
|
||||
|
||||
resultDefinition->setEclipseCase(parentContainer()->reservoirView()->eclipseCase());
|
||||
resultDefinition->loadResult();
|
||||
updateIconState();
|
||||
computeResultValueRange();
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "RimEclipsePropertyFilterCollection.h"
|
||||
|
||||
#include "RimEclipseCellColors.h"
|
||||
#include "RimEclipsePropertyFilter.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimViewController.h"
|
||||
|
@ -20,11 +20,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimEclipsePropertyFilter.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "RimPropertyFilterCollection.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
|
||||
class RimEclipsePropertyFilter;
|
||||
class RimEclipseView;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
@ -90,6 +90,19 @@ void RimViewWindow::updateMdiWindowVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimViewWindow::isMdiWindow() const
|
||||
{
|
||||
if (m_windowController())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
|
||||
void setAs3DViewMdiWindow() { setAsMdiWindow(0); }
|
||||
void setAsPlotMdiWindow() { setAsMdiWindow(1); }
|
||||
bool isMdiWindow() const;
|
||||
|
||||
void setMdiWindowGeometry(const RimMdiWindowGeometry& windowGeometry);
|
||||
RimMdiWindowGeometry mdiWindowGeometry();
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
void addCurveFilter(RimSummaryCurveFilter* curveFilter);
|
||||
|
||||
RimSummaryCurve* findRimCurveFromQwtCurve(const QwtPlotCurve* curve) const;
|
||||
size_t curveCount() const;
|
||||
|
||||
void loadDataAndUpdate();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.9 KiB |
@ -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>
|
||||
|
BIN
ApplicationCode/Resources/SummaryPlotLight16x16.png
Normal file
After Width: | Height: | Size: 776 B |
Before Width: | Height: | Size: 879 B After Width: | Height: | Size: 864 B |
BIN
ApplicationCode/Resources/WellAllocLegend16x16.png
Normal file
After Width: | Height: | Size: 406 B |
BIN
ApplicationCode/Resources/WellAllocPie16x16.png
Normal file
After Width: | Height: | Size: 695 B |
BIN
ApplicationCode/Resources/WellAllocPlot16x16.png
Normal file
After Width: | Height: | Size: 766 B |
BIN
ApplicationCode/Resources/WellAllocPlots16x16.png
Normal file
After Width: | Height: | Size: 712 B |
BIN
ApplicationCode/Resources/WellFlowPlot16x16.png
Normal file
After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 855 B After Width: | Height: | Size: 889 B |
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -43,7 +43,8 @@ add_library( ${PROJECT_NAME}
|
||||
cvfStructGrid.h
|
||||
cvfCellRange.cpp
|
||||
cvfCellRange.h
|
||||
|
||||
cafColorTable.cpp
|
||||
cafColorTable.h
|
||||
|
||||
cvfStructGridGeometryGenerator.cpp
|
||||
cvfStructGridGeometryGenerator.h
|
||||
|
161
Fwk/AppFwk/CommonCode/cafColorTable.cpp
Normal 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
|