Merge #51 Legend background and #2478 Edge axis top into dev

This commit is contained in:
Jacob Støren
2018-03-08 16:16:50 +01:00
46 changed files with 1754 additions and 659 deletions

View File

@@ -22,8 +22,6 @@
#include "RiaArgumentParser.h"
#include "RiaBaseDefs.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaLogging.h"
#include "RiaPreferences.h"
@@ -32,88 +30,57 @@
#include "RiaVersionInfo.h"
#include "RiaViewRedrawScheduler.h"
#include "RigGridManager.h"
#include "RigEclipseCaseData.h"
#include "RicImportInputEclipseCaseFeature.h"
#include "RicImportSummaryCaseFeature.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include "Rim2dIntersectionViewCollection.h"
#include "Rim3dOverlayInfoConfig.h"
#include "RimCaseCollection.h"
#include "RimCellEdgeColors.h"
#include "RimCellRangeFilterCollection.h"
#include "RimCommandObject.h"
#include "RimEclipseCase.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseView.h"
#include "RimFaultInViewCollection.h"
#include "RimFlowCharacteristicsPlot.h"
#include "RimFlowPlotCollection.h"
#include "RimFormationNamesCollection.h"
#include "RimRftPlotCollection.h"
#include "RimPltPlotCollection.h"
#include "RimEclipseCase.h"
#include "RimFractureTemplateCollection.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechCellColors.h"
#include "RimGeoMechModels.h"
#include "RimGeoMechView.h"
#include "RimGeoMechView.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimMainPlotCollection.h"
#include "RimObservedData.h"
#include "RimObservedDataCollection.h"
#include "RimOilField.h"
#include "RimPltPlotCollection.h"
#include "RimProject.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimScriptCollection.h"
#include "RimRftPlotCollection.h"
#include "RimStimPlanColors.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCrossPlotCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "RimViewLinker.h"
#include "RimViewLinkerCollection.h"
#include "RimWellAllocationPlot.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellRftPlot.h"
#include "RimWellPathFracture.h"
#include "RimWellPltPlot.h"
#include "RimWellRftPlot.h"
#include "RiuMainPlotWindow.h"
#include "RiuMainWindow.h"
#include "RiuProcessMonitor.h"
#include "RiuRecentFileActionProvider.h"
#include "RiuSelectionManager.h"
#include "RiuSummaryQwtPlot.h"
#include "RiuViewer.h"
#include "RiuWellLogPlot.h"
#include "RiuWellAllocationPlot.h"
#include "RiuFlowCharacteristicsPlot.h"
#include "RimFractureTemplateCollection.h"
#include "RimWellPathFracture.h"
#include "RimStimPlanColors.h"
#include "RicImportInputEclipseCaseFeature.h"
#include "RicImportSummaryCaseFeature.h"
#include "ExportCommands/RicSnapshotViewToFileFeature.h"
#include "ExportCommands/RicSnapshotAllPlotsToFileFeature.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include "SummaryPlotCommands/RicNewSummaryPlotFeature.h"
#include "RicfCommandFileExecutor.h"
#include "cafFixedAtlasFont.h"
#include "cafAppEnum.h"
#include "cafCeetronPlusNavigation.h"
#include "cafEffectCache.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafEffectGenerator.h"
#include "cafFixedAtlasFont.h"
#include "cafPdmSettings.h"
#include "cafPdmUiModelChangeDetector.h"
#include "cafPdmUiTreeView.h"
@@ -125,22 +92,20 @@
#include "cvfProgramOptions.h"
#include "cvfqtUtils.h"
#include <QAction>
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QTimer>
#include <QUrl>
#include <QTreeView>
#ifndef WIN32
#include <unistd.h> // for usleep
#endif //WIN32
#ifdef USE_UNIT_TESTS
#include "gtest/gtest.h"
#ifdef WIN32
#include <fcntl.h>
#endif
#endif // USE_UNIT_TESTS
namespace caf
{
@@ -155,19 +120,6 @@ void AppEnum< RiaApplication::RINavigationPolicy >::setUp()
}
}
namespace RegTestNames
{
const QString generatedFolderName = "RegTestGeneratedImages";
const QString diffFolderName = "RegTestDiffImages";
const QString baseFolderName = "RegTestBaseImages";
const QString testProjectName = "RegressionTest";
const QString testFolderFilter = "TestCase*";
const QString imageCompareExeName = "compare";
const QString reportFileName = "ResInsightRegressionTestReport.html";
const QString commandFileFilter = "commandfile-*";
};
@@ -229,8 +181,6 @@ RiaApplication::RiaApplication(int& argc, char** argv)
// instead of using the application font
m_standardFont = new caf::FixedAtlasFont(caf::FixedAtlasFont::POINT_SIZE_8);
m_runningRegressionTests = false;
m_runningWorkerProcess = false;
m_mainPlotWindow = nullptr;
@@ -1537,6 +1487,19 @@ std::vector<QString> RiaApplication::readFileListFromTextFile(QString listFileNa
return fileList;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::waitUntilCommandObjectsHasBeenProcessed()
{
// Wait until all command objects have completed
while (!m_commandQueueLock.tryLock())
{
processEvents();
}
m_commandQueueLock.unlock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -1962,303 +1925,6 @@ void RiaApplication::runMultiCaseSnapshots(const QString& templateProjectFileNam
mainWnd->loadWinGeoAndDockToolBarLayout();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void removeDirectoryWithContent(QDir dirToDelete )
{
QStringList files = dirToDelete.entryList();
for (int fIdx = 0; fIdx < files.size(); ++fIdx)
{
dirToDelete.remove(files[fIdx]);
}
dirToDelete.rmdir(".");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void logInfoTextWithTimeInSeconds(const QTime& time, const QString& msg)
{
double timeRunning = time.elapsed() / 1000.0;
QString timeText = QString("(%1 s) ").arg(timeRunning, 0, 'f', 1);
RiaLogging::info(timeText + msg);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::runRegressionTest(const QString& testRootPath, QStringList* testFilter)
{
m_runningRegressionTests = true;
QString generatedFolderName = RegTestNames::generatedFolderName;
QString diffFolderName = RegTestNames::diffFolderName;
QString baseFolderName = RegTestNames::baseFolderName;
QString regTestProjectName = RegTestNames::testProjectName;
QString regTestFolderFilter = RegTestNames::testFolderFilter;
// Find all sub folders
QDir testDir(testRootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(regTestFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = testDir.entryInfoList();
if (testFilter && testFilter->size() > 0)
{
QFileInfoList subset;
for (auto fi : folderList)
{
QString path = fi.path();
QString baseName = fi.baseName();
for (auto s : *testFilter)
{
QString trimmed = s.trimmed();
if (baseName.contains(trimmed))
{
subset.push_back(fi);
}
}
}
folderList = subset;
}
// delete diff and generated images
for (int i = 0; i < folderList.size(); ++i)
{
QDir testCaseFolder(folderList[i].filePath());
QDir genDir(testCaseFolder.filePath(generatedFolderName));
removeDirectoryWithContent(genDir);
QDir diffDir(testCaseFolder.filePath(diffFolderName));
removeDirectoryWithContent(diffDir);
QDir baseDir(testCaseFolder.filePath(baseFolderName));
}
// Generate html report
RiaImageCompareReporter imageCompareReporter;
// Minor workaround
// Use registry to define if interactive diff images should be created
// Defined by user in RiaRegressionTest
{
QSettings settings;
bool useInteractiveDiff = settings.value("showInteractiveDiffImages").toBool();
if (useInteractiveDiff)
{
imageCompareReporter.showInteractiveOnly();
}
}
QTime timeStamp;
timeStamp.start();
logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n");
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
QString testFolderName = testCaseFolder.dirName();
QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName);
QString reportGeneratedFolderName = testCaseFolder.filePath(generatedFolderName);
QString reportDiffFolderName = testCaseFolder.filePath(diffFolderName);
imageCompareReporter.addImageDirectoryComparisonSet(testFolderName.toStdString(), reportBaseFolderName.toStdString(), reportGeneratedFolderName.toStdString(), reportDiffFolderName.toStdString());
}
QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName);
imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString());
// Open HTML report
QDesktopServices::openUrl(htmlReportFileName);
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
// Detect any command files
QStringList filterList;
filterList << RegTestNames::commandFileFilter;
QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList);
if (!commandFileEntries.empty())
{
QString currentApplicationPath = QDir::current().absolutePath();
// Set current path to the folder containing the command file, as this is required when using file references
// in the command file
QDir::setCurrent(folderList[dirIdx].filePath());
for (const auto& fileInfo : commandFileEntries)
{
QString commandFile = fileInfo.absoluteFilePath();
QFile file(commandFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
RiaLogging::error("Failed to open command file : " + commandFile);
}
else
{
QTextStream in(&file);
RicfCommandFileExecutor::instance()->executeCommands(in);
}
}
QDir::setCurrent(currentApplicationPath);
}
QString projectFileName;
if (testCaseFolder.exists(regTestProjectName + ".rip"))
{
projectFileName = regTestProjectName + ".rip";
}
if (testCaseFolder.exists(regTestProjectName + ".rsp"))
{
projectFileName = regTestProjectName + ".rsp";
}
if (!projectFileName.isEmpty())
{
logInfoTextWithTimeInSeconds(timeStamp, "Initializing test :" + testCaseFolder.absolutePath());
loadProject(testCaseFolder.filePath(projectFileName));
// Wait until all command objects have completed
while (!m_commandQueueLock.tryLock())
{
processEvents();
}
m_commandQueueLock.unlock();
regressionTestConfigureProject();
resizeMaximizedPlotWindows();
QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName);
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder);
RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder);
QDir baseDir(testCaseFolder.filePath(baseFolderName));
QDir genDir(testCaseFolder.filePath(generatedFolderName));
QDir diffDir(testCaseFolder.filePath(diffFolderName));
if (!diffDir.exists()) testCaseFolder.mkdir(diffFolderName);
baseDir.setFilter(QDir::Files);
QStringList baseImageFileNames = baseDir.entryList();
for (int fIdx = 0; fIdx < baseImageFileNames.size(); ++fIdx)
{
QString fileName = baseImageFileNames[fIdx];
RiaImageFileCompare imgComparator(RegTestNames::imageCompareExeName);
bool ok = imgComparator.runComparison(genDir.filePath(fileName), baseDir.filePath(fileName), diffDir.filePath(fileName));
if (!ok)
{
qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails();
}
}
closeProject();
logInfoTextWithTimeInSeconds(timeStamp, "Completed test :" + testCaseFolder.absolutePath());
}
else
{
RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" + regTestProjectName + ".rsp");
}
}
RiaLogging::info("\n");
logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests");
m_runningRegressionTests = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::resizeMaximizedPlotWindows()
{
std::vector<RimViewWindow*> viewWindows;
m_project->mainPlotCollection()->descendantsIncludingThisOfType(viewWindows);
for (auto viewWindow : viewWindows)
{
if (viewWindow->isMdiWindow())
{
RimMdiWindowGeometry wndGeo = viewWindow->mdiWindowGeometry();
if (wndGeo.isMaximized)
{
QWidget* viewWidget = viewWindow->viewWidget();
if (viewWidget)
{
QMdiSubWindow* mdiWindow = m_mainPlotWindow->findMdiSubWindow(viewWidget);
if (mdiWindow)
{
mdiWindow->showNormal();
viewWidget->resize(RiaApplication::regressionDefaultImageSize());
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::updateRegressionTest(const QString& testRootPath)
{
// Find all sub folders
QDir testDir(testRootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(RegTestNames::testFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = testDir.entryInfoList();
for (int i = 0; i < folderList.size(); ++i)
{
QDir testCaseFolder(folderList[i].filePath());
QDir baseDir(testCaseFolder.filePath(RegTestNames::baseFolderName));
removeDirectoryWithContent(baseDir);
testCaseFolder.mkdir(RegTestNames::baseFolderName);
QDir genDir(testCaseFolder.filePath(RegTestNames::generatedFolderName));
QStringList imageFileNames = genDir.entryList();
for (int fIdx = 0; fIdx < imageFileNames.size(); ++fIdx)
{
QString fileName = imageFileNames[fIdx];
QFile::copy(genDir.filePath(fileName), baseDir.filePath(fileName));
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -2424,79 +2090,6 @@ void RiaApplication::executeCommandObjects()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::isRunningRegressionTests() const
{
return m_runningRegressionTests;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::executeRegressionTests(const QString& regressionTestPath, QStringList* testFilter)
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (mainWnd)
{
mainWnd->hideAllDockWindows();
mainWnd->setDefaultWindowSize();
runRegressionTest(regressionTestPath, testFilter);
mainWnd->loadWinGeoAndDockToolBarLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::regressionTestConfigureProject()
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (!mainWnd) return;
if (m_project.isNull()) return;
std::vector<RimCase*> projectCases;
m_project->allCases(projectCases);
for (size_t i = 0; i < projectCases.size(); i++)
{
RimCase* cas = projectCases[i];
if (!cas) continue;
std::vector<Rim3dView*> views = cas->views();
for (size_t j = 0; j < views.size(); j++)
{
Rim3dView* riv = views[j];
if (riv && riv->viewer())
{
// Make sure all views are maximized for snapshotting
QMdiSubWindow* subWnd = mainWnd->findMdiSubWindow(riv->viewer()->layoutWidget());
if (subWnd)
{
subWnd->showMaximized();
}
// This size is set to match the regression test reference images
riv->viewer()->setFixedSize(RiaApplication::regressionDefaultImageSize());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiaApplication::regressionDefaultImageSize()
{
return QSize(1000, 745);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -93,21 +93,20 @@ public:
public:
RiaApplication(int& argc, char** argv);
~RiaApplication();
static RiaApplication* instance();
static RiaApplication* instance();
int parseArgumentsAndRunUnitTestsIfRequested();
bool parseArguments();
int parseArgumentsAndRunUnitTestsIfRequested();
bool parseArguments();
void executeRegressionTests(const QString& regressionTestPath, QStringList* testFilter = nullptr);
void setActiveReservoirView(Rim3dView*);
Rim3dView* activeReservoirView();
const Rim3dView* activeReservoirView() const;
RimGridView* activeGridView();
void setActiveReservoirView(Rim3dView*);
Rim3dView* activeReservoirView();
const Rim3dView* activeReservoirView() const;
RimGridView* activeGridView();
RimViewWindow* activePlotWindow() const;
RimViewWindow* activePlotWindow() const;
RimProject* project();
RimProject* project();
void createMockModel();
void createResultsMockModel();
@@ -140,7 +139,6 @@ public:
void addWellLogsToModel(const QList<QString>& wellLogFilePaths);
void runMultiCaseSnapshots(const QString& templateProjectFileName, std::vector<QString> gridFileNames, const QString& snapshotFolderName);
void runRegressionTest(const QString& testRootPath, QStringList* testFilter = nullptr);
void processNonGuiEvents();
@@ -179,8 +177,6 @@ public:
void addCommandObject(RimCommandObject* commandObject);
void executeCommandObjects();
bool isRunningRegressionTests() const;
int launchUnitTests();
int launchUnitTestsWithConsole();
@@ -203,9 +199,10 @@ public:
static std::vector<QString> readFileListFromTextFile(QString listFileName);
void waitUntilCommandObjectsHasBeenProcessed();
private:
void onProjectOpenedOrClosed();
void setWindowCaptionFromAppState();
@@ -216,25 +213,16 @@ private:
void storeTreeViewState();
void resizeMaximizedPlotWindows();
void updateRegressionTest(const QString& testRootPath);
void regressionTestConfigureProject();
static QSize regressionDefaultImageSize();
friend RiaArgumentParser;
void setHelpText(const QString& helpText);
private slots:
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
caf::PdmPointer<Rim3dView> m_activeReservoirView;
caf::PdmPointer<Rim3dView> m_activeReservoirView;
caf::PdmPointer<RimProject> m_project;
RiaSocketServer* m_socketServer;
caf::UiProcess* m_workerProcess;
@@ -258,7 +246,6 @@ private:
QMutex m_commandQueueLock;
QString m_helpText;
bool m_runningRegressionTests;
bool m_runningWorkerProcess;

View File

@@ -20,6 +20,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaStringEncodingTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTextStringTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.h
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.h
)
set (SOURCE_GROUP_SOURCE_FILES
@@ -43,6 +45,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaSimWellBranchTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaStringEncodingTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTextStringTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -18,11 +18,12 @@
#include "RiaArgumentParser.h"
#include "RiaProjectModifier.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaBaseDefs.h"
#include "RiaImportEclipseCaseTools.h"
#include "RiaPreferences.h"
#include "RiaProjectModifier.h"
#include "RiaRegressionTestRunner.h"
#include "RimProject.h"
@@ -115,7 +116,7 @@ bool RiaArgumentParser::parseArguments()
{
CVF_ASSERT(o.valueCount() == 1);
QString regressionTestPath = cvfqt::Utils::toQString(o.value(0));
RiaApplication::instance()->executeRegressionTests(regressionTestPath);
RiaRegressionTestRunner::instance()->executeRegressionTests(regressionTestPath, QStringList());
return false;
}
@@ -123,7 +124,7 @@ bool RiaArgumentParser::parseArguments()
{
CVF_ASSERT(o.valueCount() == 1);
QString regressionTestPath = cvfqt::Utils::toQString(o.value(0));
RiaApplication::instance()->updateRegressionTest(regressionTestPath);
RiaRegressionTestRunner::instance()->updateRegressionTest(regressionTestPath);
return false;
}

View File

@@ -18,6 +18,7 @@
#include "RiaRegressionTest.h"
#include "cafPdmSettings.h"
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTextEditor.h"
@@ -29,9 +30,12 @@ CAF_PDM_SOURCE_INIT(RiaRegressionTest, "RiaRegressionTest");
//--------------------------------------------------------------------------------------------------
RiaRegressionTest::RiaRegressionTest(void)
{
CAF_PDM_InitFieldNoDefault(&applicationWorkingFolder, "workingFolder", "Folder containing <b>compare</b>", "", "Location of compare tool from Image Magic suite", "");
applicationWorkingFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&folderContainingCompareTool, "workingFolder", "Folder containing <b>compare</b>", "", "Location of compare tool from Image Magic suite", "");
folderContainingCompareTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&folderContainingDiffTool, "folderContainingDiffTool", "Folder containing <b>diff</b>", "", "Location of diff tool used for text compare", "");
folderContainingDiffTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&regressionTestFolder, "regressionTestFolder", "Regression Test Folder", "", "", "");
regressionTestFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName());
@@ -49,12 +53,28 @@ RiaRegressionTest::~RiaRegressionTest(void)
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::writeSettingsToApplicationStore() const
{
caf::PdmSettings::writeFieldsToApplicationStore(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::readSettingsFromApplicationStore()
{
caf::PdmSettings::readFieldsFromApplicationStore(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
{
if (field == &applicationWorkingFolder || field == &regressionTestFolder)
if (field == &folderContainingDiffTool || field == &folderContainingCompareTool || field == &regressionTestFolder)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)
@@ -63,5 +83,3 @@ void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field,
}
}
}

View File

@@ -32,8 +32,12 @@ public:
RiaRegressionTest(void);
virtual ~RiaRegressionTest(void);
void writeSettingsToApplicationStore() const;
void readSettingsFromApplicationStore();
public:
caf::PdmField<QString> applicationWorkingFolder;
caf::PdmField<QString> folderContainingCompareTool;
caf::PdmField<QString> folderContainingDiffTool;
caf::PdmField<QString> regressionTestFolder;
caf::PdmField<QString> testFilter;
caf::PdmField<bool> showInteractiveDiffImages;

View File

@@ -0,0 +1,546 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 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 "RiaRegressionTestRunner.h"
#include "RiaApplication.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
#include "RiaLogging.h"
#include "RiaRegressionTest.h"
#include "RiaTextFileCompare.h"
#include "RicfCommandFileExecutor.h"
#include "Rim3dView.h"
#include "RimCase.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RiuMainPlotWindow.h"
#include "RiuMainWindow.h"
#include "RiuViewer.h"
#include "ExportCommands/RicSnapshotAllPlotsToFileFeature.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include <QDateTime>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QMdiSubWindow>
#include <QSettings>
#include <QString>
#include <QUrl>
namespace RegTestNames
{
const QString generatedFilesFolderName = "RegTestGeneratedFiles";
const QString baseFilesFolderName = "RegTestBaseFiles";
const QString generatedFolderName = "RegTestGeneratedImages";
const QString diffFolderName = "RegTestDiffImages";
const QString baseFolderName = "RegTestBaseImages";
const QString testProjectName = "RegressionTest";
const QString testFolderFilter = "TestCase*";
const QString imageCompareExeName = "compare";
const QString reportFileName = "ResInsightRegressionTestReport.html";
const QString commandFileFilter = "commandfile-*";
}; // namespace RegTestNames
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void logInfoTextWithTimeInSeconds(const QTime& time, const QString& msg)
{
double timeRunning = time.elapsed() / 1000.0;
QString timeText = QString("(%1 s) ").arg(timeRunning, 0, 'f', 1);
RiaLogging::info(timeText + msg);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTestRunner::RiaRegressionTestRunner()
: m_runningRegressionTests(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTestRunner* RiaRegressionTestRunner::instance()
{
static RiaRegressionTestRunner* singleton = new RiaRegressionTestRunner;
return singleton;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, const QStringList& testFilter)
{
m_runningRegressionTests = true;
RiaRegressionTest regressionTestConfig;
regressionTestConfig.readSettingsFromApplicationStore();
QString currentApplicationPath = QDir::currentPath();
if (!regressionTestConfig.folderContainingCompareTool().isEmpty())
{
// Windows Only : The image compare tool requires current working directory to be at the folder
// containing the image compare tool
QDir::setCurrent(regressionTestConfig.folderContainingCompareTool());
}
QString generatedFolderName = RegTestNames::generatedFolderName;
QString diffFolderName = RegTestNames::diffFolderName;
QString baseFolderName = RegTestNames::baseFolderName;
QString regTestProjectName = RegTestNames::testProjectName;
QString regTestFolderFilter = RegTestNames::testFolderFilter;
QDir testDir(testRootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(regTestFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = testDir.entryInfoList();
if (!testFilter.isEmpty())
{
QFileInfoList subset;
for (auto fi : folderList)
{
QString path = fi.path();
QString baseName = fi.baseName();
for (auto s : testFilter)
{
QString trimmed = s.trimmed();
if (baseName.contains(trimmed))
{
subset.push_back(fi);
}
}
}
folderList = subset;
}
// delete diff and generated images
for (int i = 0; i < folderList.size(); ++i)
{
QDir testCaseFolder(folderList[i].filePath());
QDir genDir(testCaseFolder.filePath(generatedFolderName));
removeDirectoryWithContent(genDir);
QDir diffDir(testCaseFolder.filePath(diffFolderName));
removeDirectoryWithContent(diffDir);
QDir baseDir(testCaseFolder.filePath(baseFolderName));
}
// Generate html report
RiaImageCompareReporter imageCompareReporter;
// Minor workaround
// Use registry to define if interactive diff images should be created
// Defined by user in RiaRegressionTest
{
QSettings settings;
bool useInteractiveDiff = settings.value("showInteractiveDiffImages").toBool();
if (useInteractiveDiff)
{
imageCompareReporter.showInteractiveOnly();
}
}
QTime timeStamp;
timeStamp.start();
logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n");
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
QString testFolderName = testCaseFolder.dirName();
QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName);
QString reportGeneratedFolderName = testCaseFolder.filePath(generatedFolderName);
QString reportDiffFolderName = testCaseFolder.filePath(diffFolderName);
imageCompareReporter.addImageDirectoryComparisonSet(testFolderName.toStdString(),
reportBaseFolderName.toStdString(),
reportGeneratedFolderName.toStdString(),
reportDiffFolderName.toStdString());
}
QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName);
imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString());
// Open HTML report
QDesktopServices::openUrl(htmlReportFileName);
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
// Detect any command files
QStringList filterList;
filterList << RegTestNames::commandFileFilter;
QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList);
if (!commandFileEntries.empty())
{
QString currentApplicationPath = QDir::current().absolutePath();
// Set current path to the folder containing the command file, as this is required when using file references
// in the command file
QDir::setCurrent(folderList[dirIdx].filePath());
for (const auto& fileInfo : commandFileEntries)
{
QString commandFile = fileInfo.absoluteFilePath();
QFile file(commandFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
RiaLogging::error("Failed to open command file : " + commandFile);
}
else
{
QTextStream in(&file);
RicfCommandFileExecutor::instance()->executeCommands(in);
}
}
QDir::setCurrent(currentApplicationPath);
// Create diff based on generated folders
{
QString html;
RiaRegressionTest regressionTestConfig;
regressionTestConfig.readSettingsFromApplicationStore();
RiaTextFileCompare textFileCompare(regressionTestConfig.folderContainingDiffTool());
QString baseFilesFolderName = testCaseFolder.filePath(RegTestNames::baseFilesFolderName);
QString generatedFilesFolderName = testCaseFolder.filePath(RegTestNames::generatedFilesFolderName);
QFileInfo fib(baseFilesFolderName);
QFileInfo fig(generatedFilesFolderName);
if (fib.exists() && fig.exists())
{
{
QString headerText = testCaseFolder.dirName();
html += "<table>\n";
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"darkblue\" height=\"40\"> <b><font color=\"white\" size=\"3\"> " + headerText + " </font></b> </td>\n";
html += " </tr>\n";
textFileCompare.runComparison(baseFilesFolderName, generatedFilesFolderName);
QString diff = textFileCompare.diffOutput();
if (diff.isEmpty())
{
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"lightgray\"> <font color=\"green\">No text diff detected</font> </td> \n";
html += " </tr>\n";
}
else
{
html += " <tr>\n";
html += " <td colspan=\"3\" bgcolor=\"lightgray\"> <font color=\"red\">Text diff detected - output from diff tool : </font> </td> \n";
html += " </tr>\n";
}
// Table end
html += "</table>\n";
if (!diff.isEmpty())
{
html += QString("<code> %1 </code>").arg(diff);
}
}
QFile file(htmlReportFileName);
if (file.open(QIODevice::Append | QIODevice::Text))
{
QTextStream stream(&file);
stream << html;
}
}
}
}
QString projectFileName;
if (testCaseFolder.exists(regTestProjectName + ".rip"))
{
projectFileName = regTestProjectName + ".rip";
}
if (testCaseFolder.exists(regTestProjectName + ".rsp"))
{
projectFileName = regTestProjectName + ".rsp";
}
if (!projectFileName.isEmpty())
{
logInfoTextWithTimeInSeconds(timeStamp, "Initializing test :" + testCaseFolder.absolutePath());
RiaApplication* app = RiaApplication::instance();
app->loadProject(testCaseFolder.filePath(projectFileName));
// Wait until all command objects have completed
app->waitUntilCommandObjectsHasBeenProcessed();
regressionTestConfigureProject();
resizeMaximizedPlotWindows();
QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName);
RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder);
RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder);
QDir baseDir(testCaseFolder.filePath(baseFolderName));
QDir genDir(testCaseFolder.filePath(generatedFolderName));
QDir diffDir(testCaseFolder.filePath(diffFolderName));
if (!diffDir.exists()) testCaseFolder.mkdir(diffFolderName);
baseDir.setFilter(QDir::Files);
QStringList baseImageFileNames = baseDir.entryList();
for (int fIdx = 0; fIdx < baseImageFileNames.size(); ++fIdx)
{
QString fileName = baseImageFileNames[fIdx];
RiaImageFileCompare imgComparator(RegTestNames::imageCompareExeName);
bool ok = imgComparator.runComparison(
genDir.filePath(fileName), baseDir.filePath(fileName), diffDir.filePath(fileName));
if (!ok)
{
qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails();
}
}
app->closeProject();
logInfoTextWithTimeInSeconds(timeStamp, "Completed test :" + testCaseFolder.absolutePath());
}
else
{
RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" +
regTestProjectName + ".rsp");
}
}
RiaLogging::info("\n");
logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests");
QDir::setCurrent(currentApplicationPath);
m_runningRegressionTests = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::removeDirectoryWithContent(QDir& dirToDelete)
{
QStringList files = dirToDelete.entryList();
for (int fIdx = 0; fIdx < files.size(); ++fIdx)
{
dirToDelete.remove(files[fIdx]);
}
dirToDelete.rmdir(".");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::regressionTestConfigureProject()
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (!mainWnd) return;
RimProject* proj = RiaApplication::instance()->project();
if (!proj) return;
std::vector<RimCase*> projectCases;
proj->allCases(projectCases);
for (size_t i = 0; i < projectCases.size(); i++)
{
RimCase* cas = projectCases[i];
if (!cas) continue;
std::vector<Rim3dView*> views = cas->views();
for (size_t j = 0; j < views.size(); j++)
{
Rim3dView* riv = views[j];
if (riv && riv->viewer())
{
// Make sure all views are maximized for snapshotting
QMdiSubWindow* subWnd = mainWnd->findMdiSubWindow(riv->viewer()->layoutWidget());
if (subWnd)
{
subWnd->showMaximized();
}
// This size is set to match the regression test reference images
riv->viewer()->setFixedSize(RiaRegressionTestRunner::regressionDefaultImageSize());
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::resizeMaximizedPlotWindows()
{
RimProject* proj = RiaApplication::instance()->project();
if (!proj) return;
RiuMainPlotWindow* plotMainWindow = RiaApplication::instance()->mainPlotWindow();
if (!plotMainWindow) return;
std::vector<RimViewWindow*> viewWindows;
proj->mainPlotCollection()->descendantsIncludingThisOfType(viewWindows);
for (auto viewWindow : viewWindows)
{
if (viewWindow->isMdiWindow())
{
RimMdiWindowGeometry wndGeo = viewWindow->mdiWindowGeometry();
if (wndGeo.isMaximized)
{
QWidget* viewWidget = viewWindow->viewWidget();
if (viewWidget)
{
QMdiSubWindow* mdiWindow = plotMainWindow->findMdiSubWindow(viewWidget);
if (mdiWindow)
{
mdiWindow->showNormal();
viewWidget->resize(RiaRegressionTestRunner::regressionDefaultImageSize());
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiaRegressionTestRunner::regressionDefaultImageSize()
{
return QSize(1000, 745);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::executeRegressionTests()
{
RiaRegressionTest testConfig;
testConfig.readSettingsFromApplicationStore();
QString testPath = testConfig.regressionTestFolder();
QStringList testFilter = testConfig.testFilter().split(";", QString::SkipEmptyParts);
executeRegressionTests(testPath, testFilter);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::executeRegressionTests(const QString& regressionTestPath, const QStringList& testFilter)
{
RiuMainWindow* mainWnd = RiuMainWindow::instance();
if (mainWnd)
{
mainWnd->hideAllDockWindows();
mainWnd->setDefaultWindowSize();
runRegressionTest(regressionTestPath, testFilter);
mainWnd->loadWinGeoAndDockToolBarLayout();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaRegressionTestRunner::isRunningRegressionTests() const
{
return m_runningRegressionTests;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::updateRegressionTest(const QString& testRootPath)
{
// Find all sub folders
QDir testDir(testRootPath); // If string is empty it will end up as cwd
testDir.setFilter(QDir::Dirs);
QStringList dirNameFilter;
dirNameFilter.append(RegTestNames::testFolderFilter);
testDir.setNameFilters(dirNameFilter);
QFileInfoList folderList = testDir.entryInfoList();
for (int i = 0; i < folderList.size(); ++i)
{
QDir testCaseFolder(folderList[i].filePath());
QDir baseDir(testCaseFolder.filePath(RegTestNames::baseFolderName));
removeDirectoryWithContent(baseDir);
testCaseFolder.mkdir(RegTestNames::baseFolderName);
QDir genDir(testCaseFolder.filePath(RegTestNames::generatedFolderName));
QStringList imageFileNames = genDir.entryList();
for (int fIdx = 0; fIdx < imageFileNames.size(); ++fIdx)
{
QString fileName = imageFileNames[fIdx];
QFile::copy(genDir.filePath(fileName), baseDir.filePath(fileName));
}
}
}

View File

@@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 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 <QSize>
#include <QStringList>
class QDir;
//==================================================================================================
//
//==================================================================================================
class RiaRegressionTestRunner
{
public:
RiaRegressionTestRunner();
static RiaRegressionTestRunner* instance();
void executeRegressionTests(const QString& regressionTestPath, const QStringList& testFilter);
void executeRegressionTests();
bool isRunningRegressionTests() const;
static void updateRegressionTest(const QString& testRootPath);
private:
void runRegressionTest(const QString& testRootPath, const QStringList& testFilter);
static void removeDirectoryWithContent(QDir& dirToDelete);
static void regressionTestConfigureProject();
static void resizeMaximizedPlotWindows();
static QSize regressionDefaultImageSize();
private:
const QString m_rootPath;
const QStringList m_testFilter;
bool m_runningRegressionTests;
};

View File

@@ -0,0 +1,139 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 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 "RiaTextFileCompare.h"
#include "cafUtils.h"
#include <QProcess>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::RiaTextFileCompare(const QString& pathToDiffTool)
: m_pathToDiffTool(pathToDiffTool)
{
reset();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::~RiaTextFileCompare() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaTextFileCompare::reset()
{
m_lastError = IC_NO_ERROR;
m_errorMsg.clear();
m_errorDetails.clear();
m_diffOutput.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaTextFileCompare::runComparison(const QString& baseFolder, const QString& generatedFolder)
{
reset();
QString fullFilePath = "diff";
if (!m_pathToDiffTool.isEmpty())
{
fullFilePath = m_pathToDiffTool + "/" + fullFilePath;
}
// Run compare recursively with '-r'
QString args = "-r -u";
QString completeCommand = QString("\"%1\" %2 %3 %4").arg(fullFilePath).arg(baseFolder).arg(generatedFolder).arg(args);
// Launch process and wait
QProcess proc;
proc.start(completeCommand);
proc.waitForFinished(30000);
QProcess::ProcessError procError = proc.error();
if (procError != QProcess::UnknownError)
{
m_lastError = SEVERE_ERROR;
m_errorMsg = "Error running 'diff' tool process";
m_errorDetails = completeCommand;
return false;
}
QByteArray stdErr = proc.readAllStandardError();
int procExitCode = proc.exitCode();
if (procExitCode == 0)
{
return true;
}
else if (procExitCode == 1)
{
QByteArray stdOut = proc.readAllStandardOutput();
m_diffOutput = stdOut;
return false;
}
else
{
stdErr = stdErr.simplified();
// Report non-severe error
m_lastError = IC_ERROR;
m_errorMsg = "Error running 'diff' tool process";
m_errorDetails = stdErr;
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaTextFileCompare::ErrorType RiaTextFileCompare::error() const
{
return m_lastError;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::errorMessage() const
{
return m_errorMsg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::errorDetails() const
{
return m_errorDetails;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaTextFileCompare::diffOutput() const
{
return m_diffOutput;
}

View File

@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018 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 <QString>
//==================================================================================================
//
// Execute text compare between to folders recursively using the external tool 'diff'
//
//==================================================================================================
class RiaTextFileCompare
{
public:
enum ErrorType
{
IC_NO_ERROR, // No error occurred
IC_ERROR, // An error occurred
SEVERE_ERROR // Severe error occurred, it is likely that another call to compare() will also fail
};
public:
explicit RiaTextFileCompare(const QString& pathToDiffTool);
~RiaTextFileCompare();
bool runComparison(const QString& baseFolder, const QString& generatedFolder);
ErrorType error() const;
QString errorMessage() const;
QString errorDetails() const;
QString diffOutput() const;
private:
void reset();
private:
const QString m_pathToDiffTool;
ErrorType m_lastError;
QString m_errorMsg;
QString m_errorDetails;
QString m_diffOutput;
};

View File

@@ -18,8 +18,7 @@
#include "RicLaunchRegressionTestsFeature.h"
#include "RiaApplication.h"
#include "RiaRegressionTest.h"
#include "RiaRegressionTestRunner.h"
#include "cafPdmSettings.h"
@@ -41,14 +40,7 @@ bool RicLaunchRegressionTestsFeature::isCommandEnabled()
//--------------------------------------------------------------------------------------------------
void RicLaunchRegressionTestsFeature::onActionTriggered(bool isChecked)
{
RiaRegressionTest regTestConfig;
caf::PdmSettings::readFieldsFromApplicationStore(&regTestConfig);
QStringList testFilter = regTestConfig.testFilter().split(";", QString::SkipEmptyParts);
// Launch regression test using the current test folder and test filter
RiaApplication::instance()->executeRegressionTests(regTestConfig.regressionTestFolder, &testFilter);
RiaRegressionTestRunner::instance()->executeRegressionTests();
}
//--------------------------------------------------------------------------------------------------

View File

@@ -31,6 +31,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHideIntersectionFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicHideIntersectionBoxFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicImportElementPropertyFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicSelectColorResult.h
${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicWellLogsImportFileFeature.h
@@ -99,6 +100,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicHideIntersectionFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicHideIntersectionBoxFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicImportElementPropertyFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSelectColorResult.cpp
${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicTogglePerspectiveViewFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseFeature.cpp

View File

@@ -488,10 +488,9 @@ void RicWellPathExportCompletionDataFeatureImpl::printCompletionsToFile(
if (completionsPerGrid.empty()) return;
QDir exportFolder(folderName);
if (!exportFolder.exists())
{
bool createdPath = exportFolder.mkpath(folderName);
bool createdPath = exportFolder.mkpath(".");
if (createdPath)
RiaLogging::info("Created export folder " + folderName);
else

View File

@@ -222,6 +222,11 @@ RimCase* commonGridCase(std::vector<caf::PdmUiItem*> selectedItems)
for (caf::PdmUiItem* item : selectedItems)
{
caf::PdmObjectHandle* obj = dynamic_cast<caf::PdmObjectHandle*>(item);
if (!obj)
{
continue;
}
RimCase* itemCase = nullptr;
obj->firstAncestorOrThisOfType(itemCase);

View File

@@ -0,0 +1,80 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "RicAdd3dWellLogCurveFeature.h"
#include "RiaApplication.h"
#include "RicWellLogTools.h"
#include "Rim3dWellLogCurve.h"
#include "RimCase.h"
#include "RimProject.h"
#include "RimWellPath.h"
#include "Riu3DMainWindowTools.h"
#include <QAction>
CAF_CMD_SOURCE_INIT(RicAdd3dWellLogCurveFeature, "RicAdd3dWellLogCurveFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicAdd3dWellLogCurveFeature::isCommandEnabled()
{
std::vector<RimCase*> cases;
RiaApplication::instance()->project()->allCases(cases);
if (cases.empty()) return false;
return (RicWellLogTools::selectedWellPath() != nullptr);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicAdd3dWellLogCurveFeature::onActionTriggered(bool isChecked)
{
RimWellPath* selectedWellPath = RicWellLogTools::selectedWellPath();
Rim3dWellLogCurve* rim3dWellLogCurve = new Rim3dWellLogCurve();
Rim3dView* view = RiaApplication::instance()->activeReservoirView();
if (view)
{
rim3dWellLogCurve->setPropertiesFromView(view);
}
selectedWellPath->add3dWellLogCurve(rim3dWellLogCurve);
RiaApplication::instance()->project()->updateConnectedEditors();
Riu3DMainWindowTools::selectAsCurrentItem(rim3dWellLogCurve);
Riu3DMainWindowTools::setExpanded(selectedWellPath);
selectedWellPath->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicAdd3dWellLogCurveFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setIcon(QIcon(":/WellLogCurve16x16.png"));
actionToSetup->setText("Add 3D Well Log Curve");
}

View File

@@ -0,0 +1,34 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "cafCmdFeature.h"
//==================================================================================================
///
//==================================================================================================
class RicAdd3dWellLogCurveFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
virtual bool isCommandEnabled() override;
virtual void onActionTriggered( bool isChecked ) override;
virtual void setupActionLook( QAction* actionToSetup ) override;
};

View File

@@ -27,9 +27,10 @@
#include "RigWellLogCurveData.h"
#include "Rim3dView.h"
#include "RimProject.h"
#include "RimSimWellInView.h"
#include "Rim3dView.h"
#include "RimSimWellInViewCollection.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
@@ -44,7 +45,6 @@
#include <QAction>
#include <vector>
#include "RimSimWellInViewCollection.h"
CAF_CMD_SOURCE_INIT(RicNewWellLogCurveExtractionFeature, "RicNewWellLogCurveExtractionFeature");
@@ -125,5 +125,5 @@ bool RicNewWellLogCurveExtractionFeature::caseAvailable()
std::vector<RimCase*> cases;
RiaApplication::instance()->project()->allCases(cases);
return cases.size() > 0;
return !cases.empty();
}

View File

@@ -340,23 +340,18 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createEllipseSurfacePart(const RimEc
{
std::vector<cvf::Vec3f> nodeCoords;
std::vector<cvf::uint> triangleIndices;
m_rimFracture->triangleGeometry(&triangleIndices, &nodeCoords);
std::vector<cvf::Vec3f> displayCoords;
m_rimFracture->fractureTemplate()->fractureTriangleGeometry(&nodeCoords, &triangleIndices);
for (const auto& nodeCoord : nodeCoords)
{
cvf::Vec3d nodeCoordsDouble = static_cast<cvf::Vec3d>(nodeCoord);
cvf::Vec3d displayCoordsDouble = displayCoordTransform->transformToDisplayCoord(nodeCoordsDouble);
displayCoords.push_back(static_cast<cvf::Vec3f>(displayCoordsDouble));
}
cvf::Mat4d fractureXf = m_rimFracture->transformMatrix();
std::vector<cvf::Vec3f> nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform);
if (triangleIndices.empty() || displayCoords.empty())
if (triangleIndices.empty() || nodeDisplayCoords.empty())
{
return nullptr;
}
cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triangleIndices, displayCoords);
cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triangleIndices, nodeDisplayCoords);
CVF_ASSERT(geo.notNull());
cvf::ref<cvf::Part> surfacePart = new cvf::Part(0, "FractureSurfacePart_ellipse");
@@ -415,21 +410,17 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa
// If this ever changes, the entire code must be revisited
std::vector<cvf::Vec3f> nodeCoords;
std::vector<cvf::uint> triangleIndices;
m_rimFracture->triangleGeometry(&triangleIndices, &nodeCoords);
stimPlanFracTemplate->fractureTriangleGeometry(&nodeCoords, &triangleIndices);
if (triangleIndices.empty() || nodeCoords.empty())
{
return nullptr;
}
// Transforms the node coordinates for display
for (auto& nodeCoord : nodeCoords)
{
cvf::Vec3d doubleCoord(nodeCoord);
doubleCoord = displayCoordTransform->transformToDisplayCoord(doubleCoord);
nodeCoord = cvf::Vec3f(doubleCoord);
}
cvf::Mat4d fractureXf = m_rimFracture->transformMatrix();
std::vector<cvf::Vec3f> nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform);
RimLegendConfig* legendConfig = nullptr;
if (activeView.fractureColors() && activeView.fractureColors()->isChecked())
{
@@ -441,7 +432,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa
{
// Construct array with per node result values that correspond to the node coordinates of the triangle mesh
// Since some time steps don't have result vales, we initialize the array to well known values before populating it
std::vector<double> perNodeResultValues(nodeCoords.size(), HUGE_VAL);
std::vector<double> perNodeResultValues(nodeDisplayCoords.size(), HUGE_VAL);
{
size_t idx = 0;
const std::vector<std::vector<double> > dataToPlot = stimPlanFracTemplate->resultValues(activeView.fractureColors()->uiResultName(), activeView.fractureColors()->unit(), stimPlanFracTemplate->activeTimeStepIndex());
@@ -453,8 +444,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa
}
}
}
CVF_ASSERT(perNodeResultValues.size() == nodeCoords.size());
CVF_ASSERT(perNodeResultValues.size() == nodeDisplayCoords.size());
std::vector<cvf::uint> triIndicesToInclude;
for (size_t i = 0; i < triangleIndices.size(); i += 6)
@@ -483,15 +473,11 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa
return nullptr;
}
cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeCoords);
cvf::ref<cvf::Part> surfacePart = new cvf::Part(0, "FractureSurfacePart_stimPlan");
surfacePart->setDrawable(geo.p());
surfacePart->setPriority(RivPartPriority::PartType::BaseLevel);
surfacePart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture));
cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords);
const cvf::ScalarMapper* scalarMapper = legendConfig->scalarMapper();
CVF_ASSERT(scalarMapper);
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(nodeCoords.size());
cvf::ref<cvf::Vec2fArray> textureCoords = new cvf::Vec2fArray(nodeDisplayCoords.size());
textureCoords->setAll(cvf::Vec2f(0.5f, 1.0f));
for (size_t i = 0; i < perNodeResultValues.size(); i++)
{
@@ -503,10 +489,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa
}
geo->setTextureCoordArray(textureCoords.p());
caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1);
effGen.disableLighting(activeView.isLightingDisabled());
cvf::ref<cvf::Effect> eff = effGen.generateCachedEffect();
surfacePart->setEffect(eff.p());
cvf::ref<cvf::Part> surfacePart = createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled());
return surfacePart;
}
@@ -640,19 +623,11 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanElementColorSurfacePar
}
cvf::ref<cvf::DrawableGeo> geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords);
cvf::ref<cvf::Part> surfacePart = new cvf::Part(0, "FractureSurfacePart_stimPlan");
surfacePart->setDrawable(geo.p());
surfacePart->setPriority(RivPartPriority::PartType::BaseLevel);
surfacePart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture));
geo->setTextureCoordArray(textureCoords.p());
caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1);
effGen.disableLighting(activeView.isLightingDisabled());
cvf::ref<cvf::Effect> eff = effGen.generateCachedEffect();
surfacePart->setEffect(eff.p());
cvf::ref<cvf::Part> surfacePart = createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled());
return surfacePart;
return surfacePart;
}
else
{
@@ -667,7 +642,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanElementColorSurfacePar
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellFracturePartMgr::createContainmentMaskPart(const RimEclipseView& activeView)
{
std::vector<cvf::Vec3f> borderPolygonLocalCS = m_rimFracture->fractureTemplate()->fractureBorderPolygon();
std::vector<cvf::Vec3d> borderPolygonLocalCS = fractureBorderPolygon();
cvf::Mat4d frMx = m_rimFracture->transformMatrix();
cvf::BoundingBox frBBox;
@@ -871,7 +846,7 @@ cvf::ref<cvf::Part> RivWellFracturePartMgr::createStimPlanMeshPart(const RimEcli
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView) const
cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView)
{
if (!stimPlanFracTemplate->fractureGrid()) return nullptr;
@@ -888,6 +863,7 @@ cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri
resultUnitFromColors,
stimPlanFracTemplate->activeTimeStepIndex());
m_visibleFracturePolygons.clear();
for ( size_t cIdx = 0; cIdx < stimPlanCells.size() ; ++cIdx)
{
if (prCellResults[cIdx] > 1e-7)
@@ -898,6 +874,7 @@ cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri
{
stimPlanMeshVertices.push_back(static_cast<cvf::Vec3f>(cellCorner));
}
m_visibleFracturePolygons.push_back(stimPlanCellPolygon);
}
}
@@ -907,7 +884,7 @@ cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri
}
cvf::Mat4d fractureXf = m_rimFracture->transformMatrix();
std::vector<cvf::Vec3f> stimPlanMeshVerticesDisplayCoords = transformToFractureDisplayCoords(stimPlanMeshVertices,
std::vector<cvf::Vec3f> stimPlanMeshVerticesDisplayCoords = transformToFractureDisplayCoords(stimPlanMeshVertices,
fractureXf,
*displayCoordTransform);
@@ -926,6 +903,36 @@ cvf::ref<cvf::DrawableGeo> RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri
return stimPlanMeshGeo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellFracturePartMgr::createScalarMapperPart(cvf::DrawableGeo* drawableGeo,
const cvf::ScalarMapper* scalarMapper,
RimFracture* fracture,
bool disableLighting)
{
cvf::ref<cvf::Part> surfacePart = new cvf::Part(0, "FractureSurfacePart_stimPlan");
surfacePart->setDrawable(drawableGeo);
surfacePart->setPriority(RivPartPriority::PartType::BaseLevel);
surfacePart->setSourceInfo(new RivObjectSourceInfo(fracture));
caf::ScalarMapperEffectGenerator effGen(scalarMapper, caf::PO_1);
effGen.disableLighting(disableLighting);
cvf::ref<cvf::Effect> eff = effGen.generateCachedEffect();
surfacePart->setEffect(eff.p());
return surfacePart;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RivWellFracturePartMgr::fractureBorderPolygon()
{
return RigCellGeometryTools::unionOfPolygons(m_visibleFracturePolygons);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -30,10 +30,11 @@
namespace cvf
{
class ModelBasicList;
class DrawableGeo;
class Part;
class Color3f;
class ModelBasicList;
class DrawableGeo;
class Part;
class Color3f;
class ScalarMapper;
}
namespace caf
@@ -42,6 +43,7 @@ namespace caf
}
class RimFracture;
class RimFractureTemplate;
class RimStimPlanFractureTemplate;
class RimEclipseView;
class RigFractureCell;
@@ -74,9 +76,13 @@ private:
void appendFracturePerforationLengthParts(const RimEclipseView& activeView, cvf::ModelBasicList* model);
cvf::ref<cvf::Part> createStimPlanMeshPart(const RimEclipseView& activeView);
cvf::ref<cvf::DrawableGeo> createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView) const;
cvf::ref<cvf::DrawableGeo> createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView);
static std::vector<cvf::Vec3f> transformToFractureDisplayCoords(const std::vector<cvf::Vec3f>& polygon,
std::vector<cvf::Vec3d> fractureBorderPolygon();
static cvf::ref<cvf::Part> createScalarMapperPart(cvf::DrawableGeo* drawableGeo, const cvf::ScalarMapper* scalarMapper, RimFracture* fracture, bool disableLighting);
static std::vector<cvf::Vec3f> transformToFractureDisplayCoords(const std::vector<cvf::Vec3f>& polygon,
cvf::Mat4d m,
const caf::DisplayCoordTransform& displayCoordTransform);
@@ -84,4 +90,6 @@ private:
private:
caf::PdmPointer<RimFracture> m_rimFracture;
std::vector<std::vector<cvf::Vec3d>> m_visibleFracturePolygons;
};

View File

@@ -98,6 +98,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationVariable.h
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanLegendConfig.h
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanColors.h
${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurve.h
)
@@ -200,6 +201,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationVariable.cpp
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanLegendConfig.cpp
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanColors.cpp
${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurve.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -20,6 +20,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSimWellFractureCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanFractureTemplate.h
${CMAKE_CURRENT_LIST_DIR}/RimWellPathFracture.h
${CMAKE_CURRENT_LIST_DIR}/RimWellPathFractureCollection.h
${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurveCollection.h
)
@@ -44,6 +45,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSimWellFractureCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanFractureTemplate.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathFracture.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellPathFractureCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurveCollection.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -0,0 +1,72 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "Rim3dWellLogCurveCollection.h"
#include "Rim3dWellLogCurve.h"
CAF_PDM_SOURCE_INIT(Rim3dWellLogCurveCollection, "Rim3dWellLogCurveCollection");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dWellLogCurveCollection::Rim3dWellLogCurveCollection()
{
CAF_PDM_InitObject("3D Track", ":/WellLogCurve16x16.png", "", "");
CAF_PDM_InitField(&m_showCurves, "Show3dWellLogCurves", true, "Show 3d Well Log Curves", "", "", "");
m_showCurves.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_3dWellLogCurves, "ArrayOf3dWellLogCurves", "", "", "", "");
m_3dWellLogCurves.uiCapability()->setUiTreeHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dWellLogCurveCollection::~Rim3dWellLogCurveCollection()
{
m_3dWellLogCurves.deleteAllChildObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Rim3dWellLogCurveCollection::has3dWellLogCurves() const
{
return !m_3dWellLogCurves.empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dWellLogCurveCollection::add3dWellLogCurve(Rim3dWellLogCurve* curve)
{
if (curve)
{
m_3dWellLogCurves.push_back(curve);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* Rim3dWellLogCurveCollection::objectToggleField()
{
return &m_showCurves;
}

View File

@@ -0,0 +1,48 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
class Rim3dWellLogCurve;
//==================================================================================================
///
///
//==================================================================================================
class Rim3dWellLogCurveCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
Rim3dWellLogCurveCollection();
virtual ~Rim3dWellLogCurveCollection();
bool has3dWellLogCurves() const;
void add3dWellLogCurve(Rim3dWellLogCurve* curve);
private:
virtual caf::PdmFieldHandle* objectToggleField() override;
private:
caf::PdmField<bool> m_showCurves;
caf::PdmChildArrayField<Rim3dWellLogCurve*> m_3dWellLogCurves;
};

View File

@@ -746,20 +746,7 @@ void RimStimPlanFractureTemplate::fractureTriangleGeometry(std::vector<cvf::Vec3
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3f> RimStimPlanFractureTemplate::fractureBorderPolygon()
{
if (m_stimPlanFractureDefinitionData.isNull()) return std::vector<cvf::Vec3f>();
QString parameterName = m_borderPolygonResultName;
QString parameterUnit = getUnitForStimPlanParameter(parameterName);
if (m_stimPlanFractureDefinitionData.notNull())
{
return m_stimPlanFractureDefinitionData->createFractureBorderPolygon(parameterName,
parameterUnit,
m_activeTimeStepIndex,
m_wellPathDepthAtFracture,
name());
}
// Not implemented
return std::vector<cvf::Vec3f>();
}

View File

@@ -0,0 +1,245 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "Rim3dWellLogCurve.h"
#include "Rim3dView.h"
#include "RimEclipseCase.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseResultDefinition.h"
#include "RimEclipseView.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechResultDefinition.h"
#include "RimGeoMechView.h"
#include "RimTools.h"
//==================================================================================================
///
///
//==================================================================================================
CAF_PDM_SOURCE_INIT(Rim3dWellLogCurve, "Rim3dWellLogCurve");
namespace caf
{
template<>
void AppEnum< Rim3dWellLogCurve::DrawPlane >::setUp()
{
addItem(Rim3dWellLogCurve::HORIZONTAL_LEFT, "HORIZONTAL_LEFT", "Horizontal - Left");
addItem(Rim3dWellLogCurve::HORIZONTAL_RIGHT, "HORIZONTAL_RIGHT", "Horizontal - Right");
addItem(Rim3dWellLogCurve::VERTICAL_ABOVE, "VERTICAL_ABOVE", "Vertical - Above");
addItem(Rim3dWellLogCurve::VERTICAL_BELOW, "VERTICAL_BELOW", "Vertical - Below");
addItem(Rim3dWellLogCurve::CAMERA_ALIGNED_SIDE1, "CAMERA_ALIGNED_SIDE_1", "Camera Aligned - Side 1");
addItem(Rim3dWellLogCurve::CAMERA_ALIGNED_SIDE2, "CAMERA_ALIGNED_SIDE_2", "Camera Aligned - Side 2");
setDefault(Rim3dWellLogCurve::HORIZONTAL_LEFT);
}
template<>
void AppEnum< Rim3dWellLogCurve::DrawStyle >::setUp()
{
addItem(Rim3dWellLogCurve::LINE, "LINE", "Line");
addItem(Rim3dWellLogCurve::FILLED, "FILLED", "Filled");
setDefault(Rim3dWellLogCurve::LINE);
}
template<>
void AppEnum< Rim3dWellLogCurve::ColoringStyle >::setUp()
{
addItem(Rim3dWellLogCurve::SINGLE_COLOR, "SINGLE_COLOR", "Single Color");
addItem(Rim3dWellLogCurve::CURVE_VALUE, "CURVE_VALUE", "Curve Value");
addItem(Rim3dWellLogCurve::OTHER_RESULT, "OTHER_RESULT", "Other Result");
setDefault(Rim3dWellLogCurve::SINGLE_COLOR);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dWellLogCurve::Rim3dWellLogCurve()
{
CAF_PDM_InitObject("3d Well Log Curve", ":/WellLogCurve16x16.png", "", "");
CAF_PDM_InitField(&m_showCurve, "Show3dWellLogCurve", true, "Show 3d Well Log Curve", "", "", "");
m_showCurve.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_drawPlane, "DrawPlane", "Draw Plane", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_drawStyle, "DrawStyle", "Draw Style", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_coloringStyle, "ColoringStyle", "Coloring Style", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_case, "CurveCase", "Case", "", "", "");
m_case.uiCapability()->setUiTreeChildrenHidden(true);
m_case = nullptr;
CAF_PDM_InitFieldNoDefault(&m_eclipseResultDefinition, "CurveEclipseResult", "", "", "", "");
m_eclipseResultDefinition.uiCapability()->setUiHidden(true);
m_eclipseResultDefinition.uiCapability()->setUiTreeChildrenHidden(true);
m_eclipseResultDefinition = new RimEclipseResultDefinition;
m_eclipseResultDefinition->findField("MResultType")->uiCapability()->setUiName("Result Type");
CAF_PDM_InitFieldNoDefault(&m_geomResultDefinition, "CurveGeomechResult", "", "", "", "");
m_geomResultDefinition.uiCapability()->setUiHidden(true);
m_geomResultDefinition.uiCapability()->setUiTreeChildrenHidden(true);
m_geomResultDefinition = new RimGeoMechResultDefinition;
CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", 0, "Time Step", "", "", "");
CAF_PDM_InitField(&m_name, "Name", QString("3D Well Log Curve"), "3d Well Log Curve", "", "", "");
m_name.uiCapability()->setUiHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Rim3dWellLogCurve::~Rim3dWellLogCurve()
{
delete m_geomResultDefinition;
delete m_eclipseResultDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dWellLogCurve::setPropertiesFromView(Rim3dView* view)
{
if (!view) return;
m_case = view->ownerCase();
RimGeoMechCase* geomCase = dynamic_cast<RimGeoMechCase*>(m_case.value());
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case.value());
m_eclipseResultDefinition->setEclipseCase(eclipseCase);
m_geomResultDefinition->setGeoMechCase(geomCase);
RimEclipseView* eclipseView = dynamic_cast<RimEclipseView*>(view);
if (eclipseView)
{
m_eclipseResultDefinition->simpleCopy(eclipseView->cellResult());
m_timeStep = eclipseView->currentTimeStep();
}
RimGeoMechView* geoMechView = dynamic_cast<RimGeoMechView*>(view);
if (geoMechView)
{
m_geomResultDefinition->setResultAddress(geoMechView->cellResultResultDefinition()->resultAddress());
m_timeStep = geoMechView->currentTimeStep();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* Rim3dWellLogCurve::objectToggleField()
{
return &m_showCurve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dWellLogCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> Rim3dWellLogCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (fieldNeedingOptions == &m_case)
{
RimTools::caseOptionItems(&options);
options.push_front(caf::PdmOptionItemInfo("None", nullptr));
}
else if (fieldNeedingOptions == &m_timeStep)
{
QStringList timeStepNames;
if (m_case)
{
timeStepNames = m_case->timeStepStrings();
}
for (int i = 0; i < timeStepNames.size(); i++)
{
options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i));
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* Rim3dWellLogCurve::userDescriptionField()
{
return &m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dWellLogCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup("Curve Data");
curveDataGroup->add(&m_case);
RimGeoMechCase* geomCase = dynamic_cast<RimGeoMechCase*>(m_case.value());
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case.value());
if (eclipseCase)
{
m_eclipseResultDefinition->uiOrdering(uiConfigName, *curveDataGroup);
}
else if (geomCase)
{
m_geomResultDefinition->uiOrdering(uiConfigName, *curveDataGroup);
}
if ((eclipseCase && m_eclipseResultDefinition->hasDynamicResult())
|| geomCase)
{
curveDataGroup->add(&m_timeStep);
}
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance");
appearanceGroup->add(&m_drawPlane);
appearanceGroup->add(&m_drawStyle);
appearanceGroup->add(&m_coloringStyle);
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Rim3dWellLogCurve::initAfterRead()
{
RimGeoMechCase* geomCase = dynamic_cast<RimGeoMechCase*>(m_case.value());
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(m_case.value());
m_eclipseResultDefinition->setEclipseCase(eclipseCase);
m_geomResultDefinition->setGeoMechCase(geomCase);
}

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2018- 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 "cafAppEnum.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "RimCase.h"
class RimGeoMechResultDefinition;
class RimEclipseResultDefinition;
//==================================================================================================
///
///
//==================================================================================================
class Rim3dWellLogCurve : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
enum DrawPlane
{
HORIZONTAL_LEFT,
HORIZONTAL_RIGHT,
VERTICAL_ABOVE,
VERTICAL_BELOW,
CAMERA_ALIGNED_SIDE1,
CAMERA_ALIGNED_SIDE2
};
enum DrawStyle
{
LINE,
FILLED
};
enum ColoringStyle
{
SINGLE_COLOR,
CURVE_VALUE,
OTHER_RESULT
};
public:
Rim3dWellLogCurve();
virtual ~Rim3dWellLogCurve();
void setPropertiesFromView(Rim3dView* view);
private:
virtual caf::PdmFieldHandle* objectToggleField() override;
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 caf::PdmFieldHandle* userDescriptionField() override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void initAfterRead() override;
private:
caf::PdmField<bool> m_showCurve;
caf::PdmField<QString> m_name;
caf::PdmPtrField<RimCase*> m_case;
caf::PdmField<int> m_timeStep;
caf::PdmChildField<RimEclipseResultDefinition*> m_eclipseResultDefinition;
caf::PdmChildField<RimGeoMechResultDefinition*> m_geomResultDefinition;
caf::PdmField<caf::AppEnum<DrawPlane>> m_drawPlane;
caf::PdmField<caf::AppEnum<DrawStyle>> m_drawStyle;
caf::PdmField<caf::AppEnum<ColoringStyle>> m_coloringStyle;
};

View File

@@ -258,11 +258,16 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "RicShowWellAllocationPlotFeature";
menuBuilder << "RicNewWellLogFileCurveFeature";
menuBuilder << "RicNewWellLogCurveExtractionFeature";
menuBuilder << "RicNewWellPathIntersectionFeature";
menuBuilder.subMenuEnd();
menuBuilder.addSeparator();
menuBuilder << "RicAdd3dWellLogCurveFeature";
menuBuilder << "RicNewWellPathIntersectionFeature";
menuBuilder.addSeparator();
menuBuilder.subMenuStart("Completions", QIcon(":/FishBoneGroup16x16.png"));
menuBuilder << "RicNewWellPathFractureFeature";
menuBuilder << "RicNewFishbonesSubsFeature";

View File

@@ -68,14 +68,14 @@ public:
void setEclipseResultVariable(const QString& resVarname);
protected:
virtual QString createCurveAutoName();
virtual void onLoadDataAndUpdate(bool updateParentPlot);
virtual QString createCurveAutoName() override;
virtual void onLoadDataAndUpdate(bool updateParentPlot) override;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering);
virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "");
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly);
virtual void initAfterRead();
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
virtual void initAfterRead() override;
private:
void setLogScaleFromSelectedResult();

View File

@@ -29,6 +29,8 @@
#include "RigWellPath.h"
#include "Rim3dWellLogCurve.h"
#include "Rim3dWellLogCurveCollection.h"
#include "RimFishbonesMultipleSubs.h"
#include "RimMainPlotCollection.h"
#include "RimProject.h"
@@ -128,6 +130,10 @@ RimWellPath::RimWellPath()
CAF_PDM_InitFieldNoDefault(&m_wellLogFiles, "WellLogFiles", "Well Log Files", "", "", "");
m_wellLogFiles.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitFieldNoDefault(&m_3dWellLogCurves, "CollectionOf3dWellLogCurves", "3D Track", "", "", "");
m_3dWellLogCurves = new Rim3dWellLogCurveCollection;
m_3dWellLogCurves.uiCapability()->setUiTreeHidden(true);
CAF_PDM_InitField(&m_formationKeyInFile, "WellPathFormationKeyInFile", QString(""), "Key in File", "", "", "");
m_formationKeyInFile.uiCapability()->setUiReadOnly(true);
@@ -511,6 +517,11 @@ void RimWellPath::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, Q
uiTreeOrdering.add(&m_completions);
}
if (m_3dWellLogCurves->has3dWellLogCurves())
{
uiTreeOrdering.add(&m_3dWellLogCurves);
}
uiTreeOrdering.skipRemainingChildren(true);
}
@@ -790,6 +801,14 @@ const RigWellPathFormations* RimWellPath::formationsGeometry() const
return m_wellPathFormations.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPath::add3dWellLogCurve(Rim3dWellLogCurve* rim3dWellLogCurve)
{
m_3dWellLogCurves->add3dWellLogCurve(rim3dWellLogCurve);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -41,6 +41,7 @@ class RifWellPathFormationsImporter;
class RigWellPath;
class RimProject;
class RimWellLogFile;
class RimFractureTemplateCollection;
class RimFishboneWellPathCollection;
class RimFishbonesCollection;
@@ -49,6 +50,8 @@ class RimWellPathCompletions;
class RigWellPathFormations;
class RimWellPathFractureCollection;
class Rim3dWellLogCurveCollection;
class Rim3dWellLogCurve;
//==================================================================================================
///
@@ -75,6 +78,8 @@ public:
bool hasFormations() const;
const RigWellPathFormations* formationsGeometry() const;
void add3dWellLogCurve(Rim3dWellLogCurve* rim3dWellLogCurve);
virtual caf::PdmFieldHandle* userDescriptionField() override;
virtual caf::PdmFieldHandle* objectToggleField() override;
@@ -171,6 +176,8 @@ private:
caf::PdmField<QString> m_formationKeyInFile;
caf::PdmChildArrayField<RimWellLogFile*> m_wellLogFiles;
caf::PdmChildField<Rim3dWellLogCurveCollection*> m_3dWellLogCurves;
caf::PdmChildField<RimWellLogFile*> m_wellLogFile_OBSOLETE;
};

View File

@@ -455,6 +455,43 @@ double RigCellGeometryTools::getLengthOfPolygonAlongLine(const std::pair<cvf::Ve
return length;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigCellGeometryTools::unionOfPolygons(std::vector<std::vector<cvf::Vec3d>> polygons)
{
// Convert to int for clipper library and store as clipper "path"
std::vector<ClipperLib::Path> polygonPaths;
for (const std::vector<cvf::Vec3d>& polygon : polygons)
{
polygonPaths.emplace_back();
auto& p = polygonPaths.back();
for (const cvf::Vec3d& pp : polygon)
{
p.push_back(toClipperPoint(pp));
}
}
ClipperLib::Clipper clpr;
clpr.AddPaths(polygonPaths, ClipperLib::ptSubject, true);
ClipperLib::Paths solution;
clpr.Execute(ClipperLib::ctUnion, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
// Convert back to std::vector<std::vector<cvf::Vec3d> >
std::vector<cvf::Vec3d> unionPolygon;
for (ClipperLib::Path pathInSol : solution)
{
std::vector<cvf::Vec3d> clippedPolygon;
for (ClipperLib::IntPoint IntPosition : pathInSol)
{
unionPolygon.push_back(fromClipperPoint(IntPosition));
}
}
return unionPolygon;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -51,6 +51,8 @@ public:
static double getLengthOfPolygonAlongLine(const std::pair<cvf::Vec3d, cvf::Vec3d>& line, const std::vector<cvf::Vec3d>& polygon);
static std::vector<cvf::Vec3d> unionOfPolygons(std::vector<std::vector<cvf::Vec3d>> polygons);
private:
static std::vector<cvf::Vec3d> ajustPolygonToAvoidIntersectionsAtVertex(const std::vector<cvf::Vec3d>& polyLine,
const std::vector<cvf::Vec3d>& polygon);

View File

@@ -31,7 +31,6 @@
#include <cmath>
//--------------------------------------------------------------------------------------------------
/// Internal functions
//--------------------------------------------------------------------------------------------------
@@ -408,13 +407,13 @@ cvf::ref<RigFractureGrid> RigStimPlanFractureDefinition::createFractureGrid(cons
RiaLogging::error("Did not find stim plan cell at well crossing!");
}
cvf::ref<RigFractureGrid> m_fractureGrid = new RigFractureGrid;
m_fractureGrid->setFractureCells(stimPlanCells);
m_fractureGrid->setWellCenterFractureCellIJ(wellCenterStimPlanCellIJ);
m_fractureGrid->setICellCount(this->m_Xs.size() - 2);
m_fractureGrid->setJCellCount(this->adjustedYCoordsAroundWellPathPosition(wellPathIntersectionAtFractureDepth).size() - 2);
cvf::ref<RigFractureGrid> fractureGrid = new RigFractureGrid;
fractureGrid->setFractureCells(stimPlanCells);
fractureGrid->setWellCenterFractureCellIJ(wellCenterStimPlanCellIJ);
fractureGrid->setICellCount(this->m_Xs.size() - 2);
fractureGrid->setJCellCount(this->adjustedYCoordsAroundWellPathPosition(wellPathIntersectionAtFractureDepth).size() - 2);
return m_fractureGrid;
return fractureGrid;
}
//--------------------------------------------------------------------------------------------------
@@ -526,68 +525,6 @@ void sortPolygon(std::vector<cvf::Vec3f> &polygon)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3f> RigStimPlanFractureDefinition::createFractureBorderPolygon(const QString& resultName,
const QString& resultUnit,
int activeTimeStepIndex,
double wellPathIntersectionAtFractureDepth,
const QString& fractureUserName)
{
std::vector<cvf::Vec3f> polygon;
std::vector<std::vector<double>> dataAtTimeStep = this->getDataAtTimeIndex(resultName, resultUnit, activeTimeStepIndex);
std::vector<double> adjustedYs = this->adjustedYCoordsAroundWellPathPosition(wellPathIntersectionAtFractureDepth);
for ( int k = 0; k < static_cast<int>(dataAtTimeStep.size()); k++ )
{
for ( int i = 0; i < static_cast<int>(dataAtTimeStep[k].size()); i++ )
{
if ( (dataAtTimeStep[k])[i] < 1e-7 ) //polygon should consist of nodes with value 0
{
if ( (i > 0) && ((dataAtTimeStep[k])[(i - 1)] > 1e-7) ) //side neighbour cell different from 0
{
polygon.push_back(cvf::Vec3f(static_cast<float>(this->m_Xs[i]),
static_cast<float>(adjustedYs[k]), 0.0f));
}
else if ( (k < static_cast<int>(dataAtTimeStep.size()) - 1) && ((dataAtTimeStep[k + 1])[(i)] > 1e-7) )//cell below different from 0
{
polygon.push_back(cvf::Vec3f(static_cast<float>(this->m_Xs[i]),
static_cast<float>(adjustedYs[k]), 0.0f));
}
else if ( (k > 0) && ((dataAtTimeStep[k - 1])[(i)] > 1e-7) )//cell above different from 0
{
polygon.push_back(cvf::Vec3f(static_cast<float>(this->m_Xs[i]),
static_cast<float>(adjustedYs[k]), 0.0f));
}
}
}
}
sortPolygon(polygon);
std::vector<cvf::Vec3f> negPolygon;
for ( const cvf::Vec3f& node : polygon )
{
cvf::Vec3f negNode = node;
negNode.x() = -negNode.x();
negPolygon.insert(negPolygon.begin(), negNode);
}
for ( const cvf::Vec3f& negNode : negPolygon )
{
polygon.push_back(negNode);
}
//Adding first point last - to close the polygon
if ( polygon.size()>0 ) polygon.push_back(polygon[0]);
return polygon;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -81,12 +81,6 @@ public:
std::vector<cvf::Vec3f>* vertices,
std::vector<cvf::uint>* triangleIndices);
std::vector<cvf::Vec3f> createFractureBorderPolygon(const QString& resultName,
const QString& resultUnit,
int activeTimeStepIndex,
double wellPathIntersectionAtFractureDepth,
const QString& fractureUserName);
const std::vector<double>& timeSteps() const;
void addTimeStep(double time);
size_t totalNumberTimeSteps();

View File

@@ -38,7 +38,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaProjectFileVersionTools-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RifElementPropertyTableReader-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RimRelocatePath-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RigTransmissibilityCondenser-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaEclipseUnitTools-Test
${CMAKE_CURRENT_LIST_DIR}/RiaEclipseUnitTools-Test.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare-Test.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@@ -0,0 +1,68 @@
#include "gtest/gtest.h"
#include "RiaRegressionTest.h"
#include "RiaTestDataDirectory.h"
#include "RiaTextFileCompare.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RiaTextFileCompareTest, BasicCompareWithDiff)
{
RiaRegressionTest regTestConfig;
regTestConfig.readSettingsFromApplicationStore();
QString folderContainingDiff = regTestConfig.folderContainingDiffTool();
QString baseFolder = QString("%1/TextCompare/base").arg(TEST_DATA_DIR);
QString referenceFolder = QString("%1/TextCompare/reference").arg(TEST_DATA_DIR);
RiaTextFileCompare compare(folderContainingDiff);
bool noDifference = compare.runComparison(baseFolder, referenceFolder);
EXPECT_FALSE(noDifference);
QString diffOutput = compare.diffOutput();
EXPECT_FALSE(diffOutput.isEmpty());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RiaTextFileCompareTest, BasicCompareNoDiff)
{
RiaRegressionTest regTestConfig;
regTestConfig.readSettingsFromApplicationStore();
QString folderContainingDiff = regTestConfig.folderContainingDiffTool();
QString baseFolder = QString("%1/TextCompare/base/folderB").arg(TEST_DATA_DIR);
QString referenceFolder = QString("%1/TextCompare/reference/folderB").arg(TEST_DATA_DIR);
RiaTextFileCompare compare(folderContainingDiff);
bool noDifference = compare.runComparison(baseFolder, referenceFolder);
EXPECT_TRUE(noDifference);
QString diffOutput = compare.diffOutput();
EXPECT_TRUE(diffOutput.isEmpty());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(RiaTextFileCompareTest, BasicCompareError)
{
RiaRegressionTest regTestConfig;
regTestConfig.readSettingsFromApplicationStore();
QString folderContainingDiff = regTestConfig.folderContainingDiffTool();
QString baseFolder = QString("%1/TextCompare/baseDoesNotExist").arg(TEST_DATA_DIR);
QString referenceFolder = QString("%1/TextCompare/reference/folderB").arg(TEST_DATA_DIR);
RiaTextFileCompare compare(folderContainingDiff);
bool noDifference = compare.runComparison(baseFolder, referenceFolder);
EXPECT_FALSE(noDifference);
QString error = compare.errorMessage();
EXPECT_FALSE(error.isEmpty());
}

View File

@@ -0,0 +1,12 @@
some text
some more text
some more text
some more text some more text some more text
some more text
some more text
some more text
some more text

View File

@@ -0,0 +1,12 @@
some text
some more text
some more text
some more text some more text some more text
some more text
some more text
some more text
some more text

View File

@@ -0,0 +1,12 @@
some text
some more text
some more text somthing has changed
some more text some more text some more text
some more text
some more text
some more text
some more text

View File

@@ -0,0 +1,12 @@
some text
some more text
some more text
some more text some more text some more text
some more text
some more text
some more text
some more text

View File

@@ -24,6 +24,7 @@
#include "RiaBaseDefs.h"
#include "RiaPreferences.h"
#include "RiaRegressionTest.h"
#include "RiaRegressionTestRunner.h"
#include "Rim3dView.h"
#include "RimCellEdgeColors.h"
@@ -1716,9 +1717,7 @@ void RiuMainWindow::slotCreateCommandObject()
void RiuMainWindow::slotShowRegressionTestDialog()
{
RiaRegressionTest regTestConfig;
RiaApplication* app = RiaApplication::instance();
caf::PdmSettings::readFieldsFromApplicationStore(&regTestConfig);
regTestConfig.readSettingsFromApplicationStore();
caf::PdmUiPropertyViewDialog regressionTestDialog(this, &regTestConfig, "Regression Test", "");
regressionTestDialog.resize(QSize(600, 300));
@@ -1726,17 +1725,9 @@ void RiuMainWindow::slotShowRegressionTestDialog()
if (regressionTestDialog.exec() == QDialog::Accepted)
{
// Write preferences using QSettings and apply them to the application
caf::PdmSettings::writeFieldsToApplicationStore(&regTestConfig);
regTestConfig.writeSettingsToApplicationStore();
QString currentApplicationPath = QDir::currentPath();
QDir::setCurrent(regTestConfig.applicationWorkingFolder);
QStringList testFilter = regTestConfig.testFilter().split(";", QString::SkipEmptyParts);
app->executeRegressionTests(regTestConfig.regressionTestFolder, &testFilter);
QDir::setCurrent(currentApplicationPath);
RiaRegressionTestRunner::instance()->executeRegressionTests();
}
}

View File

@@ -23,6 +23,7 @@
#include "RiaApplication.h"
#include "RiaBaseDefs.h"
#include "RiaColorTools.h"
#include "RiaRegressionTestRunner.h"
#include "RimCase.h"
#include "RimProject.h"
@@ -157,7 +158,7 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent)
m_viewerCommands = new RiuViewerCommands(this);
if (RiaApplication::instance()->isRunningRegressionTests())
if (RiaRegressionTestRunner::instance()->isRunningRegressionTests())
{
QFont regTestFont = m_infoLabel->font();
regTestFont.setPixelSize(11);

View File

@@ -355,6 +355,10 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event)
menuBuilder.addSeparator();
menuBuilder << "RicAdd3dWellLogCurveFeature";
menuBuilder.addSeparator();
menuBuilder.subMenuStart("Completions", QIcon(":/FishBoneGroup16x16.png"));
menuBuilder << "RicNewWellPathFractureAtPosFeature";

View File

@@ -94,7 +94,7 @@ void PdmSettings::readFieldsFromApplicationStore(caf::PdmObjectHandle* object, c
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmSettings::writeFieldsToApplicationStore(caf::PdmObjectHandle* object, const QString context)
void PdmSettings::writeFieldsToApplicationStore(const caf::PdmObjectHandle* object, const QString context)
{
CAF_ASSERT(object);

View File

@@ -48,7 +48,7 @@ class PdmSettings
{
public:
static void readFieldsFromApplicationStore(caf::PdmObjectHandle* object, const QString context = "");
static void writeFieldsToApplicationStore(caf::PdmObjectHandle* object, const QString context = "");
static void writeFieldsToApplicationStore(const caf::PdmObjectHandle* object, const QString context = "");
};

View File

@@ -3,7 +3,7 @@
Title Classes related to fractures
note as N1
Updated 2018-02-07
Updated 2018-03-07
end note
class RimFracture {
@@ -19,6 +19,10 @@ class RimWellPathFracture {
RimFracture <|-- RimSimWellFracture
RimFracture <|-- RimWellPathFracture
RimFracture -> RimStimPlanFractureTemplate
RimFracture -> RivWellFracturePartMgr
RivWellFracturePartMgr ->RimFracture
class RimFractureTemplate {
RimDefines::UnitSystemType fractureTemplateUnit;