diff --git a/ApplicationCode/Adm/RIBaseDefs.h b/ApplicationCode/Adm/RiaBaseDefs.h similarity index 100% rename from ApplicationCode/Adm/RIBaseDefs.h rename to ApplicationCode/Adm/RiaBaseDefs.h diff --git a/ApplicationCode/Adm/RIVersionInfo.h.cmake b/ApplicationCode/Adm/RiaVersionInfo.h.cmake similarity index 100% rename from ApplicationCode/Adm/RIVersionInfo.h.cmake rename to ApplicationCode/Adm/RiaVersionInfo.h.cmake diff --git a/ApplicationCode/Application/RIApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp similarity index 80% rename from ApplicationCode/Application/RIApplication.cpp rename to ApplicationCode/Application/RiaApplication.cpp index 4222dfd27e..c534ebc91d 100644 --- a/ApplicationCode/Application/RIApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafLog.h" #include "cafEffectCache.h" @@ -26,20 +26,20 @@ #include "cvfStructGridGeometryGenerator.h" -#include "RIVersionInfo.h" -#include "RIBaseDefs.h" +#include "RiaVersionInfo.h" +#include "RiaBaseDefs.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RIViewer.h" -#include "RIProcessMonitor.h" -#include "RIPreferences.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RiuViewer.h" +#include "RiuProcessMonitor.h" +#include "RiaPreferences.h" -#include "RimResultReservoir.h" -#include "RimInputReservoir.h" +#include "RimResultCase.h" +#include "RimInputCase.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigCell.h" #include "RigReservoirBuilderMock.h" @@ -55,15 +55,16 @@ #include "RimUiTreeModelPdm.h" #include "RiaImageCompareReporter.h" #include "RiaImageFileCompare.h" +#include "cafProgressInfo.h" namespace caf { template<> -void AppEnum< RIApplication::RINavigationPolicy >::setUp() +void AppEnum< RiaApplication::RINavigationPolicy >::setUp() { - addItem(RIApplication::NAVIGATION_POLICY_CEETRON, "NAVIGATION_POLICY_CEETRON", "Ceetron"); - addItem(RIApplication::NAVIGATION_POLICY_CAD, "NAVIGATION_POLICY_CAD", "CAD"); - setDefault(RIApplication::NAVIGATION_POLICY_CAD); + addItem(RiaApplication::NAVIGATION_POLICY_CEETRON, "NAVIGATION_POLICY_CEETRON", "Ceetron"); + addItem(RiaApplication::NAVIGATION_POLICY_CAD, "NAVIGATION_POLICY_CAD", "CAD"); + setDefault(RiaApplication::NAVIGATION_POLICY_CAD); } } @@ -82,7 +83,7 @@ namespace RegTestNames //================================================================================================== /// -/// \class RIApplication +/// \class RiaApplication /// /// Application class /// @@ -92,7 +93,7 @@ namespace RegTestNames //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::RIApplication(int& argc, char** argv) +RiaApplication::RiaApplication(int& argc, char** argv) : QApplication(argc, argv) { // USed to get registry settings in the right place @@ -105,7 +106,7 @@ RIApplication::RIApplication(int& argc, char** argv) //cvf::Trace::enable(false); - m_preferences = new RIPreferences; + m_preferences = new RiaPreferences; readPreferences(); applyPreferences(); @@ -132,14 +133,14 @@ RIApplication::RIApplication(int& argc, char** argv) #ifdef WIN32 //m_startupDefaultDirectory += "/My Documents/"; #endif - + setDefaultFileDialogDirectory("MULTICASEIMPORT", "/"); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::~RIApplication() +RiaApplication::~RiaApplication() { delete m_preferences; } @@ -148,18 +149,18 @@ RIApplication::~RIApplication() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication* RIApplication::instance() +RiaApplication* RiaApplication::instance() { - return static_castqApp; + return static_castqApp; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setWindowCaptionFromAppState() +void RiaApplication::setWindowCaptionFromAppState() { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; // The stuff being done here should really be handled by Qt automatically as a result of @@ -185,7 +186,7 @@ void RIApplication::setWindowCaptionFromAppState() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::processNonGuiEvents() +void RiaApplication::processNonGuiEvents() { processEvents(QEventLoop::ExcludeUserInputEvents); } @@ -194,7 +195,7 @@ void RIApplication::processNonGuiEvents() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const char* RIApplication::getVersionStringApp(bool includeCrtInfo) +const char* RiaApplication::getVersionStringApp(bool includeCrtInfo) { // Use static buf so we can return ptr static char szBuf[1024]; @@ -220,16 +221,23 @@ const char* RIApplication::getVersionStringApp(bool includeCrtInfo) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::loadProject(const QString& projectFileName) +bool RiaApplication::loadProject(const QString& projectFileName) { + // First Close the current project + if (!closeProject(true)) return false; + // Open the project file and read the serialized data. + // Will initialize itself. + if (!QFile::exists(projectFileName)) return false; m_project->fileName = projectFileName; m_project->readFile(); m_project->fileName = projectFileName; // Make sure we overwrite the old filename read from the project file + // On error, delete everything, and bail out. + if (m_project->projectFileVersionString().isEmpty()) { closeProject(false); @@ -237,37 +245,84 @@ bool RIApplication::loadProject(const QString& projectFileName) QString tmp = QString("Unknown project file version detected in file \n%1\n\nCould not open project.").arg(projectFileName); QMessageBox::warning(NULL, "Error when opening project file", tmp); - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); mainWnd->setPdmRoot(NULL); // Delete all object possibly generated by readFile() delete m_project; m_project = new RimProject; + + onProjectOpenedOrClosed(); + + return true; } - else + + /////// + // Load the external data, and initialize stuff that needs specific ordering + + m_preferences->lastUsedProjectFileName = projectFileName; + writePreferences(); + + for (size_t cgIdx = 0; cgIdx < m_project->caseGroups.size(); ++cgIdx) { - m_preferences->lastUsedProjectFileName = projectFileName; - writePreferences(); + // Load the Main case of each IdenticalGridCaseGroup - size_t i; - for (i = 0; i < m_project->reservoirs().size(); ++i) + RimIdenticalGridCaseGroup* igcg = m_project->caseGroups[cgIdx]; + igcg->loadMainCaseAndActiveCellInfo(); + } + + // Now load the ReservoirViews for the cases + + std::vector casesToLoad; + + // Add all "native" cases in the project + for (size_t cIdx = 0; cIdx < m_project->reservoirs().size(); ++cIdx) + { + casesToLoad.push_back(m_project->reservoirs()[cIdx]); + } + + // Add all statistics cases as well + for (size_t cgIdx = 0; cgIdx < m_project->caseGroups().size(); ++cgIdx) + { + if (m_project->caseGroups[cgIdx]->statisticsCaseCollection()) { - RimReservoir* ri = m_project->reservoirs()[i]; - CVF_ASSERT(ri); - - size_t j; - for (j = 0; j < ri->reservoirViews().size(); j++) + caf::PdmPointersField & statCases = m_project->caseGroups[cgIdx]->statisticsCaseCollection()->reservoirs(); + for (size_t scIdx = 0; scIdx < statCases.size(); ++scIdx) { - RimReservoirView* riv = ri->reservoirViews()[j]; - CVF_ASSERT(riv); - - riv->loadDataAndUpdate(); + casesToLoad.push_back(statCases[scIdx]); } } } + caf::ProgressInfo caseProgress(casesToLoad.size() , "Reading Cases"); + + for (size_t cIdx = 0; cIdx < casesToLoad.size(); ++cIdx) + { + RimCase* ri = casesToLoad[cIdx]; + CVF_ASSERT(ri); + + caseProgress.setProgressDescription(ri->caseName()); + + caf::ProgressInfo viewProgress(ri->reservoirViews().size() , "Creating Views"); + + size_t j; + for (j = 0; j < ri->reservoirViews().size(); j++) + { + RimReservoirView* riv = ri->reservoirViews[j]; + CVF_ASSERT(riv); + + viewProgress.setProgressDescription(riv->name()); + + riv->loadDataAndUpdate(); + + viewProgress.incrementProgress(); + } + + caseProgress.incrementProgress(); + } + onProjectOpenedOrClosed(); - + return true; } @@ -275,7 +330,7 @@ bool RIApplication::loadProject(const QString& projectFileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::loadLastUsedProject() +bool RiaApplication::loadLastUsedProject() { return loadProject(m_preferences->lastUsedProjectFileName); } @@ -284,7 +339,7 @@ bool RIApplication::loadLastUsedProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProject() +bool RiaApplication::saveProject() { CVF_ASSERT(m_project.notNull()); @@ -302,11 +357,11 @@ bool RIApplication::saveProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProjectPromptForFileName() +bool RiaApplication::saveProjectPromptForFileName() { //if (m_project.isNull()) return true; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString startPath; if (!m_project->fileName().isEmpty()) @@ -341,7 +396,7 @@ bool RIApplication::saveProjectPromptForFileName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::saveProjectAs(const QString& fileName) +bool RiaApplication::saveProjectAs(const QString& fileName) { m_project->fileName = fileName; m_project->writeFile(); @@ -356,9 +411,9 @@ bool RIApplication::saveProjectAs(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::closeProject(bool askToSaveIfDirty) +bool RiaApplication::closeProject(bool askToSaveIfDirty) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); terminateProcess(); @@ -396,9 +451,9 @@ bool RIApplication::closeProject(bool askToSaveIfDirty) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::onProjectOpenedOrClosed() +void RiaApplication::onProjectOpenedOrClosed() { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; mainWnd->initializeGuiNewProjectLoaded(); @@ -411,7 +466,7 @@ void RIApplication::onProjectOpenedOrClosed() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::currentProjectFileName() const +QString RiaApplication::currentProjectFileName() const { return m_project->fileName(); } @@ -420,7 +475,7 @@ QString RIApplication::currentProjectFileName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openEclipseCaseFromFile(const QString& fileName) +bool RiaApplication::openEclipseCaseFromFile(const QString& fileName) { if (!QFile::exists(fileName)) return false; @@ -434,12 +489,12 @@ bool RIApplication::openEclipseCaseFromFile(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openEclipseCase(const QString& caseName, const QString& caseFileName) +bool RiaApplication::openEclipseCase(const QString& caseName, const QString& caseFileName) { QFileInfo gridFileName(caseFileName); QString casePath = gridFileName.absolutePath(); - RimResultReservoir* rimResultReservoir = new RimResultReservoir(); + RimResultCase* rimResultReservoir = new RimResultCase(); rimResultReservoir->caseName = caseName; rimResultReservoir->caseFileName = caseFileName; rimResultReservoir->caseDirectory = casePath; @@ -472,9 +527,9 @@ bool RIApplication::openEclipseCase(const QString& caseName, const QString& case //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames) +bool RiaApplication::openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames) { - RimInputReservoir* rimInputReservoir = new RimInputReservoir(); + RimInputCase* rimInputReservoir = new RimInputCase(); rimInputReservoir->caseName = caseName; rimInputReservoir->openDataFileSet(caseFileNames); @@ -502,7 +557,7 @@ bool RIApplication::openInputEclipseCase(const QString& caseName, const QStringL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createMockModel() +void RiaApplication::createMockModel() { openEclipseCase("Result Mock Debug Model Simple", "Result Mock Debug Model Simple"); } @@ -510,7 +565,7 @@ void RIApplication::createMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createResultsMockModel() +void RiaApplication::createResultsMockModel() { openEclipseCase("Result Mock Debug Model With Results", "Result Mock Debug Model With Results"); } @@ -519,7 +574,7 @@ void RIApplication::createResultsMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createLargeResultsMockModel() +void RiaApplication::createLargeResultsMockModel() { openEclipseCase("Result Mock Debug Model Large With Results", "Result Mock Debug Model Large With Results"); } @@ -527,7 +582,7 @@ void RIApplication::createLargeResultsMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::createInputMockModel() +void RiaApplication::createInputMockModel() { openInputEclipseCase("Input Mock Debug Model Simple", QStringList("Input Mock Debug Model Simple")); } @@ -535,7 +590,7 @@ void RIApplication::createInputMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RimReservoirView* RIApplication::activeReservoirView() const +const RimReservoirView* RiaApplication::activeReservoirView() const { return m_activeReservoirView; } @@ -543,7 +598,7 @@ const RimReservoirView* RIApplication::activeReservoirView() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimReservoirView* RIApplication::activeReservoirView() +RimReservoirView* RiaApplication::activeReservoirView() { return m_activeReservoirView; } @@ -551,7 +606,7 @@ RimReservoirView* RIApplication::activeReservoirView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setActiveReservoirView(RimReservoirView* rv) +void RiaApplication::setActiveReservoirView(RimReservoirView* rv) { m_activeReservoirView = rv; } @@ -559,7 +614,7 @@ void RIApplication::setActiveReservoirView(RimReservoirView* rv) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setUseShaders(bool enable) +void RiaApplication::setUseShaders(bool enable) { m_preferences->useShaders = enable; writePreferences(); @@ -568,7 +623,7 @@ void RIApplication::setUseShaders(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::useShaders() const +bool RiaApplication::useShaders() const { if (!m_preferences->useShaders) return false; @@ -582,7 +637,7 @@ bool RIApplication::useShaders() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIApplication::RINavigationPolicy RIApplication::navigationPolicy() const +RiaApplication::RINavigationPolicy RiaApplication::navigationPolicy() const { return m_preferences->navigationPolicy(); } @@ -591,7 +646,7 @@ RIApplication::RINavigationPolicy RIApplication::navigationPolicy() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setShowPerformanceInfo(bool enable) +void RiaApplication::setShowPerformanceInfo(bool enable) { m_preferences->showHud = enable; writePreferences(); @@ -601,7 +656,7 @@ void RIApplication::setShowPerformanceInfo(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::showPerformanceInfo() const +bool RiaApplication::showPerformanceInfo() const { return m_preferences->showHud; } @@ -610,7 +665,7 @@ bool RIApplication::showPerformanceInfo() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::parseArguments() +bool RiaApplication::parseArguments() { QStringList arguments = QCoreApplication::arguments(); @@ -765,7 +820,7 @@ bool RIApplication::parseArguments() if (isRunRegressionTest) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (mainWnd) { mainWnd->hideAllDockWindows(); @@ -830,7 +885,7 @@ bool RIApplication::parseArguments() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::scriptDirectory() const +QString RiaApplication::scriptDirectory() const { return m_preferences->scriptDirectory(); } @@ -838,7 +893,7 @@ QString RIApplication::scriptDirectory() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::scriptEditorPath() const +QString RiaApplication::scriptEditorPath() const { return m_preferences->scriptEditorExecutable(); } @@ -846,7 +901,7 @@ QString RIApplication::scriptEditorPath() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::octavePath() const +QString RiaApplication::octavePath() const { return m_preferences->octaveExecutable(); } @@ -854,9 +909,9 @@ QString RIApplication::octavePath() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +void RiaApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { - RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); + RiuMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); // Execute delete later so that other slots that are hooked up // get a chance to run before we delete the object @@ -888,14 +943,14 @@ void RIApplication::slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIApplication::launchProcess(const QString& program, const QStringList& arguments) +bool RiaApplication::launchProcess(const QString& program, const QStringList& arguments) { if (m_workerProcess == NULL) { m_workerProcess = new caf::UiProcess(this); connect(m_workerProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(slotWorkerProcessFinished(int, QProcess::ExitStatus))); - RIMainWindow::instance()->processMonitor()->startMonitorWorkProcess(m_workerProcess); + RiuMainWindow::instance()->processMonitor()->startMonitorWorkProcess(m_workerProcess); m_workerProcess->start(program, arguments); if (!m_workerProcess->waitForStarted(1000)) @@ -903,9 +958,9 @@ bool RIApplication::launchProcess(const QString& program, const QStringList& arg m_workerProcess->close(); m_workerProcess = NULL; - RIMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); + RiuMainWindow::instance()->processMonitor()->stopMonitorWorkProcess(); - QMessageBox::warning(RIMainWindow::instance(), "Script execution", "Failed to start script executable located at\n" + program); + QMessageBox::warning(RiuMainWindow::instance(), "Script execution", "Failed to start script executable located at\n" + program); return false; } @@ -922,7 +977,7 @@ bool RIApplication::launchProcess(const QString& program, const QStringList& arg //-------------------------------------------------------------------------------------------------- /// Read fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RIApplication::readPreferences() +void RiaApplication::readPreferences() { QSettings settings; std::vector fields; @@ -944,7 +999,7 @@ void RIApplication::readPreferences() //-------------------------------------------------------------------------------------------------- /// Write fields of a Pdm object using QSettings //-------------------------------------------------------------------------------------------------- -void RIApplication::writePreferences() +void RiaApplication::writePreferences() { QSettings settings; @@ -963,7 +1018,7 @@ void RIApplication::writePreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences* RIApplication::preferences() +RiaPreferences* RiaApplication::preferences() { return m_preferences; } @@ -971,7 +1026,7 @@ RIPreferences* RIApplication::preferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::applyPreferences() +void RiaApplication::applyPreferences() { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -999,7 +1054,7 @@ void RIApplication::applyPreferences() if (this->project()) { this->project()->setUserScriptPath(m_preferences->scriptDirectory()); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); if (treeModel) treeModel->rebuildUiSubTree(this->project()->scriptCollection()); } @@ -1008,7 +1063,7 @@ void RIApplication::applyPreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::terminateProcess() +void RiaApplication::terminateProcess() { if (m_workerProcess) { @@ -1021,7 +1076,7 @@ void RIApplication::terminateProcess() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RIApplication::defaultFileDialogDirectory(const QString& dialogName) +QString RiaApplication::defaultFileDialogDirectory(const QString& dialogName) { QString defaultDirectory = m_startupDefaultDirectory; std::map::iterator it; @@ -1038,7 +1093,7 @@ QString RIApplication::defaultFileDialogDirectory(const QString& dialogName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::setDefaultFileDialogDirectory(const QString& dialogName, const QString& defaultDirectory) +void RiaApplication::setDefaultFileDialogDirectory(const QString& dialogName, const QString& defaultDirectory) { m_fileDialogDefaultDirectories[dialogName] = defaultDirectory; } @@ -1046,7 +1101,7 @@ void RIApplication::setDefaultFileDialogDirectory(const QString& dialogName, con //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotPromtpForFilename() +void RiaApplication::saveSnapshotPromtpForFilename() { QString startPath; if (!m_project->fileName().isEmpty()) @@ -1076,7 +1131,7 @@ void RIApplication::saveSnapshotPromtpForFilename() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotAs(const QString& fileName) +void RiaApplication::saveSnapshotAs(const QString& fileName) { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -1095,7 +1150,7 @@ void RIApplication::saveSnapshotAs(const QString& fileName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::copySnapshotToClipboard() +void RiaApplication::copySnapshotToClipboard() { if (m_activeReservoirView && m_activeReservoirView->viewer()) { @@ -1112,9 +1167,9 @@ void RIApplication::copySnapshotToClipboard() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) +void RiaApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) { - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; if (m_project.isNull()) return; @@ -1134,7 +1189,7 @@ void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) for (size_t i = 0; i < m_project->reservoirs().size(); ++i) { - RimReservoir* ri = m_project->reservoirs()[i]; + RimCase* ri = m_project->reservoirs()[i]; if (!ri) continue; for (size_t j = 0; j < ri->reservoirViews().size(); j++) @@ -1145,7 +1200,7 @@ void RIApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) { setActiveReservoirView(riv); - RIViewer* viewer = riv->viewer(); + RiuViewer* viewer = riv->viewer(); mainWnd->setActiveViewer(viewer); // Process all events to avoid a black image when grabbing frame buffer @@ -1174,7 +1229,7 @@ void removeDirectoryWithContent(QDir dirToDelete ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::runRegressionTest(const QString& testRootPath) +void RiaApplication::runRegressionTest(const QString& testRootPath) { QString generatedFolderName = RegTestNames::generatedFolderName; QString diffFolderName = RegTestNames::diffFolderName; @@ -1253,6 +1308,8 @@ void RIApplication::runRegressionTest(const QString& testRootPath) qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails(); } } + + closeProject(false); } } } @@ -1260,7 +1317,7 @@ void RIApplication::runRegressionTest(const QString& testRootPath) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIApplication::updateRegressionTest(const QString& testRootPath) +void RiaApplication::updateRegressionTest(const QString& testRootPath) { // Find all sub folders @@ -1291,3 +1348,72 @@ void RIApplication::updateRegressionTest(const QString& testRootPath) } } } + +//-------------------------------------------------------------------------------------------------- +/// Make sure changes in this functions is validated to RimIdenticalGridCaseGroup::initAfterRead() +//-------------------------------------------------------------------------------------------------- +bool RiaApplication::addEclipseCases(const QStringList& fileNames) +{ + if (fileNames.size() == 0) return true; + + + // First file is read completely including grid. + // The main grid from the first case is reused directly in for the other cases. + // When reading active cell info, only the total cell count is tested for consistency + RigCaseData* mainEclipseCase = NULL; + + { + QString firstFileName = fileNames[0]; + QFileInfo gridFileName(firstFileName); + + QString caseName = gridFileName.completeBaseName(); + QString casePath = gridFileName.absolutePath(); + + RimResultCase* rimResultReservoir = new RimResultCase(); + rimResultReservoir->caseName = caseName; + rimResultReservoir->caseFileName = firstFileName; + rimResultReservoir->caseDirectory = casePath; + + m_project->reservoirs.push_back(rimResultReservoir); + + if (!rimResultReservoir->openEclipseGridFile()) + { + return false; + } + + m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir); + + mainEclipseCase = rimResultReservoir->reservoirData(); + } + + caf::ProgressInfo info(fileNames.size(), "Reading Active Cell data"); + + for (int i = 1; i < fileNames.size(); i++) + { + QString fileName = fileNames[i]; + QFileInfo gridFileName(fileName); + + QString caseName = gridFileName.completeBaseName(); + QString casePath = gridFileName.absolutePath(); + + RimResultCase* rimResultReservoir = new RimResultCase(); + rimResultReservoir->caseName = caseName; + rimResultReservoir->caseFileName = fileName; + rimResultReservoir->caseDirectory = casePath; + + m_project->reservoirs.push_back(rimResultReservoir); + + if (!rimResultReservoir->openAndReadActiveCellData(mainEclipseCase)) + { + return false; + } + + m_project->moveEclipseCaseIntoCaseGroup(rimResultReservoir); + + info.setProgress(i); + } + + onProjectOpenedOrClosed(); + + return true; +} diff --git a/ApplicationCode/Application/RIApplication.h b/ApplicationCode/Application/RiaApplication.h similarity index 92% rename from ApplicationCode/Application/RIApplication.h rename to ApplicationCode/Application/RiaApplication.h index f8f7d65eea..00b984a186 100644 --- a/ApplicationCode/Application/RIApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -30,11 +30,11 @@ #include "RimProject.h" class RIProcess; -class RigReservoir; -class RimReservoir; +class RigCaseData; +class RimCase; class Drawable; class RiaSocketServer; -class RIPreferences; +class RiaPreferences; namespace caf { @@ -46,7 +46,7 @@ namespace caf // // //================================================================================================== -class RIApplication : public QApplication +class RiaApplication : public QApplication { Q_OBJECT @@ -58,9 +58,9 @@ public: }; public: - RIApplication(int& argc, char** argv); - ~RIApplication(); - static RIApplication* instance(); + RiaApplication(int& argc, char** argv); + ~RiaApplication(); + static RiaApplication* instance(); bool parseArguments(); @@ -80,6 +80,7 @@ public: bool openEclipseCaseFromFile(const QString& fileName); bool openEclipseCase(const QString& caseName, const QString& caseFileName); + bool addEclipseCases(const QStringList& fileNames); bool openInputEclipseCase(const QString& caseName, const QStringList& caseFileNames); bool loadLastUsedProject(); @@ -115,7 +116,7 @@ public: bool launchProcess(const QString& program, const QStringList& arguments); void terminateProcess(); - RIPreferences* preferences(); + RiaPreferences* preferences(); void readPreferences(); void writePreferences(); void applyPreferences(); @@ -138,7 +139,7 @@ private: caf::UiProcess* m_workerProcess; - RIPreferences* m_preferences; + RiaPreferences* m_preferences; std::map m_fileDialogDefaultDirectories; QString m_startupDefaultDirectory; diff --git a/ApplicationCode/Application/RIPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp similarity index 88% rename from ApplicationCode/Application/RIPreferences.cpp rename to ApplicationCode/Application/RiaPreferences.cpp index 57aeee9a06..725e13a58c 100644 --- a/ApplicationCode/Application/RIPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -16,17 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIPreferences.h" +#include "RiaStdInclude.h" +#include "RiaPreferences.h" #include "cafPdmUiFilePathEditor.h" -CAF_PDM_SOURCE_INIT(RIPreferences, "RIPreferences"); +CAF_PDM_SOURCE_INIT(RiaPreferences, "RiaPreferences"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences::RIPreferences(void) +RiaPreferences::RiaPreferences(void) { - CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum(RIApplication::NAVIGATION_POLICY_CAD), "Navigation mode", "", "", ""); + CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum(RiaApplication::NAVIGATION_POLICY_CAD), "Navigation mode", "", "", ""); CAF_PDM_InitFieldNoDefault(&scriptDirectory, "scriptDirectory", "Shared Script Folder", "", "", ""); scriptDirectory.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); @@ -53,7 +53,7 @@ RIPreferences::RIPreferences(void) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferences::~RIPreferences(void) +RiaPreferences::~RiaPreferences(void) { } @@ -61,7 +61,7 @@ RIPreferences::~RIPreferences(void) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) { if (field == &scriptDirectory) { @@ -76,7 +76,7 @@ void RIPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QStr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const +void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const { uiOrdering.add(&navigationPolicy); diff --git a/ApplicationCode/Application/RIPreferences.h b/ApplicationCode/Application/RiaPreferences.h similarity index 87% rename from ApplicationCode/Application/RIPreferences.h rename to ApplicationCode/Application/RiaPreferences.h index a35ba41997..367c8ddbde 100644 --- a/ApplicationCode/Application/RIPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -19,18 +19,18 @@ #pragma once #include "cafPdmObject.h" -#include "RIApplication.h" +#include "RiaApplication.h" -class RIPreferences : public caf::PdmObject +class RiaPreferences : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - RIPreferences(void); - virtual ~RIPreferences(void); + RiaPreferences(void); + virtual ~RiaPreferences(void); public: // Pdm Fields - caf::PdmField > navigationPolicy; + caf::PdmField > navigationPolicy; caf::PdmField scriptDirectory; caf::PdmField scriptEditorExecutable; diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 7995ceb2e2..ded18b4cc5 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -4,8 +4,8 @@ project (ApplicationCode) # NB: The generated file is written to Cmake binary folder to avoid source tree pollution # This folder is added to include_directories -CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RIVersionInfo.h.cmake - ${CMAKE_BINARY_DIR}/Generated/RIVersionInfo.h +CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.h.cmake + ${CMAKE_BINARY_DIR}/Generated/RiaVersionInfo.h ) @@ -20,20 +20,21 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel ${CMAKE_CURRENT_SOURCE_DIR}/ReservoirDataModel ${CMAKE_BINARY_DIR}/Generated + ${CMAKE_CURRENT_BINARY_DIR} ) -# Use all cpp and h files in the subdirectories +# Use all h files in the subdirectories to make them available in the project file( GLOB_RECURSE HEADER_FILES *.h ) list( APPEND CPP_SOURCES - RIMain.cpp - RIStdInclude.cpp + RiaMain.cpp + RiaStdInclude.cpp ) list( APPEND CPP_SOURCES - Application/RIApplication.cpp - Application/RIPreferences.cpp + Application/RiaApplication.cpp + Application/RiaPreferences.cpp Application/RiaImageFileCompare.cpp Application/RiaImageCompareReporter.cpp ) @@ -49,22 +50,12 @@ list( APPEND CPP_SOURCES ModelVisualization/RivWellHeadPartMgr.cpp ) -list( APPEND CPP_SOURCES - FileInterface/RifEclipseInputFileTools.cpp - FileInterface/RifEclipseOutputFileTools.cpp - FileInterface/RifEclipseRestartFilesetAccess.cpp - FileInterface/RifEclipseRestartDataAccess.cpp - FileInterface/RifEclipseUnifiedRestartFileAccess.cpp - FileInterface/RifReaderEclipseInput.cpp - FileInterface/RifReaderEclipseOutput.cpp - FileInterface/RifReaderMockModel.cpp -) - list( APPEND CPP_SOURCES SocketInterface/RiaSocketServer.cpp ) list( APPEND CPP_SOURCES + ProjectDataModel/RimCaseCollection.cpp ProjectDataModel/RimCellFilter.cpp ProjectDataModel/RimCellPropertyFilter.cpp ProjectDataModel/RimCellPropertyFilterCollection.cpp @@ -73,11 +64,12 @@ list( APPEND CPP_SOURCES ProjectDataModel/RimDefines.cpp ProjectDataModel/RimLegendConfig.cpp ProjectDataModel/RimProject.cpp - ProjectDataModel/RimReservoir.cpp + ProjectDataModel/RimCase.cpp + ProjectDataModel/RimIdenticalGridCaseGroup.cpp ProjectDataModel/RimInputProperty.cpp ProjectDataModel/RimInputPropertyCollection.cpp - ProjectDataModel/RimInputReservoir.cpp - ProjectDataModel/RimResultReservoir.cpp + ProjectDataModel/RimInputCase.cpp + ProjectDataModel/RimResultCase.cpp ProjectDataModel/RimReservoirView.cpp ProjectDataModel/RimResultDefinition.cpp ProjectDataModel/RimResultSlot.cpp @@ -85,55 +77,62 @@ list( APPEND CPP_SOURCES ProjectDataModel/RimWell.cpp ProjectDataModel/RimWellCollection.cpp ProjectDataModel/RimScriptCollection.cpp + ProjectDataModel/RimStatisticsCase.cpp + ProjectDataModel/RimStatisticsCaseCollection.cpp ProjectDataModel/RimCalcScript.cpp ProjectDataModel/RimExportInputPropertySettings.cpp ProjectDataModel/RimBinaryExportSettings.cpp ProjectDataModel/Rim3dOverlayInfoConfig.cpp ProjectDataModel/RimUiTreeModelPdm.cpp ProjectDataModel/RimUiTreeView.cpp + ProjectDataModel/RimReservoirCellResultsCacher.cpp + ProjectDataModel/RimStatisticsCaseEvaluator.cpp +) + +# Populate the filenames into variable lists +include ("ReservoirDataModel/CMakeLists_files.cmake") +include ("FileInterface/CMakeLists_files.cmake") +list( APPEND CPP_SOURCES + ${CODE_SOURCE_FILES} ) list( APPEND CPP_SOURCES - ReservoirDataModel/RigCell.cpp - ReservoirDataModel/RigGridBase.cpp - ReservoirDataModel/RigReservoirCellResults.cpp - ReservoirDataModel/RigLocalGrid.cpp - ReservoirDataModel/RigMainGrid.cpp - ReservoirDataModel/RigReservoir.cpp - ReservoirDataModel/RigReservoirBuilderMock.cpp - ReservoirDataModel/RigWellResults.cpp - ReservoirDataModel/RigGridScalarDataAccess.cpp -) - -list( APPEND CPP_SOURCES - UserInterface/RICursors.cpp - UserInterface/RIMainWindow.cpp - UserInterface/RIPreferencesDialog.cpp - UserInterface/RIResultInfoPanel.cpp - UserInterface/RIViewer.cpp + UserInterface/RiuCursors.cpp + UserInterface/RiuMainWindow.cpp + UserInterface/RiuPreferencesDialog.cpp + UserInterface/RiuResultInfoPanel.cpp + UserInterface/RiuViewer.cpp UserInterface/RiuSimpleHistogramWidget.cpp - - UserInterface/RIProcessMonitor.cpp + UserInterface/RiuMultiCaseImportDialog.cpp + UserInterface/RiuProcessMonitor.cpp ) # Define files for MOC-ing set ( QT_MOC_HEADERS - Application/RIApplication.h + Application/RiaApplication.h ProjectDataModel/RimUiTreeModelPdm.h ProjectDataModel/RimUiTreeView.h - UserInterface/RIMainWindow.h - UserInterface/RIPreferencesDialog.h - UserInterface/RIResultInfoPanel.h - UserInterface/RIViewer.h - UserInterface/RIProcessMonitor.h + UserInterface/RiuMainWindow.h + UserInterface/RiuPreferencesDialog.h + UserInterface/RiuResultInfoPanel.h + UserInterface/RiuViewer.h + UserInterface/RiuProcessMonitor.h SocketInterface/RiaSocketServer.h + UserInterface/RiuMultiCaseImportDialog.h ) qt4_wrap_cpp( MOC_FILES_CPP ${QT_MOC_HEADERS} ) +# Define files for the uic compiler +set ( QT_UI_FILES + UserInterface/RiuMultiCaseImportDialog.ui +) + +qt4_wrap_ui( FORM_FILES_CPP ${QT_UI_FILES} ) + # NOTE! Resources in subfolders must append to QRC_FILES using the following statement # set( QRC_FILES # ${QRC_FILES} @@ -155,19 +154,20 @@ qt4_add_resources( QRC_FILES_CPP ${QRC_FILES} ) ############################################################################# set( RAW_SOURCES ${CPP_SOURCES} ) -list( REMOVE_ITEM RAW_SOURCES RIStdInclude.cpp) -list( REMOVE_ITEM RAW_SOURCES ReservoirDataModel/RigReaderInterfaceECL.cpp) -list( REMOVE_ITEM RAW_SOURCES ReservoirDataModel/RigGridScalarDataAccess.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivCellEdgeEffectGenerator.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivPipeGeometryGenerator.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellPipesPartMgr.cpp) -list( REMOVE_ITEM RAW_SOURCES ModelVisualization/RivWellHeadPartMgr.cpp) -list( REMOVE_ITEM RAW_SOURCES Application/RiaImageFileCompare.cpp) -list( REMOVE_ITEM RAW_SOURCES Application/RiaImageCompareReporter.cpp) +list( REMOVE_ITEM RAW_SOURCES + RiaStdInclude.cpp + ${CODE_SOURCE_FILES} -list( REMOVE_ITEM RAW_SOURCES + ModelVisualization/RivCellEdgeEffectGenerator.cpp + ModelVisualization/RivPipeGeometryGenerator.cpp + ModelVisualization/RivWellPipesPartMgr.cpp + ModelVisualization/RivWellHeadPartMgr.cpp + + Application/RiaImageFileCompare.cpp + Application/RiaImageCompareReporter.cpp + FileInterface/RifEclipseInputFileTools.cpp FileInterface/RifEclipseOutputFileTools.cpp FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -175,8 +175,9 @@ list( REMOVE_ITEM RAW_SOURCES FileInterface/RifEclipseUnifiedRestartFileAccess.cpp FileInterface/RifReaderEclipseInput.cpp FileInterface/RifReaderEclipseOutput.cpp - UserInterface/RiuSimpleHistogramWidget.cpp + UserInterface/RiuSimpleHistogramWidget.cpp + UserInterface/RiuMultiCaseImportDialog.cpp ) include( CustomPCH.cmake ) @@ -189,7 +190,7 @@ set( ALL_INCLUDES ${QT_INCLUDES} ) -set( PCH_NAME RIStdInclude ) +set( PCH_NAME RiaStdInclude ) set( GCC_PCH_TARGET gccPCH ) set( PCH_COMPILER_DEFINE EMPTY ) IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -205,6 +206,7 @@ precompiled_header( RAW_SOURCES ALL_INCLUDES ${GCC_PCH_TARGET} ${PCH_NAME} ${PCH add_executable(ResInsight ${CPP_SOURCES} ${MOC_FILES_CPP} + ${FORM_FILES_CPP} ${QRC_FILES_CPP} ${HEADER_FILES} ) diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake new file mode 100644 index 0000000000..7e80dd49d8 --- /dev/null +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -0,0 +1,31 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + + +list(APPEND CODE_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.h +${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.h +${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.h +${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.h +${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.h +${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.h +${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.h +${CEE_CURRENT_LIST_DIR}RifReaderInterface.h +${CEE_CURRENT_LIST_DIR}RifReaderMockModel.h +) + +list(APPEND CODE_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RifEclipseInputFileTools.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseOutputFileTools.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseRestartDataAccess.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseRestartFilesetAccess.cpp +${CEE_CURRENT_LIST_DIR}RifEclipseUnifiedRestartFileAccess.cpp +${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.cpp +${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.cpp +${CEE_CURRENT_LIST_DIR}RifReaderMockModel.cpp +) + + diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt index 7ae8924546..e66fbc896c 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/CMakeLists.txt @@ -18,39 +18,39 @@ include_directories( ${ResInsight_SOURCE_DIR}/cafProjectDataModel ${ResInsight_SOURCE_DIR}/CommonCode + + #Remove when RigStatistics is out + ${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization ) -set( FILEINTERFACE_CPP_SOURCES - ../RifEclipseInputFileTools.cpp - ../RifEclipseOutputFileTools.cpp - ../RifEclipseRestartFilesetAccess.cpp - ../RifEclipseRestartDataAccess.cpp - ../RifEclipseUnifiedRestartFileAccess.cpp - ../RifReaderEclipseOutput.cpp - ../RifReaderEclipseInput.cpp - ../RifReaderMockModel.cpp -) -set( RESERVOIRDATAMODEL_CPP_SOURCES - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigCell.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigGridBase.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoir.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigWellResults.cpp - ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp +# Populate variables from read from CMakeLists_files.cmake +set (CODE_SOURCE_FILES ) +include ("${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface/CMakeLists_files.cmake") +set( CPP_SOURCES + ${CPP_SOURCES} + ${CODE_SOURCE_FILES} +) +source_group( "FileInterface" FILES ${CODE_SOURCE_FILES} ) + + +# Populate variables from read from CMakeLists_files.cmake +set (CODE_SOURCE_FILES ) +include ("${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake") +set( CPP_SOURCES + ${CPP_SOURCES} + ${CODE_SOURCE_FILES} +) +source_group( "ReservoirDataModel" FILES ${CODE_SOURCE_FILES} ) + + +set( CPP_SOURCES + ${CPP_SOURCES} + ${ResInsight_SOURCE_DIR}/cafUserInterface/cafProgressInfo.cpp ) -set( CPP_SOURCES - ${FILEINTERFACE_CPP_SOURCES} - ${RESERVOIRDATAMODEL_CPP_SOURCES} -) - -source_group( "FileInterface" FILES ${FILEINTERFACE_CPP_SOURCES} ) -source_group( "ReservoirDataModel" FILES ${RESERVOIRDATAMODEL_CPP_SOURCES} ) +source_group( "Headers" FILES ${CODE_HEADER_FILES} ) set( UNIT_TEST_CPP_SOURCES main.cpp @@ -58,7 +58,6 @@ set( UNIT_TEST_CPP_SOURCES Ert-Test.cpp ) - set( LINK_LIBRARIES CommonCode @@ -75,20 +74,22 @@ set( LINK_LIBRARIES ${QT_LIBRARIES} ) - - add_executable( ${ProjectName} + ${CODE_HEADER_FILES} + ${CPP_SOURCES} ${UNIT_TEST_CPP_SOURCES} ${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc + + ${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface/CMakeLists_files.cmake + ${ResInsight_SOURCE_DIR}/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake ) set( EXTERNAL_LINK_LIBRARIES ${ERT_LIBRARY_LIST} ) target_link_libraries( ${ProjectName} ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES}) - # Copy Dlls if (MSVC) @@ -101,21 +102,4 @@ if (MSVC) ${CMAKE_CURRENT_BINARY_DIR}/$) endforeach( qtlib ) - - # DLLs ERT depends on -# add_custom_command(TARGET ${ProjectName} POST_BUILD -# COMMAND ${CMAKE_COMMAND} -E copy_directory -# "${PROJECT_SOURCE_DIR}/../../../ThirdParty/Ert-windows/bin/" -# ${CMAKE_CURRENT_BINARY_DIR}/$) - - - # ERT DLLs - # set (ERT_MODULES ecl geometry util well) - # foreach (ert_module ${ERT_MODULES}) - # add_custom_command(TARGET ${ProjectName} POST_BUILD - # COMMAND ${CMAKE_COMMAND} -E copy_if_different - # "${CMAKE_CURRENT_SOURCE_DIR}/../../../ThirdParty/Ert-windows/${ert_module}/lib/lib${ert_module}.dll" - # ${CMAKE_CURRENT_BINARY_DIR}/$) - # endforeach() - endif(MSVC) diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp index 7a2aef0cfd..390ec2cf56 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/Ert-Test.cpp @@ -37,7 +37,7 @@ #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RifReaderEclipseInput.h" #if 0 diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp index d61fdb185d..d1fbe43b49 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/RifReaderEclipseOutput-Test.cpp @@ -18,15 +18,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RifReaderEclipseOutput.h" #include "ecl_file.h" #include "RifEclipseOutputFileTools.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" @@ -68,7 +68,7 @@ TEST(RigReservoirTest, FileOutputToolsTest) void buildResultInfoString(RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, RimDefines::ResultCatType resultType) { - RigReservoirCellResults* matrixResults = reservoir->mainGrid()->results(porosityModel); + RigCaseCellResultsData* matrixResults = reservoir->results(porosityModel); { QStringList resultNames = matrixResults->resultNames(resultType); @@ -247,7 +247,7 @@ TEST(RigReservoirTest, BasicTest) TEST(RigReservoirTest, WellTest) { cvf::ref readerInterfaceEcl = new RifReaderEclipseOutput; - cvf::ref reservoir = new RigReservoir; + cvf::ref reservoir = new RigCaseData; // Location of test dataset received from Håkon Høgstøl in July 2011 with 10k active cells #ifdef WIN32 diff --git a/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp b/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp index a28cfcc87f..03d89c0085 100644 --- a/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp +++ b/ApplicationCode/FileInterface/FileInterface_UnitTests/main.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cvfBase.h" diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 11a7335234..0fcbadf854 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -18,9 +18,9 @@ #include "RifEclipseInputFileTools.h" #include "RifReaderEclipseOutput.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "cafProgressInfo.h" #include @@ -61,9 +61,9 @@ RifEclipseInputFileTools::~RifEclipseInputFileTools() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoir* reservoir) +bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); qint64 coordPos = -1; qint64 zcornPos = -1; @@ -154,7 +154,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoi progress.setProgress(6); - RifReaderEclipseOutput::transferGeometry(inputGrid, reservoir); + RifReaderEclipseOutput::transferGeometry(inputGrid, eclipseCase); progress.setProgress(7); progress.setProgressDescription("Cleaning up ..."); @@ -176,7 +176,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigReservoi //-------------------------------------------------------------------------------------------------- /// Read known properties from the input file //-------------------------------------------------------------------------------------------------- -std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigReservoir *reservoir) +std::map RifEclipseInputFileTools::readProperties(const QString &fileName, RigCaseData *reservoir) { CVF_ASSERT(reservoir); @@ -212,11 +212,11 @@ std::map RifEclipseInputFileTools::readProperties(const QStri ecl_kw_type* eclKeyWordData = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_FLOAT_TYPE); if (eclKeyWordData) { - QString newResultName = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); + QString newResultName = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(fileKeywords[i].keyword); - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword + size_t resultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); // Should really merge with inputProperty object information because we need to use PropertyName, and not keyword - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); newPropertyData.push_back(std::vector()); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); @@ -282,9 +282,9 @@ std::vector< RifKeywordAndFilePos > RifEclipseInputFileTools::findKeywordsOnFile /// Reads the property data requested into the \a reservoir, overwriting any previous /// propeties with the same name. //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, const QString& resultName) +bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; @@ -294,13 +294,13 @@ bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigReservoi if (eclKeyWordData) { QString newResultName = resultName; - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { - resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); + resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); } - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); newPropertyData.resize(1); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); @@ -370,11 +370,11 @@ const std::vector& RifEclipseInputFileTools::knownPropertyKeywords() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, RigReservoir* reservoir, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord) +bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, RigCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { return false; @@ -386,7 +386,7 @@ bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, return false; } - std::vector< std::vector >& resultData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& resultData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); if (resultData.size() == 0) { return false; @@ -402,11 +402,11 @@ bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, /// Create and write a result vector with values for all cells. /// undefinedValue is used for cells with no result //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName, RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue) +bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName, RigCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); - size_t resultIndex = reservoir->mainGrid()->results(porosityModel)->findScalarResultIndex(resultName); + size_t resultIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { return false; @@ -418,7 +418,7 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa return false; } - cvf::ref dataAccessObject = reservoir->mainGrid()->dataAccessObject(porosityModel, timeStep, resultIndex); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(eclipseCase->mainGrid(), porosityModel, timeStep, resultIndex); if (dataAccessObject.isNull()) { return false; @@ -426,13 +426,13 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa std::vector resultData; size_t i, j, k; - for (k = 0; k < reservoir->mainGrid()->cellCountK(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cellCountK(); k++) { - for (j = 0; j < reservoir->mainGrid()->cellCountJ(); j++) + for (j = 0; j < eclipseCase->mainGrid()->cellCountJ(); j++) { - for (i = 0; i < reservoir->mainGrid()->cellCountI(); i++) + for (i = 0; i < eclipseCase->mainGrid()->cellCountI(); i++) { - double resultValue = dataAccessObject->cellScalar(i, j, k); + double resultValue = dataAccessObject->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); if (resultValue == HUGE_VAL) { resultValue = undefinedValue; @@ -519,9 +519,9 @@ void RifEclipseInputFileTools::findGridKeywordPositions(const QString& filename, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) +bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); FILE* filePointer = util_fopen(fileName.toLatin1().data(), "r"); if (!filePointer) return false; @@ -532,13 +532,13 @@ bool RifEclipseInputFileTools::readPropertyAtFilePosition(const QString& fileNam if (eclKeyWordData) { QString newResultName = resultName; - size_t resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); + size_t resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(newResultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) { - resultIndex = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName); + resultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, newResultName, false); } - std::vector< std::vector >& newPropertyData = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); + std::vector< std::vector >& newPropertyData = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(resultIndex); newPropertyData.resize(1); newPropertyData[0].resize(ecl_kw_get_size(eclKeyWordData), HUGE_VAL); ecl_kw_get_data_as_double(eclKeyWordData, newPropertyData[0].data()); diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h index 220454ee6d..7d0116a29b 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h @@ -27,7 +27,7 @@ #include "RifReaderInterface.h" -class RigReservoir; +class RigCaseData; class QFile; @@ -52,19 +52,19 @@ public: RifEclipseInputFileTools(); virtual ~RifEclipseInputFileTools(); - static bool openGridFile(const QString& fileName, RigReservoir* reservoir); + static bool openGridFile(const QString& fileName, RigCaseData* eclipseCase); // Returns map of assigned resultName and Eclipse Keyword. - static std::map readProperties(const QString& fileName, RigReservoir* reservoir); - static bool readProperty (const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, const QString& resultName ); - static bool readPropertyAtFilePosition (const QString& fileName, RigReservoir* reservoir, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName ); + static std::map readProperties(const QString& fileName, RigCaseData* eclipseCase); + static bool readProperty (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, const QString& resultName ); + static bool readPropertyAtFilePosition (const QString& fileName, RigCaseData* eclipseCase, const QString& eclipseKeyWord, qint64 filePos, const QString& resultName ); static std::vector< RifKeywordAndFilePos > findKeywordsOnFile(const QString &fileName); static const std::vector& knownPropertyKeywords(); - static bool writePropertyToTextFile(const QString& fileName, RigReservoir* reservoir, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord); - static bool writeBinaryResultToTextFile(const QString& fileName, RigReservoir* reservoir, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue); + static bool writePropertyToTextFile(const QString& fileName, RigCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord); + static bool writeBinaryResultToTextFile(const QString& fileName, RigCaseData* eclipseCase, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord, const double undefinedValue); private: static void writeDataToTextFile(QFile* file, const QString& eclipseKeyWord, const std::vector& resultData); diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index 2c77fd6355..fa6c63bb75 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -46,7 +46,7 @@ RifEclipseOutputFileTools::~RifEclipseOutputFileTools() //-------------------------------------------------------------------------------------------------- /// Get list of time step texts (dates) //-------------------------------------------------------------------------------------------------- -void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList* timeSteps, bool* detectedFractionOfDay ) +void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps, bool* detectedFractionOfDay ) { CVF_ASSERT(timeSteps); CVF_ASSERT(ecl_file); @@ -84,7 +84,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList timeStepsFound; + std::vector timeStepsFound; if (hasFractionOfDay) { @@ -102,15 +102,15 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList(dayFraction * 24.0 * 60.0 * 60.0); QTime time(0, 0); time = time.addSecs(seconds); QDate reportDate = simulationStart; - reportDate = reportDate.addDays(floorDayValue); + reportDate = reportDate.addDays(static_cast(floorDayValue)); QDateTime reportDateTime(reportDate, time); - if (timeStepsFound.indexOf(reportDateTime) < 0) + if (std::find(timeStepsFound.begin(), timeStepsFound.end(), reportDateTime) == timeStepsFound.end()) { timeStepsFound.push_back(reportDateTime); } @@ -132,7 +132,7 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, QList* values) +{ + ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, keyword.toAscii().data(), static_cast(fileKeywordOccurrence)); + if (kwData) + { + size_t numValues = ecl_kw_get_size(kwData); + + std::vector integerData; + integerData.resize(numValues); + + ecl_kw_get_memcpy_int_data(kwData, integerData.data()); + values->insert(values->end(), integerData.begin(), integerData.end()); + + return true; + } + + return false; +} + //-------------------------------------------------------------------------------------------------- /// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h index b4644289de..052c1f258b 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h @@ -45,9 +45,10 @@ public: static void findKeywordsAndDataItemCounts(ecl_file_type* ecl_file, QStringList* keywords, std::vector* keywordDataItemCounts); static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values); + static bool keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values); // static void timeStepsText(ecl_file_type* ecl_file, QStringList* timeSteps); - static void timeSteps(ecl_file_type* ecl_file, QList* timeSteps, bool* detectedFractionOfDay = NULL); + static void timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps, bool* detectedFractionOfDay = NULL); static bool fileSet(const QString& fileName, QStringList* fileSet); diff --git a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h index 25cf515ee0..dd8bff2460 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h @@ -42,11 +42,13 @@ public: RifEclipseRestartDataAccess(); virtual ~RifEclipseRestartDataAccess(); - virtual bool open(const QStringList& fileSet) = 0; + virtual bool open() = 0; + virtual void setFileSet(const QStringList& fileSet) = 0; virtual void close() = 0; + virtual void setTimeSteps(const std::vector& timeSteps) {}; virtual size_t timeStepCount() = 0; - virtual QList timeSteps() = 0; + virtual std::vector timeSteps() = 0; virtual void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) = 0; virtual bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) = 0; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp index 40b3e7a631..208a6b48bc 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -40,30 +40,44 @@ RifEclipseRestartFilesetAccess::~RifEclipseRestartFilesetAccess() //-------------------------------------------------------------------------------------------------- /// Open files //-------------------------------------------------------------------------------------------------- -bool RifEclipseRestartFilesetAccess::open(const QStringList& fileSet) +bool RifEclipseRestartFilesetAccess::open() { - close(); - - int numFiles = fileSet.size(); - - caf::ProgressInfo progInfo(numFiles,""); - - int i; - for (i = 0; i < numFiles; i++) + if (m_fileNames.size() > 0) { - progInfo.setProgressDescription(fileSet[i]); + caf::ProgressInfo progInfo(m_fileNames.size(), ""); - ecl_file_type* ecl_file = ecl_file_open(fileSet[i].toAscii().data()); - if (!ecl_file) return false; + int i; + for (i = 0; i < m_fileNames.size(); i++) + { + progInfo.setProgressDescription(m_fileNames[i]); - m_ecl_files.push_back(ecl_file); + openTimeStep(i); - progInfo.incrementProgress(); + progInfo.incrementProgress(); + } } return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::setFileSet(const QStringList& fileSet) +{ + close(); + m_ecl_files.clear(); + + m_fileNames = fileSet; + + for (int i = 0; i < m_fileNames.size(); i++) + { + m_ecl_files.push_back(NULL); + } + + CVF_ASSERT(m_fileNames.size() == static_cast(m_ecl_files.size())); +} + //-------------------------------------------------------------------------------------------------- /// Close files //-------------------------------------------------------------------------------------------------- @@ -71,10 +85,22 @@ void RifEclipseRestartFilesetAccess::close() { for (size_t i = 0; i < m_ecl_files.size(); i++) { - ecl_file_close(m_ecl_files[i]); - } - m_ecl_files.clear(); + if (m_ecl_files[i]) + { + ecl_file_close(m_ecl_files[i]); + } + m_ecl_files[i] = NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::setTimeSteps(const std::vector& timeSteps) +{ + CVF_ASSERT(m_fileNames.size() == timeSteps.size()); + m_timeSteps = timeSteps; } //-------------------------------------------------------------------------------------------------- @@ -82,35 +108,39 @@ void RifEclipseRestartFilesetAccess::close() //-------------------------------------------------------------------------------------------------- size_t RifEclipseRestartFilesetAccess::timeStepCount() { - return m_ecl_files.size(); + return m_timeSteps.size(); } //-------------------------------------------------------------------------------------------------- /// Get the time steps //-------------------------------------------------------------------------------------------------- -QList RifEclipseRestartFilesetAccess::timeSteps() +std::vector RifEclipseRestartFilesetAccess::timeSteps() { - QList timeSteps; - - size_t numSteps = timeStepCount(); - size_t i; - for (i = 0; i < numSteps; i++) + if (m_timeSteps.size() == 0) { - QList stepTime; + size_t numSteps = m_fileNames.size(); + size_t i; + for (i = 0; i < numSteps; i++) + { + std::vector stepTime; - RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime); + openTimeStep(i); + + RifEclipseOutputFileTools::timeSteps(m_ecl_files[i], &stepTime); - if (stepTime.size() == 1) - { - timeSteps.push_back(stepTime[0]); - } - else - { - timeSteps.push_back(QDateTime()); + if (stepTime.size() == 1) + { + m_timeSteps.push_back(stepTime[0]); + } + else + { + m_timeSteps.push_back(QDateTime()); + } } + } - return timeSteps; + return m_timeSteps; } //-------------------------------------------------------------------------------------------------- @@ -120,6 +150,8 @@ void RifEclipseRestartFilesetAccess::resultNames(QStringList* resultNames, std:: { CVF_ASSERT(timeStepCount() > 0); + openTimeStep(0); + std::vector valueCountForOneFile; RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_files[0], resultNames, &valueCountForOneFile); @@ -134,28 +166,35 @@ void RifEclipseRestartFilesetAccess::resultNames(QStringList* resultNames, std:: //-------------------------------------------------------------------------------------------------- bool RifEclipseRestartFilesetAccess::results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) { - size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_files[timeStep], resultName.toAscii().data()); + if (timeStep >= timeStepCount()) + { + return false; + } + + openTimeStep(timeStep); + + size_t fileGridCount = ecl_file_get_num_named_kw(m_ecl_files[timeStep], resultName.toAscii().data()); // No results for this result variable for current time step found - if (numOccurrences == 0) return true; + if (fileGridCount == 0) return true; // Result handling depends on presents of result values for all grids - if (gridCount != numOccurrences) + if (gridCount != fileGridCount) { return false; } size_t i; - for (i = 0; i < numOccurrences; i++) + for (i = 0; i < fileGridCount; i++) { - std::vector partValues; + std::vector gridValues; - if (!RifEclipseOutputFileTools::keywordData(m_ecl_files[timeStep], resultName, i, &partValues)) + if (!RifEclipseOutputFileTools::keywordData(m_ecl_files[timeStep], resultName, i, &gridValues)) { return false; } - values->insert(values->end(), partValues.begin(), partValues.end()); + values->insert(values->end(), gridValues.begin(), gridValues.end()); } return true; @@ -171,6 +210,8 @@ void RifEclipseRestartFilesetAccess::readWellData(well_info_type* well_info) for (size_t i = 0; i < m_ecl_files.size(); i++) { + openTimeStep(i); + const char* fileName = ecl_file_get_src_file(m_ecl_files[i]); int reportNumber = ecl_util_filename_report_nr(fileName); if(reportNumber != -1) @@ -179,3 +220,20 @@ void RifEclipseRestartFilesetAccess::readWellData(well_info_type* well_info) } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseRestartFilesetAccess::openTimeStep(size_t timeStep) +{ + CVF_ASSERT(timeStep < m_ecl_files.size()); + + if (m_ecl_files[timeStep] == NULL) + { + int index = static_cast(timeStep); + ecl_file_type* ecl_file = ecl_file_open(m_fileNames[index].toAscii().data()); + + m_ecl_files[timeStep] = ecl_file; + } +} + diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h index 7e0b181a44..00403233d3 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h @@ -35,11 +35,13 @@ public: RifEclipseRestartFilesetAccess(); virtual ~RifEclipseRestartFilesetAccess(); - bool open(const QStringList& fileSet); + bool open(); + void setFileSet(const QStringList& fileSet); void close(); + void setTimeSteps(const std::vector& timeSteps); size_t timeStepCount(); - QList timeSteps(); + std::vector timeSteps(); void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); @@ -47,5 +49,11 @@ public: virtual void readWellData(well_info_type* well_info); private: - std::vector< ecl_file_type* > m_ecl_files; + void openTimeStep(size_t timeStep); + +private: + QStringList m_fileNames; + std::vector m_timeSteps; + + std::vector< ecl_file_type* > m_ecl_files; }; diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp index 8fecb280e2..c8fb1391fc 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.cpp @@ -38,22 +38,23 @@ RifEclipseUnifiedRestartFileAccess::RifEclipseUnifiedRestartFileAccess() //-------------------------------------------------------------------------------------------------- RifEclipseUnifiedRestartFileAccess::~RifEclipseUnifiedRestartFileAccess() { - if (m_ecl_file) - { - ecl_file_close(m_ecl_file); - } - - m_ecl_file = NULL; + close(); } //-------------------------------------------------------------------------------------------------- /// Open file //-------------------------------------------------------------------------------------------------- -bool RifEclipseUnifiedRestartFileAccess::open(const QStringList& fileSet) +bool RifEclipseUnifiedRestartFileAccess::open() { - QString fileName = fileSet[0]; + return true; +} - m_ecl_file = ecl_file_open(fileName.toAscii().data()); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseUnifiedRestartFileAccess::openFile() +{ + m_ecl_file = ecl_file_open(m_filename.toAscii().data()); if (!m_ecl_file) return false; return true; @@ -64,6 +65,12 @@ bool RifEclipseUnifiedRestartFileAccess::open(const QStringList& fileSet) //-------------------------------------------------------------------------------------------------- void RifEclipseUnifiedRestartFileAccess::close() { + if (m_ecl_file) + { + ecl_file_close(m_ecl_file); + } + + m_ecl_file = NULL; } //-------------------------------------------------------------------------------------------------- @@ -71,18 +78,25 @@ void RifEclipseUnifiedRestartFileAccess::close() //-------------------------------------------------------------------------------------------------- size_t RifEclipseUnifiedRestartFileAccess::timeStepCount() { + if (!openFile()) + { + return 0; + } + return timeSteps().size(); } //-------------------------------------------------------------------------------------------------- /// Get the time steps //-------------------------------------------------------------------------------------------------- -QList RifEclipseUnifiedRestartFileAccess::timeSteps() +std::vector RifEclipseUnifiedRestartFileAccess::timeSteps() { - CVF_ASSERT(m_ecl_file != NULL); + std::vector timeSteps; - QList timeSteps; - RifEclipseOutputFileTools::timeSteps(m_ecl_file, &timeSteps); + if (openFile()) + { + RifEclipseOutputFileTools::timeSteps(m_ecl_file, &timeSteps); + } return timeSteps; } @@ -92,7 +106,10 @@ QList RifEclipseUnifiedRestartFileAccess::timeSteps() //-------------------------------------------------------------------------------------------------- void RifEclipseUnifiedRestartFileAccess::resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) { - RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_file, resultNames, resultDataItemCounts); + if (openFile()) + { + RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_file, resultNames, resultDataItemCounts); + } } //-------------------------------------------------------------------------------------------------- @@ -100,6 +117,11 @@ void RifEclipseUnifiedRestartFileAccess::resultNames(QStringList* resultNames, s //-------------------------------------------------------------------------------------------------- bool RifEclipseUnifiedRestartFileAccess::results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) { + if (!openFile()) + { + return false; + } + size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_file, resultName.toAscii().data()); size_t startIndex = timeStep * gridCount; @@ -124,8 +146,19 @@ bool RifEclipseUnifiedRestartFileAccess::results(const QString& resultName, size void RifEclipseUnifiedRestartFileAccess::readWellData(well_info_type* well_info) { if (!well_info) return; - CVF_ASSERT(m_ecl_file); - well_info_add_UNRST_wells(well_info, m_ecl_file); + if (openFile()) + { + well_info_add_UNRST_wells(well_info, m_ecl_file); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseUnifiedRestartFileAccess::setFileSet(const QStringList& fileSet) +{ + m_filename = fileSet[0]; + } diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h index f8188db60e..f80d11fe11 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h @@ -37,11 +37,12 @@ public: RifEclipseUnifiedRestartFileAccess(); virtual ~RifEclipseUnifiedRestartFileAccess(); - bool open(const QStringList& fileSet); + void setFileSet(const QStringList& fileSet); + bool open(); void close(); size_t timeStepCount(); - QList timeSteps(); + std::vector timeSteps(); void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); @@ -49,5 +50,9 @@ public: virtual void readWellData(well_info_type * well_info); private: + bool openFile(); + +private: + QString m_filename; ecl_file_type* m_ecl_file; }; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp index 6a21dbeb51..3836f514b8 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.cpp @@ -19,8 +19,8 @@ #include "cvfBase.h" #include "RigMainGrid.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RifReaderEclipseInput.h" #include "RifReaderEclipseOutput.h" @@ -57,9 +57,9 @@ RifReaderEclipseInput::~RifReaderEclipseInput() //-------------------------------------------------------------------------------------------------- /// Open file and read geometry into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseInput::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderEclipseInput::open(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); // Make sure everything's closed close(); @@ -84,9 +84,9 @@ bool RifReaderEclipseInput::open(const QString& fileName, RigReservoir* reservoi // create InputProperty object bool isOk = false; - if (reservoir->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) + if (eclipseCase->mainGrid()->gridPointDimensions() == cvf::Vec3st(0,0,0)) { - isOk = RifEclipseInputFileTools::openGridFile(fileName, reservoir); + isOk = RifEclipseInputFileTools::openGridFile(fileName, eclipseCase); } return isOk; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.h b/ApplicationCode/FileInterface/RifReaderEclipseInput.h index 94abe84af2..32499507e4 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.h @@ -32,7 +32,7 @@ public: virtual ~RifReaderEclipseInput(); // Virtual interface implementation - virtual bool open(const QString& fileName, RigReservoir* reservoir); + virtual bool open(const QString& fileName, RigCaseData* eclipseCase); diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp index bd2ec9b0b6..e7fa03c1bd 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp @@ -19,8 +19,8 @@ #include "cvfBase.h" #include "RigMainGrid.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RifReaderEclipseOutput.h" #include "RifEclipseOutputFileTools.h" @@ -32,6 +32,8 @@ #include "ecl_grid.h" #include "well_state.h" +#include "ecl_kw_magic.h" + #include "cafProgressInfo.h" //-------------------------------------------------------------------------------------------------- @@ -84,8 +86,10 @@ static const size_t cellMappingECLRi[8] = { 0, 1, 3, 2, 4, 5, 7, 6 }; // Static functions //************************************************************************************************** -bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex) +bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellInfo, RigActiveCellInfo* fractureActiveCellInfo, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex) { + CVF_ASSERT(activeCellInfo && fractureActiveCellInfo); + int cellCount = ecl_grid_get_global_size(localEclGrid); size_t cellStartIndex = mainGrid->cells().size(); size_t nodeStartIndex = mainGrid->nodes().size(); @@ -103,39 +107,31 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e // Loop over cells and fill them with data #pragma omp parallel for - for (int gIdx = 0; gIdx < cellCount; ++gIdx) + for (int localCellIdx = 0; localCellIdx < cellCount; ++localCellIdx) { - RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx]; + RigCell& cell = mainGrid->cells()[cellStartIndex + localCellIdx]; - bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx); + bool invalid = ecl_grid_cell_invalid1(localEclGrid, localCellIdx); cell.setInvalid(invalid); - cell.setCellIndex(gIdx); + cell.setCellIndex(localCellIdx); // Active cell index - int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, gIdx); + int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, localCellIdx); if (matrixActiveIndex != -1) { - cell.setActiveIndexInMatrixModel(matrixActiveStartIndex + matrixActiveIndex); - } - else - { - cell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + activeCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, matrixActiveStartIndex + matrixActiveIndex); } - int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, gIdx); + int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, localCellIdx); if (fractureActiveIndex != -1) { - cell.setActiveIndexInFractureModel(fractureActiveStartIndex + fractureActiveIndex); - } - else - { - cell.setActiveIndexInFractureModel(cvf::UNDEFINED_SIZE_T); + fractureActiveCellInfo->setCellResultIndex(cellStartIndex + localCellIdx, fractureActiveStartIndex + fractureActiveIndex); } // Parent cell index - int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gIdx); + int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, localCellIdx); if (parentCellIndex == -1) { cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T); @@ -146,21 +142,21 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e } // Coarse cell info - ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , gIdx); + ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , localCellIdx); cell.setInCoarseCell(coarseCellData != NULL); // Corner coordinates int cIdx; for (cIdx = 0; cIdx < 8; ++cIdx) { - double * point = mainGrid->nodes()[nodeStartIndex + gIdx * 8 + cellMappingECLRi[cIdx]].ptr(); - ecl_grid_get_corner_xyz1(localEclGrid, gIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); + double * point = mainGrid->nodes()[nodeStartIndex + localCellIdx * 8 + cellMappingECLRi[cIdx]].ptr(); + ecl_grid_get_corner_xyz1(localEclGrid, localCellIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); point[2] = -point[2]; - cell.cornerIndices()[cIdx] = nodeStartIndex + gIdx*8 + cIdx; + cell.cornerIndices()[cIdx] = nodeStartIndex + localCellIdx*8 + cIdx; } // Sub grid in cell - const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gIdx); + const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, localCellIdx); if (subGrid != NULL) { int subGridFileIndex = ecl_grid_get_grid_nr(subGrid); @@ -169,7 +165,9 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e } // Mark inactive long pyramid looking cells as invalid - if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) ) + // Forslag + //if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) ) + if (!invalid) { cell.setInvalid(cell.isLongPyramidCell()); } @@ -193,7 +191,15 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const e //-------------------------------------------------------------------------------------------------- RifReaderEclipseOutput::RifReaderEclipseOutput() { - ground(); + m_fileName.clear(); + m_fileSet.clear(); + + m_timeSteps.clear(); + + m_eclipseCase = NULL; + + m_ecl_init_file = NULL; + m_dynamicResultsAccess = NULL; } //-------------------------------------------------------------------------------------------------- @@ -201,37 +207,33 @@ RifReaderEclipseOutput::RifReaderEclipseOutput() //-------------------------------------------------------------------------------------------------- RifReaderEclipseOutput::~RifReaderEclipseOutput() { + close(); } -//-------------------------------------------------------------------------------------------------- -/// Ground members -//-------------------------------------------------------------------------------------------------- -void RifReaderEclipseOutput::ground() -{ - m_fileName.clear(); - m_fileSet.clear(); - - m_timeSteps.clear(); - m_mainGrid = NULL; -} //-------------------------------------------------------------------------------------------------- /// Close interface (for now, no files are kept open after calling methods, so just clear members) //-------------------------------------------------------------------------------------------------- void RifReaderEclipseOutput::close() { - m_ecl_file = NULL; - m_dynamicResultsAccess = NULL; + if (m_ecl_init_file) + { + ecl_file_close(m_ecl_init_file); + } + m_ecl_init_file = NULL; - ground(); + if (m_dynamicResultsAccess.notNull()) + { + m_dynamicResultsAccess->close(); + } } //-------------------------------------------------------------------------------------------------- /// Read geometry from file given by name into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, RigReservoir* reservoir) +bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); if (!mainEclGrid) { @@ -239,7 +241,12 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, return false; } - RigMainGrid* mainGrid = reservoir->mainGrid(); + RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + RigActiveCellInfo* fractureActiveCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + CVF_ASSERT(activeCellInfo && fractureActiveCellInfo); + + RigMainGrid* mainGrid = eclipseCase->mainGrid(); { cvf::Vec3st gridPointDim(0,0,0); gridPointDim.x() = ecl_grid_get_nx(mainEclGrid) + 1; @@ -273,6 +280,9 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, totalCellCount += ecl_grid_get_global_size(localEclGrid); } + + activeCellInfo->setGlobalCellCount(totalCellCount); + fractureActiveCellInfo->setGlobalCellCount(totalCellCount); // Reserve room for the cells and nodes and fill them with data @@ -283,15 +293,20 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, progInfo.setProgressDescription("Main Grid"); progInfo.setNextProgressIncrement(3); - transferGridCellData(mainGrid, mainGrid, mainEclGrid, 0, 0); + transferGridCellData(mainGrid, activeCellInfo, fractureActiveCellInfo, mainGrid, mainEclGrid, 0, 0); progInfo.setProgress(3); size_t globalMatrixActiveSize = ecl_grid_get_nactive(mainEclGrid); size_t globalFractureActiveSize = ecl_grid_get_nactive_fracture(mainEclGrid); - mainGrid->setMatrixModelActiveCellCount(globalMatrixActiveSize); - mainGrid->setFractureModelActiveCellCount(globalFractureActiveSize); + activeCellInfo->setGridCount(1 + numLGRs); + fractureActiveCellInfo->setGridCount(1 + numLGRs); + + activeCellInfo->setGridActiveCellCounts(0, globalMatrixActiveSize); + fractureActiveCellInfo->setGridActiveCellCounts(0, globalFractureActiveSize); + + for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx) { @@ -300,22 +315,21 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx); RigLocalGrid* localGrid = static_cast(mainGrid->gridByIndex(lgrIdx+1)); - transferGridCellData(mainGrid, localGrid, localEclGrid, globalMatrixActiveSize, globalFractureActiveSize); + transferGridCellData(mainGrid, activeCellInfo, fractureActiveCellInfo, localGrid, localEclGrid, globalMatrixActiveSize, globalFractureActiveSize); - int activeCellCount = ecl_grid_get_nactive(localEclGrid); - localGrid->setMatrixModelActiveCellCount(activeCellCount); - globalMatrixActiveSize += activeCellCount; + int matrixActiveCellCount = ecl_grid_get_nactive(localEclGrid); + globalMatrixActiveSize += matrixActiveCellCount; - activeCellCount = ecl_grid_get_nactive_fracture(localEclGrid); - localGrid->setFractureModelActiveCellCount(activeCellCount); - globalFractureActiveSize += activeCellCount; + int fractureActiveCellCount = ecl_grid_get_nactive_fracture(localEclGrid); + globalFractureActiveSize += fractureActiveCellCount; + activeCellInfo->setGridActiveCellCounts(lgrIdx + 1, matrixActiveCellCount); + fractureActiveCellInfo->setGridActiveCellCounts(lgrIdx + 1, fractureActiveCellCount); progInfo.setProgress(3 + lgrIdx); } - - mainGrid->setGlobalMatrixModelActiveCellCount(globalMatrixActiveSize); - mainGrid->setGlobalFractureModelActiveCellCount(globalFractureActiveSize); + activeCellInfo->computeDerivedData(); + fractureActiveCellInfo->computeDerivedData(); return true; } @@ -323,9 +337,9 @@ bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, //-------------------------------------------------------------------------------------------------- /// Open file and read geometry into given reservoir object //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseCase) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); caf::ProgressInfo progInfo(100, ""); progInfo.setProgressDescription("Reading Grid"); @@ -351,7 +365,7 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo progInfo.setNextProgressIncrement(10); progInfo.setProgressDescription("Transferring grid geometry"); - if (!transferGeometry(mainEclGrid, reservoir)) return false; + if (!transferGeometry(mainEclGrid, eclipseCase)) return false; progInfo.incrementProgress(); progInfo.setProgressDescription("Releasing reader memory"); @@ -361,30 +375,157 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigReservoir* reservo progInfo.setProgressDescription("Reading Result index"); progInfo.setNextProgressIncrement(60); - m_mainGrid = reservoir->mainGrid(); - - reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(this); - reservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(this); + m_eclipseCase = eclipseCase; // Build results meta data - if (!buildMetaData(reservoir)) return false; + if (!buildMetaData()) return false; progInfo.incrementProgress(); progInfo.setNextProgressIncrement(8); progInfo.setProgressDescription("Reading Well information"); - readWellCells(reservoir); + readWellCells(); return true; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::openAndReadActiveCellData(const QString& fileName, const std::vector& mainCaseTimeSteps, RigCaseData* eclipseCase) +{ + CVF_ASSERT(eclipseCase); + + // It is required to have a main grid before reading active cell data + if (!eclipseCase->mainGrid()) + { + return false; + } + + close(); + + // Get set of files + QStringList fileSet; + if (!RifEclipseOutputFileTools::fileSet(fileName, &fileSet)) return false; + + // Keep the set of files of interest + m_fileSet = fileSet; + m_eclipseCase = eclipseCase; + + + if (!readActiveCellInfo()) + { + return false; + } + + + // Reading of metadata and well cells is not performed here + //if (!buildMetaData()) return false; + // readWellCells(); + + m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet); + + m_dynamicResultsAccess->setTimeSteps(mainCaseTimeSteps); + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +/// See also RigStatistics::computeActiveCellUnion() +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::readActiveCellInfo() +{ + CVF_ASSERT(m_eclipseCase); + CVF_ASSERT(m_eclipseCase->mainGrid()); + + QString egridFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_EGRID_FILE); + if (egridFileName.size() > 0) + { + ecl_file_type* ecl_file = ecl_file_open(egridFileName.toAscii().data()); + if (!ecl_file) return false; + + int actnumKeywordCount = ecl_file_get_num_named_kw(ecl_file, ACTNUM_KW); + if (actnumKeywordCount > 0) + { + std::vector > actnumValuesPerGrid; + actnumValuesPerGrid.resize(actnumKeywordCount); + + size_t globalCellCount = 0; + for (size_t gridIdx = 0; gridIdx < static_cast(actnumKeywordCount); gridIdx++) + { + RifEclipseOutputFileTools::keywordData(ecl_file, ACTNUM_KW, gridIdx, &actnumValuesPerGrid[gridIdx]); + + globalCellCount += actnumValuesPerGrid[gridIdx].size(); + } + + // Check if number of cells is matching + if (m_eclipseCase->mainGrid()->cells().size() != globalCellCount) + { + return false; + } + + RigActiveCellInfo* activeCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + RigActiveCellInfo* fractureActiveCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + activeCellInfo->setGlobalCellCount(globalCellCount); + fractureActiveCellInfo->setGlobalCellCount(globalCellCount); + activeCellInfo->setGridCount(actnumKeywordCount); + fractureActiveCellInfo->setGridCount(actnumKeywordCount); + + size_t cellIdx = 0; + size_t globalActiveMatrixIndex = 0; + size_t globalActiveFractureIndex = 0; + for (size_t gridIdx = 0; gridIdx < static_cast(actnumKeywordCount); gridIdx++) + { + size_t activeMatrixIndex = 0; + size_t activeFractureIndex = 0; + + std::vector& actnumValues = actnumValuesPerGrid[gridIdx]; + + for (size_t i = 0; i < actnumValues.size(); i++) + { + if (actnumValues[i] == 1 || actnumValues[i] == 3) + { + activeCellInfo->setCellResultIndex(cellIdx, globalActiveMatrixIndex++); + activeMatrixIndex++; + } + + if (actnumValues[i] == 2 || actnumValues[i] == 3) + { + fractureActiveCellInfo->setCellResultIndex(cellIdx, globalActiveFractureIndex++); + activeFractureIndex++; + } + + cellIdx++; + } + + activeCellInfo->setGridActiveCellCounts(gridIdx, activeMatrixIndex); + fractureActiveCellInfo->setGridActiveCellCounts(gridIdx, activeFractureIndex); + } + + activeCellInfo->computeDerivedData(); + fractureActiveCellInfo->computeDerivedData(); + } + + ecl_file_close(ecl_file); + + return true; + } + + return false; +} + + //-------------------------------------------------------------------------------------------------- /// Build meta data - get states and results info //-------------------------------------------------------------------------------------------------- -bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) +bool RifReaderEclipseOutput::buildMetaData() { - CVF_ASSERT(reservoir); + CVF_ASSERT(m_eclipseCase); CVF_ASSERT(m_fileSet.size() > 0); caf::ProgressInfo progInfo(m_fileSet.size() + 3,""); @@ -392,16 +533,19 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) progInfo.setNextProgressIncrement(m_fileSet.size()); // Create access object for dynamic results - m_dynamicResultsAccess = dynamicResultsAccess(m_fileSet); + m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet); if (m_dynamicResultsAccess.isNull()) { return false; } + m_dynamicResultsAccess->open(); + + progInfo.incrementProgress(); - RigReservoirCellResults* matrixModelResults = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); - RigReservoirCellResults* fractureModelResults = reservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); + RigCaseCellResultsData* matrixModelResults = m_eclipseCase->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* fractureModelResults = m_eclipseCase->results(RifReaderInterface::FRACTURE_RESULTS); if (m_dynamicResultsAccess.notNull()) { @@ -413,21 +557,27 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) m_dynamicResultsAccess->resultNames(&resultNames, &resultNamesDataItemCounts); { - QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::MATRIX_RESULTS, m_dynamicResultsAccess->timeStepCount()); + QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::MATRIX_RESULTS, m_dynamicResultsAccess->timeStepCount()); for (int i = 0; i < matrixResultNames.size(); ++i) { - size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, matrixResultNames[i]); + size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, matrixResultNames[i], false); matrixModelResults->setTimeStepDates(resIndex, m_timeSteps); } } { - QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::FRACTURE_RESULTS, m_dynamicResultsAccess->timeStepCount()); + QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::FRACTURE_RESULTS, m_dynamicResultsAccess->timeStepCount()); for (int i = 0; i < fractureResultNames.size(); ++i) { - size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, fractureResultNames[i]); + size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, fractureResultNames[i], false); fractureModelResults->setTimeStepDates(resIndex, m_timeSteps); } } @@ -436,22 +586,23 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) progInfo.incrementProgress(); - QString initFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_INIT_FILE); - if (initFileName.size() > 0) + openInitFile(); + + progInfo.incrementProgress(); + + if (m_ecl_init_file) { - ecl_file_type* ecl_file = ecl_file_open(initFileName.toAscii().data()); - if (!ecl_file) return false; - - progInfo.incrementProgress(); - QStringList resultNames; std::vector resultNamesDataItemCounts; - RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(ecl_file, &resultNames, &resultNamesDataItemCounts); + RifEclipseOutputFileTools::findKeywordsAndDataItemCounts(m_ecl_init_file, &resultNames, &resultNamesDataItemCounts); { - QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::MATRIX_RESULTS, 1); + QStringList matrixResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::MATRIX_RESULTS, 1); - QList staticDate; + std::vector staticDate; if (m_timeSteps.size() > 0) { staticDate.push_back(m_timeSteps.front()); @@ -459,15 +610,18 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) for (int i = 0; i < matrixResultNames.size(); ++i) { - size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i]); + size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i], false); matrixModelResults->setTimeStepDates(resIndex, staticDate); } } { - QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, RifReaderInterface::FRACTURE_RESULTS, 1); + QStringList fractureResultNames = validKeywordsForPorosityModel(resultNames, resultNamesDataItemCounts, + m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS), + m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS), + RifReaderInterface::FRACTURE_RESULTS, 1); - QList staticDate; + std::vector staticDate; if (m_timeSteps.size() > 0) { staticDate.push_back(m_timeSteps.front()); @@ -475,12 +629,10 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) for (int i = 0; i < fractureResultNames.size(); ++i) { - size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i]); + size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i], false); fractureModelResults->setTimeStepDates(resIndex, staticDate); } } - - m_ecl_file = ecl_file; } return true; @@ -489,7 +641,7 @@ bool RifReaderEclipseOutput::buildMetaData(RigReservoir* reservoir) //-------------------------------------------------------------------------------------------------- /// Create results access object (.UNRST or .X0001 ... .XNNNN) //-------------------------------------------------------------------------------------------------- -RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const QStringList& fileSet) +RifEclipseRestartDataAccess* RifReaderEclipseOutput::createDynamicResultsAccess(const QStringList& fileSet) { RifEclipseRestartDataAccess* resultsAccess = NULL; @@ -498,11 +650,7 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const if (unrstFileName.size() > 0) { resultsAccess = new RifEclipseUnifiedRestartFileAccess(); - if (!resultsAccess->open(QStringList(unrstFileName))) - { - delete resultsAccess; - return NULL; - } + resultsAccess->setFileSet(QStringList(unrstFileName)); } else { @@ -511,17 +659,10 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const if (restartFiles.size() > 0) { resultsAccess = new RifEclipseRestartFilesetAccess(); - if (!resultsAccess->open(restartFiles)) - { - delete resultsAccess; - return NULL; - } + resultsAccess->setFileSet(restartFiles); } } - // !! could add support for formatted result files - // !! consider priorities in case multiple types exist (.UNRST, .XNNNN, ...) - return resultsAccess; } @@ -531,16 +672,22 @@ RifEclipseRestartDataAccess* RifReaderEclipseOutput::dynamicResultsAccess(const bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values) { CVF_ASSERT(values); - CVF_ASSERT(m_ecl_file); + + if (!openInitFile()) + { + return false; + } + + CVF_ASSERT(m_ecl_init_file); std::vector fileValues; - size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_file, result.toAscii().data()); + size_t numOccurrences = ecl_file_get_num_named_kw(m_ecl_init_file, result.toAscii().data()); size_t i; for (i = 0; i < numOccurrences; i++) { std::vector partValues; - RifEclipseOutputFileTools::keywordData(m_ecl_file, result, i, &partValues); + RifEclipseOutputFileTools::keywordData(m_ecl_init_file, result, i, &partValues); fileValues.insert(fileValues.end(), partValues.begin(), partValues.end()); } @@ -554,10 +701,19 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelRe //-------------------------------------------------------------------------------------------------- bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) { - CVF_ASSERT(m_dynamicResultsAccess.notNull()); + if (m_dynamicResultsAccess.isNull()) + { + m_dynamicResultsAccess = createDynamicResultsAccess(m_fileSet); + } + + if (m_dynamicResultsAccess.isNull()) + { + CVF_ASSERT(false); + return false; + } std::vector fileValues; - if (!m_dynamicResultsAccess->results(result, stepIndex, m_mainGrid->gridCount(), &fileValues)) + if (!m_dynamicResultsAccess->results(result, stepIndex, m_eclipseCase->mainGrid()->gridCount(), &fileValues)) { return false; } @@ -570,9 +726,9 @@ bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelR //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) +void RifReaderEclipseOutput::readWellCells() { - CVF_ASSERT(reservoir); + CVF_ASSERT(m_eclipseCase); if (m_dynamicResultsAccess.isNull()) return; @@ -581,11 +737,11 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) m_dynamicResultsAccess->readWellData(ert_well_info); - RigMainGrid* mainGrid = reservoir->mainGrid(); + RigMainGrid* mainGrid = m_eclipseCase->mainGrid(); std::vector grids; - reservoir->allGrids(&grids); + m_eclipseCase->allGrids(&grids); - cvf::Collection wells; + cvf::Collection wells; caf::ProgressInfo progress(well_info_get_num_wells(ert_well_info), ""); int wellIdx; @@ -594,7 +750,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) const char* wellName = well_info_iget_well_name(ert_well_info, wellIdx); CVF_ASSERT(wellName); - cvf::ref wellResults = new RigWellResults; + cvf::ref wellResults = new RigSingleWellResultsData; wellResults->m_wellName = wellName; well_ts_type* ert_well_time_series = well_info_get_ts(ert_well_info , wellName); @@ -671,7 +827,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) // If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1 // Adjust K so index is always in valid grid region - if (cellK >= grids[gridNr]->cellCountK()) + if (cellK >= static_cast(grids[gridNr]->cellCountK())) { cellK -= static_cast(grids[gridNr]->cellCountK()); } @@ -716,7 +872,7 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) // If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1 // Adjust K so index is always in valid grid region - if (cellK >= grids[gridNr]->cellCountK()) + if (cellK >= static_cast(grids[gridNr]->cellCountK())) { cellK -= static_cast(grids[gridNr]->cellCountK()); } @@ -743,41 +899,27 @@ void RifReaderEclipseOutput::readWellCells(RigReservoir* reservoir) well_info_free(ert_well_info); - reservoir->setWellResults(wells); + m_eclipseCase->setWellResults(wells); } -//-------------------------------------------------------------------------------------------------- -// For case DUALPORO, the well K index is reported outside the grid. If this happens, -// for the given IJ position, search from K=0 and upwards for first active cell. -//-------------------------------------------------------------------------------------------------- -int RifReaderEclipseOutput::findSmallestActiveCellIndexK(const RigGridBase* grid, int cellI, int cellJ) -{ - if (!grid) return -1; - - for (int candidateCellK = 0; candidateCellK < grid->cellCountK(); candidateCellK++ ) - { - if (grid->isCellActive(cellI, cellJ, candidateCellK)) - { - return candidateCellK; - } - } - - return -1; -} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const +QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, + const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, + PorosityModelResultType matrixOrFracture, size_t timeStepCount) const { - if (keywords.size() != keywordDataItemCounts.size()) + CVF_ASSERT(activeCellInfo); + + if (keywords.size() != static_cast(keywordDataItemCounts.size())) { return QStringList(); } if (matrixOrFracture == RifReaderInterface::FRACTURE_RESULTS) { - if (m_mainGrid->globalFractureModelActiveCellCount() == 0) + if (fractureActiveCellInfo->globalActiveCellCount() == 0) { return QStringList(); } @@ -790,17 +932,27 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL QString keyword = keywords[i]; size_t keywordDataCount = keywordDataItemCounts[i]; - size_t timeStepsMatrix = keywordDataItemCounts[i] / m_mainGrid->globalMatrixModelActiveCellCount(); - size_t timeStepsMatrixRest = keywordDataItemCounts[i] % m_mainGrid->globalMatrixModelActiveCellCount(); - - size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (m_mainGrid->globalMatrixModelActiveCellCount() + m_mainGrid->globalFractureModelActiveCellCount()); - size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (m_mainGrid->globalMatrixModelActiveCellCount() + m_mainGrid->globalFractureModelActiveCellCount()); - - if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + if (activeCellInfo->globalActiveCellCount() > 0) { - if (timeStepsMatrixRest == 0 || timeStepsMatrixAndFractureRest == 0) + size_t timeStepsMatrix = keywordDataItemCounts[i] / activeCellInfo->globalActiveCellCount(); + size_t timeStepsMatrixRest = keywordDataItemCounts[i] % activeCellInfo->globalActiveCellCount(); + + size_t timeStepsMatrixAndFracture = keywordDataItemCounts[i] / (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); + size_t timeStepsMatrixAndFractureRest = keywordDataItemCounts[i] % (activeCellInfo->globalActiveCellCount() + fractureActiveCellInfo->globalActiveCellCount()); + + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) { - if (timeStepCount == timeStepsMatrix || timeStepCount == timeStepsMatrixAndFracture) + if (timeStepsMatrixRest == 0 || timeStepsMatrixAndFractureRest == 0) + { + if (timeStepCount == timeStepsMatrix || timeStepCount == timeStepsMatrixAndFracture) + { + keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); + } + } + } + else + { + if (timeStepsMatrixAndFractureRest == 0 && timeStepCount == timeStepsMatrixAndFracture) { keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); } @@ -808,57 +960,87 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL } else { - if (timeStepsMatrixAndFractureRest == 0 && timeStepCount == timeStepsMatrixAndFracture) - { - keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); - } + keywordsWithCorrectNumberOfDataItems.push_back(keywords[i]); } } return keywordsWithCorrectNumberOfDataItems; } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector* destinationResultValues, const std::vector& sourceResultValues) { - if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + RigActiveCellInfo* fracActCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS); + + + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS && fracActCellInfo->globalActiveCellCount() == 0) { - if (m_mainGrid->globalFractureModelActiveCellCount() == 0) - { - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end()); - } - else - { - size_t dataItemCount = 0; - size_t sourceStartPosition = 0; - - for (size_t i = 0; i < m_mainGrid->gridCount(); i++) - { - size_t matrixActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - size_t fractureActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin() + sourceStartPosition, sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount); - - sourceStartPosition += (matrixActiveCellCount + fractureActiveCellCount); - } - } + destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin(), sourceResultValues.end()); } else { + RigActiveCellInfo* actCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + size_t dataItemCount = 0; size_t sourceStartPosition = 0; - for (size_t i = 0; i < m_mainGrid->gridCount(); i++) + for (size_t i = 0; i < m_eclipseCase->mainGrid()->gridCount(); i++) { - size_t matrixActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); - size_t fractureActiveCellCount = m_mainGrid->gridByIndex(i)->matrixModelActiveCellCount(); + size_t matrixActiveCellCount = 0; + size_t fractureActiveCellCount = 0; + + actCellInfo->gridActiveCellCounts(i, matrixActiveCellCount); + fracActCellInfo->gridActiveCellCounts(i, fractureActiveCellCount); - destinationResultValues->insert(destinationResultValues->end(), sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount, sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount + fractureActiveCellCount); + if (matrixOrFracture == RifReaderInterface::MATRIX_RESULTS) + { + destinationResultValues->insert(destinationResultValues->end(), + sourceResultValues.begin() + sourceStartPosition, + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount); + } + else + { + destinationResultValues->insert(destinationResultValues->end(), + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount, + sourceResultValues.begin() + sourceStartPosition + matrixActiveCellCount + fractureActiveCellCount); + } sourceStartPosition += (matrixActiveCellCount + fractureActiveCellCount); } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifReaderEclipseOutput::openInitFile() +{ + if (m_ecl_init_file) + { + return true; + } + + QString initFileName = RifEclipseOutputFileTools::fileNameByType(m_fileSet, ECL_INIT_FILE); + if (initFileName.size() > 0) + { + m_ecl_init_file = ecl_file_open(initFileName.toAscii().data()); + if (m_ecl_init_file) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifReaderEclipseOutput::timeSteps() +{ + return m_timeSteps; +} + diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h index 1b961feea1..8217b58ca5 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h @@ -26,6 +26,7 @@ class RifEclipseOutputFileTools; class RifEclipseRestartDataAccess; class RigGridBase; class RigMainGrid; +class RigActiveCellInfo; typedef struct ecl_grid_struct ecl_grid_type; typedef struct ecl_file_struct ecl_file_type; @@ -42,36 +43,38 @@ public: RifReaderEclipseOutput(); virtual ~RifReaderEclipseOutput(); - bool open(const QString& fileName, RigReservoir* reservoir); + bool open(const QString& fileName, RigCaseData* eclipseCase); + virtual bool openAndReadActiveCellData(const QString& fileName, const std::vector& mainCaseTimeSteps, RigCaseData* eclipseCase); void close(); bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values); bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values); - static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigReservoir* reservoir); + static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigCaseData* eclipseCase); private: - void ground(); - bool buildMetaData(RigReservoir* reservoir); - void readWellCells(RigReservoir* reservoir); + bool readActiveCellInfo(); + bool buildMetaData(); + void readWellCells(); + + bool openInitFile(); + bool openDynamicAccess(); void extractResultValuesBasedOnPorosityModel(PorosityModelResultType matrixOrFracture, std::vector* values, const std::vector& fileValues); - int findSmallestActiveCellIndexK( const RigGridBase* grid, int cellI, int cellJ); + static RifEclipseRestartDataAccess* createDynamicResultsAccess(const QStringList& fileSet); - static RifEclipseRestartDataAccess* staticResultsAccess(const QStringList& fileSet); - static RifEclipseRestartDataAccess* dynamicResultsAccess(const QStringList& fileSet); - - QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const; + QStringList validKeywordsForPorosityModel(const QStringList& keywords, const std::vector& keywordDataItemCounts, const RigActiveCellInfo* activeCellInfo, const RigActiveCellInfo* fractureActiveCellInfo, PorosityModelResultType matrixOrFracture, size_t timeStepCount) const; + virtual std::vector timeSteps(); private: QString m_fileName; // Name of file used to start accessing Eclipse output files QStringList m_fileSet; // Set of files in filename's path with same base name as filename - cvf::cref m_mainGrid; + RigCaseData* m_eclipseCase; - QList m_timeSteps; + std::vector m_timeSteps; - ecl_file_type* m_ecl_file; // File access to static results + ecl_file_type* m_ecl_init_file; // File access to static results cvf::ref m_dynamicResultsAccess; // File access to dynamic results }; diff --git a/ApplicationCode/FileInterface/RifReaderInterface.h b/ApplicationCode/FileInterface/RifReaderInterface.h index c03ddfd0f8..7b947f9468 100644 --- a/ApplicationCode/FileInterface/RifReaderInterface.h +++ b/ApplicationCode/FileInterface/RifReaderInterface.h @@ -24,9 +24,10 @@ #include #include +#include -class RigReservoir; +class RigCaseData; //================================================================================================== // @@ -46,10 +47,11 @@ public: RifReaderInterface() {} virtual ~RifReaderInterface() {} - virtual bool open(const QString& fileName, RigReservoir* reservoir) = 0; + virtual bool open(const QString& fileName, RigCaseData* eclipseCase) = 0; virtual void close() = 0; virtual bool staticResult(const QString& result, PorosityModelResultType matrixOrFracture, std::vector* values) = 0; virtual bool dynamicResult(const QString& result, PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) = 0; -}; + virtual std::vector timeSteps() { std::vector timeSteps; return timeSteps; } +}; diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index 0cfb16c02d..f03a79e40f 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -16,25 +16,25 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RifReaderMockModel.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RifReaderInterface.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) +bool RifReaderMockModel::open(const QString& fileName, RigCaseData* eclipseCase) { - m_reservoirBuilder.populateReservoir(reservoir); + m_reservoirBuilder.populateReservoir(eclipseCase); - m_reservoir = reservoir; + m_reservoir = eclipseCase; - RigReservoirCellResults* cellResults = reservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* cellResults = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS); - QList dates; + std::vector dates; for (int i = 0; i < static_cast(m_reservoirBuilder.timeStepCount()); i++) { @@ -43,13 +43,13 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) for (size_t i = 0; i < m_reservoirBuilder.resultCount(); i++) { - size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i)); + size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, QString("Dynamic_Result_%1").arg(i), false); cellResults->setTimeStepDates(resIdx, dates); } if (m_reservoirBuilder.timeStepCount() == 0) return true; - QList staticDates; + std::vector staticDates; staticDates.push_back(dates[0]); for (int i = 0; i < static_cast(m_reservoirBuilder.resultCount()); i++) { @@ -59,7 +59,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) int resIndex = 0; if (i > 1) resIndex = i; - size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd)); + size_t resIdx = cellResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, QString("Static_Result_%1%2").arg(resIndex).arg(varEnd), false); cellResults->setTimeStepDates(resIdx, staticDates); } @@ -68,7 +68,7 @@ bool RifReaderMockModel::open(const QString& fileName, RigReservoir* reservoir) { \ size_t resIdx; \ QString resultName(Name); \ - resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName); \ + resIdx = cellResults->addEmptyScalarResult(RimDefines::INPUT_PROPERTY, resultName, false); \ cellResults->setTimeStepDates(resIdx, staticDates); \ cellResults->cellScalarResults(resIdx).resize(1); \ std::vector& values = cellResults->cellScalarResults(resIdx)[0]; \ @@ -96,7 +96,7 @@ void RifReaderMockModel::close() //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::inputProperty(const QString& propertyName, std::vector* values) { - return m_reservoirBuilder.inputProperty(m_reservoir.p(), propertyName, values); + return m_reservoirBuilder.inputProperty(m_reservoir, propertyName, values); } //-------------------------------------------------------------------------------------------------- @@ -104,7 +104,7 @@ bool RifReaderMockModel::inputProperty(const QString& propertyName, std::vector< //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::staticResult(const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, std::vector* values) { - m_reservoirBuilder.staticResult(m_reservoir.p(), result, values); + m_reservoirBuilder.staticResult(m_reservoir, result, values); return true; } @@ -114,7 +114,7 @@ bool RifReaderMockModel::staticResult(const QString& result, RifReaderInterface: //-------------------------------------------------------------------------------------------------- bool RifReaderMockModel::dynamicResult(const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values) { - m_reservoirBuilder.dynamicResult(m_reservoir.p(), result, stepIndex, values); + m_reservoirBuilder.dynamicResult(m_reservoir, result, stepIndex, values); return true; } @@ -170,8 +170,8 @@ void RifReaderMockModel::addLocalGridRefinement(const cvf::Vec3st& minCellPositi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderMockModel::populateReservoir(RigReservoir* reservoir) +void RifReaderMockModel::populateReservoir(RigCaseData* eclipseCase) { - m_reservoirBuilder.populateReservoir(reservoir); + m_reservoirBuilder.populateReservoir(eclipseCase); } diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index 73e1260f66..0237381bbe 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -33,17 +33,17 @@ public: void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); - virtual bool open( const QString& fileName, RigReservoir* reservoir ); + virtual bool open( const QString& fileName, RigCaseData* eclipseCase ); virtual void close(); virtual bool staticResult( const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, std::vector* values ); virtual bool dynamicResult( const QString& result, RifReaderInterface::PorosityModelResultType matrixOrFracture, size_t stepIndex, std::vector* values ); private: - void populateReservoir(RigReservoir* reservoir); + void populateReservoir(RigCaseData* eclipseCase); bool inputProperty( const QString& propertyName, std::vector* values ); RigReservoirBuilderMock m_reservoirBuilder; - cvf::ref m_reservoir; + RigCaseData* m_reservoir; }; diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp index e05c0b0e8c..1973d147c8 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivCellEdgeEffectGenerator.h" @@ -33,20 +33,27 @@ #include "cvfShaderProgram.h" #include "cvfRenderStateCullFace.h" -#include -#include -#include - -#include "RimReservoirView.h" -#include "RigGridBase.h" -#include "RigMainGrid.h" -#include "RigReservoirCellResults.h" #include "cvfTextureImage.h" #include "cvfTexture.h" #include "cvfSampler.h" #include "cvfScalarMapper.h" #include "cafEffectGenerator.h" +#include + +#include +#include + +#include "RimReservoirView.h" +#include "RimResultSlot.h" + +#include "RigGridBase.h" +#include "RigMainGrid.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigActiveCellInfo.h" + + //-------------------------------------------------------------------------------------------------- /// @@ -87,12 +94,12 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultSlot->legendConfig()->scalarMapper(); const RigGridBase* grid = dynamic_cast(generator->activeGrid()); - CVF_ASSERT(grid != NULL); - bool cellScalarResultUseGlobalActiveIndex = true; - bool edgeScalarResultUseGlobalActiveIndex[6]; + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); + cvf::ref cellCenterDataAccessObject = NULL; if (cellResultSlot->hasResult()) { if (!cellResultSlot->hasDynamicResult()) @@ -101,23 +108,30 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( timeStepIndex = 0; } - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cellScalarResultUseGlobalActiveIndex = grid->mainGrid()->results(porosityModel)->isUsingGlobalActiveIndex(cellResultSlot->gridScalarIndex()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + cellCenterDataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, cellResultSlot->gridScalarIndex()); } + CVF_ASSERT(cellEdgeResultSlot->hasResult()); + size_t resultIndices[6]; cellEdgeResultSlot->gridScalarIndices(resultIndices); - if (cellEdgeResultSlot->hasResult()) + cvf::Collection cellEdgeDataAccessObjects; + + size_t cubeFaceIdx; + for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) { - size_t cubeFaceIdx; - for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + cvf::ref daObj; + + if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T) { - if (resultIndices[cubeFaceIdx] != cvf::UNDEFINED_SIZE_T) - { - edgeScalarResultUseGlobalActiveIndex[cubeFaceIdx] = grid->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->isUsingGlobalActiveIndex(resultIndices[cubeFaceIdx]); - } + // Assuming static values to be mapped onto cell edge, always using time step zero + // TODO: Now hardcoded matrix results, should it be possible to use fracture results? + daObj = eclipseCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, 0, resultIndices[cubeFaceIdx]); } + + cellEdgeDataAccessObjects.push_back(daObj.p()); } double ignoredScalarValue = cellEdgeResultSlot->ignoredScalarValue(); @@ -138,15 +152,14 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color size_t cellIndex = quadToCell[quadIdx]; - size_t resultValueIndex = cellIndex; - if (cellScalarResultUseGlobalActiveIndex) { - resultValueIndex = grid->cell(cellIndex).activeIndexInMatrixModel(); - } + double scalarValue = HUGE_VAL; + + if (cellCenterDataAccessObject.notNull()) + { + scalarValue = cellCenterDataAccessObject->cellScalar(cellIndex); + } - { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - double scalarValue = grid->mainGrid()->results(porosityModel)->cellScalarResult(timeStepIndex, cellResultSlot->gridScalarIndex(), resultValueIndex); if (scalarValue != HUGE_VAL) { cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; @@ -168,14 +181,12 @@ void RivCellEdgeGeometryGenerator::addCellEdgeResultsToDrawableGeo( { edgeColor = -1.0f; // Undefined texture coord. Shader handles this. - resultValueIndex = cellIndex; - if (edgeScalarResultUseGlobalActiveIndex[cubeFaceIdx]) + double scalarValue = HUGE_VAL; + if (cellEdgeDataAccessObjects[cubeFaceIdx].notNull()) { - resultValueIndex = grid->cell(cellIndex).activeIndexInMatrixModel(); + scalarValue = cellEdgeDataAccessObjects[cubeFaceIdx]->cellScalar(cellIndex); } - // Assuming static values to be mapped onto cell edge, always using time step zero - double scalarValue = grid->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResult(0, resultIndices[cubeFaceIdx], resultValueIndex); if (scalarValue != HUGE_VAL && scalarValue != ignoredScalarValue) { edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index b27f38c339..64e1f6437c 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivGridPartMgr.h" #include "cvfPart.h" #include "cafEffectGenerator.h" @@ -28,7 +28,8 @@ #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RigGridScalarDataAccess.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" //-------------------------------------------------------------------------------------------------- @@ -220,8 +221,11 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimResultSlot* size_t resTimeStepIdx = timeStepIndex; if (cellResultSlot->hasStaticResult()) resTimeStepIdx = 0; - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); - cvf::ref dataAccessObject = m_grid->dataAccessObject(porosityModel, resTimeStepIdx, scalarSetIndex); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultSlot->porosityModel()); + + RigCaseData* eclipseCase = cellResultSlot->reservoirView()->eclipseCase()->reservoirData(); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(m_grid.p(), porosityModel, resTimeStepIdx, scalarSetIndex); + if (dataAccessObject.isNull()) return; // Outer surface diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp index e7562e8b05..c96ad5d33e 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp @@ -83,6 +83,7 @@ void RivPipeGeometryGenerator::setBendScalingFactor(double scaleFactor) //-------------------------------------------------------------------------------------------------- void RivPipeGeometryGenerator::setRadius(double radius) { + CVF_ASSERT(0 <= radius && radius < 1e100); m_radius = radius; clearComputedData(); @@ -93,6 +94,7 @@ void RivPipeGeometryGenerator::setRadius(double radius) //-------------------------------------------------------------------------------------------------- void RivPipeGeometryGenerator::setCrossSectionVertexCount(size_t nodeCount) { + CVF_ASSERT( 2 < nodeCount && nodeCount < 1000000); m_crossSectionNodeCount = nodeCount; clearComputedData(); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 369f3279f0..c51ec3c230 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -16,23 +16,23 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirPartMgr.h" #include "RivGridPartMgr.h" #include "cvfStructGrid.h" #include "cvfModelBasicList.h" -#include "RigReservoir.h" +#include "RigCaseData.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPartMgr::clearAndSetReservoir(const RigReservoir* reservoir) +void RivReservoirPartMgr::clearAndSetReservoir(const RigCaseData* eclipseCase) { m_allGrids.clear(); - if (reservoir) + if (eclipseCase) { std::vector grids; - reservoir->allGrids(&grids); + eclipseCase->allGrids(&grids); for (size_t i = 0; i < grids.size() ; ++i) { m_allGrids.push_back(new RivGridPartMgr(grids[i], i) ); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h index 7ae4eb5b57..58d4dc08f6 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h @@ -30,7 +30,7 @@ namespace cvf class RimResultSlot; class RimCellEdgeResultSlot; class RivGridPartMgr; -class RigReservoir; +class RigCaseData; //================================================================================================== @@ -43,7 +43,7 @@ class RigReservoir; class RivReservoirPartMgr: public cvf::Object { public: - void clearAndSetReservoir(const RigReservoir* reservoir); + void clearAndSetReservoir(const RigCaseData* eclipseCase); void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities ); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp index 4767910b98..156b3d572e 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirPipesPartMgr.h" #include "RimReservoirView.h" diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index a9d1817e16..7f81bee176 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RivReservoirViewPartMgr.h" #include "RivGridPartMgr.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RigGridScalarDataAccess.h" //-------------------------------------------------------------------------------------------------- @@ -125,10 +125,10 @@ void RivReservoirViewPartMgr::scheduleGeometryRegen(ReservoirGeometryCacheType g //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geomType) { - RigReservoir* reservoir = NULL; + RigCaseData* eclipseCase = NULL; if (m_reservoirView != NULL && m_reservoirView->eclipseCase()) { - reservoir = m_reservoirView->eclipseCase()->reservoirData(); + eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); } if (geomType == PROPERTY_FILTERED) @@ -138,7 +138,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredGeometryFramesNeedsRegen[i] = true; if (m_propFilteredGeometryFrames[i].notNull()) { - m_propFilteredGeometryFrames[i]->clearAndSetReservoir(reservoir); + m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase); m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -150,7 +150,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom m_propFilteredWellGeometryFramesNeedsRegen[i] = true; if (m_propFilteredWellGeometryFrames[i].notNull()) { - m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(reservoir); + m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase); m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -158,7 +158,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(ReservoirGeometryCacheType geom else { m_geometriesNeedsRegen[geomType] = true; - m_geometries[geomType].clearAndSetReservoir(reservoir); + m_geometries[geomType].clearAndSetReservoir(eclipseCase); m_geometries[geomType].setTransform(m_scaleTransform.p()); } } @@ -224,7 +224,7 @@ void RivReservoirViewPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicL //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometryType) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); m_geometries[geometryType].clearAndSetReservoir(res); m_geometries[geometryType].setTransform(m_scaleTransform.p()); std::vector grids; @@ -246,13 +246,16 @@ void RivReservoirViewPartMgr::createGeometry(ReservoirGeometryCacheType geometry //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, ReservoirGeometryCacheType geometryType, RigGridBase* grid, size_t gridIdx) { + RigCaseData* eclipseCase = m_reservoirView->eclipseCase()->reservoirData(); + RigActiveCellInfo* activeCellInfo = m_reservoirView->currentActiveCellInfo(); + switch (geometryType) { case ACTIVE: - computeNativeVisibility(cellVisibility, grid, false, false, true, m_reservoirView->showMainGrid() ); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), false, false, true, m_reservoirView->showMainGrid() ); break; case ALL_WELL_CELLS: - computeAllWellCellsVisibility(cellVisibility, grid); + copyByteArray(cellVisibility, eclipseCase->wellCellsInGrid(gridIdx)); break; case VISIBLE_WELL_CELLS: { @@ -287,7 +290,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, } break; case INACTIVE: - computeNativeVisibility(cellVisibility, grid, m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid()); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid()); break; case RANGE_FILTERED: { @@ -367,7 +370,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); if ( frameIndex >= m_propFilteredGeometryFrames.size()) { @@ -382,28 +385,29 @@ void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells(); - for (size_t i = 0; i < grids.size(); ++i) + for (size_t gIdx = 0; gIdx < grids.size(); ++gIdx) { - cvf::ref cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility(i); + cvf::ref cellVisibility = m_propFilteredGeometryFrames[frameIndex]->cellVisibility(gIdx); cvf::ref rangeVisibility; cvf::ref fenceVisibility; + cvf::cref cellIsWellCellStatuses = res->wellCellsInGrid(gIdx); if (m_geometriesNeedsRegen[RANGE_FILTERED]) createGeometry(RANGE_FILTERED); if (m_geometriesNeedsRegen[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER); - rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility(i); - fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i); + rangeVisibility = m_geometries[RANGE_FILTERED].cellVisibility(gIdx); + fenceVisibility = m_geometries[VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(gIdx); cellVisibility->resize(rangeVisibility->size()); #pragma omp parallel for for (int cellIdx = 0; cellIdx < static_cast(cellVisibility->size()); ++cellIdx) { - (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && !grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*fenceVisibility)[cellIdx]; + (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && !(*cellIsWellCellStatuses)[cellIdx]) || (*rangeVisibility)[cellIdx] || (*fenceVisibility)[cellIdx]; } - computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); + computePropertyVisibility(cellVisibility.p(), grids[gIdx], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); - m_propFilteredGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p()); + m_propFilteredGeometryFrames[frameIndex]->setCellVisibility(gIdx, cellVisibility.p()); } m_propFilteredGeometryFramesNeedsRegen[frameIndex] = false; @@ -414,7 +418,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredGeometry(size_t frameIndex) //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameIndex) { - RigReservoir* res = m_reservoirView->eclipseCase()->reservoirData(); + RigCaseData* res = m_reservoirView->eclipseCase()->reservoirData(); if ( frameIndex >= m_propFilteredWellGeometryFrames.size()) { @@ -432,26 +436,28 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd bool hasActiveRangeFilters = m_reservoirView->rangeFilterCollection()->hasActiveFilters() || m_reservoirView->wellCollection()->hasVisibleWellCells(); - for (size_t i = 0; i < grids.size(); ++i) + for (size_t gIdx = 0; gIdx < grids.size(); ++gIdx) { - cvf::ref cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility(i); + cvf::ref cellVisibility = m_propFilteredWellGeometryFrames[frameIndex]->cellVisibility(gIdx); cvf::ref rangeVisibility; cvf::ref wellCellsOutsideVisibility; + cvf::cref cellIsWellCellStatuses = res->wellCellsInGrid(gIdx); + if (m_geometriesNeedsRegen[RANGE_FILTERED_WELL_CELLS]) createGeometry(RANGE_FILTERED_WELL_CELLS); - rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(i); + rangeVisibility = m_geometries[RANGE_FILTERED_WELL_CELLS].cellVisibility(gIdx); if (m_geometriesNeedsRegen[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER]) createGeometry(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER); - wellCellsOutsideVisibility = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(i); + wellCellsOutsideVisibility = m_geometries[VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER].cellVisibility(gIdx); cellVisibility->resize(rangeVisibility->size()); #pragma omp parallel for for (int cellIdx = 0; cellIdx < static_cast(cellVisibility->size()); ++cellIdx) { - (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && grids[i]->cell(cellIdx).isWellCell()) || (*rangeVisibility)[cellIdx] || (*wellCellsOutsideVisibility)[cellIdx]; + (*cellVisibility)[cellIdx] = (!hasActiveRangeFilters && (*cellIsWellCellStatuses)[cellIdx]) || (*rangeVisibility)[cellIdx] || (*wellCellsOutsideVisibility)[cellIdx]; } - computePropertyVisibility(cellVisibility.p(), grids[i], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); - m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility(i, cellVisibility.p()); + computePropertyVisibility(cellVisibility.p(), grids[gIdx], frameIndex, cellVisibility.p(), m_reservoirView->propertyFilterCollection()); + m_propFilteredWellGeometryFrames[frameIndex]->setCellVisibility(gIdx, cellVisibility.p()); } m_propFilteredWellGeometryFramesNeedsRegen[frameIndex] = false; @@ -460,7 +466,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd //-------------------------------------------------------------------------------------------------- /// Evaluate visibility based on cell state //-------------------------------------------------------------------------------------------------- -void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, +void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, @@ -468,18 +474,23 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib { CVF_ASSERT(cellVisibility != NULL); CVF_ASSERT(grid != NULL); + CVF_ASSERT(activeCellInfo != NULL); + CVF_ASSERT(cellIsInWellStatuses != NULL); + CVF_ASSERT(cellIsInWellStatuses->size() >= grid->cellCount()); + cellVisibility->resize(grid->cellCount()); #pragma omp parallel for for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) { const RigCell& cell = grid->cell(cellIndex); + size_t globalCellIndex = cell.mainGridCellIndex(); if ( !invalidCellsIsVisible && cell.isInvalid() - || !inactiveCellsIsVisible && !cell.isActiveInMatrixModel() - || !activeCellsIsVisible && cell.isActiveInMatrixModel() + || !inactiveCellsIsVisible && !activeCellInfo->isActive(globalCellIndex) + || !activeCellsIsVisible && activeCellInfo->isActive(globalCellIndex) || mainGridIsVisible && (cell.subGrid() != NULL) - || cell.isWellCell() + || (*cellIsInWellStatuses)[cellIndex] ) { (*cellVisibility)[cellIndex] = false; @@ -493,27 +504,23 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib //-------------------------------------------------------------------------------------------------- -/// Evaluate Well cell visibility based on cell state +/// Copy the data from source into destination. This is not trivial to do using cvf::Array ... +/// using parallelized operator [] and not memcopy. Do not know what is faster. //-------------------------------------------------------------------------------------------------- -void RivReservoirViewPartMgr::computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid ) +void RivReservoirViewPartMgr::copyByteArray(cvf::UByteArray* destination, const cvf::UByteArray* source ) { - CVF_ASSERT(cellVisibility != NULL); - CVF_ASSERT(grid != NULL); - cellVisibility->resize(grid->cellCount()); + CVF_ASSERT(destination != NULL); + CVF_ASSERT(source != NULL); + + if (destination->size() != source->size()) + { + destination->resize(source->size()); + } #pragma omp parallel for - for (int cellIndex = 0; cellIndex < static_cast(grid->cellCount()); cellIndex++) + for (int cellIndex = 0; cellIndex < static_cast(source->size()); cellIndex++) { - const RigCell& cell = grid->cell(cellIndex); - - if ( cell.isWellCell() ) - { - (*cellVisibility)[cellIndex] = true; - } - else - { - (*cellVisibility)[cellIndex] = false; - } + (*destination)[cellIndex] = (*source)[cellIndex]; } } @@ -599,8 +606,10 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis const RimCellFilter::FilterModeType filterType = (*pfIt)->filterMode(); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, timeStepIndex, scalarResultIndex); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel((*pfIt)->resultDefinition()->porosityModel()); + RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); + + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, timeStepIndex, scalarResultIndex); CVF_ASSERT(dataAccessObject.notNull()); #pragma omp parallel for schedule(dynamic) diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h index 286e2c4a45..fb4bb6420b 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h @@ -28,6 +28,7 @@ class RimReservoirView; class RigGridBase; class RimCellRangeFilterCollection; class RimCellPropertyFilterCollection; +class RigActiveCellInfo; class RivReservoirViewPartMgr: public cvf::Object { @@ -77,10 +78,10 @@ private: void clearGeometryCache(ReservoirGeometryCacheType geomType); - static void computeNativeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible); - static void computeRangeVisibility (cvf::UByteArray* cellVisibility, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); - static void computePropertyVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl); - static void computeAllWellCellsVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid ); + static void computeNativeVisibility (cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible); + static void computeRangeVisibility (cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); + static void computePropertyVisibility(cvf::UByteArray* cellVisibilities, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimCellPropertyFilterCollection* propFilterColl); + static void copyByteArray(cvf::UByteArray* cellVisibilities, const cvf::UByteArray* cellIsWellStatuses ); private: diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp index 8eba80f828..d578779940 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp @@ -36,7 +36,7 @@ #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigCell.h" #include "RivPipeGeometryGenerator.h" @@ -72,11 +72,11 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) if (m_rimReservoirView.isNull()) return; - RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); + RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); RimWell* well = m_rimWell; - RigWellResults* wellResults = well->wellResults(); + RigSingleWellResultsData* wellResults = well->wellResults(); if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0) { @@ -90,7 +90,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) const RigCell& whCell = rigReservoir->cellFromWellResultCell(wellResultFrame.m_wellHead); - double characteristicCellSize = rigReservoir->mainGrid()->characteristicCellSize(); + double characteristicCellSize = rigReservoir->mainGrid()->characteristicIJCellSize(); // Match this position with pipe start position in RivWellPipesPartMgr::calculateWellPipeCenterline() cvf::Vec3d whStartPos = whCell.faceCenter(cvf::StructGridInterface::NEG_K); diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp index 46929737c8..7d82f2f717 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp @@ -19,8 +19,8 @@ #include "cvfLibCore.h" -#include "RimReservoir.h" -#include "RigReservoir.h" +#include "RimCase.h" +#include "RigCaseData.h" #include "RivWellPipesPartMgr.h" #include "RigCell.h" #include "RivPipeGeometryGenerator.h" @@ -86,7 +86,7 @@ void RivWellPipesPartMgr::buildWellPipeParts() calculateWellPipeCenterline(pipeBranchesCLCoords, pipeBranchesCellIds); - double characteristicCellSize = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid()->characteristicCellSize(); + double characteristicCellSize = m_rimReservoirView->eclipseCase()->reservoirData()->mainGrid()->characteristicIJCellSize(); double pipeRadius = m_rimReservoirView->wellCollection()->pipeRadiusScaleFactor() *m_rimWell->pipeRadiusScaleFactor() * characteristicCellSize; for (size_t brIdx = 0; brIdx < pipeBranchesCellIds.size(); ++brIdx) @@ -158,8 +158,8 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector bool isAutoDetectBranches = m_rimReservoirView->wellCollection()->isAutoDetectingBranches(); - RigReservoir* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); - RigWellResults* wellResults = m_rimWell->wellResults(); + RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData(); + RigSingleWellResultsData* wellResults = m_rimWell->wellResults(); const RigWellResultFrame& staticWellFrame = m_rimWell->wellResults()->m_staticWellCells; @@ -357,7 +357,7 @@ void RivWellPipesPartMgr::updatePipeResultColor(size_t frameIndex) { if (m_rimWell == NULL) return; - RigWellResults* wRes = m_rimWell->wellResults(); + RigSingleWellResultsData* wRes = m_rimWell->wellResults(); if (wRes == NULL) return; if (frameIndex < wRes->firstResultTimeStep()) return; // Or reset colors or something diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h index f3fc473a50..942b50866c 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.h @@ -20,7 +20,7 @@ #include "cafPdmPointer.h" #include -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" namespace cvf { diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 86e6d05cb5..09ec328590 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "Rim3dOverlayInfoConfig.h" #include "RimReservoirView.h" -#include "RIViewer.h" -#include "RimReservoir.h" -#include "RigReservoir.h" +#include "RiuViewer.h" +#include "RimCase.h" +#include "RigCaseData.h" #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" CAF_PDM_SOURCE_INIT(Rim3dOverlayInfoConfig, "View3dOverlayInfoConfig"); @@ -70,7 +70,8 @@ void Rim3dOverlayInfoConfig::setPosition(cvf::Vec2ui position) //-------------------------------------------------------------------------------------------------- void Rim3dOverlayInfoConfig::update3DInfo() { - if (!m_reservoirView && m_reservoirView->viewer()) return; + if (!m_reservoirView) return; + if (!m_reservoirView->viewer()) return; m_reservoirView->viewer()->showInfoText(showInfoText()); m_reservoirView->viewer()->showHistogram(false); @@ -80,16 +81,22 @@ void Rim3dOverlayInfoConfig::update3DInfo() { QString caseName; QString totCellCount; - QString activeCellCount; + QString activeCellCountText; + QString fractureActiveCellCount; QString iSize, jSize, kSize; QString propName; QString cellEdgeName; - if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) { caseName = m_reservoirView->eclipseCase()->caseName(); totCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cells().size()); - activeCellCount = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->globalMatrixModelActiveCellCount()); + size_t mxActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); + size_t frActCellCount = m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount(); + if (frActCellCount > 0) activeCellCountText += "Matrix : "; + activeCellCountText += QString::number(mxActCellCount); + if (frActCellCount > 0) activeCellCountText += " Fracture : " + QString::number(frActCellCount); + iSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountI()); jSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountJ()); kSize = QString::number(m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->cellCountK()); @@ -100,7 +107,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() QString infoText = QString( "

-- %1 --

" "Cell count. Total: %2 Active: %3
" - "Main Grid I,J,K: %4, %5, %6
").arg(caseName, totCellCount, activeCellCount, iSize, jSize, kSize); + "Main Grid I,J,K: %4, %5, %6
").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize); if (m_reservoirView->animationMode() && m_reservoirView->cellResult()->hasResult()) { @@ -110,9 +117,9 @@ void Rim3dOverlayInfoConfig::update3DInfo() double p10, p90; double mean; size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); - m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max); - m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); - m_reservoirView->gridCellResults()->meanCellScalarValues(scalarIndex, mean); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); + m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); + m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); //infoText += QString("

Min: %1 P10: %2 Mean: %3 P90: %4 Max: %5
").arg(min).arg(p10).arg(mean).arg(p90).arg(max); //infoText += QString("
Min: %1   P10: %2   Mean: %3 \n  P90: %4   Max: %5 
").arg(min).arg(p10).arg(mean).arg(p90).arg(max); @@ -134,7 +141,7 @@ void Rim3dOverlayInfoConfig::update3DInfo() || m_reservoirView->wellCollection()->hasVisibleWellPipes()) { int currentTimeStep = m_reservoirView->currentTimeStep(); - QDateTime date = m_reservoirView->gridCellResults()->timeStepDate(0, currentTimeStep); + QDateTime date = m_reservoirView->currentGridCellResults()->cellResults()->timeStepDate(0, currentTimeStep); infoText += QString("Time Step: %1 Time: %2").arg(currentTimeStep).arg(date.toString("dd.MMM yyyy")); } @@ -150,12 +157,12 @@ void Rim3dOverlayInfoConfig::update3DInfo() double mean; size_t scalarIndex = m_reservoirView->cellResult()->gridScalarIndex(); - m_reservoirView->gridCellResults()->minMaxCellScalarValues(scalarIndex, min, max); - m_reservoirView->gridCellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); - m_reservoirView->gridCellResults()->meanCellScalarValues(scalarIndex, mean); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); + m_reservoirView->currentGridCellResults()->cellResults()->p10p90CellScalarValues(scalarIndex, p10, p90); + m_reservoirView->currentGridCellResults()->cellResults()->meanCellScalarValues(scalarIndex, mean); m_reservoirView->viewer()->showHistogram(true); - m_reservoirView->viewer()->setHistogram(min, max, m_reservoirView->gridCellResults()->cellScalarValuesHistogram(scalarIndex)); + m_reservoirView->viewer()->setHistogram(min, max, m_reservoirView->currentGridCellResults()->cellResults()->cellScalarValuesHistogram(scalarIndex)); m_reservoirView->viewer()->setHistogramPercentiles(p10, p90, mean); } } diff --git a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp index 0a59a198b2..4d22f6ebe6 100644 --- a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimBinaryExportSettings.h" #include "cafPdmUiFilePathEditor.h" diff --git a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp index b16fe12977..f9f44a8f46 100644 --- a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp +++ b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafPdmField.h" @@ -35,6 +35,7 @@ RimCalcScript::RimCalcScript() CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "" ,""); CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "" ,""); content.setUiHidden(true); + content.setIOWritable(false); absolutePath.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } diff --git a/ApplicationCode/ProjectDataModel/RimReservoir.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp similarity index 59% rename from ApplicationCode/ProjectDataModel/RimReservoir.cpp rename to ApplicationCode/ProjectDataModel/RimCase.cpp index 79bd2bf00a..d7f1beae97 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoir.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -16,60 +16,84 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RifReaderEclipseOutput.h" #include "RifReaderMockModel.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "cvfAssert.h" #include "cafPdmUiPushButtonEditor.h" #include +#include "RimProject.h" +#include "RimReservoirCellResultsCacher.h" -//-------------------------------------------------------------------------------------------------- +CAF_PDM_SOURCE_INIT(RimCase, "RimReservoir"); + +//------------------------------------------------------------------------------------------------ /// //-------------------------------------------------------------------------------------------------- -RimReservoir::RimReservoir() +RimCase::RimCase() { - m_rigReservoir = NULL; - CAF_PDM_InitField(&caseName, "CaseName", QString(), "Case name", "", "" ,""); -// CAF_PDM_InitField(&releaseResultMemory, "ReleaseResultMemory", true, "Release result memory", "", "" ,""); -// releaseResultMemory.setIOReadable(false); -// releaseResultMemory.setIOWritable(false); -// releaseResultMemory.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", ""); + m_matrixModelResults.setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", ""); + m_fractureModelResults.setUiHidden(true); + + m_matrixModelResults = new RimReservoirCellResultsStorage; + m_fractureModelResults = new RimReservoirCellResultsStorage; + + this->setReservoirData( NULL ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigReservoir* RimReservoir::reservoirData() +RimCase::~RimCase() { - return m_rigReservoir.p(); + reservoirViews.deleteAllChildObjects(); + + delete m_matrixModelResults(); + delete m_fractureModelResults(); + + if (this->reservoirData()) + { + // At this point, we assume that memory should be released + CVF_ASSERT(this->reservoirData()->refCount() == 1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData* RimCase::reservoirData() +{ + return m_rigEclipseCase.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigReservoir* RimReservoir::reservoirData() const +const RigCaseData* RimCase::reservoirData() const { - return m_rigReservoir.p(); + return m_rigEclipseCase.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoir::initAfterRead() +void RimCase::initAfterRead() { size_t j; for (j = 0; j < reservoirViews().size(); j++) @@ -84,16 +108,19 @@ void RimReservoir::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimReservoir::~RimReservoir() +RimReservoirView* RimCase::createAndAddReservoirView() { - reservoirViews.deleteAllChildObjects(); -} + // If parent is collection, and number of views is zero, make sure rig is set to NULL to initiate normal case loading + if (parentCaseCollection() != NULL && reservoirViews().size() == 0) + { + if (this->reservoirData()) + { + CVF_ASSERT(this->reservoirData()->refCount() == 1); + } + + this->setReservoirData( NULL ); + } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimReservoirView* RimReservoir::createAndAddReservoirView() -{ RimReservoirView* riv = new RimReservoirView(); riv->setEclipseCase(this); @@ -108,7 +135,7 @@ RimReservoirView* RimReservoir::createAndAddReservoirView() //-------------------------------------------------------------------------------------------------- /// TODO: Move this functionality to PdmPointersField //-------------------------------------------------------------------------------------------------- -void RimReservoir::removeReservoirView(RimReservoirView* reservoirView) +void RimCase::removeReservoirView(RimReservoirView* reservoirView) { std::vector indices; @@ -132,7 +159,7 @@ void RimReservoir::removeReservoirView(RimReservoirView* reservoirView) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoir::removeResult(const QString& resultName) +void RimCase::removeResult(const QString& resultName) { size_t i; for (i = 0; i < reservoirViews().size(); i++) @@ -183,11 +210,11 @@ void RimReservoir::removeResult(const QString& resultName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { if (changedField == &releaseResultMemory) { - if (m_rigReservoir.notNull()) + if (this->reservoirData()) { for (size_t i = 0; i < reservoirViews().size(); i++) { @@ -209,13 +236,13 @@ void RimReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, con reservoirView->createDisplayModelAndRedraw(); } - RigReservoirCellResults* matrixModelResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* matrixModelResults = reservoirData()->results(RifReaderInterface::MATRIX_RESULTS); if (matrixModelResults) { matrixModelResults->clearAllResults(); } - RigReservoirCellResults* fractureModelResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); + RigCaseCellResultsData* fractureModelResults = reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS); if (fractureModelResults) { fractureModelResults->clearAllResults(); @@ -226,3 +253,78 @@ void RimReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, con } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::computeCachedData() +{ + RigCaseData* rigEclipseCase = reservoirData(); + if (rigEclipseCase) + { + rigEclipseCase->computeActiveCellBoundingBoxes(); + + rigEclipseCase->mainGrid()->computeCachedData(); + + std::vector grids; + rigEclipseCase->allGrids(&grids); + + size_t i; + for (i = 0; i < grids.size(); i++) + { + grids[i]->computeFaults(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection* RimCase::parentCaseCollection() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCase::setReservoirData(RigCaseData* eclipseCase) +{ + m_rigEclipseCase = eclipseCase; + if (this->reservoirData()) + { + m_fractureModelResults()->setCellResults(reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)); + m_matrixModelResults()->setCellResults(reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)); + m_fractureModelResults()->setMainGrid(this->reservoirData()->mainGrid()); + m_matrixModelResults()->setMainGrid(this->reservoirData()->mainGrid()); + } + else + { + m_fractureModelResults()->setCellResults(NULL); + m_matrixModelResults()->setCellResults(NULL); + m_fractureModelResults()->setMainGrid(NULL); + m_matrixModelResults()->setMainGrid(NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage* RimCase::results(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults(); + } + + return m_fractureModelResults(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h new file mode 100644 index 0000000000..12b1b6aaff --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "RimReservoirCellResultsCacher.h" +#include "RifReaderInterface.h" + +class QString; + +class RigCaseData; +class RigGridBase; +class RimReservoirView; +class RimCaseCollection; +//class RimReservoirCellResultsCacher; + +//================================================================================================== +// +// Interface for reservoirs. +// +//================================================================================================== +class RimCase : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimCase(); + virtual ~RimCase(); + + // Fields: + caf::PdmField caseName; + caf::PdmField releaseResultMemory; + caf::PdmPointersField reservoirViews; + + virtual bool openEclipseGridFile() { return false;}; // Should be pure virtual but PDM does not allow that. + + RigCaseData* reservoirData(); + const RigCaseData* reservoirData() const; + + RimReservoirCellResultsStorage* results(RifReaderInterface::PorosityModelResultType porosityModel); + + RimReservoirView* createAndAddReservoirView(); + void removeReservoirView(RimReservoirView* reservoirView); + + void removeResult(const QString& resultName); + + virtual QString locationOnDisc() const { return QString(); } + + RimCaseCollection* parentCaseCollection(); + + // Overridden methods from PdmObject +public: + virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName; } +protected: + virtual void initAfterRead(); + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + + // Internal methods +protected: + void computeCachedData(); + void setReservoirData(RigCaseData* eclipseCase); + + +private: + cvf::ref m_rigEclipseCase; + +private: + caf::PdmField m_matrixModelResults; + caf::PdmField m_fractureModelResults; + +}; diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp new file mode 100644 index 0000000000..0df12839a9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStdInclude.h" + + +#include "RimCaseCollection.h" + +#include "RimReservoirView.h" +#include "RimIdenticalGridCaseGroup.h" + +CAF_PDM_SOURCE_INIT(RimCaseCollection, "RimCaseCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection::RimCaseCollection() +{ + CAF_PDM_InitObject("Derived Statistics", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection::~RimCaseCollection() +{ + reservoirs.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimCaseCollection::parentCaseGroup() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.h b/ApplicationCode/ProjectDataModel/RimCaseCollection.h new file mode 100644 index 0000000000..bd1e1a48b2 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimStatisticsCase.h" + + +//================================================================================================== +// +// +// +//================================================================================================== +class RimCaseCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimCaseCollection(); + virtual ~RimCaseCollection(); + + caf::PdmPointersField reservoirs; + + RimIdenticalGridCaseGroup* parentCaseGroup(); + +private: + +}; diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp index 00c2b06d67..28f638ff9d 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellEdgeResultSlot.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "RimReservoirView.h" -#include "RigReservoirCellResults.h" -#include "RigReservoir.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" #include "cafPdmUiListEditor.h" @@ -71,7 +71,7 @@ void RimCellEdgeResultSlot::setReservoirView(RimReservoirView* ownerReservoirVie //-------------------------------------------------------------------------------------------------- void RimCellEdgeResultSlot::loadResult() { - CVF_ASSERT(m_reservoirView && m_reservoirView->gridCellResults()); + CVF_ASSERT(m_reservoirView && m_reservoirView->currentGridCellResults()); resetResultIndices(); QStringList vars = findResultVariableNames(); @@ -80,7 +80,7 @@ void RimCellEdgeResultSlot::loadResult() int i; for (i = 0; i < vars.size(); ++i) { - size_t resultindex = m_reservoirView->gridCellResults()->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, vars[i]); + size_t resultindex = m_reservoirView->currentGridCellResults()->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, vars[i]); int cubeFaceIdx; for (cubeFaceIdx = 0; cubeFaceIdx < 6; ++cubeFaceIdx) { @@ -130,10 +130,10 @@ QList RimCellEdgeResultSlot::calculateValueOptions(const { if (fieldNeedingOptions == &resultVariable) { - if (m_reservoirView && m_reservoirView->gridCellResults()) + if (m_reservoirView && m_reservoirView->currentGridCellResults()) { QStringList varList; - varList = m_reservoirView->gridCellResults()->resultNames(RimDefines::STATIC_NATIVE); + varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(RimDefines::STATIC_NATIVE); //TODO: Must also handle input properties //varList += m_reservoirView->gridCellResults()->resultNames(RimDefines::INPUT_PROPERTY); @@ -205,10 +205,10 @@ QStringList RimCellEdgeResultSlot::findResultVariableNames() { QStringList varNames; - if (m_reservoirView && m_reservoirView->gridCellResults() && !resultVariable().isEmpty()) + if (m_reservoirView && m_reservoirView->currentGridCellResults() && !resultVariable().isEmpty()) { QStringList varList; - varList = m_reservoirView->gridCellResults()->resultNames(RimDefines::STATIC_NATIVE); + varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(RimDefines::STATIC_NATIVE); //TODO: Must handle Input properties int i; @@ -313,7 +313,7 @@ void RimCellEdgeResultSlot::minMaxCellEdgeValues(double& min, double& max) { double cMin, cMax; - m_reservoirView->gridCellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); + m_reservoirView->currentGridCellResults()->cellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); globalMin = CVF_MIN(globalMin, cMin); globalMax = CVF_MAX(globalMax, cMax); diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h index c37bc7577d..8f4eb1eba9 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeResultSlot.h @@ -23,7 +23,7 @@ #include "cafAppEnum.h" #include "RimDefines.h" -class RigReservoirCellResults; +class RigCaseCellResultsData; namespace caf { diff --git a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp index 0b7f188005..6e901ff774 100644 --- a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp index d4c887a866..8666c153d5 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimReservoirView.h" #include "RimCellPropertyFilter.h" #include "RimCellPropertyFilterCollection.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "cafPdmUiDoubleSliderEditor.h" @@ -143,10 +143,10 @@ void RimCellPropertyFilter::setDefaultValues() size_t scalarIndex = resultDefinition->gridScalarIndex(); if (scalarIndex != cvf::UNDEFINED_SIZE_T) { - RigReservoirCellResults* results = m_parentContainer->reservoirView()->gridCellResults(); + RimReservoirCellResultsStorage* results = m_parentContainer->reservoirView()->currentGridCellResults(); if (results) { - results->minMaxCellScalarValues(scalarIndex, min, max); + results->cellResults()->minMaxCellScalarValues(scalarIndex, min, max); } } diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h index 228826cb6b..344c2c5eb2 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilter.h @@ -32,7 +32,7 @@ class RimCellPropertyFilterCollection; class RimResultDefinition; class RigGridBase; -class RigReservoirCellResults; +class RigCaseCellResultsData; namespace cvf { diff --git a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp index 828aad2447..c69141e0a7 100644 --- a/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellPropertyFilterCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellPropertyFilterCollection.h" #include "RimReservoirView.h" #include "RigGridBase.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" CAF_PDM_SOURCE_INIT(RimCellPropertyFilterCollection, "CellPropertyFilters"); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp index 72d07621f2..965a93f78f 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp @@ -16,12 +16,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellRangeFilter.h" #include "RimCellRangeFilterCollection.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" #include "cafPdmUiSliderEditor.h" @@ -115,11 +115,11 @@ void RimCellRangeFilter::setDefaultValues() { CVF_ASSERT(m_parentContainer); - RigMainGrid* mainGrid = m_parentContainer->mainGrid(); - if (mainGrid) + RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); + if (actCellInfo) { cvf::Vec3st min, max; - mainGrid->matrixModelActiveCellsBoundingBox(min, max); + actCellInfo->IJKBoundingBox(min, max); // Adjust to Eclipse indexing min.x() = min.x() + 1; @@ -159,10 +159,13 @@ void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, } RigMainGrid* mainGrid = m_parentContainer->mainGrid(); - if (mainGrid) + CVF_ASSERT(mainGrid); + + RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); + if (actCellInfo) { cvf::Vec3st min, max; - mainGrid->matrixModelActiveCellsBoundingBox(min, max); + actCellInfo->IJKBoundingBox(min, max); // Adjust to Eclipse indexing min.x() = min.x() + 1; diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp index 37be195aa2..73f90a8c7e 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp @@ -16,12 +16,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimCellRangeFilterCollection.h" #include "RimReservoirView.h" -#include "RigReservoir.h" +#include "RigCaseData.h" @@ -97,8 +97,6 @@ void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* } } - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -126,9 +124,21 @@ RigMainGrid* RimCellRangeFilterCollection::mainGrid() const m_reservoirView->eclipseCase()->reservoirData()->mainGrid()) { - RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + return m_reservoirView->eclipseCase()->reservoirData()->mainGrid(); + } - return mainGrid; + return NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RimCellRangeFilterCollection::activeCellInfo() const +{ + if (m_reservoirView ) + { + return m_reservoirView->currentActiveCellInfo(); } return NULL; @@ -209,3 +219,4 @@ bool RimCellRangeFilterCollection::hasActiveFilters() const return false; } + diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h index c85fcab117..ee0fa83543 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h @@ -20,6 +20,8 @@ #include "RimCellRangeFilter.h" +class RigActiveCellInfo; + //================================================================================================== /// /// @@ -42,9 +44,10 @@ public: void compoundCellRangeFilter(cvf::CellRangeFilter* cellRangeFilter) const; bool hasActiveFilters() const; - void setReservoirView(RimReservoirView* reservoirView); - RimReservoirView* reservoirView(); - RigMainGrid* mainGrid() const; + void setReservoirView(RimReservoirView* reservoirView); + RimReservoirView* reservoirView(); + RigMainGrid* mainGrid() const; + RigActiveCellInfo* activeCellInfo() const; // Overridden methods virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); diff --git a/ApplicationCode/ProjectDataModel/RimDefines.cpp b/ApplicationCode/ProjectDataModel/RimDefines.cpp index 5002d0c42a..9fce926af4 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.cpp +++ b/ApplicationCode/ProjectDataModel/RimDefines.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimDefines.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp index f2f432b775..8a2e491420 100644 --- a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimExportInputPropertySettings.h" #include "cafPdmUiFilePathEditor.h" diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp new file mode 100644 index 0000000000..b05b711df2 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -0,0 +1,407 @@ +///////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStdInclude.h" + +#include "RimIdenticalGridCaseGroup.h" +#include "RimCase.h" +#include "RimReservoirView.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" + +#include "RimStatisticsCase.h" +#include "RimStatisticsCaseCollection.h" +#include "RimResultCase.h" +#include "cafProgressInfo.h" +#include "RigActiveCellInfo.h" + + +CAF_PDM_SOURCE_INIT(RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup::RimIdenticalGridCaseGroup() +{ + CAF_PDM_InitObject("Grid Case Group", ":/GridCaseGroup16x16.png", "", ""); + + CAF_PDM_InitField(&name, "UserDescription", QString("Grid Case Group"), "Name", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&statisticsCaseCollection, "StatisticsCaseCollection", "Derived Statistics", ":/Histograms16x16.png", "", ""); + CAF_PDM_InitFieldNoDefault(&caseCollection, "CaseCollection", "Cases", ":/Cases16x16.png", "", ""); + + caseCollection = new RimCaseCollection; + statisticsCaseCollection = new RimCaseCollection; + + m_mainGrid = NULL; + + m_unionOfMatrixActiveCells = new RigActiveCellInfo; + m_unionOfFractureActiveCells = new RigActiveCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup::~RimIdenticalGridCaseGroup() +{ + m_mainGrid = NULL; + + delete caseCollection; + caseCollection = NULL; + + delete statisticsCaseCollection; + statisticsCaseCollection = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::addCase(RimCase* reservoir) +{ + CVF_ASSERT(reservoir); + + if (!reservoir) return; + + RigMainGrid* incomingMainGrid = reservoir->reservoirData()->mainGrid(); + + if (!m_mainGrid) + { + m_mainGrid = incomingMainGrid; + } + + CVF_ASSERT(m_mainGrid == incomingMainGrid); + + caseCollection()->reservoirs().push_back(reservoir); + + if (statisticsCaseCollection->reservoirs().size() == 0) + { + createAndAppendStatisticsCase(); + } + + clearActiveCellUnions(); + clearStatisticsResults(); + updateMainGridAndActiveCellsForStatisticsCases(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::removeCase(RimCase* reservoir) +{ + caseCollection()->reservoirs().removeChildObject(reservoir); + + if (caseCollection()->reservoirs().size() == 0) + { + m_mainGrid = NULL; + } + + clearActiveCellUnions(); + clearStatisticsResults(); + updateMainGridAndActiveCellsForStatisticsCases(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RimIdenticalGridCaseGroup::mainGrid() +{ + if (m_mainGrid) return m_mainGrid; + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimIdenticalGridCaseGroup::userDescriptionField() +{ + return &name; +} + +//-------------------------------------------------------------------------------------------------- +/// Make sure changes in this functions is validated to RiaApplication::addEclipseCases() +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo() +{ + if (caseCollection()->reservoirs().size() == 0) + { + return; + } + + // Read the main case completely including grid. + // The mainGrid from the first case is reused directly in for the other cases. + // When reading active cell info, only the total cell count is tested for consistency + + RimCase* mainCase = caseCollection()->reservoirs[0]; + mainCase->openEclipseGridFile(); + RigCaseData* mainEclipseCase = mainCase->reservoirData(); + CVF_ASSERT(mainEclipseCase); + + // Read active cell info from all source cases + + caf::ProgressInfo info(caseCollection()->reservoirs.size(), "Case group - Reading Active Cell data"); + for (size_t i = 1; i < caseCollection()->reservoirs.size(); i++) + { + RimResultCase* rimReservoir = dynamic_cast(caseCollection()->reservoirs[i]); + if(!rimReservoir) continue; // Input reservoir + + if (!rimReservoir->openAndReadActiveCellData(mainEclipseCase)) + { + CVF_ASSERT(false); + } + + info.incrementProgress(); + } + + m_mainGrid = mainEclipseCase->mainGrid(); + + // Check if we need to calculate the union of the active cells + + bool foundResultsInCache = false; + for (size_t i = 0; i < statisticsCaseCollection()->reservoirs.size(); i++) + { + RimCase* rimReservoir = statisticsCaseCollection()->reservoirs[i]; + + // Check if any results are stored in cache + if (rimReservoir->results(RifReaderInterface::MATRIX_RESULTS)->storedResultsCount() > 0 || + rimReservoir->results(RifReaderInterface::FRACTURE_RESULTS)->storedResultsCount() > 0) + { + foundResultsInCache = true; + break; + } + } + + if (foundResultsInCache) + { + computeUnionOfActiveCells(); + } + + // "Load" the statistical cases + + for (size_t i = 0; i < statisticsCaseCollection()->reservoirs.size(); i++) + { + RimCase* rimReservoir = statisticsCaseCollection()->reservoirs[i]; + + rimReservoir->openEclipseGridFile(); + + if (i == 0) + { + rimReservoir->reservoirData()->computeActiveCellBoundingBoxes(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::computeUnionOfActiveCells() +{ + if (m_unionOfMatrixActiveCells->globalActiveCellCount() > 0) + { + return; + } + + if (caseCollection->reservoirs.size() == 0 || !m_mainGrid) + { + this->clearActiveCellUnions(); + + return; + } + + m_unionOfMatrixActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); + m_unionOfFractureActiveCells->setGlobalCellCount(m_mainGrid->cells().size()); + m_unionOfMatrixActiveCells->setGridCount(m_mainGrid->gridCount()); + m_unionOfFractureActiveCells->setGridCount(m_mainGrid->gridCount()); + + size_t globalActiveMatrixIndex = 0; + size_t globalActiveFractureIndex = 0; + + for (size_t gridIdx = 0; gridIdx < m_mainGrid->gridCount(); gridIdx++) + { + RigGridBase* grid = m_mainGrid->gridByIndex(gridIdx); + + std::vector activeM(grid->cellCount(), 0); + std::vector activeF(grid->cellCount(), 0); + + for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + { + for (size_t caseIdx = 0; caseIdx < caseCollection->reservoirs.size(); caseIdx++) + { + size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + + if (activeM[localGridCellIdx] == 0) + { + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(globalCellIdx)) + { + activeM[localGridCellIdx] = 1; + } + } + + if (activeF[localGridCellIdx] == 0) + { + if (caseCollection->reservoirs[caseIdx]->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->isActive(globalCellIdx)) + { + activeF[localGridCellIdx] = 1; + } + } + } + } + + size_t activeMatrixIndex = 0; + size_t activeFractureIndex = 0; + + for (size_t localGridCellIdx = 0; localGridCellIdx < grid->cellCount(); localGridCellIdx++) + { + size_t globalCellIdx = grid->globalGridCellIndex(localGridCellIdx); + + if (activeM[localGridCellIdx] != 0) + { + m_unionOfMatrixActiveCells->setCellResultIndex(globalCellIdx, globalActiveMatrixIndex++); + activeMatrixIndex++; + } + + if (activeF[localGridCellIdx] != 0) + { + m_unionOfFractureActiveCells->setCellResultIndex(globalCellIdx, globalActiveFractureIndex++); + activeFractureIndex++; + } + } + + m_unionOfMatrixActiveCells->setGridActiveCellCounts(gridIdx, activeMatrixIndex); + m_unionOfFractureActiveCells->setGridActiveCellCounts(gridIdx, activeFractureIndex); + } + + m_unionOfMatrixActiveCells->computeDerivedData(); + m_unionOfFractureActiveCells->computeDerivedData(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase* RimIdenticalGridCaseGroup::createAndAppendStatisticsCase() +{ + RimStatisticsCase* newStatisticsCase = new RimStatisticsCase; + + newStatisticsCase->caseName = QString("Statistics ") + QString::number(statisticsCaseCollection()->reservoirs.size()+1); + statisticsCaseCollection()->reservoirs.push_back(newStatisticsCase); + + newStatisticsCase->openEclipseGridFile(); + + return newStatisticsCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::updateMainGridAndActiveCellsForStatisticsCases() +{ + for (size_t i = 0; i < statisticsCaseCollection->reservoirs().size(); i++) + { + RimCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; + + rimStaticsCase->reservoirData()->setMainGrid(this->mainGrid()); + + if (i == 0) + { + rimStaticsCase->reservoirData()->computeActiveCellBoundingBoxes(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::clearStatisticsResults() +{ + for (size_t i = 0; i < statisticsCaseCollection->reservoirs().size(); i++) + { + RimCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; + if (!rimStaticsCase) continue; + + rimStaticsCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->clearAllResults(); + rimStaticsCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()->clearAllResults(); + + for (size_t j = 0; j < rimStaticsCase->reservoirViews.size(); j++) + { + RimReservoirView* rimReservoirView = rimStaticsCase->reservoirViews[j]; + rimReservoirView->cellResult()->resultVariable = RimDefines::undefinedResultName(); + rimReservoirView->cellEdgeResult()->resultVariable = RimDefines::undefinedResultName(); + rimReservoirView->loadDataAndUpdate(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIdenticalGridCaseGroup::clearActiveCellUnions() +{ + m_unionOfMatrixActiveCells->clear(); + m_unionOfFractureActiveCells->clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimIdenticalGridCaseGroup::contains(RimCase* reservoir) const +{ + CVF_ASSERT(reservoir); + + for (size_t i = 0; i < caseCollection()->reservoirs().size(); i++) + { + RimCase* rimReservoir = caseCollection()->reservoirs()[i]; + if (reservoir->caseName == reservoir->caseName) + { + return true; + } + } + + return false; +} + +RigActiveCellInfo* RimIdenticalGridCaseGroup::unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType) +{ + if (porosityType == RifReaderInterface::MATRIX_RESULTS) + { + return m_unionOfMatrixActiveCells.p(); + } + else + { + return m_unionOfFractureActiveCells.p(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimIdenticalGridCaseGroup::isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection) +{ + std::vector fields; + rimCaseCollection->parentFields(fields); + if (fields.size() == 1) + { + if (fields[0]->keyword() == "StatisticsCaseCollection") + { + return true; + } + } + + return false; +} diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h new file mode 100644 index 0000000000..7e379b4a10 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimStatisticsCaseCollection.h" +#include "RimCaseCollection.h" + +class RimCase; +class RigMainGrid; +class RigActiveCellInfo; + +//================================================================================================== +// +// +// +//================================================================================================== +class RimIdenticalGridCaseGroup : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimIdenticalGridCaseGroup(); + virtual ~RimIdenticalGridCaseGroup(); + + caf::PdmField name; + + void addCase(RimCase* reservoir); + void removeCase(RimCase* reservoir); + bool contains(RimCase* reservoir) const; + + RimStatisticsCase* createAndAppendStatisticsCase(); + + caf::PdmField caseCollection; + caf::PdmField statisticsCaseCollection; + + void loadMainCaseAndActiveCellInfo(); + + RigMainGrid* mainGrid(); + RigActiveCellInfo* unionOfActiveCells(RifReaderInterface::PorosityModelResultType porosityType); + + void computeUnionOfActiveCells(); + + static bool isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection); + +protected: + virtual caf::PdmFieldHandle* userDescriptionField(); + +private: + void updateMainGridAndActiveCellsForStatisticsCases(); + void clearStatisticsResults(); + void clearActiveCellUnions(); + +private: + RigMainGrid* m_mainGrid; + + cvf::ref m_unionOfMatrixActiveCells; + cvf::ref m_unionOfFractureActiveCells; +}; diff --git a/ApplicationCode/ProjectDataModel/RimInputReservoir.cpp b/ApplicationCode/ProjectDataModel/RimInputCase.cpp similarity index 77% rename from ApplicationCode/ProjectDataModel/RimInputReservoir.cpp rename to ApplicationCode/ProjectDataModel/RimInputCase.cpp index b2f5544dbe..229d25dd73 100644 --- a/ApplicationCode/ProjectDataModel/RimInputReservoir.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputCase.cpp @@ -16,16 +16,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimInputProperty.h" #include "RimReservoirView.h" #include "RifReaderEclipseInput.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "cvfAssert.h" @@ -34,18 +34,18 @@ #include "RifEclipseInputFileTools.h" #include "cafProgressInfo.h" -#include "RIApplication.h" -#include "RIPreferences.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" -CAF_PDM_SOURCE_INIT(RimInputReservoir, "RimInputReservoir"); +CAF_PDM_SOURCE_INIT(RimInputCase, "RimInputReservoir"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimInputReservoir::RimInputReservoir() - : RimReservoir() +RimInputCase::RimInputCase() + : RimCase() { - CAF_PDM_InitObject("RimInputReservoir", ":/EclipseInput48x48.png", "", ""); + CAF_PDM_InitObject("RimInputCase", ":/EclipseInput48x48.png", "", ""); CAF_PDM_InitField(&m_gridFileName, "GridFileName", QString(), "Case grid filename", "", "" ,""); CAF_PDM_InitFieldNoDefault(&m_additionalFileNames, "AdditionalFileNames", "Additional files", "", "" ,""); @@ -58,7 +58,7 @@ RimInputReservoir::RimInputReservoir() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimInputReservoir::~RimInputReservoir() +RimInputCase::~RimInputCase() { delete m_inputPropertyCollection; } @@ -67,42 +67,23 @@ RimInputReservoir::~RimInputReservoir() /// Open the supplied file set. If no grid data has been read, it will first find the possible /// grid data among the files then read all supported properties from the files matching the grid //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::openDataFileSet(const QStringList& filenames) +void RimInputCase::openDataFileSet(const QStringList& filenames) { if (caseName().contains("Input Mock Debug Model")) { cvf::ref readerInterface = this->createMockModel(this->caseName()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); - size_t matrixActiveCellCount = 0; - size_t fractureActiveCellCount = 0; - - for (size_t cellIdx = 0; cellIdx < m_rigReservoir->mainGrid()->cells().size(); cellIdx++) - { - const RigCell& cell = m_rigReservoir->mainGrid()->cells()[cellIdx]; - - if (cell.isActiveInMatrixModel()) - { - matrixActiveCellCount++; - } - if (cell.isActiveInFractureModel()) - { - fractureActiveCellCount++; - } - - } - - m_rigReservoir->mainGrid()->setGlobalMatrixModelActiveCellCount(matrixActiveCellCount); - m_rigReservoir->mainGrid()->setGlobalFractureModelActiveCellCount(fractureActiveCellCount); + reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->computeDerivedData(); + reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->computeDerivedData(); return; } - if (m_rigReservoir.isNull()) + if (this->reservoirData() == NULL) { - RigReservoir* reservoir = new RigReservoir; - m_rigReservoir = reservoir; + this->setReservoirData(new RigCaseData); } // First find and read the grid data @@ -114,8 +95,7 @@ void RimInputReservoir::openDataFileSet(const QStringList& filenames) { m_gridFileName = filenames[i]; - m_rigReservoir->computeFaults(); - m_rigReservoir->mainGrid()->computeCachedData(); + computeCachedData(); break; } @@ -174,10 +154,10 @@ void RimInputReservoir::openDataFileSet(const QStringList& filenames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimInputReservoir::openEclipseGridFile() +bool RimInputCase::openEclipseGridFile() { // Early exit if reservoir data is created - if (m_rigReservoir.isNull()) + if (this->reservoirData() == NULL) { cvf::ref readerInterface; @@ -187,33 +167,32 @@ bool RimInputReservoir::openEclipseGridFile() } else { - RigReservoir* reservoir = new RigReservoir; + cvf::ref eclipseCase = new RigCaseData; readerInterface = new RifReaderEclipseInput; - if (!readerInterface->open(m_gridFileName, reservoir)) + if (!readerInterface->open(m_gridFileName, eclipseCase.p())) { - delete reservoir; return false; } - m_rigReservoir = reservoir; - loadAndSyncronizeInputProperties(); + this->setReservoirData( eclipseCase.p() ); } - CVF_ASSERT(m_rigReservoir.notNull()); + CVF_ASSERT(this->reservoirData()); CVF_ASSERT(readerInterface.notNull()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->computeFaults(); - m_rigReservoir->mainGrid()->computeCachedData(); + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + + computeCachedData(); + loadAndSyncronizeInputProperties(); } - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeDepthRelatedProperties) { - RigReservoirCellResults* matrixResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); - RigReservoirCellResults* fractureResults = m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS); + RimReservoirCellResultsStorage* matrixResults = results(RifReaderInterface::MATRIX_RESULTS); + RimReservoirCellResultsStorage* fractureResults = results(RifReaderInterface::FRACTURE_RESULTS); matrixResults->computeDepthRelatedResults(); fractureResults->computeDepthRelatedResults(); @@ -227,11 +206,11 @@ bool RimInputReservoir::openEclipseGridFile() /// Loads input property data from the gridFile and additional files /// Creates new InputProperties if necessary, and flags the unused ones as obsolete //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::loadAndSyncronizeInputProperties() +void RimInputCase::loadAndSyncronizeInputProperties() { // Make sure we actually have reservoir data - CVF_ASSERT(m_rigReservoir.notNull()); + CVF_ASSERT(this->reservoirData()); CVF_ASSERT(this->reservoirData()->mainGrid()->gridPointDimensions() != cvf::Vec3st(0,0,0)); // Then read the properties from all the files referenced by the InputReservoir @@ -305,7 +284,7 @@ void RimInputReservoir::loadAndSyncronizeInputProperties() { if (fileKeywordSet.count(knownKeywords[fkIt])) { - QString resultName = this->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(knownKeywords[fkIt]); + QString resultName = this->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->makeResultNameUnique(knownKeywords[fkIt]); if (RifEclipseInputFileTools::readProperty(filenames[i], this->reservoirData(), knownKeywords[fkIt], resultName)) { RimInputProperty* inputProperty = new RimInputProperty; @@ -334,7 +313,7 @@ void RimInputReservoir::loadAndSyncronizeInputProperties() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimInputCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { } @@ -342,7 +321,7 @@ void RimInputReservoir::fieldChangedByUi(const caf::PdmFieldHandle* changedField //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::addFiles(const QStringList& newFileNames) +void RimInputCase::addFiles(const QStringList& newFileNames) { } @@ -351,7 +330,7 @@ void RimInputReservoir::addFiles(const QStringList& newFileNames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::removeFiles(const QStringList& obsoleteFileNames) +void RimInputCase::removeFiles(const QStringList& obsoleteFileNames) { } @@ -359,7 +338,7 @@ void RimInputReservoir::removeFiles(const QStringList& obsoleteFileNames) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) +void RimInputCase::removeProperty(RimInputProperty* inputProperty) { bool isPropertyFileReferencedByOthers = false; @@ -380,7 +359,7 @@ void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) } // Remove the results pointed to by this input property - RigReservoirCellResults* results = m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS); + RigCaseCellResultsData* results = reservoirData()->results(RifReaderInterface::MATRIX_RESULTS); results->removeResult(inputProperty->resultName); this->removeResult(inputProperty->resultName); @@ -389,9 +368,9 @@ void RimInputReservoir::removeProperty(RimInputProperty* inputProperty) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RimInputReservoir::createMockModel(QString modelName) +cvf::ref RimInputCase::createMockModel(QString modelName) { - cvf::ref reservoir = new RigReservoir; + cvf::ref reservoir = new RigCaseData; cvf::ref mockFileInterface = new RifReaderMockModel; if (modelName == "Input Mock Debug Model Simple") @@ -405,12 +384,16 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam mockFileInterface->open("", reservoir.p()); { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } // Add a property @@ -421,7 +404,7 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam m_inputPropertyCollection->inputProperties.push_back(inputProperty); } - m_rigReservoir = reservoir; + this->setReservoirData( reservoir.p() ); return mockFileInterface.p(); } @@ -429,7 +412,7 @@ cvf::ref RimInputReservoir::createMockModel(QString modelNam //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimInputReservoir::locationOnDisc() const +QString RimInputCase::locationOnDisc() const { if (m_gridFileName().isEmpty()) return QString(); diff --git a/ApplicationCode/ProjectDataModel/RimInputReservoir.h b/ApplicationCode/ProjectDataModel/RimInputCase.h similarity index 93% rename from ApplicationCode/ProjectDataModel/RimInputReservoir.h rename to ApplicationCode/ProjectDataModel/RimInputCase.h index 45f06d8c7c..525937c9ab 100644 --- a/ApplicationCode/ProjectDataModel/RimInputReservoir.h +++ b/ApplicationCode/ProjectDataModel/RimInputCase.h @@ -23,7 +23,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "RimInputPropertyCollection.h" @@ -36,13 +36,13 @@ class RifReaderInterface; // // //================================================================================================== -class RimInputReservoir : public RimReservoir +class RimInputCase : public RimCase { CAF_PDM_HEADER_INIT; public: - RimInputReservoir(); - virtual ~RimInputReservoir(); + RimInputCase(); + virtual ~RimInputCase(); // Fields caf::PdmField > m_additionalFileNames; @@ -56,7 +56,7 @@ public: void removeProperty(RimInputProperty* inputProperty); - // RimReservoir overrides + // RimCase overrides virtual bool openEclipseGridFile(); // Find grid file among file set. Read, Find read and validate property date. Syncronize child property sets. // PdmObject overrides diff --git a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp index f226a8673c..95936e5f54 100644 --- a/ApplicationCode/ProjectDataModel/RimInputProperty.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputProperty.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimInputProperty.h" diff --git a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp index 4520653a03..5798253f13 100644 --- a/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimInputPropertyCollection.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimInputPropertyCollection.h" diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 33fca47d93..a9d392c359 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" @@ -405,13 +405,13 @@ void RimLegendConfig::recreateLegend() //-------------------------------------------------------------------------------------------------- double RimLegendConfig::adjust(double domainValue, double precision) { - double decadeValue = cvf::Math::abs(domainValue); - double threshold = 1e-6; - if (decadeValue < threshold) + double absDomainValue = cvf::Math::abs(domainValue); + if (absDomainValue == 0.0) { return 0.0; } - double logDecValue = log10(decadeValue); + + double logDecValue = log10(absDomainValue); logDecValue = cvf::Math::ceil(logDecValue); double factor = pow(10.0, precision - logDecValue); diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index c2df1b93ff..540c0a63f2 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -92,7 +92,7 @@ private: caf::PdmPointer m_reservoirView; cvf::ref m_linDiscreteScalarMapper; - cvf::ref m_logDiscreteScalarMapper; + cvf::ref m_logDiscreteScalarMapper; cvf::ref m_logSmoothScalarMapper; cvf::ref m_linSmoothScalarMapper; cvf::ref m_currentScalarMapper; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 4a07ccbb52..a939da0784 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -16,12 +16,16 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimProject.h" -#include "RIApplication.h" -#include "RIVersionInfo.h" -#include "RimScriptCollection.h" +#include "RiaApplication.h" +#include "RiaVersionInfo.h" + +#include "RigGridManager.h" +#include "RigCaseData.h" +#include "RimResultCase.h" + CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); //-------------------------------------------------------------------------------------------------- @@ -33,11 +37,15 @@ RimProject::RimProject(void) m_projectFileVersionString.setUiHidden(true); CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&caseGroups, "CaseGroups", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&scriptCollection, "ScriptCollection", "Scripts", ":/Default.png", "", ""); scriptCollection = new RimScriptCollection(); scriptCollection->directory.setUiHidden(true); + m_gridCollection = new RigGridManager; + initAfterRead(); } @@ -46,6 +54,8 @@ RimProject::RimProject(void) //-------------------------------------------------------------------------------------------------- RimProject::~RimProject(void) { + close(); + if (scriptCollection()) delete scriptCollection(); reservoirs.deleteAllChildObjects(); @@ -56,7 +66,10 @@ RimProject::~RimProject(void) //-------------------------------------------------------------------------------------------------- void RimProject::close() { + m_gridCollection->clear(); + reservoirs.deleteAllChildObjects(); + caseGroups.deleteAllChildObjects(); fileName = ""; } @@ -69,7 +82,7 @@ void RimProject::initAfterRead() // // TODO : Must store content of scripts in project file and notify user if stored content is different from disk on execute and edit // - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptDirectory = app->scriptDirectory(); this->setUserScriptPath(scriptDirectory); @@ -113,3 +126,108 @@ QString RimProject::projectFileVersionString() const { return m_projectFileVersionString; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::moveEclipseCaseIntoCaseGroup(RimCase* rimReservoir) +{ + CVF_ASSERT(rimReservoir); + + RigCaseData* rigEclipseCase = rimReservoir->reservoirData(); + RigMainGrid* equalGrid = registerCaseInGridCollection(rigEclipseCase); + CVF_ASSERT(equalGrid); + + // Insert in identical grid group + bool foundGroup = false; + + for (size_t i = 0; i < caseGroups.size(); i++) + { + RimIdenticalGridCaseGroup* cg = caseGroups()[i]; + + if (cg->mainGrid() == equalGrid) + { + cg->addCase(rimReservoir); + foundGroup = true; + } + } + + if (!foundGroup) + { + RimIdenticalGridCaseGroup* group = new RimIdenticalGridCaseGroup; + group->addCase(rimReservoir); + + caseGroups().push_back(group); + } + + // Remove reservoir from main container + reservoirs().removeChildObject(rimReservoir); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::removeCaseFromAllGroups(RimCase* reservoir) +{ + m_gridCollection->removeCase(reservoir->reservoirData()); + + for (size_t i = 0; i < caseGroups.size(); i++) + { + RimIdenticalGridCaseGroup* cg = caseGroups()[i]; + + cg->removeCase(reservoir); + } + + reservoirs().removeChildObject(reservoir); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RimProject::registerCaseInGridCollection(RigCaseData* rigEclipseCase) +{ + CVF_ASSERT(rigEclipseCase); + + RigMainGrid* equalGrid = m_gridCollection->findEqualGrid(rigEclipseCase->mainGrid()); + + if (equalGrid) + { + // Replace the grid with an already registered grid + rigEclipseCase->setMainGrid(equalGrid); + } + else + { + // This is the first insertion of this grid, compute cached data + rigEclipseCase->mainGrid()->computeCachedData(); + + std::vector grids; + rigEclipseCase->allGrids(&grids); + + size_t i; + for (i = 0; i < grids.size(); i++) + { + grids[i]->computeFaults(); + } + + equalGrid = rigEclipseCase->mainGrid(); + } + + m_gridCollection->addCase(rigEclipseCase); + + return equalGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, RimCase* rimReservoir) +{ + CVF_ASSERT(rimReservoir); + + RigCaseData* rigEclipseCase = rimReservoir->reservoirData(); + registerCaseInGridCollection(rigEclipseCase); + + caseGroup->addCase(rimReservoir); +} + diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index c295f230d7..084e92dff2 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -20,8 +20,10 @@ #include "cafPdmDocument.h" #include "RimScriptCollection.h" +#include "RimIdenticalGridCaseGroup.h" -class RimReservoir; +class RimCase; +class RigGridManager; //================================================================================================== /// @@ -32,8 +34,9 @@ class RimProject : public caf::PdmDocument CAF_PDM_HEADER_INIT; public: - caf::PdmPointersField reservoirs; - caf::PdmField scriptCollection; + caf::PdmPointersField reservoirs; + caf::PdmPointersField caseGroups; + caf::PdmField scriptCollection; void setUserScriptPath(const QString& path); //void updateProjectScriptPath(); @@ -45,11 +48,21 @@ public: void close(); + void insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, RimCase* rimReservoir); + + void moveEclipseCaseIntoCaseGroup(RimCase* rimReservoir); + void removeCaseFromAllGroups(RimCase* rimReservoir); + +private: + RigMainGrid* registerCaseInGridCollection(RigCaseData* rigEclipseCase); + protected: // Overridden methods virtual void initAfterRead(); virtual void setupBeforeSave(); private: - caf::PdmField m_projectFileVersionString; + caf::PdmField m_projectFileVersionString; + + cvf::ref m_gridCollection; }; diff --git a/ApplicationCode/ProjectDataModel/RimReservoir.h b/ApplicationCode/ProjectDataModel/RimReservoir.h deleted file mode 100644 index 0a8be97631..0000000000 --- a/ApplicationCode/ProjectDataModel/RimReservoir.h +++ /dev/null @@ -1,76 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cvfBase.h" -#include "cvfObject.h" -#include "cafPdmField.h" -#include "cafPdmObject.h" - - -class QString; - -class RigReservoir; -class RigGridBase; -class RimReservoirView; - -//================================================================================================== -// -// Interface for reservoirs. -// As this is a pure virtual class, the factory macros are not relevant (nor possible) to use -// CAF_PDM_HEADER_INIT and CAF_PDM_SOURCE_INIT -// -//================================================================================================== -class RimReservoir : public caf::PdmObject -{ - -public: - RimReservoir(); - virtual ~RimReservoir(); - - virtual bool openEclipseGridFile() = 0; - - RigReservoir* reservoirData(); - const RigReservoir* reservoirData() const; - - RimReservoirView* createAndAddReservoirView(); - void removeReservoirView(RimReservoirView* reservoirView); - - void removeResult(const QString& resultName); - - // Fields: - caf::PdmField caseName; - caf::PdmField releaseResultMemory; - - caf::PdmPointersField reservoirViews; - - virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName; } - - virtual QString locationOnDisc() const { return QString(); } - -protected: - // Overridden methods - virtual void initAfterRead(); - - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); - -protected: - cvf::ref m_rigReservoir; -}; - diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp new file mode 100644 index 0000000000..b88a70c3c3 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.cpp @@ -0,0 +1,699 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStdInclude.h" +#include "RimReservoirCellResultsCacher.h" +#include "RigCaseCellResultsData.h" +#include "RiaApplication.h" +#include "RigMainGrid.h" +#include "RigCell.h" +#include "cafProgressInfo.h" + +CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorage, "ReservoirCellResultStorage"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage::RimReservoirCellResultsStorage() + : m_cellResults(NULL), + m_ownerMainGrid(NULL) +{ + CAF_PDM_InitObject("Cacher", "", "", ""); + + CAF_PDM_InitField(&m_resultCacheFileName, "ResultCacheFileName", QString(), "UiDummyname", "", "" ,""); + m_resultCacheFileName.setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_resultCacheMetaData, "ResultCacheEntries", "UiDummyname", "", "", ""); + m_resultCacheMetaData.setUiHidden(true); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorage::~RimReservoirCellResultsStorage() +{ + m_resultCacheMetaData.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// This override populates the metainfo regarding the cell results data in the RigCaseCellResultsData +/// object. This metainfo will then be written to the project file when saving, and thus read on project file open. +/// This method then writes the actual double arrays to the data file in a simple format: +/// MagicNumber, Version, ResultVariables< Array < TimeStep< CellDataArraySize, CellData< Array > > > +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setupBeforeSave() +{ + m_resultCacheMetaData.deleteAllChildObjects(); + QString newValidCacheFileName = getValidCacheFileName(); + + // Delete the storage file + + QFileInfo storageFileInfo(newValidCacheFileName); + if (storageFileInfo.exists()) + { + QDir storageDir = storageFileInfo.dir(); + storageDir.remove(storageFileInfo.fileName()); + } + + if (!m_cellResults) return; + + const std::vector& resInfo = m_cellResults->infoForEachResultIndex(); + + bool hasResultsToStore = false; + for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) + { + if (resInfo[rIdx].m_needsToBeStored) + { + hasResultsToStore = true; + break; + } + } + + if(resInfo.size() && hasResultsToStore) + { + QDir::root().mkpath(getCacheDirectoryPath()); + + QFile cacheFile(newValidCacheFileName); + + if (!cacheFile.open(QIODevice::WriteOnly)) + { + qWarning() << "Saving project: Can't open the cache file : " + newValidCacheFileName; + return; + } + + m_resultCacheFileName = newValidCacheFileName; + + QDataStream stream(&cacheFile); + stream.setVersion(QDataStream::Qt_4_6); + stream << (quint32)0xCEECAC4E; // magic number + stream << (quint32)1; // Version number. Increment if needing to extend the format in ways that can not be handled generically by the reader + + caf::ProgressInfo progInfo(resInfo.size(), "Saving generated and imported properties"); + + for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) + { + // If there is no data, we do not store anything for the current result variable + // (Even not the metadata, of cause) + size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size(); + + if (timestepCount && resInfo[rIdx].m_needsToBeStored) + { + progInfo.setProgressDescription(resInfo[rIdx].m_resultName); + + // Create and setup the cache information for this result + RimReservoirCellResultsStorageEntryInfo* cacheEntry = new RimReservoirCellResultsStorageEntryInfo; + m_resultCacheMetaData.push_back(cacheEntry); + + cacheEntry->m_resultType = resInfo[rIdx].m_resultType; + cacheEntry->m_resultName = resInfo[rIdx].m_resultName; + cacheEntry->m_timeStepDates = resInfo[rIdx].m_timeStepDates; + + // Take note of the file position for fast lookup later + cacheEntry->m_filePosition = cacheFile.pos(); + + // Write all the scalar values for each time step to the stream, + // starting with the number of values + for (size_t tsIdx = 0; tsIdx < resInfo[rIdx].m_timeStepDates.size() ; ++tsIdx) + { + const std::vector* data = NULL; + if (tsIdx < timestepCount) + { + data = &(m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex, tsIdx)); + } + + if (data && data->size()) + { + + stream << (quint64)(data->size()); + for (size_t cIdx = 0; cIdx < data->size(); ++cIdx) + { + stream << (*data)[cIdx]; + } + } + else + { + stream << (quint64)0; + } + } + } + + progInfo.incrementProgress(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimReservoirCellResultsStorage::getValidCacheFileName() +{ + QString cacheFileName; + if (m_resultCacheFileName().isEmpty()) + { + QString newCacheDirPath = getCacheDirectoryPath(); + QUuid guid = QUuid::createUuid(); + cacheFileName = newCacheDirPath + "/" + guid.toString(); + } + else + { + // Make the path correct related to the possibly new project filename + QString newCacheDirPath = getCacheDirectoryPath(); + QFileInfo oldCacheFile(m_resultCacheFileName()); + + cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); + } + return cacheFileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimReservoirCellResultsStorage::getCacheDirectoryPath() +{ + QString cacheDirPath; + QString projectFileName = RiaApplication::instance()->project()->fileName(); + QFileInfo fileInfo(projectFileName); + cacheDirPath = fileInfo.canonicalPath(); + cacheDirPath += "/" + fileInfo.completeBaseName() + "_cache"; + return cacheDirPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setReaderInterface(RifReaderInterface* readerInterface) +{ + m_readerInterface = readerInterface; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderInterface* RimReservoirCellResultsStorage::readerInterface() +{ + return m_readerInterface.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex) +{ + // Special handling for SOIL + if (type == RimDefines::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL") + { + loadOrComputeSOILForTimeStep(timeStepIndex); + } + + size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; + + scalarResultIndex = m_cellResults->findScalarResultIndex(type, resultName); + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; + + if (type == RimDefines::GENERATED) + { + return cvf::UNDEFINED_SIZE_T; + } + + if (m_readerInterface.notNull()) + { + size_t timeStepCount = m_cellResults->infoForEachResultIndex()[scalarResultIndex].m_timeStepDates.size(); + + bool resultLoadingSucess = true; + + if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(timeStepCount); + + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[timeStepIndex]; + if (values.size() == 0) + { + if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, timeStepIndex, &values)) + { + resultLoadingSucess = false; + } + } + } + else if (type == RimDefines::STATIC_NATIVE) + { + m_cellResults->cellScalarResults(scalarResultIndex).resize(1); + + std::vector& values = m_cellResults->cellScalarResults(scalarResultIndex)[0]; + if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) + { + resultLoadingSucess = false; + } + } + + if (!resultLoadingSucess) + { + // Error logging + CVF_ASSERT(false); + } + } + + return scalarResultIndex; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName) +{ + size_t resultGridIndex = cvf::UNDEFINED_SIZE_T; + + resultGridIndex = m_cellResults->findScalarResultIndex(type, resultName); + + if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; + + // If we have any results on any timestep, assume we have loaded results already + + for (size_t tsIdx = 0; tsIdx < m_cellResults->timeStepCount(resultGridIndex); ++tsIdx) + { + if (m_cellResults->cellScalarResults(resultGridIndex, tsIdx).size()) + { + return resultGridIndex; + } + } + + if (type == RimDefines::GENERATED) + { + return cvf::UNDEFINED_SIZE_T; + } + + if (m_readerInterface.notNull()) + { + // Add one more result to result container + size_t timeStepCount = m_cellResults->infoForEachResultIndex()[resultGridIndex].m_timeStepDates.size(); + + bool resultLoadingSucess = true; + + if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) + { + m_cellResults->cellScalarResults(resultGridIndex).resize(timeStepCount); + + size_t i; + for (i = 0; i < timeStepCount; i++) + { + std::vector& values = m_cellResults->cellScalarResults(resultGridIndex)[i]; + if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, i, &values)) + { + resultLoadingSucess = false; + } + } + } + else if (type == RimDefines::STATIC_NATIVE) + { + m_cellResults->cellScalarResults(resultGridIndex).resize(1); + + std::vector& values = m_cellResults->cellScalarResults(resultGridIndex)[0]; + if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) + { + resultLoadingSucess = false; + } + } + + if (!resultLoadingSucess) + { + // Remove last scalar result because loading of result failed + m_cellResults->cellScalarResults(resultGridIndex).clear(); + } + } + + return resultGridIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::loadOrComputeSOIL() +{ + for (size_t timeStepIdx = 0; timeStepIdx < m_cellResults->maxTimeStepCount(); timeStepIdx++) + { + loadOrComputeSOILForTimeStep(timeStepIdx); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::loadOrComputeSOILForTimeStep(size_t timeStepIndex) +{ + size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex); + size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RimDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex); + + // Early exit if none of SWAT or SGAS is present + if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) + { + return; + } + + size_t soilResultValueCount = 0; + size_t soilTimeStepCount = 0; + + std::vector* swatForTimeStep = NULL; + std::vector* sgasForTimeStep = NULL; + if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) + { + swatForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSWAT, timeStepIndex)); + if (swatForTimeStep->size() == 0) + { + swatForTimeStep = NULL; + } + else + { + soilResultValueCount = swatForTimeStep->size(); + soilTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepDates.size(); + } + } + + if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) + { + sgasForTimeStep = &(m_cellResults->cellScalarResults(scalarIndexSGAS, timeStepIndex)); + if (sgasForTimeStep->size() == 0) + { + sgasForTimeStep = NULL; + } + else + { + soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep->size()); + + size_t sgasTimeStepCount = m_cellResults->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepDates.size(); + soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); + } + } + + size_t soilResultGridIndex = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + if (soilResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + soilResultGridIndex = m_cellResults->addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL", false); + CVF_ASSERT(soilResultGridIndex != cvf::UNDEFINED_SIZE_T); + + m_cellResults->cellScalarResults(soilResultGridIndex).resize(soilTimeStepCount); + + for (size_t timeStepIdx = 0; timeStepIdx < soilTimeStepCount; timeStepIdx++) + { + m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIdx).resize(soilResultValueCount); + } + } + + std::vector& soilForTimeStep = m_cellResults->cellScalarResults(soilResultGridIndex, timeStepIndex); + +#pragma omp parallel for + for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) + { + double soilValue = 1.0; + if (sgasForTimeStep) + { + soilValue -= sgasForTimeStep->at(idx); + } + + if (swatForTimeStep) + { + soilValue -= swatForTimeStep->at(idx); + } + + soilForTimeStep[idx] = soilValue; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::computeDepthRelatedResults() +{ + size_t depthResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DEPTH"); + size_t dxResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DX"); + size_t dyResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DY"); + size_t dzResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DZ"); + size_t topsResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "TOPS"); + size_t bottomResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM"); + + bool computeDepth = false; + bool computeDx = false; + bool computeDy = false; + bool computeDz = false; + bool computeTops = false; + bool computeBottom = false; + + size_t resultValueCount = m_ownerMainGrid->cells().size(); + + if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + depthResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); + computeDepth = true; + } + + if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dxResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DX", false, resultValueCount); + computeDx = true; + } + + if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dyResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DY", false, resultValueCount); + computeDy = true; + } + + if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + dzResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "DZ", false, resultValueCount); + computeDz = true; + } + + if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + topsResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "TOPS", false, resultValueCount); + computeTops = true; + } + + if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) + { + bottomResultGridIndex = m_cellResults->addStaticScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM", false, resultValueCount); + computeBottom = true; + } + + std::vector< std::vector >& depth = m_cellResults->cellScalarResults(depthResultGridIndex); + std::vector< std::vector >& dx = m_cellResults->cellScalarResults(dxResultGridIndex); + std::vector< std::vector >& dy = m_cellResults->cellScalarResults(dyResultGridIndex); + std::vector< std::vector >& dz = m_cellResults->cellScalarResults(dzResultGridIndex); + std::vector< std::vector >& tops = m_cellResults->cellScalarResults(topsResultGridIndex); + std::vector< std::vector >& bottom = m_cellResults->cellScalarResults(bottomResultGridIndex); + + size_t cellIdx = 0; + for (cellIdx = 0; cellIdx < m_ownerMainGrid->cells().size(); cellIdx++) + { + const RigCell& cell = m_ownerMainGrid->cells()[cellIdx]; + + if (computeDepth) + { + depth[0][cellIdx] = cvf::Math::abs(cell.center().z()); + } + + if (computeDx) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); + dx[0][cellIdx] = cvf::Math::abs(cellWidth.x()); + } + + if (computeDy) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); + dy[0][cellIdx] = cvf::Math::abs(cellWidth.y()); + } + + if (computeDz) + { + cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); + dz[0][cellIdx] = cvf::Math::abs(cellWidth.z()); + } + + if (computeTops) + { + tops[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); + } + + if (computeBottom) + { + bottom[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& resultName) +{ + size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; + + scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = this->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, resultName); + } + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::GENERATED, resultName); + } + + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + scalarResultIndex = m_cellResults->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName); + } + + return scalarResultIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cellResults) +{ + m_cellResults = cellResults; + + if (m_cellResults == NULL) + return; + + // Now that we have got the results container, we can finally + // Read data from the internal storage and populate it + + if (m_resultCacheFileName().isEmpty()) + return; + + // Get the name of the cache name relative to the current project file position + QString newValidCacheFileName = getValidCacheFileName(); + + QFile storageFile(newValidCacheFileName); + + // Warn if we thought we were to find some data on the storage file + + if (!storageFile.exists() && m_resultCacheMetaData.size()) + { + qWarning() << "Reading stored results: Missing the storage file : " + newValidCacheFileName; + return; + } + + if (!storageFile.open(QIODevice::ReadOnly)) + { + qWarning() << "Reading stored results: Can't open the file : " + newValidCacheFileName; + return; + } + + QDataStream stream(&storageFile); + stream.setVersion(QDataStream::Qt_4_6); + quint32 magicNumber = 0; + quint32 versionNumber = 0; + stream >> magicNumber; + + if (magicNumber != 0xCEECAC4E) + { + qWarning() << "Reading stored results: The storage file has wrong type "; + return; + } + + stream >> versionNumber; + if (versionNumber > 1 ) + { + qWarning() << "Reading stored results: The storage file has been written by a newer version of ResInsight"; + return; + } + + caf::ProgressInfo progress(m_resultCacheMetaData.size(), "Reading internally stored results"); + // Fill the object with data from the storage + + for (size_t rIdx = 0; rIdx < m_resultCacheMetaData.size(); ++rIdx) + { + RimReservoirCellResultsStorageEntryInfo* resInfo = m_resultCacheMetaData[rIdx]; + size_t resultIndex = m_cellResults->addEmptyScalarResult(resInfo->m_resultType(), resInfo->m_resultName(), true); + + m_cellResults->setTimeStepDates(resultIndex, resInfo->m_timeStepDates()); + + progress.setProgressDescription(resInfo->m_resultName); + + for (size_t tsIdx = 0; tsIdx < resInfo->m_timeStepDates().size(); ++tsIdx) + { + std::vector* data = NULL; + + data = &(m_cellResults->cellScalarResults(rIdx, tsIdx)); + + quint64 cellCount = 0; + stream >> cellCount; + data->resize(cellCount, HUGE_VAL); + + for (size_t cIdx = 0; cIdx < cellCount; ++cIdx) + { + stream >> (*data)[cIdx]; + } + } + + progress.incrementProgress(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimReservoirCellResultsStorage::setMainGrid(RigMainGrid* mainGrid) +{ + m_ownerMainGrid = mainGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimReservoirCellResultsStorage::storedResultsCount() +{ + return m_resultCacheMetaData.size(); +} + + +CAF_PDM_SOURCE_INIT(RimReservoirCellResultsStorageEntryInfo, "ResultStorageEntryInfo"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorageEntryInfo::RimReservoirCellResultsStorageEntryInfo() +{ + CAF_PDM_InitObject("Cache Entry", "", "", ""); + + CAF_PDM_InitField(&m_resultType, "ResultType", caf::AppEnum(RimDefines::REMOVED), "ResultType", "", "" ,""); + CAF_PDM_InitField(&m_resultName, "ResultName", QString(), "ResultName", "", "" ,""); + CAF_PDM_InitFieldNoDefault(&m_timeStepDates, "TimeSteps", "TimeSteps", "", "" ,""); + CAF_PDM_InitField(&m_filePosition, "FilePositionDataStart", qint64(-1), "FilePositionDataStart", "", "" ,""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimReservoirCellResultsStorageEntryInfo::~RimReservoirCellResultsStorageEntryInfo() +{ + +} diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h new file mode 100644 index 0000000000..dd0e154388 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsCacher.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafAppEnum.h" +#include "RimDefines.h" + +class RimReservoirCellResultsStorageEntryInfo; +class RigCaseCellResultsData; +class RifReaderInterface; +class RigMainGrid; + +class RimReservoirCellResultsStorage : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimReservoirCellResultsStorage(); + virtual ~RimReservoirCellResultsStorage(); + + void setCellResults(RigCaseCellResultsData* cellResults); + RigCaseCellResultsData* cellResults() { return m_cellResults; } + const RigCaseCellResultsData* cellResults() const { return m_cellResults; } + + size_t storedResultsCount(); + + void setMainGrid(RigMainGrid* mainGrid); + + void setReaderInterface(RifReaderInterface* readerInterface); + RifReaderInterface* readerInterface(); + + void loadOrComputeSOIL(); + void computeDepthRelatedResults(); + + size_t findOrLoadScalarResultForTimeStep(RimDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex); + size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); + size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types. + +protected: + // Overridden methods from PdmObject + virtual void setupBeforeSave(); + +private: + void loadOrComputeSOILForTimeStep(size_t timeStepIndex); + + QString getValidCacheFileName(); + QString getCacheDirectoryPath(); + + // Fields + caf::PdmField m_resultCacheFileName; + caf::PdmPointersField + m_resultCacheMetaData; + + cvf::ref m_readerInterface; + RigCaseCellResultsData* m_cellResults; + RigMainGrid* m_ownerMainGrid; +}; + +class RimReservoirCellResultsStorageEntryInfo : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimReservoirCellResultsStorageEntryInfo(); + virtual ~RimReservoirCellResultsStorageEntryInfo(); + + caf::PdmField > m_resultType; + caf::PdmField m_resultName; + caf::PdmField< std::vector > m_timeStepDates; + caf::PdmField m_filePosition; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp index ecad221c2f..8135349553 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.cpp @@ -16,15 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIViewer.h" +#include "RiaStdInclude.h" +#include "RiuViewer.h" #include "RimReservoirView.h" -#include "RIMainWindow.h" +#include "RiuMainWindow.h" #include "RigGridBase.h" -#include "RigReservoir.h" -#include "RIApplication.h" -#include "RIPreferences.h" +#include "RigCaseData.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" #include "cafEffectGenerator.h" #include "cafFrameAnimationControl.h" @@ -32,7 +32,7 @@ #include "RimCellRangeFilterCollection.h" #include "cvfStructGridGeometryGenerator.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RivCellEdgeEffectGenerator.h" #include "RimCellEdgeResultSlot.h" #include "cvfqtUtils.h" @@ -41,7 +41,7 @@ #include "cafCadNavigation.h" #include "cafCeetronNavigation.h" -#include "RimReservoir.h" +#include "RimCase.h" #include "Rim3dOverlayInfoConfig.h" #include "RigGridScalarDataAccess.h" @@ -82,8 +82,8 @@ CAF_PDM_SOURCE_INIT(RimReservoirView, "ReservoirView"); //-------------------------------------------------------------------------------------------------- RimReservoirView::RimReservoirView() { - RIApplication* app = RIApplication::instance(); - RIPreferences* preferences = app->preferences(); + RiaApplication* app = RiaApplication::instance(); + RiaPreferences* preferences = app->preferences(); CVF_ASSERT(preferences); CAF_PDM_InitObject("Reservoir View", ":/ReservoirView.png", "", ""); @@ -137,6 +137,9 @@ RimReservoirView::RimReservoirView() CAF_PDM_InitField(&showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells", "", "", ""); CAF_PDM_InitField(&showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", ""); + CAF_PDM_InitField(&backgroundColor, "ViewBackgroundColor", cvf::Color3f(0.69f, 0.77f, 0.87f), "Viewer Background", "", "", ""); + + CAF_PDM_InitField(&cameraPosition, "CameraPosition", cvf::Mat4d::IDENTITY, "", "", "", ""); @@ -169,7 +172,7 @@ RimReservoirView::~RimReservoirView() if (m_viewer) { - RIMainWindow::instance()->removeViewer(m_viewer); + RiuMainWindow::instance()->removeViewer(m_viewer); } m_geometry->clearGeometryCache(); @@ -189,19 +192,19 @@ void RimReservoirView::updateViewerWidget() if (!m_viewer) { QGLFormat glFormat; - glFormat.setDirectRendering(RIApplication::instance()->useShaders()); + glFormat.setDirectRendering(RiaApplication::instance()->useShaders()); - m_viewer = new RIViewer(glFormat, NULL); + m_viewer = new RiuViewer(glFormat, NULL); m_viewer->setOwnerReservoirView(this); - RIMainWindow::instance()->addViewer(m_viewer); + RiuMainWindow::instance()->addViewer(m_viewer); m_viewer->setMinNearPlaneDistance(10); this->cellResult()->legendConfig->recreateLegend(); this->cellEdgeResult()->legendConfig->recreateLegend(); m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend()); m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend()); - if (RIApplication::instance()->navigationPolicy() == RIApplication::NAVIGATION_POLICY_CEETRON) + if (RiaApplication::instance()->navigationPolicy() == RiaApplication::NAVIGATION_POLICY_CEETRON) { m_viewer->setNavigationPolicy(new caf::CeetronNavigation); } @@ -210,16 +213,18 @@ void RimReservoirView::updateViewerWidget() m_viewer->setNavigationPolicy(new caf::CadNavigation); } - m_viewer->enablePerfInfoHud(RIApplication::instance()->showPerformanceInfo()); + m_viewer->enablePerfInfoHud(RiaApplication::instance()->showPerformanceInfo()); //m_viewer->layoutWidget()->showMaximized(); isViewerCreated = true; } - RIMainWindow::instance()->setActiveViewer(m_viewer); + RiuMainWindow::instance()->setActiveViewer(m_viewer); if (isViewerCreated) m_viewer->mainCamera()->setViewMatrix(cameraPosition); + m_viewer->mainCamera()->viewport()->setClearColor(cvf::Color4f(backgroundColor())); + m_viewer->update(); } else @@ -267,11 +272,11 @@ void RimReservoirView::updateViewerWidgetWindowTitle() void RimReservoirView::clampCurrentTimestep() { // Clamp the current timestep to actual possibilities - if (this->gridCellResults()) + if (this->currentGridCellResults()->cellResults()) { - if (m_currentTimeStep() > this->gridCellResults()->maxTimeStepCount()) + if (m_currentTimeStep() >= static_cast(this->currentGridCellResults()->cellResults()->maxTimeStepCount())) { - m_currentTimeStep = static_cast(this->gridCellResults()->maxTimeStepCount()) -1; + m_currentTimeStep = static_cast(this->currentGridCellResults()->cellResults()->maxTimeStepCount()) -1; } } @@ -298,7 +303,7 @@ void RimReservoirView::createDisplayModelAndRedraw() } } - RIMainWindow::instance()->refreshAnimationActions(); + RiuMainWindow::instance()->refreshAnimationActions(); } //-------------------------------------------------------------------------------------------------- @@ -358,6 +363,13 @@ void RimReservoirView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, createDisplayModelAndRedraw(); } } + else if (changedField == &backgroundColor ) + { + if (viewer() != NULL) + { + updateViewerWidget(); + } + } else if (changedField == &m_currentTimeStep) { if (m_viewer) @@ -448,10 +460,10 @@ void RimReservoirView::createDisplayModel() || this->propertyFilterCollection()->hasActiveDynamicFilters() || this->wellCollection->hasVisibleWellPipes()) { - CVF_ASSERT(gridCellResults()); + CVF_ASSERT(currentGridCellResults()); size_t i; - for (i = 0; i < gridCellResults()->maxTimeStepCount(); i++) + for (i = 0; i < currentGridCellResults()->cellResults()->maxTimeStepCount(); i++) { timeStepIndices.push_back(i); } @@ -690,16 +702,16 @@ void RimReservoirView::loadDataAndUpdate() { if (!m_reservoir->openEclipseGridFile()) { - QMessageBox::warning(RIMainWindow::instance(), "Error when opening project file", "Could not open the Eclipse Grid file (EGRID/GRID): \n"+ m_reservoir->caseName()); + QMessageBox::warning(RiuMainWindow::instance(), "Error when opening project file", "Could not open the Eclipse Grid file (EGRID/GRID): \n"+ m_reservoir->caseName()); m_reservoir = NULL; return; } else { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeSOIL) { - RigReservoirCellResults* results = gridCellResults(); + RimReservoirCellResultsStorage* results = currentGridCellResults(); CVF_ASSERT(results); results->loadOrComputeSOIL(); } @@ -709,7 +721,7 @@ void RimReservoirView::loadDataAndUpdate() CVF_ASSERT(this->cellResult() != NULL); this->cellResult()->loadResult(); - if (m_reservoir->reservoirData()->mainGrid()->globalFractureModelActiveCellCount() == 0) + if (m_reservoir->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) { this->cellResult->porosityModel.setUiHidden(true); } @@ -820,7 +832,7 @@ void RimReservoirView::updateStaticCellColors(unsigned short geometryType) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer* RimReservoirView::viewer() +RiuViewer* RimReservoirView::viewer() { return m_viewer; } @@ -835,20 +847,20 @@ bool RimReservoirView::pickInfo(size_t gridIndex, size_t cellIndex, const cvf::V if (m_reservoir) { - const RigReservoir* reservoir = m_reservoir->reservoirData(); - if (reservoir) + const RigCaseData* eclipseCase = m_reservoir->reservoirData(); + if (eclipseCase) { size_t i = 0; size_t j = 0; size_t k = 0; - if (reservoir->grid(gridIndex)->ijkFromCellIndex(cellIndex, &i, &j, &k)) + if (eclipseCase->grid(gridIndex)->ijkFromCellIndex(cellIndex, &i, &j, &k)) { // Adjust to 1-based Eclipse indexing i++; j++; k++; - cvf::Vec3d domainCoord = point + reservoir->grid(gridIndex)->displayModelOffset(); + cvf::Vec3d domainCoord = point + eclipseCase->grid(gridIndex)->displayModelOffset(); pickInfoText->sprintf("Hit grid %u, cell [%u, %u, %u], intersection point: [E: %.2f, N: %.2f, Depth: %.2f]", static_cast(gridIndex), static_cast(i), static_cast(j), static_cast(k), domainCoord.x(), domainCoord.y(), -domainCoord.z()); return true; @@ -862,18 +874,19 @@ bool RimReservoirView::pickInfo(size_t gridIndex, size_t cellIndex, const cvf::V //-------------------------------------------------------------------------------------------------- /// Get the current scalar value for the display face at the given index //-------------------------------------------------------------------------------------------------- -void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) const +void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) { CVF_ASSERT(resultInfoText); if (m_reservoir && m_reservoir->reservoirData()) { - const RigReservoir* reservoir = m_reservoir->reservoirData(); - const RigGridBase* grid = reservoir->grid(gridIndex); + RigCaseData* eclipseCase = m_reservoir->reservoirData(); + RigGridBase* grid = eclipseCase->grid(gridIndex); + if (this->cellResult()->hasResult()) { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, m_currentTimeStep, this->cellResult()->gridScalarIndex()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, m_currentTimeStep, this->cellResult()->gridScalarIndex()); if (dataAccessObject.notNull()) { double scalarValue = dataAccessObject->cellScalar(cellIndex); @@ -893,8 +906,8 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex, if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; // Cell edge results are static, results are loaded for first time step only - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - cvf::ref dataAccessObject = grid->dataAccessObject(porosityModel, 0, resultIndices[idx]); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + cvf::ref dataAccessObject = eclipseCase->dataAccessObject(grid, porosityModel, 0, resultIndices[idx]); if (dataAccessObject.notNull()) { double scalarValue = dataAccessObject->cellScalar(cellIndex); @@ -957,16 +970,30 @@ void RimReservoirView::setupBeforeSave() //-------------------------------------------------------------------------------------------------- /// Convenience for quick access to results //-------------------------------------------------------------------------------------------------- -RigReservoirCellResults* RimReservoirView::gridCellResults() +RimReservoirCellResultsStorage* RimReservoirView::currentGridCellResults() +{ + if (m_reservoir) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult->porosityModel()); + + return m_reservoir->results(porosityModel); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RimReservoirView::currentActiveCellInfo() { if (m_reservoir && - m_reservoir->reservoirData() && - m_reservoir->reservoirData()->mainGrid() + m_reservoir->reservoirData() ) { - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult->porosityModel()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult->porosityModel()); - return m_reservoir->reservoirData()->mainGrid()->results(porosityModel); + return m_reservoir->reservoirData()->activeCellInfo(porosityModel); } return NULL; @@ -1032,11 +1059,11 @@ void RimReservoirView::updateLegends() return; } - RigReservoir* reservoir = m_reservoir->reservoirData(); - CVF_ASSERT(reservoir); + RigCaseData* eclipseCase = m_reservoir->reservoirData(); + CVF_ASSERT(eclipseCase); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); - RigReservoirCellResults* results = reservoir->mainGrid()->results(porosityModel); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResult()->porosityModel()); + RigCaseCellResultsData* results = eclipseCase->results(porosityModel); CVF_ASSERT(results); if (this->cellResult()->hasResult()) @@ -1085,7 +1112,7 @@ void RimReservoirView::updateLegends() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimReservoirView::setEclipseCase(RimReservoir* reservoir) +void RimReservoirView::setEclipseCase(RimCase* reservoir) { m_reservoir = reservoir; } @@ -1093,7 +1120,7 @@ void RimReservoirView::setEclipseCase(RimReservoir* reservoir) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimReservoir* RimReservoirView::eclipseCase() +RimCase* RimReservoirView::eclipseCase() { return m_reservoir; } @@ -1115,7 +1142,7 @@ void RimReservoirView::syncronizeWellsWithResults() { if (!(m_reservoir && m_reservoir->reservoirData()) ) return; - cvf::Collection wellResults = m_reservoir->reservoirData()->wellResults(); + cvf::Collection wellResults = m_reservoir->reservoirData()->wellResults(); // Find corresponding well from well result, or create a new size_t wIdx; @@ -1137,7 +1164,7 @@ void RimReservoirView::syncronizeWellsWithResults() for (wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx) { RimWell* well = this->wellCollection()->wells()[wIdx]; - RigWellResults* wellRes = well->wellResults(); + RigSingleWellResultsData* wellRes = well->wellResults(); if (wellRes == NULL) { delete well; @@ -1171,13 +1198,17 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl // If all wells are forced off, return if (this->wellCollection()->wellCellVisibility() == RimWellCollection::FORCE_ALL_OFF) return; + RigActiveCellInfo* activeCellInfo = this->currentActiveCellInfo(); + + CVF_ASSERT(activeCellInfo); + // Loop over the wells and find their contribution for (size_t wIdx = 0; wIdx < this->wellCollection()->wells().size(); ++wIdx) { RimWell* well = this->wellCollection()->wells()[wIdx]; if (this->wellCollection()->wellCellVisibility() == RimWellCollection::FORCE_ALL_ON || well->showWellCells()) { - RigWellResults* wres = well->wellResults(); + RigSingleWellResultsData* wres = well->wellResults(); if (!wres) continue; const std::vector< RigWellResultFrame >& wellResFrames = wres->m_wellCellsTimeSteps; @@ -1235,7 +1266,9 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl for ( fIdx = 0; fIdx < cellCountFenceDirection; ++fIdx) { size_t fenceCellIndex = grid->cellIndexFromIJK(*pI,*pJ,*pK); - if (grid->cell(fenceCellIndex).isActiveInMatrixModel()) + size_t globalGridCellIndex = grid->globalGridCellIndex(fenceCellIndex); + + if (activeCellInfo && activeCellInfo->isActive(globalGridCellIndex)) { (*visibleCells)[fenceCellIndex] = true; } diff --git a/ApplicationCode/ProjectDataModel/RimReservoirView.h b/ApplicationCode/ProjectDataModel/RimReservoirView.h index 2dcb730882..68ecde5cac 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirView.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirView.h @@ -23,7 +23,7 @@ #include #include -#include "RimReservoir.h" +#include "RimCase.h" #include "RimResultSlot.h" #include "RimCellEdgeResultSlot.h" #include "RimCellRangeFilter.h" @@ -39,7 +39,7 @@ #include "RivReservoirViewPartMgr.h" #include "RivReservoirPipesPartMgr.h" -class RIViewer; +class RiuViewer; class RigGridBase; class RigGridCellFaceVisibilityFilter; class RivReservoirViewPartMgr; @@ -51,7 +51,6 @@ namespace cvf class ModelBasicList; } - enum ViewState { GEOMETRY_ONLY, @@ -85,97 +84,103 @@ public: NO_SURFACE }; - // Public fields: + // Fields containing child objects : - caf::PdmField cellResult; - caf::PdmField cellEdgeResult; - caf::PdmField overlayInfoConfig; + caf::PdmField cellResult; + caf::PdmField cellEdgeResult; - caf::PdmField scaleZ; - caf::PdmField showWindow; - caf::PdmField name; + caf::PdmField rangeFilterCollection; + caf::PdmField propertyFilterCollection; - // Visibility - caf::PdmField showInvalidCells; - caf::PdmField showInactiveCells; - caf::PdmField showMainGrid; + caf::PdmField wellCollection; - caf::PdmField wellCollection; + caf::PdmField overlayInfoConfig; - caf::PdmField rangeFilterCollection; - caf::PdmField propertyFilterCollection; + // Visualization setup fields - caf::PdmField< caf::AppEnum< MeshModeType > > meshMode; - caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode; + caf::PdmField name; + caf::PdmField scaleZ; + caf::PdmField showWindow; + + caf::PdmField showInvalidCells; + caf::PdmField showInactiveCells; + caf::PdmField showMainGrid; + + caf::PdmField< caf::AppEnum< MeshModeType > > meshMode; + caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode; + + caf::PdmField< cvf::Color3f > backgroundColor; + + caf::PdmField cameraPosition; + + caf::PdmField maximumFrameRate; + caf::PdmField animationMode; + + // Access internal objects + RimReservoirCellResultsStorage* currentGridCellResults(); + RigActiveCellInfo* currentActiveCellInfo(); + + void setEclipseCase(RimCase* reservoir); + RimCase* eclipseCase(); // Animation - caf::PdmField maximumFrameRate; - caf::PdmField animationMode; - - int currentTimeStep() { return m_currentTimeStep;} - void setCurrentTimeStep(int frameIdx); - void updateCurrentTimeStepAndRedraw(); - void endAnimation(); + int currentTimeStep() { return m_currentTimeStep;} + void setCurrentTimeStep(int frameIdx); + void updateCurrentTimeStepAndRedraw(); + void endAnimation(); // 3D Viewer - // Cam pos should be a field, but is not yet supported bu caf::Pdm - caf::PdmField cameraPosition; - void setDefaultView(); - - RIViewer* viewer(); - void updateViewerWidget(); - void updateViewerWidgetWindowTitle(); + RiuViewer* viewer(); + void updateViewerWidget(); + void updateViewerWidgetWindowTitle(); + void setDefaultView(); // Picking info - bool pickInfo(size_t gridIndex, size_t cellIndex, const cvf::Vec3d& point, QString* pickInfoText) const; - void appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) const; - - RigReservoirCellResults* gridCellResults(); - - void setEclipseCase(RimReservoir* reservoir); - RimReservoir* eclipseCase(); - - void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); + bool pickInfo(size_t gridIndex, size_t cellIndex, const cvf::Vec3d& point, QString* pickInfoText) const; + void appendCellResultInfo(size_t gridIndex, size_t cellIndex, QString* resultInfoText) ; + // Does this belong here, really ? + void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); // Display model generation public: - void loadDataAndUpdate(); - void createDisplayModelAndRedraw(); - void scheduleGeometryRegen(unsigned short geometryType); - void schedulePipeGeometryRegen(); + void loadDataAndUpdate(); + void createDisplayModelAndRedraw(); + void scheduleGeometryRegen(unsigned short geometryType); + void schedulePipeGeometryRegen(); + + // Display model generation +private: + void createDisplayModel(); + void updateDisplayModelVisibility(); + void updateCurrentTimeStep(); + void indicesToVisibleGrids(std::vector* gridIndices); + void updateScaleTransform(); + void updateStaticCellColors(); + void updateStaticCellColors(unsigned short geometryType); + void updateLegends(); + + cvf::ref m_geometry; + cvf::ref m_pipesPartManager; // Overridden PDM methods: public: - virtual caf::PdmFieldHandle* userDescriptionField() { return &name;} - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual caf::PdmFieldHandle* userDescriptionField() { return &name;} + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); protected: - virtual void initAfterRead(); - virtual void setupBeforeSave(); + virtual void initAfterRead(); + virtual void setupBeforeSave(); + // Really private +private: + void syncronizeWellsWithResults(); + void clampCurrentTimestep(); private: - void syncronizeWellsWithResults(); - void clampCurrentTimestep(); - -private: - caf::PdmField m_currentTimeStep; - QPointer m_viewer; - caf::PdmPointer m_reservoir; + caf::PdmField m_currentTimeStep; + QPointer m_viewer; + caf::PdmPointer m_reservoir; -// Display model generation -private: - void createDisplayModel(); - void updateDisplayModelVisibility(); - void updateCurrentTimeStep(); - void indicesToVisibleGrids(std::vector* gridIndices); - void updateScaleTransform(); - void updateStaticCellColors(); - void updateStaticCellColors(unsigned short geometryType); - void updateLegends(); - - cvf::ref m_geometry; - cvf::ref m_pipesPartManager; }; diff --git a/ApplicationCode/ProjectDataModel/RimResultReservoir.cpp b/ApplicationCode/ProjectDataModel/RimResultCase.cpp similarity index 65% rename from ApplicationCode/ProjectDataModel/RimResultReservoir.cpp rename to ApplicationCode/ProjectDataModel/RimResultCase.cpp index fb42bda412..4f4f7fca76 100644 --- a/ApplicationCode/ProjectDataModel/RimResultReservoir.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultCase.cpp @@ -16,11 +16,11 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RimResultReservoir.h" -#include "RigReservoir.h" +#include "RiaStdInclude.h" +#include "RimResultCase.h" +#include "RigCaseData.h" #include "RifReaderEclipseOutput.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RimReservoirView.h" #include "RifReaderMockModel.h" #include "RifReaderEclipseInput.h" @@ -28,13 +28,15 @@ #include "RimProject.h" -CAF_PDM_SOURCE_INIT(RimResultReservoir, "EclipseCase"); +CAF_PDM_SOURCE_INIT(RimResultCase, "EclipseCase"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimResultReservoir::RimResultReservoir() - : RimReservoir() +RimResultCase::RimResultCase() + : RimCase() { + CAF_PDM_InitObject("Eclipse Case", ":/AppLogo48x48.png", "", ""); + CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case file name", "", "" ,""); CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,""); } @@ -43,14 +45,14 @@ RimResultReservoir::RimResultReservoir() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimResultReservoir::openEclipseGridFile() +bool RimResultCase::openEclipseGridFile() { caf::ProgressInfo progInfo(50, "Reading Eclipse Grid File"); progInfo.setProgressDescription("Open Grid File"); progInfo.setNextProgressIncrement(48); // Early exit if reservoir data is created - if (m_rigReservoir.notNull()) return true; + if (this->reservoirData()) return true; cvf::ref readerInterface; @@ -58,28 +60,6 @@ bool RimResultReservoir::openEclipseGridFile() { readerInterface = this->createMockModel(this->caseName()); - size_t matrixActiveCellCount = 0; - size_t fractureActiveCellCount = 0; - - for (size_t cellIdx = 0; cellIdx < m_rigReservoir->mainGrid()->cells().size(); cellIdx++) - { - const RigCell& cell = m_rigReservoir->mainGrid()->cells()[cellIdx]; - - if (cell.isActiveInMatrixModel()) - { - matrixActiveCellCount++; - } - if (cell.isActiveInFractureModel()) - { - fractureActiveCellCount++; - } - - } - m_rigReservoir->mainGrid()->setGlobalMatrixModelActiveCellCount(matrixActiveCellCount); - m_rigReservoir->mainGrid()->setGlobalFractureModelActiveCellCount(fractureActiveCellCount); - - m_rigReservoir->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); - m_rigReservoir->mainGrid()->results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); } else { @@ -89,40 +69,96 @@ bool RimResultReservoir::openEclipseGridFile() return false; } - RigReservoir* reservoir = new RigReservoir; + cvf::ref eclipseCase = new RigCaseData; readerInterface = new RifReaderEclipseOutput; - if (!readerInterface->open(fname, reservoir)) + if (!readerInterface->open(fname, eclipseCase.p())) { - delete reservoir; return false; } - m_rigReservoir = reservoir; + this->setReservoirData( eclipseCase.p() ); } + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + progInfo.incrementProgress(); - CVF_ASSERT(m_rigReservoir.notNull()); + CVF_ASSERT(this->reservoirData()); CVF_ASSERT(readerInterface.notNull()); - progInfo.setProgressDescription("Computing Faults"); - m_rigReservoir->computeFaults(); - - progInfo.incrementProgress(); - progInfo.setProgressDescription("Computing Cache"); - m_rigReservoir->mainGrid()->computeCachedData(); + progInfo.setProgressDescription("Computing Case Cache"); + computeCachedData(); return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimResultCase::openAndReadActiveCellData(RigCaseData* mainEclipseCase) +{ + cvf::ref readerInterface; + + if (caseName().contains("Result Mock Debug Model")) + { + readerInterface = this->createMockModel(this->caseName()); + } + else + { + QString fname = createAbsoluteFilenameFromCase(caseName); + if (fname.isEmpty()) + { + return false; + } + + cvf::ref eclipseCase = new RigCaseData; + + CVF_ASSERT(mainEclipseCase && mainEclipseCase->mainGrid()); + eclipseCase->setMainGrid(mainEclipseCase->mainGrid()); + + size_t scalarIndexWithMaxTimeStepCount = cvf::UNDEFINED_SIZE_T; + mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->maxTimeStepCount(&scalarIndexWithMaxTimeStepCount); + if (scalarIndexWithMaxTimeStepCount == cvf::UNDEFINED_SIZE_T) + { + return false; + } + + std::vector timeStepDates = mainEclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->timeStepDates(scalarIndexWithMaxTimeStepCount); + + cvf::ref readerEclipseOutput = new RifReaderEclipseOutput; + if (!readerEclipseOutput->openAndReadActiveCellData(fname, timeStepDates, eclipseCase.p())) + { + return false; + } + + readerEclipseOutput->close(); + + this->setReservoirData( eclipseCase.p() ); + + readerInterface = readerEclipseOutput; + } + + results(RifReaderInterface::MATRIX_RESULTS)->setReaderInterface(readerInterface.p()); + results(RifReaderInterface::FRACTURE_RESULTS)->setReaderInterface(readerInterface.p()); + + CVF_ASSERT(this->reservoirData()); + CVF_ASSERT(readerInterface.notNull()); + + reservoirData()->computeActiveCellBoundingBoxes(); + + return true; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RimResultReservoir::createMockModel(QString modelName) +cvf::ref RimResultCase::createMockModel(QString modelName) { cvf::ref mockFileInterface = new RifReaderMockModel; - cvf::ref reservoir = new RigReservoir; + cvf::ref reservoir = new RigCaseData; if (modelName == "Result Mock Debug Model Simple") { @@ -134,12 +170,16 @@ cvf::ref RimResultReservoir::createMockModel(QString modelNa mockFileInterface->open("", reservoir.p()); { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } { size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); - reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); + + //TODO: Rewrite active cell info in mock models + //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } } else if (modelName == "Result Mock Debug Model With Results") @@ -184,7 +224,7 @@ cvf::ref RimResultReservoir::createMockModel(QString modelNa } - m_rigReservoir = reservoir; + this->setReservoirData( reservoir.p() ); return mockFileInterface.p(); } @@ -193,7 +233,7 @@ cvf::ref RimResultReservoir::createMockModel(QString modelNa //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimResultReservoir::~RimResultReservoir() +RimResultCase::~RimResultCase() { reservoirViews.deleteAllChildObjects(); } @@ -201,7 +241,7 @@ RimResultReservoir::~RimResultReservoir() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimResultReservoir::locationOnDisc() const +QString RimResultCase::locationOnDisc() const { return caseDirectory; } @@ -209,7 +249,7 @@ QString RimResultReservoir::locationOnDisc() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimResultReservoir::createAbsoluteFilenameFromCase(const QString& caseName) +QString RimResultCase::createAbsoluteFilenameFromCase(const QString& caseName) { QString candidate; diff --git a/ApplicationCode/ProjectDataModel/RimResultReservoir.h b/ApplicationCode/ProjectDataModel/RimResultCase.h similarity index 86% rename from ApplicationCode/ProjectDataModel/RimResultReservoir.h rename to ApplicationCode/ProjectDataModel/RimResultCase.h index cfbffd5abc..1b2aa10235 100644 --- a/ApplicationCode/ProjectDataModel/RimResultReservoir.h +++ b/ApplicationCode/ProjectDataModel/RimResultCase.h @@ -22,22 +22,23 @@ #include "cvfObject.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimReservoir.h" +#include "RimCase.h" - class RifReaderInterface; +class RifReaderInterface; +class RigMainGrid; //================================================================================================== // // // //================================================================================================== -class RimResultReservoir : public RimReservoir +class RimResultCase : public RimCase { CAF_PDM_HEADER_INIT; public: - RimResultReservoir(); - virtual ~RimResultReservoir(); + RimResultCase(); + virtual ~RimResultCase(); // Fields: @@ -45,6 +46,7 @@ public: caf::PdmField caseDirectory; virtual bool openEclipseGridFile(); + bool openAndReadActiveCellData(RigCaseData* mainEclipseCase); //virtual caf::PdmFieldHandle* userDescriptionField() { return &caseName;} diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp index 29ec38da4a..9af564420b 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.cpp @@ -16,14 +16,14 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimResultDefinition.h" #include "RimReservoirView.h" -#include "RimReservoir.h" -#include "RigReservoirCellResults.h" -#include "RigReservoir.h" +#include "RimCase.h" +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" #include "RigMainGrid.h" #include "cafPdmUiListEditor.h" @@ -63,9 +63,9 @@ void RimResultDefinition::setReservoirView(RimReservoirView* ownerReservoirView) // TODO: This code is executed before reservoir is read, and then porosity model is never set to zero if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData() && - m_reservoirView->eclipseCase()->reservoirData()->mainGrid() ) + m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) { - if (m_reservoirView->eclipseCase()->reservoirData()->mainGrid()->globalFractureModelActiveCellCount() == 0) + if (m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->globalActiveCellCount() == 0) { porosityModel.setUiHidden(true); } @@ -92,9 +92,9 @@ QList RimResultDefinition::calculateValueOptions(const c { if (fieldNeedingOptions == &resultVariable) { - if (m_reservoirView && m_reservoirView->gridCellResults()) + if (m_reservoirView && m_reservoirView->currentGridCellResults()) { - QStringList varList = m_reservoirView->gridCellResults()->resultNames(resultType()); + QStringList varList = m_reservoirView->currentGridCellResults()->cellResults()->resultNames(resultType()); QList optionList; int i; for (i = 0; i < varList.size(); ++i) @@ -119,8 +119,8 @@ size_t RimResultDefinition::gridScalarIndex() const { if (m_gridScalarResultIndex == cvf::UNDEFINED_SIZE_T) { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); - if (gridCellResults) m_gridScalarResultIndex = gridCellResults->findScalarResultIndex(resultType(), resultVariable()); + const RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); + if (gridCellResults) m_gridScalarResultIndex = gridCellResults->cellResults()->findScalarResultIndex(resultType(), resultVariable()); } return m_gridScalarResultIndex; } @@ -130,7 +130,7 @@ size_t RimResultDefinition::gridScalarIndex() const //-------------------------------------------------------------------------------------------------- void RimResultDefinition::loadResult() { - RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); + RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); if (gridCellResults) { m_gridScalarResultIndex = gridCellResults->findOrLoadScalarResult(resultType(), resultVariable); @@ -148,8 +148,8 @@ void RimResultDefinition::loadResult() //-------------------------------------------------------------------------------------------------- bool RimResultDefinition::hasStaticResult() const { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); - if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) == 1 ) + const RimReservoirCellResultsStorage* gridCellResults = m_reservoirView->currentGridCellResults(); + if (hasResult() && gridCellResults->cellResults()->timeStepCount(m_gridScalarResultIndex) == 1 ) { return true; } @@ -166,7 +166,7 @@ bool RimResultDefinition::hasResult() const { if (m_gridScalarResultIndex != cvf::UNDEFINED_SIZE_T) return true; - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); + const RigCaseCellResultsData* gridCellResults = m_reservoirView->currentGridCellResults()->cellResults(); if (gridCellResults) { m_gridScalarResultIndex = gridCellResults->findScalarResultIndex(resultType(), resultVariable()); @@ -182,7 +182,7 @@ bool RimResultDefinition::hasResult() const //-------------------------------------------------------------------------------------------------- bool RimResultDefinition::hasDynamicResult() const { - const RigReservoirCellResults* gridCellResults = m_reservoirView->gridCellResults(); + const RigCaseCellResultsData* gridCellResults = m_reservoirView->currentGridCellResults()->cellResults(); if (hasResult() && gridCellResults->timeStepCount(m_gridScalarResultIndex) > 1 ) return true; else diff --git a/ApplicationCode/ProjectDataModel/RimResultDefinition.h b/ApplicationCode/ProjectDataModel/RimResultDefinition.h index a9a159935b..138ce0a5ab 100644 --- a/ApplicationCode/ProjectDataModel/RimResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimResultDefinition.h @@ -26,7 +26,7 @@ class RimReservoirView; -class RigReservoirCellResults; +class RigCaseCellResultsData; //================================================================================================== /// diff --git a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp index 9d1564a564..3e7cbac4ff 100644 --- a/ApplicationCode/ProjectDataModel/RimResultSlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimResultSlot.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimResultSlot.h" #include "RimLegendConfig.h" #include "RimReservoirView.h" -#include "RimReservoir.h" -#include "RIMainWindow.h" +#include "RimCase.h" +#include "RiuMainWindow.h" #include "RimUiTreeModelPdm.h" @@ -91,7 +91,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) m_legendConfigData.v().erase(it); m_legendConfigData.v().push_back(this->legendConfig()); this->legendConfig = newLegend; - RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); + RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); found = true; break; } @@ -105,7 +105,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend) newLegend->resultVariableName = resultVarNameOfNewLegend; m_legendConfigData.v().push_back(this->legendConfig()); this->legendConfig = newLegend; - RIMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); + RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp index f7e6a2e344..e267ab6389 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimScriptCollection.h" #include "cafPdmField.h" #include "cafUtils.h" -#include "RIMainWindow.h" +#include "RiuMainWindow.h" #include "RimUiTreeModelPdm.h" #include "cafPdmUiFilePathEditor.h" @@ -161,7 +161,7 @@ void RimScriptCollection::fieldChangedByUi(const caf::PdmFieldHandle *changedFie QFileInfo fi(directory); this->setUiName(fi.baseName()); this->readContentFromDisc(); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); if (treeModel) treeModel->rebuildUiSubTree(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp new file mode 100644 index 0000000000..e50e084f43 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.cpp @@ -0,0 +1,220 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStdInclude.h" + +#include "RimStatisticsCase.h" +#include "RimReservoirView.h" +#include "cafPdmUiOrdering.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" +#include "RimStatisticsCaseEvaluator.h" +#include "RigMainGrid.h" + + +CAF_PDM_SOURCE_INIT(RimStatisticsCase, "RimStatisticalCalculation"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase::RimStatisticsCase() + : RimCase() +{ + CAF_PDM_InitObject("Case Group Statistics", ":/Histogram16x16.png", "", ""); + CAF_PDM_InitField(&m_resultName, "ResultName", QString("PRESSURE"), "ResultName", "", "", ""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase::~RimStatisticsCase() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::setMainGrid(RigMainGrid* mainGrid) +{ + CVF_ASSERT(mainGrid); + CVF_ASSERT(this->reservoirData()); + + reservoirData()->setMainGrid(mainGrid); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimStatisticsCase::openEclipseGridFile() +{ + if (this->reservoirData()) return true; + + cvf::ref eclipseCase = new RigCaseData; + + CVF_ASSERT(parentStatisticsCaseCollection()); + + RimIdenticalGridCaseGroup* gridCaseGroup = parentStatisticsCaseCollection()->parentCaseGroup(); + CVF_ASSERT(gridCaseGroup); + + RigMainGrid* mainGrid = gridCaseGroup->mainGrid(); + + eclipseCase->setMainGrid(mainGrid); + + eclipseCase->setActiveCellInfo(RifReaderInterface::MATRIX_RESULTS, gridCaseGroup->unionOfActiveCells(RifReaderInterface::MATRIX_RESULTS)); + eclipseCase->setActiveCellInfo(RifReaderInterface::FRACTURE_RESULTS, gridCaseGroup->unionOfActiveCells(RifReaderInterface::FRACTURE_RESULTS)); + + this->setReservoirData( eclipseCase.p() ); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) const +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCaseCollection* RimStatisticsCase::parentStatisticsCaseCollection() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::computeStatistics() +{ + if (this->reservoirData() == NULL) + { + openEclipseGridFile(); + } + + RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup(); + CVF_ASSERT(gridCaseGroup); + gridCaseGroup->computeUnionOfActiveCells(); + + std::vector sourceCases; + + getSourceCases(sourceCases); + + if (sourceCases.size() == 0) + { + return; + } + + // The first source has been read completely from disk, and contains grid and meta data + // Use this information for all cases in the case group + size_t timeStepCount = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->maxTimeStepCount(); + + RimStatisticsConfig statisticsConfig; + + std::vector timeStepIndices; + for (size_t i = 0; i < timeStepCount; i++) + { + timeStepIndices.push_back(i); + } + + RigCaseData* resultCase = reservoirData(); + + QList > resultSpecification; + + //resultSpecification.append(qMakePair(RimDefines::DYNAMIC_NATIVE, QString("PRESSURE"))); + + + { + QStringList resultNames = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->resultNames(RimDefines::DYNAMIC_NATIVE); + foreach(QString resultName, resultNames) + { + resultSpecification.append(qMakePair(RimDefines::DYNAMIC_NATIVE, resultName)); + } + } + + { + QStringList resultNames = sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->resultNames(RimDefines::STATIC_NATIVE); + foreach(QString resultName, resultNames) + { + resultSpecification.append(qMakePair(RimDefines::STATIC_NATIVE, resultName)); + } + } + + + RimStatisticsCaseEvaluator stat(sourceCases, timeStepIndices, statisticsConfig, resultCase); + stat.evaluateForResults(resultSpecification); + + for (size_t i = 0; i < reservoirViews().size(); i++) + { + RimReservoirView* reservoirView = reservoirViews()[i]; + CVF_ASSERT(reservoirView); + + reservoirView->scheduleGeometryRegen(RivReservoirViewPartMgr::ACTIVE); + reservoirView->createDisplayModelAndRedraw(); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCase::getSourceCases(std::vector& sourceCases) +{ + RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup(); + if (gridCaseGroup) + { + size_t caseCount = gridCaseGroup->caseCollection->reservoirs.size(); + for (size_t i = 0; i < caseCount; i++) + { + CVF_ASSERT(gridCaseGroup->caseCollection); + CVF_ASSERT(gridCaseGroup->caseCollection->reservoirs[i]); + CVF_ASSERT(gridCaseGroup->caseCollection->reservoirs[i]->reservoirData()); + + RimCase* sourceCase = gridCaseGroup->caseCollection->reservoirs[i]; + sourceCases.push_back(sourceCase); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimStatisticsCase::caseGroup() +{ + RimCaseCollection* parentCollection = parentStatisticsCaseCollection(); + if (parentCollection) + { + return parentCollection->parentCaseGroup(); + } + + return NULL; +} diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCase.h b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h new file mode 100644 index 0000000000..0d8418a29a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCase.h @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimCase.h" + +class RimIdenticalGridCaseGroup; +class RimResultDefinition; +class RimStatisticsCaseCollection; +class RigMainGrid; + + +//================================================================================================== +// +// +// +//================================================================================================== +class RimStatisticsCase : public RimCase +{ + CAF_PDM_HEADER_INIT; + +public: + RimStatisticsCase(); + virtual ~RimStatisticsCase(); + + void setMainGrid(RigMainGrid* mainGrid); + + virtual bool openEclipseGridFile(); + + caf::PdmField m_resultName; + + RimCaseCollection* parentStatisticsCaseCollection(); + + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) const; + void computeStatistics(); + +private: + RimIdenticalGridCaseGroup* caseGroup(); + + void getSourceCases(std::vector& sourceCases); + +}; diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp new file mode 100644 index 0000000000..0d68ebdf07 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.cpp @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStdInclude.h" + +#include "RimReservoirView.h" + +#include "RimStatisticsCaseCollection.h" +#include "RimIdenticalGridCaseGroup.h" + + +CAF_PDM_SOURCE_INIT(RimStatisticsCaseCollection, "RimStatisticalCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseCollection::RimStatisticsCaseCollection() + : PdmObject() +{ + CAF_PDM_InitObject("Derived Statistics", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&cases, "Reservoirs", "", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseCollection::~RimStatisticsCaseCollection() +{ + cases.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimStatisticsCaseCollection::parentCaseGroup() +{ + std::vector parentObjects; + this->parentObjectsOfType(parentObjects); + + if (parentObjects.size() > 0) + { + return parentObjects[0]; + } + + return NULL; +} + diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h new file mode 100644 index 0000000000..e7c0059363 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseCollection.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "RimStatisticsCase.h" + + + +//================================================================================================== +// +// +// +//================================================================================================== +class RimStatisticsCaseCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimStatisticsCaseCollection(); + virtual ~RimStatisticsCaseCollection(); + + caf::PdmPointersField cases; + + RimIdenticalGridCaseGroup* parentCaseGroup(); + +private: + +}; diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp new file mode 100644 index 0000000000..8ce57e857e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.cpp @@ -0,0 +1,425 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RiaStdInclude.h" + +#include "RimStatisticsCaseEvaluator.h" +#include "RigCaseCellResultsData.h" +#include "RimReservoirView.h" +#include "RimCase.h" +#include "RigCaseData.h" + +//#include "RigCaseData.h" +#include +#include "cafProgressInfo.h" + +//-------------------------------------------------------------------------------------------------- +/// An internal class to do the actual computations +//-------------------------------------------------------------------------------------------------- +class RimStatisticsEvaluator +{ +public: + RimStatisticsEvaluator(const std::vector& values) + : m_values(values), + m_min(HUGE_VAL), + m_max(-HUGE_VAL), + m_mean(HUGE_VAL), + m_dev(HUGE_VAL) + { + } + + + void getStatistics(double& min, double& max, double& mean, double& dev, double& range) + { + evaluate(); + + min = m_min; + max = m_max; + mean = m_mean; + dev = m_dev; + + range = m_max - m_min; + } + +private: + void evaluate() + { + double sum = 0.0; + double sumSquared = 0.0; + + size_t validValueCount = 0; + + for (size_t i = 0; i < m_values.size(); i++) + { + double val = m_values[i]; + if (val == HUGE_VAL) continue; + + validValueCount++; + + if (val < m_min) m_min = val; + if (val > m_max) m_max = val; + + sum += val; + sumSquared += (val * val); + } + + if (validValueCount > 0) + { + m_mean = sum / validValueCount; + + + // http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods + // Running standard deviation + + double s0 = validValueCount; + double s1 = sum; + double s2 = sumSquared; + + m_dev = cvf::Math::sqrt( (s0 * s2) - (s1 * s1) ) / s0; + } + } + + +private: + const std::vector& m_values; + + double m_min; + double m_max; + double m_mean; + double m_dev; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::addNamedResult(RigCaseCellResultsData* destinationCellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeUnionCellCount) +{ + // Use time step dates from first result in first source case + CVF_ASSERT(m_sourceCases.size() > 0); + + std::vector sourceTimeStepDates = m_sourceCases[0]->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(0); + + size_t destinationScalarResultIndex = destinationCellResults->addEmptyScalarResult(resultType, resultName, true); + CVF_ASSERT(destinationScalarResultIndex != cvf::UNDEFINED_SIZE_T); + + destinationCellResults->setTimeStepDates(destinationScalarResultIndex, sourceTimeStepDates); + std::vector< std::vector >& dataValues = destinationCellResults->cellScalarResults(destinationScalarResultIndex); + dataValues.resize(sourceTimeStepDates.size()); + + + // Initializes the size of the destination dataset to active union cell count + for (size_t i = 0; i < sourceTimeStepDates.size(); i++) + { + dataValues[i].resize(activeUnionCellCount, HUGE_VAL); + } +} + + +QString createResultNameMin(const QString& resultName) { return resultName + "_MIN"; } +QString createResultNameMax(const QString& resultName) { return resultName + "_MAX"; } +QString createResultNameMean(const QString& resultName) { return resultName + "_MEAN"; } +QString createResultNameDev(const QString& resultName) { return resultName + "_DEV"; } +QString createResultNameRange(const QString& resultName) { return resultName + "_RANGE"; } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::buildSourceMetaData(RimDefines::ResultCatType resultType, const QString& resultName) +{ + if (m_sourceCases.size() == 0) return; + + std::vector timeStepDates = m_sourceCases[0]->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(0); + + for (size_t caseIdx = 1; caseIdx < m_sourceCases.size(); caseIdx++) + { + RigCaseData* eclipseCase = m_sourceCases.at(caseIdx)->reservoirData(); + + RimReservoirCellResultsStorage* matrixResults = m_sourceCases[caseIdx]->results(RifReaderInterface::MATRIX_RESULTS); + size_t scalarResultIndex = matrixResults->findOrLoadScalarResult(resultType, resultName); + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) + { + size_t scalarResultIndex = matrixResults->cellResults()->addEmptyScalarResult(resultType, resultName, false); + matrixResults->cellResults()->setTimeStepDates(scalarResultIndex, timeStepDates); + + std::vector< std::vector >& dataValues = matrixResults->cellResults()->cellScalarResults(scalarResultIndex); + dataValues.resize(timeStepDates.size()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::evaluateForResults(const QList >& resultSpecification) +{ + CVF_ASSERT(m_destinationCase); + + size_t activeMatrixCellCount = m_destinationCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); + RigCaseCellResultsData* matrixResults = m_destinationCase->results(RifReaderInterface::MATRIX_RESULTS); + + for (int i = 0; i < resultSpecification.size(); i++) + { + RimDefines::ResultCatType resultType = resultSpecification[i].first; + QString resultName = resultSpecification[i].second; + + // Special handling if SOIL is asked for + // Build SGAS/SWAT meta data, SOIL is automatically generated as part of RigCaseCellResultsData::findOrLoadScalarResultForTimeStep + if (resultName.toUpper() == "SOIL") + { + size_t swatIndex = m_sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->findScalarResultIndex(resultType, "SWAT"); + if (swatIndex != cvf::UNDEFINED_SIZE_T) + { + buildSourceMetaData(resultType, "SWAT"); + } + + size_t sgasIndex = m_sourceCases.at(0)->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->findScalarResultIndex(resultType, "SGAS"); + if (sgasIndex != cvf::UNDEFINED_SIZE_T) + { + buildSourceMetaData(resultType, "SGAS"); + } + } + else + { + // Meta info is loaded from disk for first case only + // Build metadata for all other source cases + buildSourceMetaData(resultType, resultName); + } + + QString minResultName = createResultNameMin(resultName); + QString maxResultName = createResultNameMax(resultName); + QString meanResultName = createResultNameMean(resultName); + QString devResultName = createResultNameDev(resultName); + QString rangeResultName = createResultNameRange(resultName); + + if (activeMatrixCellCount > 0) + { + addNamedResult(matrixResults, resultType, minResultName, activeMatrixCellCount); + addNamedResult(matrixResults, resultType, maxResultName, activeMatrixCellCount); + addNamedResult(matrixResults, resultType, meanResultName, activeMatrixCellCount); + addNamedResult(matrixResults, resultType, devResultName, activeMatrixCellCount); + addNamedResult(matrixResults, resultType, rangeResultName, activeMatrixCellCount); + } + } + + if (activeMatrixCellCount > 0) + { + caf::ProgressInfo info(m_timeStepIndices.size(), "Computing Statistics"); + + for (size_t timeIndicesIdx = 0; timeIndicesIdx < m_timeStepIndices.size(); timeIndicesIdx++) + { + size_t timeStepIdx = m_timeStepIndices[timeIndicesIdx]; + + size_t gridCount = 0; + for (size_t gridIdx = 0; gridIdx < m_destinationCase->gridCount(); gridIdx++) + { + RigGridBase* grid = m_destinationCase->grid(gridIdx); + + for (int i = 0; i < resultSpecification.size(); i++) + { + RimDefines::ResultCatType resultType = resultSpecification[i].first; + QString resultName = resultSpecification[i].second; + + size_t dataAccessTimeStepIndex = timeStepIdx; + + // Always evaluate statistics once, and always use time step index zero + if (resultType == RimDefines::STATIC_NATIVE) + { + if (timeIndicesIdx > 0) continue; + + dataAccessTimeStepIndex = 0; + } + + // Build data access objects for source scalar results + cvf::Collection dataAccesObjectList; + for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) + { + RimCase* eclipseCase = m_sourceCases.at(caseIdx); + + size_t scalarResultIndex = eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); + + cvf::ref dataAccessObject = eclipseCase->reservoirData()->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + if (dataAccessObject.notNull()) + { + dataAccesObjectList.push_back(dataAccessObject.p()); + } + } + + + // Build data access objects form destination scalar results + cvf::ref dataAccessObjectMin = NULL; + cvf::ref dataAccessObjectMax = NULL; + cvf::ref dataAccessObjectMean = NULL; + cvf::ref dataAccessObjectDev = NULL; + cvf::ref dataAccessObjectRange = NULL; + + { + size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMin(resultName)); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + dataAccessObjectMin = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + } + } + + { + size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMax(resultName)); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + dataAccessObjectMax = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + } + } + + { + size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameMean(resultName)); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + dataAccessObjectMean = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + } + } + + { + size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameDev(resultName)); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + dataAccessObjectDev = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + } + } + + { + size_t scalarResultIndex = matrixResults->findScalarResultIndex(resultType, createResultNameRange(resultName)); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + dataAccessObjectRange = m_destinationCase->dataAccessObject(grid, RifReaderInterface::MATRIX_RESULTS, dataAccessTimeStepIndex, scalarResultIndex); + } + } + + double min, max, mean, dev, range; + for (size_t cellIdx = 0; cellIdx < grid->cellCount(); cellIdx++) + { + std::vector values(dataAccesObjectList.size(), HUGE_VAL); + + size_t globalGridCellIdx = grid->globalGridCellIndex(cellIdx); + if (m_destinationCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->isActive(globalGridCellIdx)) + { + bool foundAnyValidValues = false; + for (size_t caseIdx = 0; caseIdx < dataAccesObjectList.size(); caseIdx++) + { + double val = dataAccesObjectList.at(caseIdx)->cellScalar(cellIdx); + values[caseIdx] = val; + + if (val != HUGE_VAL) + { + foundAnyValidValues = true; + } + } + + min = HUGE_VAL; + max = HUGE_VAL; + mean = HUGE_VAL; + dev = HUGE_VAL; + range = HUGE_VAL; + + if (foundAnyValidValues) + { + RimStatisticsEvaluator stat(values); + stat.getStatistics(min, max, mean, dev, range); + } + + if (dataAccessObjectMin.notNull()) + { + dataAccessObjectMin->setCellScalar(cellIdx, min); + } + + if (dataAccessObjectMax.notNull()) + { + dataAccessObjectMax->setCellScalar(cellIdx, max); + } + + if (dataAccessObjectMean.notNull()) + { + dataAccessObjectMean->setCellScalar(cellIdx, mean); + } + + if (dataAccessObjectDev.notNull()) + { + dataAccessObjectDev->setCellScalar(cellIdx, dev); + } + + if (dataAccessObjectRange.notNull()) + { + dataAccessObjectRange->setCellScalar(cellIdx, range); + } + } + } + } + } + + for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) + { + RimCase* eclipseCase = m_sourceCases.at(caseIdx); + + // When one time step is completed, close all result files. + // Microsoft note: On Windows, the maximum number of files open at the same time is 512 + // http://msdn.microsoft.com/en-us/library/kdfaxaay%28vs.71%29.aspx + // + eclipseCase->results(RifReaderInterface::MATRIX_RESULTS)->readerInterface()->close(); + } + + info.setProgress(timeIndicesIdx); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStatisticsCaseEvaluator::debugOutput(RimDefines::ResultCatType resultType, const QString& resultName, size_t timeStepIdx) +{ + CVF_ASSERT(m_destinationCase); + + qDebug() << resultName << "timeIdx : " << timeStepIdx; + + size_t scalarResultIndex = m_destinationCase->results(RifReaderInterface::MATRIX_RESULTS)->findScalarResultIndex(resultType, resultName); + + cvf::ref dataAccessObject = m_destinationCase->dataAccessObject(m_destinationCase->mainGrid(), RifReaderInterface::MATRIX_RESULTS, timeStepIdx, scalarResultIndex); + if (dataAccessObject.isNull()) return; + + for (size_t cellIdx = 0; cellIdx < m_globalCellCount; cellIdx++) + { + qDebug() << dataAccessObject->cellScalar(cellIdx); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCaseEvaluator::RimStatisticsCaseEvaluator(const std::vector& sourceCases, const std::vector& timeStepIndices, const RimStatisticsConfig& statisticsConfig, RigCaseData* destinationCase) + : m_sourceCases(sourceCases), + m_statisticsConfig(statisticsConfig), + m_destinationCase(destinationCase), + m_globalCellCount(0), + m_timeStepIndices(timeStepIndices) +{ + if (sourceCases.size() > 0) + { + m_globalCellCount = sourceCases[0]->reservoirData()->mainGrid()->cells().size(); + } + + CVF_ASSERT(m_destinationCase); +} + diff --git a/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h new file mode 100644 index 0000000000..14a80a6b0d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimStatisticsCaseEvaluator.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfCollection.h" +#include +#include + +#include +#include "RimDefines.h" + +class RimCase; +class RigCaseData; +class RigCaseCellResultsData; + + +class RimStatisticsConfig +{ +public: + RimStatisticsConfig() + : m_min(true), + m_max(true), + m_mean(true), + m_stdDev(true) + { + } + +public: + bool m_min; + bool m_max; + bool m_mean; + bool m_stdDev; +}; + + +class RimStatisticsCaseEvaluator +{ +public: + RimStatisticsCaseEvaluator(const std::vector& sourceCases, + const std::vector& timeStepIndices, + const RimStatisticsConfig& statisticsConfig, + RigCaseData* destinationCase); + + + void evaluateForResults(const QList >& resultSpecification); + + void debugOutput(RimDefines::ResultCatType resultType, const QString& resultName, size_t timeStepIdx); + +private: + void addNamedResult(RigCaseCellResultsData* cellResults, RimDefines::ResultCatType resultType, const QString& resultName, size_t activeCellCount); + void buildSourceMetaData(RimDefines::ResultCatType resultType, const QString& resultName); + +private: + std::vector m_sourceCases; + std::vector m_timeStepIndices; + + size_t m_globalCellCount; + RimStatisticsConfig m_statisticsConfig; + RigCaseData* m_destinationCase; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp index 34713d1ba4..7d642a029e 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "RimUiTreeModelPdm.h" #include "RimCellRangeFilter.h" @@ -27,14 +27,16 @@ #include "RimCellPropertyFilterCollection.h" #include "RimReservoirView.h" -#include "RIViewer.h" +#include "RiuViewer.h" #include "RimCalcScript.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "RimInputProperty.h" #include "RimInputPropertyCollection.h" #include "cafPdmField.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" +#include "RimStatisticsCase.h" +#include "RimResultCase.h" //-------------------------------------------------------------------------------------------------- /// @@ -49,9 +51,9 @@ RimUiTreeModelPdm::RimUiTreeModelPdm(QObject* parent) } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool RimUiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { caf::PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -124,7 +126,7 @@ bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); propertyFilterCollection->remove(propertyFilter); delete propertyFilter; @@ -138,6 +140,9 @@ bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) { propertyFilterCollection->reservoirView()->createDisplayModelAndRedraw(); } + + clearClipboard(); + return true; } @@ -161,7 +166,7 @@ bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) bool wasSomeFilterActive = rangeFilterCollection->hasActiveFilters(); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); rangeFilterCollection->remove(rangeFilter); delete rangeFilter; @@ -176,6 +181,8 @@ bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); } + clearClipboard(); + return true; } @@ -193,34 +200,51 @@ bool RimUiTreeModelPdm::deleteReservoirView(const QModelIndex& itemIndex) CVF_ASSERT(reservoirView); // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); reservoirView->eclipseCase()->removeReservoirView(reservoirView); delete reservoirView; + clearClipboard(); + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteReservoir(const QModelIndex& itemIndex) +void RimUiTreeModelPdm::deleteReservoir(RimCase* reservoir) { - CVF_ASSERT(itemIndex.isValid()); + RimCaseCollection* caseCollection = reservoir->parentCaseCollection(); + QModelIndex caseCollectionModelIndex = getModelIndexFromPdmObject(caseCollection); + if (!caseCollectionModelIndex.isValid()) return; - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(uiItem); + QModelIndex mi = getModelIndexFromPdmObjectRecursive(caseCollectionModelIndex, reservoir); + if (mi.isValid()) + { + caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi); + CVF_ASSERT(uiItem); - RimReservoir* reservoir = dynamic_cast(uiItem->dataObject().p()); - CVF_ASSERT(reservoir); + // Remove Ui items pointing at the pdm object to delete + removeRows_special(mi.row(), 1, mi.parent()); + } - // Remove Ui items pointing at the pdm object to delete - removeRow(itemIndex.row(), itemIndex.parent()); + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(caseCollection)) + { + RimIdenticalGridCaseGroup* caseGroup = caseCollection->parentCaseGroup(); + CVF_ASSERT(caseGroup); - RimProject* proj = RIApplication::instance()->project(); - proj->reservoirs().removeChildObject(reservoir); + caseGroup->statisticsCaseCollection()->reservoirs.removeChildObject(reservoir); + } + else + { + RimProject* proj = RiaApplication::instance()->project(); + proj->removeCaseFromAllGroups(reservoir); + } delete reservoir; + + clearClipboard(); } //-------------------------------------------------------------------------------------------------- @@ -322,24 +346,40 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); if (!currentItem) return NULL; - RimReservoirView* reservoirView = dynamic_cast(currentItem->dataObject().p()); - if (!reservoirView) return NULL; + caf::PdmUiTreeItem* collectionItem = NULL; - RimReservoirView* insertedView = reservoirView->eclipseCase()->createAndAddReservoirView(); - caf::PdmUiTreeItem* collectionItem = currentItem->parent(); + bool itemIndexIsCollection = false; + QModelIndex collectionIndex; + if (dynamic_cast(currentItem->dataObject().p())) + { + collectionItem = currentItem->parent(); + collectionIndex = itemIndex.parent(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + collectionItem = currentItem; + collectionIndex = itemIndex; + } - int viewCount = rowCount(itemIndex.parent()); - beginInsertRows(itemIndex.parent(), viewCount, viewCount); + if (collectionItem) + { + RimCase* rimReservoir = dynamic_cast(collectionItem->dataObject().p()); + RimReservoirView* insertedView = rimReservoir->createAndAddReservoirView(); - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(collectionItem, viewCount, insertedView); + int viewCount = rowCount(collectionIndex); + beginInsertRows(collectionIndex, viewCount, viewCount); - endInsertRows(); + // NOTE: -1 as second argument indicates append + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(collectionItem, -1, insertedView); + + endInsertRows(); - insertedView->loadDataAndUpdate(); + insertedView->loadDataAndUpdate(); - rebuildUiSubTree(insertedView); - - return insertedView; + return insertedView; + } + + return NULL; } @@ -348,7 +388,7 @@ RimReservoirView* RimUiTreeModelPdm::addReservoirView(const QModelIndex& itemInd //-------------------------------------------------------------------------------------------------- void RimUiTreeModelPdm::updateScriptPaths() { - RimProject* proj = RIApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); if (!proj || !proj->scriptCollection()) return; @@ -368,7 +408,7 @@ void RimUiTreeModelPdm::updateScriptPaths() //-------------------------------------------------------------------------------------------------- void RimUiTreeModelPdm::slotRefreshScriptTree(QString path) { - RimProject* proj = RIApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); if (!proj || !proj->scriptCollection()) return; @@ -390,13 +430,11 @@ void RimUiTreeModelPdm::addInputProperty(const QModelIndex& itemIndex, const QSt RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(currentItem->dataObject().p()); CVF_ASSERT(inputPropertyCollection); - std::vector parentObjects; - inputPropertyCollection->parentObjects(parentObjects); - - + std::vector parentObjects; + inputPropertyCollection->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputReservoir* inputReservoir = dynamic_cast(parentObjects[0]); + RimInputCase* inputReservoir = parentObjects[0]; CVF_ASSERT(inputReservoir); if (inputReservoir) { @@ -421,24 +459,361 @@ void RimUiTreeModelPdm::deleteInputProperty(const QModelIndex& itemIndex) if (!inputProperty) return; // Remove item from UI tree model before delete of project data structure - removeRow(itemIndex.row(), itemIndex.parent()); + removeRows_special(itemIndex.row(), 1, itemIndex.parent()); - std::vector parentObjects; - object->parentObjects(parentObjects); + std::vector parentObjects; + object->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(parentObjects[0]); + RimInputPropertyCollection* inputPropertyCollection = parentObjects[0]; if (!inputPropertyCollection) return; - std::vector parentObjects2; - inputPropertyCollection->parentObjects(parentObjects2); + std::vector parentObjects2; + inputPropertyCollection->parentObjectsOfType(parentObjects2); CVF_ASSERT(parentObjects2.size() == 1); - RimInputReservoir* inputReservoir = dynamic_cast(parentObjects2[0]); + RimInputCase* inputReservoir = parentObjects2[0]; if (!inputReservoir) return; inputReservoir->removeProperty(inputProperty); delete inputProperty; + + clearClipboard(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimStatisticsCase* RimUiTreeModelPdm::addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) +{ + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + + QModelIndex collectionIndex; + RimIdenticalGridCaseGroup* caseGroup = NULL; + caf::PdmUiTreeItem* parentCollectionItem = NULL; + int position = 0; + + if (dynamic_cast(currentItem->dataObject().p())) + { + RimStatisticsCase* currentObject = dynamic_cast(currentItem->dataObject().p()); + caseGroup = currentObject->parentStatisticsCaseCollection()->parentCaseGroup(); + parentCollectionItem = currentItem->parent(); + position = itemIndex.row(); + collectionIndex = itemIndex.parent(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + RimCaseCollection* statColl = dynamic_cast(currentItem->dataObject().p()); + caseGroup = statColl->parentCaseGroup(); + parentCollectionItem = currentItem; + position = parentCollectionItem->childCount(); + collectionIndex = itemIndex; + } + + if (parentCollectionItem && caseGroup) + { + beginInsertRows(collectionIndex, position, position); + + RimStatisticsCase* createdObject = caseGroup->createAndAppendStatisticsCase(); + caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(parentCollectionItem, position, createdObject); + + endInsertRows(); + + insertedModelIndex = index(position, 0, collectionIndex); + + return createdObject; + } + else + { + return NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + + if (dynamic_cast(currentItem->dataObject().p()) || + dynamic_cast(currentItem->dataObject().p())) + { + QModelIndex rootIndex = itemIndex.parent(); + caf::PdmUiTreeItem* rootTreeItem = currentItem->parent(); + + // New case group is inserted before the last item, the script item + int position = rootTreeItem->childCount() - 1; + + beginInsertRows(rootIndex, position, position); + + RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup; + proj->caseGroups().push_back(createdObject); + + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(rootTreeItem, position, createdObject); + endInsertRows(); + + insertedModelIndex = index(position, 0, rootIndex); + + return createdObject; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects) +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + + RimIdenticalGridCaseGroup* gridCaseGroup = NULL; + RimCaseCollection* caseCollection = NULL; + + if (dynamic_cast(currentItem->dataObject().p())) + { + gridCaseGroup = dynamic_cast(currentItem->dataObject().p()); + caseCollection = gridCaseGroup->caseCollection(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + caseCollection = dynamic_cast(currentItem->dataObject().p()); + CVF_ASSERT(caseCollection); + + gridCaseGroup = caseCollection->parentCaseGroup(); + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + RimCase* rimReservoir = dynamic_cast(currentItem->dataObject().p()); + CVF_ASSERT(rimReservoir); + + caseCollection = rimReservoir->parentCaseCollection(); + if (caseCollection) + { + gridCaseGroup = caseCollection->parentCaseGroup(); + } + } + else + { + return; + } + + if (gridCaseGroup) + { + std::vector > typedObjects; + pdmObjects.createCopyByType(&typedObjects); + + RigCaseData* mainEclipseCase = NULL; + if (gridCaseGroup->caseCollection()->reservoirs().size() > 0) + { + RimCase* mainReservoir = gridCaseGroup->caseCollection()->reservoirs()[0];; + mainEclipseCase = mainReservoir->reservoirData(); + } + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimResultCase* rimResultReservoir = typedObjects[i]; + + if (gridCaseGroup->contains(rimResultReservoir)) + { + continue; + } + + if (gridCaseGroup->mainGrid() == NULL) + { + rimResultReservoir->openEclipseGridFile(); + mainEclipseCase = rimResultReservoir->reservoirData(); + } + else + { + if (!rimResultReservoir->openAndReadActiveCellData(mainEclipseCase)) + { + CVF_ASSERT(false); + } + } + + proj->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir); + + caf::PdmObjectGroup::initAfterReadTraversal(rimResultReservoir); + + { + QModelIndex rootIndex = getModelIndexFromPdmObject(caseCollection); + caf::PdmUiTreeItem* caseCollectionUiItem = getTreeItemFromIndex(rootIndex); + + int position = rowCount(rootIndex); + beginInsertRows(rootIndex, position, position); + caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(caseCollectionUiItem, -1, rimResultReservoir); + endInsertRows(); + } + + for (size_t i = 0; i < rimResultReservoir->reservoirViews.size(); i++) + { + RimReservoirView* riv = rimResultReservoir->reservoirViews()[i]; + riv->loadDataAndUpdate(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeModelPdm::deleteObjectFromPdmPointersField(const QModelIndex& itemIndex) +{ + if (!itemIndex.isValid()) + { + return false; + } + + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); + CVF_ASSERT(currentItem); + + caf::PdmObject* currentPdmObject = currentItem->dataObject().p(); + CVF_ASSERT(currentPdmObject); + + std::vector parentFields; + currentPdmObject->parentFields(parentFields); + + if (parentFields.size() == 1) + { + beginRemoveRows(itemIndex.parent(), itemIndex.row(), itemIndex.row()); + if (currentItem->parent()) + { + currentItem->parent()->removeChildren(itemIndex.row(), 1); + } + endRemoveRows(); + + caf::PdmPointersField* caseGroup = dynamic_cast *>(parentFields[0]); + if (caseGroup) + { + caseGroup->removeChildObject(currentPdmObject); + + delete currentPdmObject; + } + } + + clearClipboard(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeModelPdm::clearClipboard() +{ + // We use QModelIndex to identify a selection on the clipboard + // When we delete or move an entity, the clipboard data might be invalid + + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + if (dynamic_cast(clipboard->mimeData())) + { + clipboard->clear(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::DropActions RimUiTreeModelPdm::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags RimUiTreeModelPdm::flags(const QModelIndex &index) const +{ + Qt::ItemFlags defaultFlags = caf::UiTreeModelPdm::flags(index); + if (index.isValid()) + { + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(index); + CVF_ASSERT(currentItem); + CVF_ASSERT(currentItem->dataObject().p()); + + if (dynamic_cast(currentItem->dataObject().p()) || + dynamic_cast(currentItem->dataObject().p())) + { + return Qt::ItemIsDropEnabled | defaultFlags; + } + else if (dynamic_cast(currentItem->dataObject().p())) + { + // TODO: Remember to handle reservoir holding the main grid + return Qt::ItemIsDragEnabled | defaultFlags; + } + } + + return defaultFlags; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeModelPdm::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + const MimeDataWithIndexes* myMimeData = qobject_cast(data); + if (myMimeData && parent.isValid()) + { + caf::PdmObjectGroup pog; + + for (int i = 0; i < myMimeData->indexes().size(); i++) + { + QModelIndex mi = myMimeData->indexes().at(i); + caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(mi); + caf::PdmObject* pdmObj = currentItem->dataObject().p(); + + pog.objects().push_back(pdmObj); + } + + addObjects(parent, pog); + + if (action == Qt::MoveAction) + { + std::vector > typedObjects; + pog.objectsByType(&typedObjects); + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimCase* rimReservoir = typedObjects[i]; + deleteReservoir(rimReservoir); + } + } + + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMimeData* RimUiTreeModelPdm::mimeData(const QModelIndexList &indexes) const +{ + MimeDataWithIndexes* myObj = new MimeDataWithIndexes(); + myObj->setIndexes(indexes); + return myObj; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimUiTreeModelPdm::mimeTypes() const +{ + QStringList types; + types << MimeDataWithIndexes::formatName(); + return types; } diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h index 1e41d090a3..af0372e21f 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h @@ -20,15 +20,71 @@ #include "cafPdmObject.h" #include "cafPdmPointer.h" +#include "cafPdmDocument.h" #include "cafUiTreeModelPdm.h" +#include + class QFileSystemWatcher; class RimCellPropertyFilter; class RimCellRangeFilter; +class RimCase; class RimReservoirView; class RimInputProperty; +class RimStatisticsCase; +class RimIdenticalGridCaseGroup; +//-------------------------------------------------------------------------------------------------- +/// MimeData class used to carry a QModelIndexList +//-------------------------------------------------------------------------------------------------- +class MimeDataWithIndexes : public QMimeData +{ + Q_OBJECT + +public: + MimeDataWithIndexes() + { + } + + + MimeDataWithIndexes(const MimeDataWithIndexes & other) : QMimeData() + { + setIndexes(other.indexes()); + } + + void setIndexes(const QModelIndexList & indexes) + { + m_indexes = indexes; + } + + const QModelIndexList& indexes() const { return m_indexes; } + + virtual bool hasFormat( const QString &mimetype ) const + { + return (mimetype == formatName()); + } + + virtual QStringList formats() const + { + QStringList supportedFormats = QMimeData::formats(); + supportedFormats << formatName(); + + return supportedFormats; + } + + static QString formatName() + { + return "MimeDataWithIndexes"; + } + +private: + QModelIndexList m_indexes; +}; + +Q_DECLARE_METATYPE(MimeDataWithIndexes) + + //================================================================================================== /// /// @@ -40,31 +96,43 @@ class RimUiTreeModelPdm : public caf::UiTreeModelPdm public: RimUiTreeModelPdm(QObject* parent); - // Overrides - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); // Special edit methods - bool deleteRangeFilter(const QModelIndex& itemIndex); - bool deletePropertyFilter(const QModelIndex& itemIndex); - bool deleteReservoirView(const QModelIndex& itemIndex); - void deleteInputProperty(const QModelIndex& itemIndex); - void deleteReservoir(const QModelIndex& itemIndex); + bool deleteRangeFilter(const QModelIndex& itemIndex); + bool deletePropertyFilter(const QModelIndex& itemIndex); + bool deleteReservoirView(const QModelIndex& itemIndex); + void deleteInputProperty(const QModelIndex& itemIndex); + void deleteReservoir(RimCase* reservoir); - RimCellPropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames); + RimCellPropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimReservoirView* addReservoirView(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames); + void addObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); + + RimStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); + RimIdenticalGridCaseGroup* addCaseGroup(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - void updateScriptPaths(); + bool deleteObjectFromPdmPointersField(const QModelIndex& itemIndex); + + void updateScriptPaths(); + + virtual Qt::DropActions supportedDropActions() const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual QMimeData* mimeData(const QModelIndexList &indexes) const; + virtual QStringList mimeTypes() const; private slots: - void slotRefreshScriptTree(QString path); + void slotRefreshScriptTree(QString path); private: - QFileSystemWatcher* m_scriptChangeDetector; + void clearClipboard(); + +private: + QFileSystemWatcher* m_scriptChangeDetector; }; - - - - diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp index 624104775e..c4aee2049b 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp @@ -16,21 +16,25 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" + +#include "cafPdmDocument.h" #include "RimUiTreeView.h" #include "RimUiTreeModelPdm.h" #include "RimReservoirView.h" #include "RimCalcScript.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "RimInputPropertyCollection.h" #include "RimExportInputPropertySettings.h" -#include "RIPreferencesDialog.h" +#include "RiuPreferencesDialog.h" #include "RifEclipseInputFileTools.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimBinaryExportSettings.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RimStatisticsCase.h" +#include "RimResultCase.h" //-------------------------------------------------------------------------------------------------- /// @@ -39,6 +43,16 @@ RimUiTreeView::RimUiTreeView(QWidget *parent /*= 0*/) : QTreeView(parent) { setHeaderHidden(true); + + m_pasteAction = new QAction(QString("Paste"), this); + connect(m_pasteAction, SIGNAL(triggered()), SLOT(slotPastePdmObjects())); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimUiTreeView::~RimUiTreeView() +{ } //-------------------------------------------------------------------------------------------------- @@ -46,12 +60,15 @@ RimUiTreeView::RimUiTreeView(QWidget *parent /*= 0*/) //-------------------------------------------------------------------------------------------------- void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) { + m_pasteAction->setEnabled(hasClipboardValidData()); + RimUiTreeModelPdm* myModel = dynamic_cast(model()); if (myModel) { caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); if (uiItem && uiItem->dataObject()) { + // Range filters if (dynamic_cast(uiItem->dataObject().p())) { @@ -100,7 +117,7 @@ void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) } else if (dynamic_cast(uiItem->dataObject().p())) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QMenu menu; { @@ -143,12 +160,52 @@ void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) menu.addAction(QString("Save Property To File"), this, SLOT(slotWriteBinaryResultAsInputProperty())); menu.exec(event->globalPos()); } - else if (dynamic_cast(uiItem->dataObject().p())) + else if (dynamic_cast(uiItem->dataObject().p())) { QMenu menu; + menu.addAction(QString("New Statistcs Case"), this, SLOT(slotNewStatisticsCase())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("New View"), this, SLOT(slotAddView())); + menu.addAction(QString("Compute"), this, SLOT(slotComputeStatistics())); menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); menu.exec(event->globalPos()); } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("Copy"), this, SLOT(slotCopyPdmObjectToClipboard())); + menu.addAction(m_pasteAction); + menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); + menu.addAction(QString("New View"), this, SLOT(slotAddView())); + menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); + menu.addAction(m_pasteAction); + menu.addAction(QString("Close"), this, SLOT(slotDeleteObjectFromPdmPointersField())); + menu.exec(event->globalPos()); + } + else if (dynamic_cast(uiItem->dataObject().p())) + { + QMenu menu; + menu.addAction(m_pasteAction); + + // Check if parent field is a StatisticsCaseCollection + RimCaseCollection* rimCaseCollection = dynamic_cast(uiItem->dataObject().p()); + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(rimCaseCollection)) + { + menu.addAction(QString("New Statistics Case"), this, SLOT(slotNewStatisticsCase())); + } + + menu.exec(event->globalPos()); + } } } } @@ -368,7 +425,7 @@ void RimUiTreeView::slotEditScript() { RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptEditor = app->scriptEditorPath(); if (!scriptEditor.isEmpty()) { @@ -380,7 +437,7 @@ void RimUiTreeView::slotEditScript() if (!myProcess->waitForStarted(1000)) { - QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); } } } @@ -425,7 +482,7 @@ void RimUiTreeView::slotNewScript() num++; } - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString scriptEditor = app->scriptEditorPath(); if (!scriptEditor.isEmpty()) { @@ -437,7 +494,7 @@ void RimUiTreeView::slotNewScript() if (!myProcess->waitForStarted(1000)) { - QMessageBox::warning(RIMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); } } } @@ -455,7 +512,7 @@ void RimUiTreeView::slotExecuteScript() { RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString octavePath = app->octavePath(); if (!octavePath.isEmpty()) { @@ -482,7 +539,7 @@ void RimUiTreeView::slotExecuteScript() arguments.append("-q"); arguments << calcScript->absolutePath(); - RIApplication::instance()->launchProcess(octavePath, arguments); + RiaApplication::instance()->launchProcess(octavePath, arguments); } } } @@ -496,12 +553,8 @@ void RimUiTreeView::slotAddView() RimUiTreeModelPdm* myModel = dynamic_cast(model()); caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - RimReservoirView* rimView = dynamic_cast(uiItem->dataObject().p()); - if (rimView) - { - QModelIndex insertedIndex; - myModel->addReservoirView(index, insertedIndex); - } + QModelIndex insertedIndex; + myModel->addReservoirView(index, insertedIndex); } @@ -515,7 +568,7 @@ void RimUiTreeView::slotDeleteView() { myModel->deleteReservoirView(currentIndex()); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->setActiveReservoirView(NULL); } } @@ -565,7 +618,7 @@ void RimUiTreeView::setModel(QAbstractItemModel* model) //-------------------------------------------------------------------------------------------------- void RimUiTreeView::slotAddInputProperty() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Eclipse Input Property Files", defaultDir, "All Files (*.* *)"); @@ -623,7 +676,7 @@ void RimUiTreeView::slotWriteInputProperty() if (!isResolved) { - QMessageBox::warning(RIMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); + QMessageBox::warning(RiuMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); return; } @@ -633,20 +686,20 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.eclipseKeyword = inputProperty->eclipseKeyword; // Find input reservoir for this property - RimInputReservoir* inputReservoir = NULL; + RimInputCase* inputReservoir = NULL; { - std::vector parentObjects; - inputProperty->parentObjects(parentObjects); + std::vector parentObjects; + inputProperty->parentObjectsOfType(parentObjects); CVF_ASSERT(parentObjects.size() == 1); - RimInputPropertyCollection* inputPropertyCollection = dynamic_cast(parentObjects[0]); + RimInputPropertyCollection* inputPropertyCollection = parentObjects[0]; if (!inputPropertyCollection) return; - std::vector parentObjects2; - inputPropertyCollection->parentObjects(parentObjects2); + std::vector parentObjects2; + inputPropertyCollection->parentObjectsOfType(parentObjects2); CVF_ASSERT(parentObjects2.size() == 1); - inputReservoir = dynamic_cast(parentObjects2[0]); + inputReservoir = parentObjects2[0]; } if (!inputReservoir) return; @@ -654,7 +707,7 @@ void RimUiTreeView::slotWriteInputProperty() { QString projectFolder; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString projectFileName = app->currentProjectFileName(); if (!projectFileName.isEmpty()) { @@ -671,7 +724,7 @@ void RimUiTreeView::slotWriteInputProperty() exportSettings.fileName = outputFileName; } - RIPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); + RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Eclipse Property to Text File"); if (preferencesDialog.exec() == QDialog::Accepted) { bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); @@ -707,7 +760,7 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() { QString projectFolder; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString projectFileName = app->currentProjectFileName(); if (!projectFileName.isEmpty()) { @@ -724,11 +777,11 @@ void RimUiTreeView::slotWriteBinaryResultAsInputProperty() exportSettings.fileName = outputFileName; } - RIPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); + RiuPreferencesDialog preferencesDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); if (preferencesDialog.exec() == QDialog::Accepted) { size_t timeStep = resultSlot->reservoirView()->currentTimeStep(); - RifReaderInterface::PorosityModelResultType porosityModel = RigReservoirCellResults::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultSlot->porosityModel()); bool isOk = RifEclipseInputFileTools::writeBinaryResultToTextFile(exportSettings.fileName, resultSlot->reservoirView()->eclipseCase()->reservoirData(), porosityModel, timeStep, resultSlot->resultVariable, exportSettings.eclipseKeyword, exportSettings.undefinedValue); if (!isOk) @@ -746,7 +799,203 @@ void RimUiTreeView::slotCloseCase() RimUiTreeModelPdm* myModel = dynamic_cast(model()); if (myModel) { - myModel->deleteReservoir(currentIndex()); + QItemSelectionModel* m = selectionModel(); + CVF_ASSERT(m); + + caf::PdmObjectGroup group; + + QModelIndexList mil = m->selectedRows(); + for (int i = 0; i < mil.size(); i++) + { + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(mil.at(i)); + group.addObject(uiItem->dataObject().p()); + } + + std::vector > typedObjects; + group.objectsByType(&typedObjects); + + for (size_t i = 0; i < typedObjects.size(); i++) + { + RimCase* rimReservoir = typedObjects[i]; + myModel->deleteReservoir(rimReservoir); + } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotNewStatisticsCase() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + QModelIndex insertedIndex; + RimStatisticsCase* newObject = myModel->addStatisticalCalculation(currentIndex(), insertedIndex); + setCurrentIndex(insertedIndex); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotComputeStatistics() +{ + QModelIndex index = currentIndex(); + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); + + RimStatisticsCase* statisticsCase = dynamic_cast(uiItem->dataObject().p()); + if (!statisticsCase) return; + + statisticsCase->computeStatistics(); + + if (statisticsCase->reservoirViews.size() == 0) + { + slotAddView(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotAddCaseGroup() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + QModelIndex insertedIndex; + myModel->addCaseGroup(currentIndex(), insertedIndex); + setCurrentIndex(insertedIndex); + + setExpanded(insertedIndex, true); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotDeleteObjectFromPdmPointersField() +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (myModel) + { + myModel->deleteObjectFromPdmPointersField(currentIndex()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotCopyPdmObjectToClipboard() +{ + QItemSelectionModel* m = selectionModel(); + + QModelIndexList mil = m->selectedRows(); + if (mil.size() == 0) + { + return; + } + + MimeDataWithIndexes* myObject = new MimeDataWithIndexes; + myObject->setIndexes(mil); + + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + clipboard->setMimeData(myObject); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::slotPastePdmObjects() +{ + if (!currentIndex().isValid()) return; + + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (!myModel) return; + + caf::PdmObjectGroup objectGroup; + createPdmObjectsFromClipboard(&objectGroup); + if (objectGroup.objects().size() == 0) return; + + myModel->addObjects(currentIndex(), objectGroup); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup) +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + if (!myModel) return; + + QClipboard* clipboard = QApplication::clipboard(); + if (!clipboard) return; + + const MimeDataWithIndexes* mdWithIndexes = dynamic_cast(clipboard->mimeData()); + if (!mdWithIndexes) return; + + QModelIndexList indexList = mdWithIndexes->indexes(); + for (int i = 0; i < indexList.size(); i++) + { + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(indexList.at(i)); + objectGroup->addObject(uiItem->dataObject().p()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimUiTreeView::keyPressEvent(QKeyEvent* keyEvent) +{ + RimUiTreeModelPdm* myModel = dynamic_cast(model()); + caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); + + if (dynamic_cast(uiItem->dataObject().p())) + { + if (keyEvent->matches(QKeySequence::Copy)) + { + slotCopyPdmObjectToClipboard(); + keyEvent->setAccepted(true); + + return; + } + } + + if (dynamic_cast(uiItem->dataObject().p()) + || dynamic_cast(uiItem->dataObject().p()) + || dynamic_cast(uiItem->dataObject().p())) + { + if (keyEvent->matches(QKeySequence::Paste)) + { + slotPastePdmObjects(); + keyEvent->setAccepted(true); + + return; + } + } + + QTreeView::keyPressEvent(keyEvent); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimUiTreeView::hasClipboardValidData() +{ + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + if (dynamic_cast(clipboard->mimeData())) + { + return true; + } + } + + return false; +} + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.h b/ApplicationCode/ProjectDataModel/RimUiTreeView.h index 30c4723e76..960000be44 100644 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.h +++ b/ApplicationCode/ProjectDataModel/RimUiTreeView.h @@ -24,6 +24,10 @@ class QItemSelection; +namespace caf { + class PdmObjectGroup; +} + //================================================================================================== /// /// @@ -34,6 +38,7 @@ class RimUiTreeView : public QTreeView public: RimUiTreeView(QWidget *parent = 0); + ~RimUiTreeView(); virtual void setModel(QAbstractItemModel* model); @@ -69,11 +74,28 @@ private slots: void slotCloseCase(); + void slotNewStatisticsCase(); + void slotComputeStatistics(); + + void slotAddCaseGroup(); + void slotDeleteObjectFromPdmPointersField(); + + void slotCopyPdmObjectToClipboard(); + void slotPastePdmObjects(); + void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); signals: void selectedObjectChanged( caf::PdmObject* pdmObject ); + +private: + void createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup); + bool hasClipboardValidData(); + + virtual void keyPressEvent(QKeyEvent* keyEvent); + +private: + QAction* m_pasteAction; }; - diff --git a/ApplicationCode/ProjectDataModel/RimWell.cpp b/ApplicationCode/ProjectDataModel/RimWell.cpp index 59b8a9ea4e..893a3d13ae 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.cpp +++ b/ApplicationCode/ProjectDataModel/RimWell.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimWell.h b/ApplicationCode/ProjectDataModel/RimWell.h index 56e405fe77..a9f18b1ea7 100644 --- a/ApplicationCode/ProjectDataModel/RimWell.h +++ b/ApplicationCode/ProjectDataModel/RimWell.h @@ -24,7 +24,7 @@ #include "cafAppEnum.h" #include "cafPdmFieldCvfColor.h" -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" class RimReservoirView; //================================================================================================== @@ -41,8 +41,8 @@ public: void setReservoirView(RimReservoirView* ownerReservoirView); - void setWellResults(RigWellResults* wellResults) { m_wellResults = wellResults;} - RigWellResults* wellResults() { return m_wellResults.p();} + void setWellResults(RigSingleWellResultsData* wellResults) { m_wellResults = wellResults;} + RigSingleWellResultsData* wellResults() { return m_wellResults.p();} virtual caf::PdmFieldHandle* userDescriptionField(); @@ -61,7 +61,7 @@ public: caf::PdmField pipeRadiusScaleFactor; private: - cvf::ref m_wellResults; + cvf::ref m_wellResults; RimReservoirView* m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp index 8e115ecde6..d1fd3f5ba0 100644 --- a/ApplicationCode/ProjectDataModel/RimWellCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellCollection.cpp @@ -16,13 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cafAppEnum.h" #include "cafPdmFieldCvfColor.h" -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" #include "RimWellCollection.h" #include "RimWell.h" #include "RimReservoirView.h" diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake new file mode 100644 index 0000000000..71c1ec37e7 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -0,0 +1,36 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + + +list(APPEND CODE_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RigActiveCellInfo.h +${CEE_CURRENT_LIST_DIR}RigCell.h +${CEE_CURRENT_LIST_DIR}RigCaseData.h +${CEE_CURRENT_LIST_DIR}RigGridBase.h +${CEE_CURRENT_LIST_DIR}RigGridManager.h +${CEE_CURRENT_LIST_DIR}RigGridScalarDataAccess.h +${CEE_CURRENT_LIST_DIR}RigLocalGrid.h +${CEE_CURRENT_LIST_DIR}RigMainGrid.h +${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.h +${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.h +${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.h +) + +list(APPEND CODE_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RigActiveCellInfo.cpp +${CEE_CURRENT_LIST_DIR}RigCell.cpp +${CEE_CURRENT_LIST_DIR}RigCaseData.cpp +${CEE_CURRENT_LIST_DIR}RigGridBase.cpp +${CEE_CURRENT_LIST_DIR}RigGridManager.cpp +${CEE_CURRENT_LIST_DIR}RigGridScalarDataAccess.cpp +${CEE_CURRENT_LIST_DIR}RigLocalGrid.cpp +${CEE_CURRENT_LIST_DIR}RigMainGrid.cpp +${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.cpp +${CEE_CURRENT_LIST_DIR}RigCaseCellResultsData.cpp +${CEE_CURRENT_LIST_DIR}RigSingleWellResultsData.cpp +) + + diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt index ca2ec9976e..9f20f90ac9 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt @@ -22,10 +22,30 @@ include_directories( ${ResInsight_SOURCE_DIR}/cafProjectDataModel ${ResInsight_SOURCE_DIR}/CommonCode + + #Remove when RigStatistics is out + ${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization ) -file( GLOB CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../*.cpp ) -file( GLOB UNIT_TEST_CPP_SOURCES *.cpp ) +# Populate the filenames into variable lists +include ("${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists_files.cmake") + + +set( UNIT_TEST_CPP_SOURCES + + ${ResInsight_SOURCE_DIR}/cafUserInterface/cafProgressInfo.cpp + + main.cpp + RigActiveCellInfo-Test.cpp + RigReservoir-Test.cpp +) + + +############################################################################# +# Adds folders for Visual Studio solution explorer (and for Xcode explorer) +############################################################################# +source_group( "UnitTests" FILES ${UNIT_TEST_CPP_SOURCES} ) + set( LINK_LIBRARIES @@ -45,8 +65,9 @@ set( LINK_LIBRARIES add_executable( ${ProjectName} - ${CPP_SOURCES} + ${CODE_SOURCE_FILES} ${UNIT_TEST_CPP_SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists_files.cmake ${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc ) diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp new file mode 100644 index 0000000000..57e99d4ec0 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigActiveCellInfo-Test.cpp @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "gtest/gtest.h" + +#include "RigActiveCellInfo.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigActiveCellInfo, BasicTest) +{ + RigActiveCellInfo rigActiveCellInfo; + + size_t globalActiveCellCount = 10; + rigActiveCellInfo.setGlobalCellCount(globalActiveCellCount); + + for (size_t i = 0; i < globalActiveCellCount; i++) + { + EXPECT_TRUE(rigActiveCellInfo.cellResultIndex(i) == cvf::UNDEFINED_SIZE_T); + EXPECT_FALSE(rigActiveCellInfo.isActive(i)); + } + + rigActiveCellInfo.setCellResultIndex(3, 1); + EXPECT_TRUE(rigActiveCellInfo.cellResultIndex(3) == 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigActiveCellInfo, GridCellCounts) +{ + { + RigActiveCellInfo rigActiveCellInfo; + rigActiveCellInfo.setGridCount(3); + rigActiveCellInfo.setGridActiveCellCounts(0, 0); + rigActiveCellInfo.setGridActiveCellCounts(1, 1); + rigActiveCellInfo.setGridActiveCellCounts(2, 2); + rigActiveCellInfo.computeDerivedData(); + + EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 3); + } + + { + RigActiveCellInfo rigActiveCellInfo; + rigActiveCellInfo.setGridCount(3); + rigActiveCellInfo.setGridActiveCellCounts(0, 3 ); + rigActiveCellInfo.setGridActiveCellCounts(1, 4 ); + rigActiveCellInfo.setGridActiveCellCounts(2, 5 ); + rigActiveCellInfo.computeDerivedData(); + + EXPECT_TRUE(rigActiveCellInfo.globalActiveCellCount() == 12); + } +} diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp index 6157a4751e..5fe9cd233b 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp @@ -18,19 +18,85 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "gtest/gtest.h" -#include "RigReservoir.h" +#include "RigCaseData.h" +#include "RigGridManager.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigGridManager, BasicTest) +{ + cvf::ref mainGridA = new RigMainGrid; + + cvf::ref eclipseCase = new RigCaseData; + eclipseCase->setMainGrid(mainGridA.p()); + + int count = mainGridA->refCount(); + EXPECT_EQ(mainGridA->refCount(), 2); + + RigGridManager gridCollection; + gridCollection.addCase(eclipseCase.p()); + EXPECT_EQ(mainGridA->refCount(), 2); + + cvf::ref mainGridB = mainGridA; + EXPECT_EQ(mainGridA->refCount(), 3); + + cvf::ref existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.notNull()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigGridManager, EqualTests) +{ + cvf::ref mainGridA = new RigMainGrid; + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 0)); + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 1)); + mainGridA->nodes().push_back(cvf::Vec3d(0, 0, 2)); + + cvf::ref eclipseCase = new RigCaseData; + eclipseCase->setMainGrid(mainGridA.p()); + + + RigGridManager gridCollection; + gridCollection.addCase(eclipseCase.p()); + + + cvf::ref mainGridB = new RigMainGrid; + cvf::ref existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 0)); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + // Insert nodes in opposite direction + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 2)); + mainGridB->nodes().push_back(cvf::Vec3d(0, 0, 1)); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.isNull()); + + // Overwrite to match the node structure of mainGridA + mainGridB->nodes()[1] = cvf::Vec3d(0, 0, 1); + mainGridB->nodes()[2] = cvf::Vec3d(0, 0, 2); + existingGrid = gridCollection.findEqualGrid(mainGridB.p()); + EXPECT_TRUE(existingGrid.notNull()); + +} + +/* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(RigReservoirTest, BasicTest) { - cvf::ref wellCellTimeHistory = new RigWellResults; + cvf::ref wellCellTimeHistory = new RigSingleWellResultsData; QDateTime wellStartTime = QDateTime::currentDateTime(); @@ -44,7 +110,7 @@ TEST(RigReservoirTest, BasicTest) } int resultTimeStepCount = 2 * wellTimeStepCount; - QList resultTimes; + std::vector resultTimes; for (i = 0; i < resultTimeStepCount; i++) { resultTimes.push_back(QDateTime(wellStartTime).addMonths(i * 6)); @@ -62,3 +128,5 @@ TEST(RigReservoirTest, BasicTest) } + +*/ diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp index fcfac10e30..00d12ebca0 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include "cvfBase.h" diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp new file mode 100644 index 0000000000..486470c849 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -0,0 +1,188 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigActiveCellInfo.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo::RigActiveCellInfo() + : m_globalActiveCellCount(0), + m_activeCellPositionMin(cvf::Vec3d::ZERO), + m_activeCellPositionMax(cvf::Vec3d::ZERO) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGlobalCellCount(size_t globalCellCount) +{ + m_cellIndexToResultIndex.resize(globalCellCount, cvf::UNDEFINED_SIZE_T); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigActiveCellInfo::isActive(size_t globalCellIndex) const +{ + if (m_cellIndexToResultIndex.size() == 0) + { + return true; + } + + CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + + return m_cellIndexToResultIndex[globalCellIndex] != cvf::UNDEFINED_SIZE_T; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::cellResultIndex(size_t globalCellIndex) const +{ + if (m_cellIndexToResultIndex.size() == 0) + { + return globalCellIndex; + } + + CVF_TIGHT_ASSERT(globalCellIndex < m_cellIndexToResultIndex.size()); + + return m_cellIndexToResultIndex[globalCellIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setCellResultIndex(size_t globalCellIndex, size_t globalActiveCellIndex) +{ + CVF_TIGHT_ASSERT(globalActiveCellIndex < m_cellIndexToResultIndex.size()); + + m_cellIndexToResultIndex[globalCellIndex] = globalActiveCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGridCount(size_t gridCount) +{ + m_perGridActiveCellInfo.resize(gridCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount) +{ + CVF_ASSERT(gridIndex < m_perGridActiveCellInfo.size()); + + m_perGridActiveCellInfo[gridIndex].setActiveCellCount(activeCellCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::computeDerivedData() +{ + m_globalActiveCellCount = 0; + + for (size_t i = 0; i < m_perGridActiveCellInfo.size(); i++) + { + m_globalActiveCellCount += m_perGridActiveCellInfo[i].activeCellCount(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::globalActiveCellCount() const +{ + return m_globalActiveCellCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max) +{ + m_activeCellPositionMin = min; + m_activeCellPositionMax = max; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const +{ + min = m_activeCellPositionMin; + max = m_activeCellPositionMax; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount) +{ + activeCellCount = m_perGridActiveCellInfo[gridIndex].activeCellCount(); +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const +{ + return m_activeCellsBoundingBox; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb) +{ + m_activeCellsBoundingBox = bb; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::clear() +{ + m_perGridActiveCellInfo.clear(); + m_cellIndexToResultIndex.clear(); + m_globalActiveCellCount = 0; + m_activeCellPositionMin = cvf::Vec3st(0,0,0); + m_activeCellPositionMax = cvf::Vec3st(0,0,0); + m_activeCellsBoundingBox.reset(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const +{ + return m_activeCellCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::GridActiveCellCounts::setActiveCellCount(size_t activeCellCount) +{ + m_activeCellCount = activeCellCount; +} diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h new file mode 100644 index 0000000000..7086b87d4f --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfVector3.h" +#include "cvfBoundingBox.h" + +#include + + + +class RigActiveCellInfo : public cvf::Object +{ +public: + RigActiveCellInfo(); + + void setGlobalCellCount(size_t globalCellCount); + + bool isActive(size_t globalCellIndex) const; + size_t cellResultIndex(size_t globalCellIndex) const; + void setCellResultIndex(size_t globalCellIndex, size_t globalActiveCellIndex); + + void setGridCount(size_t gridCount); + void setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount); + void gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount); + void computeDerivedData(); + + size_t globalActiveCellCount() const; + + void setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max); + void IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; + + cvf::BoundingBox geometryBoundingBox() const; + void setGeometryBoundingBox(cvf::BoundingBox bb); + + void clear(); + +private: + class GridActiveCellCounts + { + public: + size_t activeCellCount() const; + void setActiveCellCount(size_t activeCellCount); + + private: + size_t m_activeCellCount; + }; + + +private: + std::vector m_perGridActiveCellInfo; + + std::vector m_cellIndexToResultIndex; + + size_t m_globalActiveCellCount; + + cvf::Vec3st m_activeCellPositionMin; + cvf::Vec3st m_activeCellPositionMax; + + cvf::BoundingBox m_activeCellsBoundingBox; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp similarity index 55% rename from ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp rename to ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 1e0bfcea9f..517aca7693 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -16,28 +16,36 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RifReaderInterface.h" #include "RigMainGrid.h" #include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigReservoirCellResults::RigReservoirCellResults(RigMainGrid* ownerGrid) +RigCaseCellResultsData::RigCaseCellResultsData(RigMainGrid* ownerGrid) { CVF_ASSERT(ownerGrid != NULL); m_ownerMainGrid = ownerGrid; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::setMainGrid(RigMainGrid* ownerGrid) +{ + m_ownerMainGrid = ownerGrid; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max ) +void RigCaseCellResultsData::minMaxCellScalarValues( size_t scalarResultIndex, double& min, double& max ) { min = HUGE_VAL; max = -HUGE_VAL; @@ -75,7 +83,7 @@ void RigReservoirCellResults::minMaxCellScalarValues( size_t scalarResultIndex, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) +void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) { min = HUGE_VAL; max = -HUGE_VAL; @@ -129,7 +137,7 @@ void RigReservoirCellResults::minMaxCellScalarValues(size_t scalarResultIndex, s //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigReservoirCellResults::cellScalarValuesHistogram(size_t scalarResultIndex) +const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(size_t scalarResultIndex) { CVF_ASSERT(scalarResultIndex < resultCount()); @@ -170,7 +178,7 @@ const std::vector& RigReservoirCellResults::cellScalarValuesHistogram(si //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) +void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) { const std::vector& histogr = cellScalarValuesHistogram( scalarResultIndex); p10 = m_p10p90[scalarResultIndex].first; @@ -180,7 +188,7 @@ void RigReservoirCellResults::p10p90CellScalarValues(size_t scalarResultIndex, d //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) +void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) { CVF_ASSERT(scalarResultIndex < resultCount()); @@ -216,7 +224,7 @@ void RigReservoirCellResults::meanCellScalarValues(size_t scalarResultIndex, dou //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::resultCount() const +size_t RigCaseCellResultsData::resultCount() const { return m_cellScalarResults.size(); } @@ -224,7 +232,7 @@ size_t RigReservoirCellResults::resultCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::timeStepCount(size_t scalarResultIndex) const +size_t RigCaseCellResultsData::timeStepCount(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -234,7 +242,17 @@ size_t RigReservoirCellResults::timeStepCount(size_t scalarResultIndex) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector< std::vector > & RigReservoirCellResults::cellScalarResults( size_t scalarResultIndex ) +const std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) const +{ + CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); + + return m_cellScalarResults[scalarResultIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -244,7 +262,18 @@ std::vector< std::vector > & RigReservoirCellResults::cellScalarResults( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigReservoirCellResults::cellScalarResult(size_t timeStepIndex, size_t scalarResultIndex, size_t resultValueIndex) +std::vector& RigCaseCellResultsData::cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex) +{ + CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); + CVF_TIGHT_ASSERT(timeStepIndex < m_cellScalarResults[scalarResultIndex].size()); + + return m_cellScalarResults[scalarResultIndex][timeStepIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCaseCellResultsData::cellScalarResult( size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex) { if (scalarResultIndex < resultCount() && timeStepIndex < m_cellScalarResults[scalarResultIndex].size() && @@ -259,78 +288,11 @@ double RigReservoirCellResults::cellScalarResult(size_t timeStepIndex, size_t sc } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName) -{ - size_t resultGridIndex = cvf::UNDEFINED_SIZE_T; - - resultGridIndex = findScalarResultIndex(type, resultName); - - if (resultGridIndex == cvf::UNDEFINED_SIZE_T) return cvf::UNDEFINED_SIZE_T; - - if (cellScalarResults(resultGridIndex).size()) return resultGridIndex; - - if (type == RimDefines::GENERATED) - { - return cvf::UNDEFINED_SIZE_T; - } - - if (m_readerInterface.notNull()) - { - // Add one more result to result container - size_t timeStepCount = m_resultInfos[resultGridIndex].m_timeStepDates.size(); - - bool resultLoadingSucess = true; - - if (type == RimDefines::DYNAMIC_NATIVE && timeStepCount > 0) - { - m_cellScalarResults[resultGridIndex].resize(timeStepCount); - - size_t i; - for (i = 0; i < timeStepCount; i++) - { - std::vector& values = m_cellScalarResults[resultGridIndex][i]; - if (!m_readerInterface->dynamicResult(resultName, RifReaderInterface::MATRIX_RESULTS, i, &values)) - { - resultLoadingSucess = false; - } - } - } - else if (type == RimDefines::STATIC_NATIVE) - { - m_cellScalarResults[resultGridIndex].resize(1); - - std::vector& values = m_cellScalarResults[resultGridIndex][0]; - if (!m_readerInterface->staticResult(resultName, RifReaderInterface::MATRIX_RESULTS, &values)) - { - resultLoadingSucess = false; - } - } - - if (!resultLoadingSucess) - { - // Remove last scalar result because loading of result failed - m_cellScalarResults[resultGridIndex].clear(); - } - } - - return resultGridIndex; -} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::setReaderInterface(RifReaderInterface* readerInterface) -{ - m_readerInterface = readerInterface; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const +size_t RigCaseCellResultsData::findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const { std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); it++) @@ -347,7 +309,7 @@ size_t RigReservoirCellResults::findScalarResultIndex(RimDefines::ResultCatType //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findScalarResultIndex(const QString& resultName) const +size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) const { size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; @@ -371,227 +333,11 @@ size_t RigReservoirCellResults::findScalarResultIndex(const QString& resultName) return scalarResultIndex; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::loadOrComputeSOIL() -{ - size_t soilResultGridIndex = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - - if (soilResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - size_t scalarIndexSWAT = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - size_t scalarIndexSGAS = findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - - // Early exit if none of SWAT or SGAS is present - if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) - { - return; - } - - soilResultGridIndex = addEmptyScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - - const std::vector< std::vector >* swat = NULL; - const std::vector< std::vector >* sgas = NULL; - if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) - { - swat = &(cellScalarResults(scalarIndexSWAT)); - } - - if (scalarIndexSGAS != cvf::UNDEFINED_SIZE_T) - { - sgas = &(cellScalarResults(scalarIndexSGAS)); - } - - size_t soilResultValueCount = 0; - size_t soilTimeStepCount = 0; - if (swat) - { - soilResultValueCount = swat->at(0).size(); - soilTimeStepCount = m_resultInfos[scalarIndexSWAT].m_timeStepDates.size(); - } - - if (sgas) - { - soilResultValueCount = qMax(soilResultValueCount, sgas->at(0).size()); - - size_t sgasTimeStepCount = m_resultInfos[scalarIndexSGAS].m_timeStepDates.size(); - soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); - } - - m_cellScalarResults[soilResultGridIndex].resize(soilTimeStepCount); - - std::vector< std::vector >& soil = cellScalarResults(soilResultGridIndex); - - int timeStepIdx = 0; - for (timeStepIdx = 0; timeStepIdx < static_cast(soilTimeStepCount); timeStepIdx++) - { - soil[timeStepIdx].resize(soilResultValueCount); - -#pragma omp parallel for - for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) - { - double soilValue = 1.0; - if (sgas) - { - soilValue -= sgas->at(timeStepIdx)[idx]; - } - - if (swat) - { - soilValue -= swat->at(timeStepIdx)[idx]; - } - - soil[timeStepIdx][idx] = soilValue; - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::computeDepthRelatedResults() -{ - size_t depthResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DEPTH"); - size_t dxResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DX"); - size_t dyResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DY"); - size_t dzResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "DZ"); - size_t topsResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "TOPS"); - size_t bottomResultGridIndex = findOrLoadScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM"); - - bool computeDepth = false; - bool computeDx = false; - bool computeDy = false; - bool computeDz = false; - bool computeTops = false; - bool computeBottom = false; - - size_t resultValueCount = m_ownerMainGrid->cells().size(); - - if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - depthResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DEPTH", resultValueCount); - computeDepth = true; - } - - if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dxResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DX", resultValueCount); - computeDx = true; - } - - if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dyResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DY", resultValueCount); - computeDy = true; - } - - if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - dzResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "DZ", resultValueCount); - computeDz = true; - } - - if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - topsResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "TOPS", resultValueCount); - computeTops = true; - } - - if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) - { - bottomResultGridIndex = addStaticScalarResult(RimDefines::STATIC_NATIVE, "BOTTOM", resultValueCount); - computeBottom = true; - } - - std::vector< std::vector >& depth = cellScalarResults(depthResultGridIndex); - std::vector< std::vector >& dx = cellScalarResults(dxResultGridIndex); - std::vector< std::vector >& dy = cellScalarResults(dyResultGridIndex); - std::vector< std::vector >& dz = cellScalarResults(dzResultGridIndex); - std::vector< std::vector >& tops = cellScalarResults(topsResultGridIndex); - std::vector< std::vector >& bottom = cellScalarResults(bottomResultGridIndex); - - bool computeValuesForActiveCellsOnly = m_ownerMainGrid->globalMatrixModelActiveCellCount() > 0; - - size_t cellIdx = 0; - for (cellIdx = 0; cellIdx < m_ownerMainGrid->cells().size(); cellIdx++) - { - const RigCell& cell = m_ownerMainGrid->cells()[cellIdx]; - - if (computeValuesForActiveCellsOnly && !cell.isActiveInMatrixModel()) - { - continue; - } - - if (computeDepth) - { - depth[0][cellIdx] = cvf::Math::abs(cell.center().z()); - } - - if (computeDx) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); - dx[0][cellIdx] = cvf::Math::abs(cellWidth.x()); - } - - if (computeDy) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); - dy[0][cellIdx] = cvf::Math::abs(cellWidth.y()); - } - - if (computeDz) - { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); - dz[0][cellIdx] = cvf::Math::abs(cellWidth.z()); - } - - if (computeTops) - { - tops[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); - } - - if (computeBottom) - { - bottom[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::findOrLoadScalarResult(const QString& resultName) -{ - size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; - - scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = this->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, resultName); - } - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = this->findScalarResultIndex(RimDefines::GENERATED, resultName); - } - - if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) - { - scalarResultIndex = this->findScalarResultIndex(RimDefines::INPUT_PROPERTY, resultName); - } - - return scalarResultIndex; -} - //-------------------------------------------------------------------------------------------------- /// Adds an empty scalar set, and returns the scalarResultIndex to it. /// if resultName already exists, it returns the scalarResultIndex to the existing result. //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName) +size_t RigCaseCellResultsData::addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored) { size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; @@ -600,7 +346,7 @@ size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType t { scalarResultIndex = this->resultCount(); m_cellScalarResults.push_back(std::vector >()); - ResultInfo resInfo(type, resultName, scalarResultIndex); + ResultInfo resInfo(type, needsToBeStored, resultName, scalarResultIndex); m_resultInfos.push_back(resInfo); } @@ -610,7 +356,7 @@ size_t RigReservoirCellResults::addEmptyScalarResult(RimDefines::ResultCatType t //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList RigReservoirCellResults::resultNames(RimDefines::ResultCatType resType) const +QStringList RigCaseCellResultsData::resultNames(RimDefines::ResultCatType resType) const { QStringList varList; std::vector::const_iterator it; @@ -627,7 +373,7 @@ QStringList RigReservoirCellResults::resultNames(RimDefines::ResultCatType resTy //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::recalculateMinMax(size_t scalarResultIndex) +void RigCaseCellResultsData::recalculateMinMax(size_t scalarResultIndex) { // Make sure cached max min values are recalculated next time asked for, since // the data could be changed. @@ -646,26 +392,22 @@ void RigReservoirCellResults::recalculateMinMax(size_t scalarResultIndex) //-------------------------------------------------------------------------------------------------- /// Returns whether the result data in question is addressed by Active Cell Index //-------------------------------------------------------------------------------------------------- -bool RigReservoirCellResults::isUsingGlobalActiveIndex(size_t scalarResultIndex) const +bool RigCaseCellResultsData::isUsingGlobalActiveIndex(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < m_cellScalarResults.size()); if (!m_cellScalarResults[scalarResultIndex].size()) return true; size_t firstTimeStepResultValueCount = m_cellScalarResults[scalarResultIndex][0].size(); - if (firstTimeStepResultValueCount == m_ownerMainGrid->globalMatrixModelActiveCellCount()) return true; - if (firstTimeStepResultValueCount == m_ownerMainGrid->globalFractureModelActiveCellCount()) return true; if (firstTimeStepResultValueCount == m_ownerMainGrid->cells().size()) return false; - CVF_TIGHT_ASSERT(false); // Wrong number of results - - return false; + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QDateTime RigReservoirCellResults::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const +QDateTime RigCaseCellResultsData::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const { if (scalarResultIndex < m_resultInfos.size() && (size_t)(m_resultInfos[scalarResultIndex].m_timeStepDates.size()) > timeStepIndex) return m_resultInfos[scalarResultIndex].m_timeStepDates[static_cast(timeStepIndex)]; @@ -676,41 +418,56 @@ QDateTime RigReservoirCellResults::timeStepDate(size_t scalarResultIndex, size_t //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QList RigReservoirCellResults::timeStepDates(size_t scalarResultIndex) const +std::vector RigCaseCellResultsData::timeStepDates(size_t scalarResultIndex) const { if (scalarResultIndex < m_resultInfos.size() ) return m_resultInfos[scalarResultIndex].m_timeStepDates; else - return QList(); + return std::vector(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::setTimeStepDates(size_t scalarResultIndex, const QList& dates) +void RigCaseCellResultsData::setTimeStepDates(size_t scalarResultIndex, const std::vector& dates) { CVF_ASSERT(scalarResultIndex < m_resultInfos.size() ); m_resultInfos[scalarResultIndex].m_timeStepDates = dates; + + std::vector< std::vector >& dataValues = this->cellScalarResults(scalarResultIndex); + dataValues.resize(dates.size()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::maxTimeStepCount() const +size_t RigCaseCellResultsData::maxTimeStepCount(size_t* scalarResultIndexWithMostTimeSteps) const { size_t maxTsCount = 0; - for (size_t i = 0; i < m_cellScalarResults.size(); ++i) + size_t scalarResultIndexWithMaxTsCount = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_resultInfos.size(); i++) { - maxTsCount = m_cellScalarResults[i].size() > maxTsCount ? m_cellScalarResults[i].size() : maxTsCount; + if (m_resultInfos[i].m_timeStepDates.size() > maxTsCount) + { + maxTsCount = m_resultInfos[i].m_timeStepDates.size(); + scalarResultIndexWithMaxTsCount = i; + } } + + if (scalarResultIndexWithMostTimeSteps) + { + *scalarResultIndexWithMostTimeSteps = scalarResultIndexWithMaxTsCount; + } + return maxTsCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RigReservoirCellResults::makeResultNameUnique(const QString& resultNameProposal) const +QString RigCaseCellResultsData::makeResultNameUnique(const QString& resultNameProposal) const { QString newResultName = resultNameProposal; size_t resultIndex = cvf::UNDEFINED_SIZE_T; @@ -732,7 +489,7 @@ QString RigReservoirCellResults::makeResultNameUnique(const QString& resultNameP //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::removeResult(const QString& resultName) +void RigCaseCellResultsData::removeResult(const QString& resultName) { size_t resultIdx = findScalarResultIndex(resultName); if (resultIdx == cvf::UNDEFINED_SIZE_T) return; @@ -745,20 +502,23 @@ void RigReservoirCellResults::removeResult(const QString& resultName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirCellResults::clearAllResults() +void RigCaseCellResultsData::clearAllResults() { - for (size_t i = 0; i < m_cellScalarResults.size(); i++) - { - m_cellScalarResults[i].clear(); - } + m_cellScalarResults.clear(); + m_maxMinValues.clear(); + m_histograms.clear(); + m_p10p90.clear(); + m_meanValues.clear(); + m_maxMinValuesPrTs.clear(); + m_resultInfos.clear(); } //-------------------------------------------------------------------------------------------------- /// Add a result with given type and name, and allocate one result vector for the static result values //-------------------------------------------------------------------------------------------------- -size_t RigReservoirCellResults::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, size_t resultValueCount) +size_t RigCaseCellResultsData::addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount) { - size_t resultIdx = addEmptyScalarResult(type, resultName); + size_t resultIdx = addEmptyScalarResult(type, resultName, needsToBeStored); m_cellScalarResults[resultIdx].push_back(std::vector()); m_cellScalarResults[resultIdx][0].resize(resultValueCount, HUGE_VAL); @@ -769,7 +529,7 @@ size_t RigReservoirCellResults::addStaticScalarResult(RimDefines::ResultCatType //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderInterface::PorosityModelResultType RigReservoirCellResults::convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel) +RifReaderInterface::PorosityModelResultType RigCaseCellResultsData::convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel) { if (porosityModel == RimDefines::MATRIX_MODEL) return RifReaderInterface::MATRIX_RESULTS; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h similarity index 53% rename from ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h rename to ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index 577f681039..31ec57dae4 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirCellResults.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -30,79 +30,89 @@ class RigMainGrid; //================================================================================================== /// Class containing the results for the complete number of active cells. Both main grid and LGR's //================================================================================================== -class RigReservoirCellResults : public cvf::Object +class RigCaseCellResultsData : public cvf::Object { public: - RigReservoirCellResults(RigMainGrid* ownerGrid); + RigCaseCellResultsData(RigMainGrid* ownerGrid); - void setReaderInterface(RifReaderInterface* readerInterface); + void setMainGrid(RigMainGrid* ownerGrid); // Max and min values of the results - void recalculateMinMax(size_t scalarResultIndex); - void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max); - void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max); - const std::vector& cellScalarValuesHistogram(size_t scalarResultIndex); - void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90); - void meanCellScalarValues(size_t scalarResultIndex, double& meanValue); + void recalculateMinMax(size_t scalarResultIndex); + void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max); + void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max); + const std::vector& cellScalarValuesHistogram(size_t scalarResultIndex); + void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90); + void meanCellScalarValues(size_t scalarResultIndex, double& meanValue); // Access meta-information about the results - size_t resultCount() const; - size_t timeStepCount(size_t scalarResultIndex) const; - size_t maxTimeStepCount() const; - QStringList resultNames(RimDefines::ResultCatType type) const; - bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const; + size_t resultCount() const; + size_t timeStepCount(size_t scalarResultIndex) const; + size_t maxTimeStepCount(size_t* scalarResultIndex = NULL) const; + QStringList resultNames(RimDefines::ResultCatType type) const; + bool isUsingGlobalActiveIndex(size_t scalarResultIndex) const; - QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const; - QList timeStepDates(size_t scalarResultIndex) const; - void setTimeStepDates(size_t scalarResultIndex, const QList& dates); + QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const; + std::vector timeStepDates(size_t scalarResultIndex) const; + void setTimeStepDates(size_t scalarResultIndex, const std::vector& dates); // Find or create a slot for the results - size_t findOrLoadScalarResult(RimDefines::ResultCatType type, const QString& resultName); - size_t findOrLoadScalarResult(const QString& resultName); ///< Simplified search. Assumes unique names across types. - size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const; - size_t findScalarResultIndex(const QString& resultName) const; - size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName); - QString makeResultNameUnique(const QString& resultNameProposal) const; - void removeResult(const QString& resultName); - void clearAllResults(); + size_t findScalarResultIndex(RimDefines::ResultCatType type, const QString& resultName) const; + size_t findScalarResultIndex(const QString& resultName) const; - void loadOrComputeSOIL(); - void computeDepthRelatedResults(); + size_t addEmptyScalarResult(RimDefines::ResultCatType type, const QString& resultName, bool needsToBeStored); + QString makeResultNameUnique(const QString& resultNameProposal) const; + + void removeResult(const QString& resultName); + void clearAllResults(); // Access the results data - std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex); - double cellScalarResult(size_t timeStepIndex, size_t scalarResultIndex, size_t resultValueIndex); + + const std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex) const; + std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex); + std::vector& cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex); + double cellScalarResult(size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex); static RifReaderInterface::PorosityModelResultType convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel); - -private: - size_t addStaticScalarResult(RimDefines::ResultCatType type, const QString& resultName, size_t resultValueCount); - -private: - std::vector< std::vector< std::vector > > m_cellScalarResults; ///< Scalar results for each timestep for each Result index (ResultVariable) - std::vector< std::pair > m_maxMinValues; ///< Max min values for each Result index - std::vector< std::vector > m_histograms; ///< Histogram for each Result Index - std::vector< std::pair > m_p10p90; ///< P10 and p90 values for each Result Index - std::vector< double > m_meanValues; ///< Mean value for each Result Index - - std::vector< std::vector< std::pair > > m_maxMinValuesPrTs; ///< Max min values for each timestep and Result index +public: class ResultInfo { public: - ResultInfo(RimDefines::ResultCatType resultType, QString resultName, size_t gridScalarResultIndex) - : m_resultType(resultType), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex) { } + ResultInfo(RimDefines::ResultCatType resultType, bool needsToBeStored, QString resultName, size_t gridScalarResultIndex) + : m_resultType(resultType), m_needsToBeStored(needsToBeStored), m_resultName(resultName), m_gridScalarResultIndex(gridScalarResultIndex) { } public: RimDefines::ResultCatType m_resultType; + bool m_needsToBeStored; QString m_resultName; size_t m_gridScalarResultIndex; - QList m_timeStepDates; + std::vector m_timeStepDates; }; + const std::vector& infoForEachResultIndex() { return m_resultInfos;} + +public: + size_t addStaticScalarResult(RimDefines::ResultCatType type, + const QString& resultName, + bool needsToBeStored, + size_t resultValueCount); + +private: + std::vector< std::vector< std::vector > > m_cellScalarResults; ///< Scalar results on the complete reservoir for each Result index (ResultVariable) and timestep + std::vector< std::pair > m_maxMinValues; ///< Max min values for each Result index + std::vector< std::vector > m_histograms; ///< Histogram for each Result Index + std::vector< std::pair > m_p10p90; ///< P10 and p90 values for each Result Index + std::vector< double > m_meanValues; ///< Mean value for each Result Index + + std::vector< std::vector< std::pair > > m_maxMinValuesPrTs; ///< Max min values for each Result index and timestep + + + +private: std::vector m_resultInfos; - cvf::ref m_readerInterface; + RigMainGrid* m_ownerMainGrid; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp new file mode 100644 index 0000000000..b10a189744 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.cpp @@ -0,0 +1,486 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigCaseData.h" +#include "RigMainGrid.h" +#include "RigCaseCellResultsData.h" +#include "RigGridScalarDataAccess.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData::RigCaseData() +{ + m_mainGrid = new RigMainGrid(); + + m_matrixModelResults = new RigCaseCellResultsData(m_mainGrid.p()); + m_fractureModelResults = new RigCaseCellResultsData(m_mainGrid.p()); + + m_activeCellInfo = new RigActiveCellInfo; + m_fractureActiveCellInfo = new RigActiveCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseData::~RigCaseData() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setMainGrid(RigMainGrid* mainGrid) +{ + m_mainGrid = mainGrid; + + m_matrixModelResults->setMainGrid(m_mainGrid.p()); + m_fractureModelResults->setMainGrid(m_mainGrid.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::allGrids(std::vector* grids) +{ + CVF_ASSERT(grids); + + if (m_mainGrid.isNull()) + { + return; + } + + size_t i; + for (i = 0; i < m_mainGrid->gridCount(); i++) + { + grids->push_back(m_mainGrid->gridByIndex(i)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::allGrids(std::vector* grids) const +{ + CVF_ASSERT(grids); + + if (m_mainGrid.isNull()) + { + return; + } + + size_t i; + for (i = 0; i < m_mainGrid->gridCount(); i++) + { + grids->push_back(m_mainGrid->gridByIndex(i)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Get grid by index. The main grid has index 0, so the first lgr has index 1 +//-------------------------------------------------------------------------------------------------- +const RigGridBase* RigCaseData::grid(size_t index) const +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridByIndex(index); +} + + +//-------------------------------------------------------------------------------------------------- +/// Get grid by index. The main grid has index 0, so the first lgr has index 1 +//-------------------------------------------------------------------------------------------------- +RigGridBase* RigCaseData::grid(size_t index) +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridByIndex(index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigCaseData::gridCount() const +{ + CVF_ASSERT(m_mainGrid.notNull()); + return m_mainGrid->gridCount(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeWellCellsPrGrid() +{ + // If we have computed this already, return + if (m_wellCellsInGrid.size()) return; + + std::vector grids; + this->allGrids(&grids); + size_t gIdx; + + // Allocate and initialize the arrays + + m_wellCellsInGrid.resize(grids.size()); + + for (gIdx = 0; gIdx < grids.size(); ++gIdx) + { + if (m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount()) + { + m_wellCellsInGrid[gIdx] = new cvf::UByteArray; + m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount()); + + } + m_wellCellsInGrid[gIdx]->setAll(false); + } + + // Fill arrays with data + size_t wIdx; + for (wIdx = 0; wIdx < m_wellResults.size(); ++wIdx) + { + size_t tIdx; + for (tIdx = 0; tIdx < m_wellResults[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx) + { + RigWellResultFrame& wellCells = m_wellResults[wIdx]->m_wellCellsTimeSteps[tIdx]; + + size_t gridIndex = wellCells.m_wellHead.m_gridIndex; + size_t gridCellIndex = wellCells.m_wellHead.m_gridCellIndex; + + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); + m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); + + size_t sIdx; + for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx) + { + RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx]; + size_t cdIdx; + for (cdIdx = 0; cdIdx < wellSegment.m_wellCells.size(); ++cdIdx) + { + gridIndex = wellSegment.m_wellCells[cdIdx].m_gridIndex; + gridCellIndex = wellSegment.m_wellCells[cdIdx].m_gridCellIndex; + + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); + + m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setWellResults(const cvf::Collection& data) +{ + m_wellResults = data; + m_wellCellsInGrid.clear(); + computeWellCellsPrGrid(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::UByteArray* RigCaseData::wellCellsInGrid(size_t gridIndex) +{ + computeWellCellsPrGrid(); + CVF_ASSERT(gridIndex < m_wellCellsInGrid.size()); + + return m_wellCellsInGrid[gridIndex].p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCell& RigCaseData::cellFromWellResultCell(const RigWellResultCell& wellResultCell) +{ + size_t gridIndex = wellResultCell.m_gridIndex; + size_t gridCellIndex = wellResultCell.m_gridCellIndex; + + std::vector grids; + allGrids(&grids); + + return grids[gridIndex]->cell(gridCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseData::findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace,const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const +{ + size_t gridIndex = sourceWellCellResult.m_gridIndex; + size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex; + + size_t otherGridIndex = otherWellCellResult.m_gridIndex; + size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex; + + if (gridIndex != otherGridIndex) return false; + + std::vector grids; + allGrids(&grids); + + const RigGridBase* grid = grids[gridIndex]; + size_t i, j, k; + grid->ijkFromCellIndex(gridCellIndex, &i, &j, &k); + + size_t faceIdx; + for (faceIdx = 0; faceIdx < 6; faceIdx++) + { + cvf::StructGridInterface::FaceType sourceFace = static_cast(faceIdx); + + size_t ni, nj, nk; + grid->neighborIJKAtCellFace(i, j, k, sourceFace, &ni, &nj, &nk); + size_t neighborCellIndex = grid->cellIndexFromIJK(ni, nj, nk); + + if (neighborCellIndex == otherGridCellIndex) + { + sharedSourceFace = sourceFace; + return true; + } + } + + return false; +} + + + +//-------------------------------------------------------------------------------------------------- +/// Helper class used to find min/max range for valid and active cells +//-------------------------------------------------------------------------------------------------- +class CellRangeBB +{ +public: + CellRangeBB() + : m_min(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T), + m_max(cvf::Vec3st::ZERO) + { + + } + + void add(size_t i, size_t j, size_t k) + { + if (i < m_min.x()) m_min.x() = i; + if (j < m_min.y()) m_min.y() = j; + if (k < m_min.z()) m_min.z() = k; + + if (i > m_max.x()) m_max.x() = i; + if (j > m_max.y()) m_max.y() = j; + if (k > m_max.z()) m_max.z() = k; + } + +public: + cvf::Vec3st m_min; + cvf::Vec3st m_max; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellIJKBBox() +{ + if (m_mainGrid.notNull() && m_activeCellInfo.notNull() && m_fractureActiveCellInfo.notNull()) + { + CellRangeBB matrixModelActiveBB; + CellRangeBB fractureModelActiveBB; + + size_t idx; + for (idx = 0; idx < m_mainGrid->cellCount(); idx++) + { + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(idx, &i, &j, &k); + + if (m_activeCellInfo->isActive(idx)) + { + matrixModelActiveBB.add(i, j, k); + } + + if (m_fractureActiveCellInfo->isActive(idx)) + { + fractureModelActiveBB.add(i, j, k); + } + } + m_activeCellInfo->setIJKBoundingBox(matrixModelActiveBB.m_min, matrixModelActiveBB.m_max); + m_fractureActiveCellInfo->setIJKBoundingBox(fractureModelActiveBB.m_min, fractureModelActiveBB.m_max); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellBoundingBoxes() +{ + computeActiveCellIJKBBox(); + computeActiveCellsGeometryBoundingBox(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RigCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_activeCellInfo.p(); + } + + return m_fractureActiveCellInfo.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigActiveCellInfo* RigCaseData::activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_activeCellInfo.p(); + } + + return m_fractureActiveCellInfo.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + m_activeCellInfo = activeCellInfo; + } + else + { + m_fractureActiveCellInfo = activeCellInfo; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::computeActiveCellsGeometryBoundingBox() +{ + if (m_activeCellInfo.notNull() || m_fractureActiveCellInfo.notNull()) + { + return; + } + + if (m_mainGrid.isNull()) + { + cvf::BoundingBox bb; + m_activeCellInfo->setGeometryBoundingBox(bb); + m_fractureActiveCellInfo->setGeometryBoundingBox(bb); + return; + } + + RigActiveCellInfo* activeInfos[2]; + activeInfos[0] = m_fractureActiveCellInfo.p(); + activeInfos[1] = m_activeCellInfo.p(); // Last, to make this bb.min become display offset + + cvf::BoundingBox bb; + for (int acIdx = 0; acIdx < 2; ++acIdx) + { + bb.reset(); + if (m_mainGrid->nodes().size() == 0) + { + bb.add(cvf::Vec3d::ZERO); + } + else + { + for (size_t i = 0; i < m_mainGrid->cellCount(); i++) + { + if (activeInfos[acIdx]->isActive(i)) + { + const RigCell& c = m_mainGrid->cells()[i]; + const caf::SizeTArray8& indices = c.cornerIndices(); + + size_t idx; + for (idx = 0; idx < 8; idx++) + { + bb.add(m_mainGrid->nodes()[indices[idx]]); + } + } + } + } + + activeInfos[acIdx]->setGeometryBoundingBox(bb); + } + + m_mainGrid->setDisplayModelOffset(bb.min()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseCellResultsData* RigCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel) +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults.p(); + } + + return m_fractureModelResults.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigCaseCellResultsData* RigCaseData::results(RifReaderInterface::PorosityModelResultType porosityModel) const +{ + if (porosityModel == RifReaderInterface::MATRIX_RESULTS) + { + return m_matrixModelResults.p(); + } + + return m_fractureModelResults.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigCaseData::dataAccessObject(const RigGridBase* grid, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex) +{ + if (timeStepIndex != cvf::UNDEFINED_SIZE_T && + scalarSetIndex != cvf::UNDEFINED_SIZE_T) + { + cvf::ref dataAccess = RigGridScalarDataAccessFactory::createPerGridDataAccessObject( this, grid->gridIndex(), porosityModel, timeStepIndex, scalarSetIndex); + return dataAccess; + } + + return NULL; + +} + + +/* +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseData::closeReaderInterface() +{ + RifReaderInterface* readerInterface = m_matrixModelResults->readerInterface(); + + if (readerInterface) + { + readerInterface->close(); + } +} +*/ diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.h b/ApplicationCode/ReservoirDataModel/RigCaseData.h new file mode 100644 index 0000000000..866dec4819 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.h @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "RigCell.h" +#include "cvfVector3.h" +#include "cvfAssert.h" +#include "cvfObject.h" +#include "RigMainGrid.h" +#include "RigSingleWellResultsData.h" +#include "RigActiveCellInfo.h" + +class RigCaseCellResultsData; + + +class RigCaseData: public cvf::Object +{ +public: + RigCaseData(); + ~RigCaseData(); + + RigMainGrid* mainGrid() { return m_mainGrid.p(); } + const RigMainGrid* mainGrid() const { return m_mainGrid.p(); } + void setMainGrid(RigMainGrid* mainGrid); + + void allGrids(std::vector* grids); // To be removed + void allGrids(std::vector* grids) const;// To be removed + const RigGridBase* grid(size_t index) const; + RigGridBase* grid(size_t index); + size_t gridCount() const; + + RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel); + const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const; + + RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel); + const RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel) const; + void setActiveCellInfo(RifReaderInterface::PorosityModelResultType porosityModel, RigActiveCellInfo* activeCellInfo); + + + cvf::ref dataAccessObject(const RigGridBase* grid, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex); + + void setWellResults(const cvf::Collection& data); + const cvf::Collection& wellResults() { return m_wellResults; } + + cvf::UByteArray* wellCellsInGrid(size_t gridIndex); + + RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell); + bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const; + + void computeActiveCellBoundingBoxes(); + +private: + void computeActiveCellIJKBBox(); + void computeWellCellsPrGrid(); + void computeActiveCellsGeometryBoundingBox(); + +private: + cvf::ref m_mainGrid; + + cvf::ref m_activeCellInfo; + cvf::ref m_fractureActiveCellInfo; + + cvf::ref m_matrixModelResults; + cvf::ref m_fractureModelResults; + + cvf::Collection m_wellResults; //< A WellResults object for each well in the reservoir + cvf::Collection m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling wether the cell is a well cell or not +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCell.cpp b/ApplicationCode/ReservoirDataModel/RigCell.cpp index 6c7bfd573c..7e0a83724d 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCell.cpp @@ -16,11 +16,13 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigCell.h" #include "RigMainGrid.h" #include "cvfPlane.h" +#include "cvfRay.h" + +#include static size_t undefinedCornersArray[8] = {cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, @@ -39,9 +41,6 @@ RigCell::RigCell() : m_subGrid(NULL), m_hostGrid(NULL), m_isInvalid(false), - m_isWellCell(false), - m_activeIndexInMatrixModel(cvf::UNDEFINED_SIZE_T), - m_activeIndexInFractureModel(cvf::UNDEFINED_SIZE_T), m_cellIndex(cvf::UNDEFINED_SIZE_T), m_isInCoarseCell(false) { diff --git a/ApplicationCode/ReservoirDataModel/RigCell.h b/ApplicationCode/ReservoirDataModel/RigCell.h index 8e60ac1850..7e920a3bdf 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.h +++ b/ApplicationCode/ReservoirDataModel/RigCell.h @@ -37,24 +37,12 @@ public: caf::SizeTArray8& cornerIndices() { return m_cornerIndices;} const caf::SizeTArray8& cornerIndices() const { return m_cornerIndices;} - bool isActiveInMatrixModel() const { return m_activeIndexInMatrixModel != cvf::UNDEFINED_SIZE_T; } - size_t activeIndexInMatrixModel() const { return m_activeIndexInMatrixModel; } - void setActiveIndexInMatrixModel(size_t val) { m_activeIndexInMatrixModel = val; } - - bool isActiveInFractureModel() const { return m_activeIndexInFractureModel != cvf::UNDEFINED_SIZE_T; } - size_t activeIndexInFractureModel() const { return m_activeIndexInFractureModel; } - void setActiveIndexInFractureModel(size_t val) { m_activeIndexInFractureModel = val; } - bool isInvalid() const { return m_isInvalid; } void setInvalid( bool val ) { m_isInvalid = val; } - bool isWellCell() const { return m_isWellCell; } - void setAsWellCell(bool isWellCell) { m_isWellCell = isWellCell; } - size_t cellIndex() const { return m_cellIndex; } void setCellIndex(size_t val) { m_cellIndex = val; } - RigLocalGrid* subGrid() const { return m_subGrid; } void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; } @@ -89,11 +77,5 @@ private: bool m_cellFaceFaults[6]; - // Result case specific data bool m_isInvalid; - bool m_isWellCell; - - size_t m_activeIndexInMatrixModel; ///< This cell's running index of all the active calls (matrix) in the reservoir - size_t m_activeIndexInFractureModel; ///< This cell's running index of all the active calls (fracture) in the reservoir - }; diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp index e806998c92..77946bd15e 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp @@ -16,11 +16,10 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigGridBase.h" #include "RigMainGrid.h" #include "RigCell.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" #include "RigGridScalarDataAccess.h" #include "cvfAssert.h" @@ -29,9 +28,7 @@ RigGridBase::RigGridBase(RigMainGrid* mainGrid): m_gridPointDimensions(0,0,0), m_mainGrid(mainGrid), - m_indexToStartOfCells(0), - m_matrixModelActiveCellCount(cvf::UNDEFINED_SIZE_T), - m_fractureModelActiveCellCount(cvf::UNDEFINED_SIZE_T) + m_indexToStartOfCells(0) { if (mainGrid == NULL) { @@ -303,22 +300,6 @@ bool RigGridBase::isCellValid(size_t i, size_t j, size_t k) const return !c.isInvalid(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigGridBase::isCellActive(size_t i, size_t j, size_t k) const -{ - size_t idx = cellIndexFromIJK(i, j, k); - const RigCell& c = cell(idx); - if (!c.isActiveInMatrixModel() || c.isInvalid()) - { - return false; - } - else - { - return true; - } -} //-------------------------------------------------------------------------------------------------- /// TODO: Use structgrid::neighborIJKAtCellFace @@ -452,18 +433,18 @@ cvf::Vec3d RigGridBase::displayModelOffset() const } //-------------------------------------------------------------------------------------------------- -/// Returns the max size of the charactristic cell sizes +/// Returns the min size of the I and J charactristic cell sizes //-------------------------------------------------------------------------------------------------- -double RigGridBase::characteristicCellSize() +double RigGridBase::characteristicIJCellSize() { - double characteristicCellSize = 0; + double characteristicCellSize = HUGE_VAL; double cellSizeI, cellSizeJ, cellSizeK; this->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK); - if (cellSizeI > characteristicCellSize) characteristicCellSize = cellSizeI; - if (cellSizeJ > characteristicCellSize) characteristicCellSize = cellSizeJ; - if (cellSizeK > characteristicCellSize) characteristicCellSize = cellSizeK; + if (cellSizeI < characteristicCellSize) characteristicCellSize = cellSizeI; + if (cellSizeJ < characteristicCellSize) characteristicCellSize = cellSizeJ; + return characteristicCellSize; } @@ -471,51 +452,11 @@ double RigGridBase::characteristicCellSize() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigGridBase::matrixModelActiveCellCount() const +size_t RigGridBase::globalGridCellIndex(size_t localGridCellIndex) const { - return m_matrixModelActiveCellCount; + return m_indexToStartOfCells + localGridCellIndex; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigGridBase::fractureModelActiveCellCount() const -{ - return m_fractureModelActiveCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref RigGridBase::dataAccessObject(RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) const -{ - if (timeStepIndex != cvf::UNDEFINED_SIZE_T && - scalarSetIndex != cvf::UNDEFINED_SIZE_T) - { - cvf::ref dataAccess = RigGridScalarDataAccess::createDataAccessObject(this, porosityModel, timeStepIndex, scalarSetIndex); - return dataAccess; - } - - return NULL; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridBase::setFractureModelActiveCellCount(size_t activeFractureModelCellCount) -{ - m_fractureModelActiveCellCount = activeFractureModelCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridBase::setMatrixModelActiveCellCount(size_t activeMatrixModelCellCount) -{ - m_matrixModelActiveCellCount = activeMatrixModelCellCount; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.h b/ApplicationCode/ReservoirDataModel/RigGridBase.h index c9233e82d6..364de6ae10 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.h +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.h @@ -34,6 +34,7 @@ class RigMainGrid; class RigCell; class RigGridScalarDataAccess; +class RigActiveCellInfo; class RigGridBase : public cvf::StructGridInterface { @@ -48,11 +49,13 @@ public: RigCell& cell(size_t gridCellIndex); const RigCell& cell(size_t gridCellIndex) const; + size_t globalGridCellIndex(size_t localGridCellIndex) const; void setIndexToStartOfCells(size_t indexToStartOfCells) { m_indexToStartOfCells = indexToStartOfCells; } + void setGridIndex(size_t index) { m_gridIndex = index; } - size_t gridIndex() { return m_gridIndex; } + size_t gridIndex() const { return m_gridIndex; } - double characteristicCellSize(); + double characteristicIJCellSize(); std::string gridName() const; void setGridName(const std::string& gridName); @@ -60,12 +63,7 @@ public: void computeFaults(); bool isMainGrid() const; RigMainGrid* mainGrid() const { return m_mainGrid; } - - size_t matrixModelActiveCellCount() const; - void setMatrixModelActiveCellCount(size_t activeMatrixModelCellCount); - size_t fractureModelActiveCellCount() const ; - void setFractureModelActiveCellCount(size_t activeFractureModelCellCount); - + protected: friend class RigMainGrid;//::initAllSubGridsParentGridPointer(); void initSubGridParentPointer(); @@ -93,12 +91,9 @@ public: virtual size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const; virtual cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const; - virtual bool isCellActive( size_t i, size_t j, size_t k ) const; virtual bool isCellValid( size_t i, size_t j, size_t k ) const; virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const; - cvf::ref dataAccessObject(RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) const; - private: std::string m_gridName; cvf::Vec3st m_gridPointDimensions; @@ -106,9 +101,6 @@ private: size_t m_gridIndex; ///< The LGR index of this grid. Starts with 1. Main grid has index 0. RigMainGrid* m_mainGrid; - size_t m_matrixModelActiveCellCount; - size_t m_fractureModelActiveCellCount; - }; diff --git a/ApplicationCode/ReservoirDataModel/RigGridManager.cpp b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp new file mode 100644 index 0000000000..2c7fbbba91 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp @@ -0,0 +1,106 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigGridManager.h" +#include "RigCaseData.h" +#include "RigMainGrid.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::addCase(RigCaseData* eclipseCase) +{ + cvf::ref caseAndGrid = new CaseToGridMap(eclipseCase, eclipseCase->mainGrid()); + m_caseToGrid.push_back(caseAndGrid.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::removeCase(RigCaseData* eclipseCase) +{ + size_t indexToErase = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_caseToGrid.size(); i++) + { + if (m_caseToGrid[i]->m_eclipseCase == eclipseCase) + { + m_caseToGrid.eraseAt(i); + return; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigMainGrid* RigGridManager::findEqualGrid(RigMainGrid* candidateGrid) +{ + for (size_t i = 0; i < m_caseToGrid.size(); i++) + { + RigMainGrid* mainGrid = m_caseToGrid.at(i)->m_mainGrid; + if (RigGridManager::isEqual(mainGrid, candidateGrid)) + { + return mainGrid; + } + } + return NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGridManager::isEqual(RigMainGrid* gridA, RigMainGrid* gridB) +{ + if (gridA == NULL || gridB == NULL) return false; + + if (gridA == gridB) return true; + + if (gridA->gridCount() != gridB->gridCount()) return false; + + if (gridA->nodes().size() != gridB->nodes().size()) return false; + + for (size_t i = 0; i < gridA->nodes().size(); i++) + { + if (!gridA->nodes()[i].equals(gridB->nodes()[i])) + { + return false; + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridManager::clear() +{ + m_caseToGrid.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGridManager::CaseToGridMap::CaseToGridMap(RigCaseData* eclipseCase, RigMainGrid* mainGrid) : +m_eclipseCase(eclipseCase), + m_mainGrid(mainGrid) +{ +} diff --git a/ApplicationCode/ReservoirDataModel/RigGridManager.h b/ApplicationCode/ReservoirDataModel/RigGridManager.h new file mode 100644 index 0000000000..3d6dada127 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGridManager.h @@ -0,0 +1,57 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfCollection.h" + +#include + +class RigMainGrid; +class RigCaseData; + +class RigGridManager : public cvf::Object +{ +public: + void addCase(RigCaseData* eclipseCase); + + void removeCase(RigCaseData* eclipseCase); + + RigMainGrid* findEqualGrid(RigMainGrid* candidateGrid); + + void clear(); + +private: + + static bool isEqual(RigMainGrid* gridA, RigMainGrid* gridB); + + class CaseToGridMap : public cvf::Object + { + public: + CaseToGridMap(RigCaseData* eclipseCase, RigMainGrid* mainGrid); + + RigCaseData* m_eclipseCase; + RigMainGrid* m_mainGrid; + }; + + +private: + cvf::Collection m_caseToGrid; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp index bcdef620c9..68136b67d0 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.cpp @@ -21,38 +21,137 @@ #include "cvfLibCore.h" #include "cvfBase.h" +#include "cvfObject.h" #include "cvfAssert.h" #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" +#include "RigCaseCellResultsData.h" +#include "RigActiveCellInfo.h" +#include "RigGridBase.h" +#include "RigCaseData.h" +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigGridScalarDataAccess::RigGridScalarDataAccess(const RigGridBase* grid, bool useGlobalActiveIndex, std::vector* resultValues) : - m_grid(grid), - m_useGlobalActiveIndex(useGlobalActiveIndex), - m_resultValues(resultValues) +class RigGridAllCellsScalarDataAccess : public cvf::StructGridScalarDataAccess { +public: + RigGridAllCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues); + + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual void setCellScalar(size_t cellIndex, double value); + +private: + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGridAllCellsScalarDataAccess::RigGridAllCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues) +{ + CVF_ASSERT(reservoirResultValues != NULL); + CVF_ASSERT(grid != NULL); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RigGridScalarDataAccess::createDataAccessObject(const RigGridBase* grid, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex) +double RigGridAllCellsScalarDataAccess::cellScalar(size_t gridLocalCellIndex) const { - CVF_ASSERT(grid); - CVF_ASSERT(grid->mainGrid()); - CVF_ASSERT(grid->mainGrid()->results(porosityModel)); + if (m_reservoirResultValues->size() == 0 ) return HUGE_VAL; - if (!grid || !grid->mainGrid() || !grid->mainGrid()->results(porosityModel)) + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(globalGridCellIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(globalGridCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGridAllCellsScalarDataAccess::setCellScalar(size_t gridLocalCellIndex, double scalarValue) +{ + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + CVF_TIGHT_ASSERT(globalGridCellIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[globalGridCellIndex] = scalarValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RigGridMatrixActiveCellsScalarDataAccess : public cvf::StructGridScalarDataAccess +{ +public: + RigGridMatrixActiveCellsScalarDataAccess(const RigGridBase* grid, std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo) + : m_grid(grid), + m_reservoirResultValues(reservoirResultValues), + m_activeCellInfo(activeCellInfo) + { + CVF_ASSERT(reservoirResultValues != NULL); + CVF_ASSERT(grid != NULL); + } + + virtual double cellScalar(size_t gridLocalCellIndex) const + { + if (m_reservoirResultValues->size() == 0 ) return HUGE_VAL; + + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(globalGridCellIndex); + if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(resultValueIndex); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + { + size_t globalGridCellIndex = m_grid->globalGridCellIndex(gridLocalCellIndex); + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(globalGridCellIndex); + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + (*m_reservoirResultValues)[resultValueIndex] = scalarValue; + } + +private: + const RigActiveCellInfo* m_activeCellInfo; + const RigGridBase* m_grid; + std::vector* m_reservoirResultValues; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RigGridScalarDataAccessFactory::createPerGridDataAccessObject(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex) +{ + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); + + RigGridBase *grid = eclipseCase->grid(gridIndex); + + if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { return NULL; } - bool useGlobalActiveIndex = grid->mainGrid()->results(porosityModel)->isUsingGlobalActiveIndex(scalarSetIndex); - - std::vector< std::vector > & scalarSetResults = grid->mainGrid()->results(porosityModel)->cellScalarResults(scalarSetIndex); + std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(scalarSetIndex); if (timeStepIndex >= scalarSetResults.size()) { return NULL; @@ -60,72 +159,16 @@ cvf::ref RigGridScalarDataAccess::createDataAccessObjec std::vector* resultValues = &(scalarSetResults[timeStepIndex]); - cvf::ref object = new RigGridScalarDataAccess(grid, useGlobalActiveIndex, resultValues); - return object; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::cellScalar(size_t i, size_t j, size_t k) const -{ - size_t cellIndex = m_grid->cellIndexFromIJK(i, j, k); - - return cellScalar(cellIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::cellScalar(size_t cellIndex) const -{ - if (m_resultValues->size() == 0 ) return HUGE_VAL; - - size_t resultValueIndex = cellIndex; - - if (m_useGlobalActiveIndex) + bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(scalarSetIndex); + if (useGlobalActiveIndex) { - resultValueIndex = m_grid->cell(cellIndex).activeIndexInMatrixModel(); - if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + cvf::ref object = new RigGridMatrixActiveCellsScalarDataAccess(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + return object; + } + else + { + cvf::ref object = new RigGridAllCellsScalarDataAccess(grid, resultValues); + return object; } - - if (m_resultValues->size() <= resultValueIndex) return HUGE_VAL; - - return m_resultValues->at(resultValueIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigGridScalarDataAccess::gridPointScalar(size_t i, size_t j, size_t k) const -{ - CVF_ASSERT(false); - return 0.0; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigGridScalarDataAccess::cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const -{ - CVF_ASSERT(false); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigGridScalarDataAccess::pointScalar(const cvf::Vec3d& p, double* scalarValue) const -{ - CVF_ASSERT(false); - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const cvf::Vec3d* RigGridScalarDataAccess::cellVector(size_t i, size_t j, size_t k) const -{ - CVF_ASSERT(false); - return new cvf::Vec3d(); } diff --git a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h index ad4f1fb46d..4757bf5d39 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h +++ b/ApplicationCode/ReservoirDataModel/RigGridScalarDataAccess.h @@ -20,32 +20,21 @@ #pragma once #include "cvfStructGridScalarDataAccess.h" -#include "RigGridBase.h" #include "RifReaderInterface.h" -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class RigGridScalarDataAccess : public cvf::StructGridScalarDataAccess +class RigActiveCellInfo; +class RigGridBase; + +class RigGridScalarDataAccessFactory { -private: - RigGridScalarDataAccess(const RigGridBase* grid, bool useGlobalActiveIndex, std::vector* resultValues); - public: - static cvf::ref createDataAccessObject(const RigGridBase* grid, RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarSetIndex); - - virtual double cellScalar(size_t i, size_t j, size_t k) const; - virtual double cellScalar(size_t cellIndex) const; - virtual void cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const; - virtual double gridPointScalar(size_t i, size_t j, size_t k) const; - virtual bool pointScalar(const cvf::Vec3d& p, double* scalarValue) const; - - virtual const cvf::Vec3d* cellVector(size_t i, size_t j, size_t k) const; - -private: - cvf::cref m_grid; - bool m_useGlobalActiveIndex; - std::vector* m_resultValues; + static cvf::ref + createPerGridDataAccessObject(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t scalarSetIndex); }; + diff --git a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp index c67e81bb66..9b4ebbe248 100644 --- a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp @@ -16,7 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" #include "RigLocalGrid.h" diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index d73b78f7e5..a5194dc79b 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -16,28 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - #include "RigMainGrid.h" -#include "RigReservoirCellResults.h" #include "cvfAssert.h" RigMainGrid::RigMainGrid(void) - : RigGridBase(this), - m_activeCellPositionMin(cvf::Vec3st::UNDEFINED), - m_activeCellPositionMax(cvf::Vec3st::UNDEFINED), - m_validCellPositionMin(cvf::Vec3st::UNDEFINED), - m_validCellPositionMax(cvf::Vec3st::UNDEFINED), - m_globalMatrixModelActiveCellCount(cvf::UNDEFINED_SIZE_T), - m_globalFractureModelActiveCellCount(cvf::UNDEFINED_SIZE_T) + : RigGridBase(this) { - m_matrixModelResults = new RigReservoirCellResults(this); - m_fractureModelResults = new RigReservoirCellResults(this); - - m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO); + m_displayModelOffset = cvf::Vec3d::ZERO; + m_gridIndex = 0; -} +} RigMainGrid::~RigMainGrid(void) @@ -80,156 +69,22 @@ void RigMainGrid::initAllSubCellsMainGridCellIndex() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigMainGrid::globalMatrixModelActiveCellCount() const -{ - return m_globalMatrixModelActiveCellCount; - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RigMainGrid::globalFractureModelActiveCellCount() const -{ - return m_globalFractureModelActiveCellCount; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::matrixModelActiveCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const -{ - min = m_activeCellPositionMin; - max = m_activeCellPositionMax; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RigMainGrid::matrixModelActiveCellsBoundingBox() const -{ - return m_activeCellsBoundingBox; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const -{ - min = m_validCellPositionMin; - max = m_validCellPositionMax; -} - - - -//-------------------------------------------------------------------------------------------------- -/// Helper class used to find min/max range for valid and active cells -//-------------------------------------------------------------------------------------------------- -class CellRangeBB -{ -public: - CellRangeBB() - : m_min(cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T), - m_max(cvf::Vec3st::ZERO) - { - - } - - void add(size_t i, size_t j, size_t k) - { - if (i < m_min.x()) m_min.x() = i; - if (j < m_min.y()) m_min.y() = j; - if (k < m_min.z()) m_min.z() = k; - - if (i > m_max.x()) m_max.x() = i; - if (j > m_max.y()) m_max.y() = j; - if (k > m_max.z()) m_max.z() = k; - } - -public: - cvf::Vec3st m_min; - cvf::Vec3st m_max; -}; - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::computeActiveAndValidCellRanges() -{ - CellRangeBB validBB; - CellRangeBB activeBB; - - size_t idx; - for (idx = 0; idx < cellCount(); idx++) - { - const RigCell& c = cell(idx); - - size_t i, j, k; - ijkFromCellIndex(idx, &i, &j, &k); - - if (!c.isInvalid()) - { - validBB.add(i, j, k); - } - - if (c.isActiveInMatrixModel()) - { - activeBB.add(i, j, k); - } - } - - m_validCellPositionMin = validBB.m_min; - m_validCellPositionMax = validBB.m_max; - - m_activeCellPositionMin = activeBB.m_min; - m_activeCellPositionMax = activeBB.m_max; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RigMainGrid::displayModelOffset() const { - return m_activeCellsBoundingBox.min(); + return m_displayModelOffset; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigMainGrid::computeBoundingBox() +void RigMainGrid::setDisplayModelOffset(cvf::Vec3d offset) { - m_activeCellsBoundingBox.reset(); - - if (m_nodes.size() == 0) - { - m_activeCellsBoundingBox.add(cvf::Vec3d::ZERO); - } - else - { - size_t i; - for (i = 0; i < cellCount(); i++) - { - const RigCell& c = cell(i); - if (c.isActiveInMatrixModel()) - { - const caf::SizeTArray8& indices = c.cornerIndices(); - - size_t idx; - for (idx = 0; idx < 8; idx++) - { - m_activeCellsBoundingBox.add(m_nodes[indices[idx]]); - } - } - } - } + m_displayModelOffset = offset; } - //-------------------------------------------------------------------------------------------------- /// Initialize pointers from grid to parent grid /// Compute cell ranges for active and valid cells @@ -239,83 +94,6 @@ void RigMainGrid::computeCachedData() { initAllSubGridsParentGridPointer(); initAllSubCellsMainGridCellIndex(); - computeActiveAndValidCellRanges(); - computeBoundingBox(); -} - -//-------------------------------------------------------------------------------------------------- -/// -/// -/// -//-------------------------------------------------------------------------------------------------- -void RigMainGrid::calculateMatrixModelActiveCellInfo(std::vector &gridNumber, - std::vector &cellI, - std::vector &cellJ, - std::vector &cellK, - std::vector &parentGridNumber, - std::vector &hostCellI, - std::vector &hostCellJ, - std::vector &hostCellK) -{ - size_t numMatrixModelActiveCells = this->globalMatrixModelActiveCellCount(); - - gridNumber.clear(); - cellI.clear(); - cellJ.clear(); - cellK.clear(); - parentGridNumber.clear(); - hostCellI.clear(); - hostCellJ.clear(); - hostCellK.clear(); - - gridNumber.reserve(numMatrixModelActiveCells); - cellI.reserve(numMatrixModelActiveCells); - cellJ.reserve(numMatrixModelActiveCells); - cellK.reserve(numMatrixModelActiveCells); - parentGridNumber.reserve(numMatrixModelActiveCells); - hostCellI.reserve(numMatrixModelActiveCells); - hostCellJ.reserve(numMatrixModelActiveCells); - hostCellK.reserve(numMatrixModelActiveCells); - - for (size_t cIdx = 0; cIdx < m_cells.size(); ++cIdx) - { - if (m_cells[cIdx].isActiveInMatrixModel()) - { - RigGridBase* grid = m_cells[cIdx].hostGrid(); - CVF_ASSERT(grid != NULL); - size_t cellIndex = m_cells[cIdx].cellIndex(); - - size_t i, j, k; - grid->ijkFromCellIndex(cellIndex, &i, &j, &k); - - size_t pi, pj, pk; - RigGridBase* parentGrid = NULL; - - if (grid->isMainGrid()) - { - pi = i; - pj = j; - pk = k; - parentGrid = grid; - } - else - { - size_t parentCellIdx = m_cells[cIdx].parentCellIndex(); - parentGrid = (static_cast(grid))->parentGrid(); - CVF_ASSERT(parentGrid != NULL); - parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk); - } - - gridNumber.push_back(static_cast(grid->gridIndex())); - cellI.push_back(static_cast(i)); - cellJ.push_back(static_cast(j)); - cellK.push_back(static_cast(k)); - parentGridNumber.push_back(static_cast(parentGrid->gridIndex())); - hostCellI.push_back(static_cast(pi)); - hostCellJ.push_back(static_cast(pj)); - hostCellK.push_back(static_cast(pk)); - } - } } //-------------------------------------------------------------------------------------------------- @@ -338,29 +116,3 @@ const RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) const return m_localGrids[localGridIndex-1].p(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoirCellResults* RigMainGrid::results(RifReaderInterface::PorosityModelResultType porosityModel) -{ - if (porosityModel == RifReaderInterface::MATRIX_RESULTS) - { - return m_matrixModelResults.p(); - } - - return m_fractureModelResults.p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const RigReservoirCellResults* RigMainGrid::results(RifReaderInterface::PorosityModelResultType porosityModel) const -{ - if (porosityModel == RifReaderInterface::MATRIX_RESULTS) - { - return m_matrixModelResults.p(); - } - - return m_fractureModelResults.p(); -} - diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.h b/ApplicationCode/ReservoirDataModel/RigMainGrid.h index aa9d19919f..32ef9258bf 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.h @@ -27,8 +27,6 @@ #include -class RigReservoirCellResults; - class RigMainGrid : public RigGridBase { public: @@ -42,59 +40,29 @@ public: std::vector& cells() {return m_cells;} const std::vector& cells() const {return m_cells;} - RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel); - const RigReservoirCellResults* results(RifReaderInterface::PorosityModelResultType porosityModel) const; - - size_t globalMatrixModelActiveCellCount() const; - size_t globalFractureModelActiveCellCount() const; - void setGlobalMatrixModelActiveCellCount (size_t globalMatrixModelActiveCellCount) { m_globalMatrixModelActiveCellCount = globalMatrixModelActiveCellCount; } - void setGlobalFractureModelActiveCellCount(size_t globalFractureModelActiveCellCount) { m_globalFractureModelActiveCellCount = globalFractureModelActiveCellCount;} - - void matrixModelActiveCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; - void validCellsBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const; - void addLocalGrid(RigLocalGrid* localGrid); size_t gridCount() const { return m_localGrids.size() + 1; } RigGridBase* gridByIndex(size_t localGridIndex); const RigGridBase* gridByIndex(size_t localGridIndex) const; - void calculateMatrixModelActiveCellInfo(std::vector& gridNumber, - std::vector& i, - std::vector& j, - std::vector& k, - std::vector& parentGridNumber, - std::vector& hostCellI, - std::vector& hostCellJ, - std::vector& hostCellK); void computeCachedData(); cvf::BoundingBox matrixModelActiveCellsBoundingBox() const; // Overrides virtual cvf::Vec3d displayModelOffset() const; + void setDisplayModelOffset(cvf::Vec3d offset); private: void initAllSubGridsParentGridPointer(); void initAllSubCellsMainGridCellIndex(); void computeActiveAndValidCellRanges(); - void computeBoundingBox(); private: std::vector m_nodes; ///< Global vertex table std::vector m_cells; ///< Global array of all cells in the reservoir (including the ones in LGR's) cvf::Collection m_localGrids; ///< List of all the LGR's in this reservoir - cvf::ref m_matrixModelResults; - cvf::ref m_fractureModelResults; - - size_t m_globalMatrixModelActiveCellCount; - size_t m_globalFractureModelActiveCellCount; - - cvf::Vec3st m_activeCellPositionMin; - cvf::Vec3st m_activeCellPositionMax; - cvf::Vec3st m_validCellPositionMin; - cvf::Vec3st m_validCellPositionMax; - - cvf::BoundingBox m_activeCellsBoundingBox; + cvf::Vec3d m_displayModelOffset; }; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoir.cpp b/ApplicationCode/ReservoirDataModel/RigReservoir.cpp deleted file mode 100644 index cfaa91f668..0000000000 --- a/ApplicationCode/ReservoirDataModel/RigReservoir.cpp +++ /dev/null @@ -1,224 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RIStdInclude.h" -#include "RigReservoir.h" -#include "RigMainGrid.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoir::RigReservoir() -{ - m_mainGrid = new RigMainGrid(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigReservoir::~RigReservoir() -{ - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::computeFaults() -{ - std::vector grids; - allGrids(&grids); - - size_t i; - for (i = 0; i < grids.size(); i++) - { - grids[i]->computeFaults(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::allGrids(std::vector* grids) -{ - CVF_ASSERT(grids); - - size_t i; - for (i = 0; i < m_mainGrid->gridCount(); i++) - { - grids->push_back(m_mainGrid->gridByIndex(i)); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::allGrids(std::vector* grids) const -{ - CVF_ASSERT(grids); - size_t i; - for (i = 0; i < m_mainGrid->gridCount(); i++) - { - grids->push_back(m_mainGrid->gridByIndex(i)); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Get grid by index. The main grid has index 0, so the first lgr has index 1 -//-------------------------------------------------------------------------------------------------- -const RigGridBase* RigReservoir::grid(size_t index) const -{ - return m_mainGrid->gridByIndex(index); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::computeWellCellsPrGrid() -{ - // If we have computed this already, return - if (m_wellCellsInGrid.size()) return; - - std::vector grids; - this->allGrids(&grids); - size_t gIdx; - - // Allocate and initialize the arrays - - m_wellCellsInGrid.resize(grids.size()); - - for (gIdx = 0; gIdx < grids.size(); ++gIdx) - { - if (m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount()) - { - m_wellCellsInGrid[gIdx] = new cvf::UByteArray; - m_wellCellsInGrid[gIdx]->resize(grids[gIdx]->cellCount()); - - } - m_wellCellsInGrid[gIdx]->setAll(false); - } - - // Fill arrays with data - size_t wIdx; - for (wIdx = 0; wIdx < m_wellResults.size(); ++wIdx) - { - size_t tIdx; - for (tIdx = 0; tIdx < m_wellResults[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx) - { - RigWellResultFrame& wellCells = m_wellResults[wIdx]->m_wellCellsTimeSteps[tIdx]; - - size_t gridIndex = wellCells.m_wellHead.m_gridIndex; - size_t gridCellIndex = wellCells.m_wellHead.m_gridCellIndex; - - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); - grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true); - m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); - - size_t sIdx; - for (sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx) - { - RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx]; - size_t cdIdx; - for (cdIdx = 0; cdIdx < wellSegment.m_wellCells.size(); ++cdIdx) - { - gridIndex = wellSegment.m_wellCells[cdIdx].m_gridIndex; - gridCellIndex = wellSegment.m_wellCells[cdIdx].m_gridCellIndex; - - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size()); - - grids[gridIndex]->cell(gridCellIndex).setAsWellCell(true); - m_wellCellsInGrid[gridIndex]->set(gridCellIndex, true); - } - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RigReservoir::setWellResults(const cvf::Collection& data) -{ - m_wellResults = data; - m_wellCellsInGrid.clear(); - computeWellCellsPrGrid(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::UByteArray* RigReservoir::wellCellsInGrid(size_t gridIndex) -{ - computeWellCellsPrGrid(); - CVF_ASSERT(gridIndex < m_wellCellsInGrid.size()); - - return m_wellCellsInGrid[gridIndex].p(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RigCell& RigReservoir::cellFromWellResultCell(const RigWellResultCell& wellResultCell) -{ - size_t gridIndex = wellResultCell.m_gridIndex; - size_t gridCellIndex = wellResultCell.m_gridCellIndex; - - std::vector grids; - allGrids(&grids); - - return grids[gridIndex]->cell(gridCellIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigReservoir::findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace,const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const -{ - size_t gridIndex = sourceWellCellResult.m_gridIndex; - size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex; - - size_t otherGridIndex = otherWellCellResult.m_gridIndex; - size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex; - - if (gridIndex != otherGridIndex) return false; - - std::vector grids; - allGrids(&grids); - - const RigGridBase* grid = grids[gridIndex]; - size_t i, j, k; - grid->ijkFromCellIndex(gridCellIndex, &i, &j, &k); - - size_t faceIdx; - for (faceIdx = 0; faceIdx < 6; faceIdx++) - { - cvf::StructGridInterface::FaceType sourceFace = static_cast(faceIdx); - - size_t ni, nj, nk; - grid->neighborIJKAtCellFace(i, j, k, sourceFace, &ni, &nj, &nk); - size_t neighborCellIndex = grid->cellIndexFromIJK(ni, nj, nk); - - if (neighborCellIndex == otherGridCellIndex) - { - sharedSourceFace = sourceFace; - return true; - } - } - - return false; -} diff --git a/ApplicationCode/ReservoirDataModel/RigReservoir.h b/ApplicationCode/ReservoirDataModel/RigReservoir.h deleted file mode 100644 index d7518d1245..0000000000 --- a/ApplicationCode/ReservoirDataModel/RigReservoir.h +++ /dev/null @@ -1,61 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include "RigCell.h" -#include "cvfVector3.h" -#include "cvfAssert.h" -#include "cvfObject.h" -#include "RigMainGrid.h" -#include "RigWellResults.h" - - -class RigReservoir: public cvf::Object -{ -public: - RigReservoir(); - ~RigReservoir(); - - RigMainGrid* mainGrid() { return m_mainGrid.p(); } - const RigMainGrid* mainGrid() const { return m_mainGrid.p(); } - - void allGrids(std::vector* grids); - void allGrids(std::vector* grids) const; - const RigGridBase* grid(size_t index) const; - - void setWellResults(const cvf::Collection& data); - const cvf::Collection& wellResults() { return m_wellResults; } - - - cvf::UByteArray* wellCellsInGrid(size_t gridIndex); - void computeFaults(); - - RigCell& cellFromWellResultCell(const RigWellResultCell& wellResultCell); - bool findSharedSourceFace(cvf::StructGridInterface::FaceType& sharedSourceFace, const RigWellResultCell& sourceWellCellResult, const RigWellResultCell& otherWellCellResult) const; - - -private: - void computeWellCellsPrGrid(); - - cvf::ref m_mainGrid; - - cvf::Collection m_wellResults; - cvf::Collection m_wellCellsInGrid; -}; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 8a2679c2d4..74671abf98 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -16,10 +16,9 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - #include "RigReservoirBuilderMock.h" -#include "RigReservoir.h" +#include "RigCaseData.h" +#include "RigActiveCellInfo.h" /* rand example: guess the number */ @@ -154,6 +153,8 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun riCell.setParentCellIndex(0); + //TODO: Rewrite active cell info in mock models + /* if (!(i % 5)) { riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); @@ -162,6 +163,7 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun { riCell.setActiveIndexInMatrixModel(activeCellIndex++); } + */ cells.push_back(riCell); } @@ -170,15 +172,15 @@ void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCoun //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) +void RigReservoirBuilderMock::populateReservoir(RigCaseData* eclipseCase) { - std::vector& mainGridNodes = reservoir->mainGrid()->nodes(); + std::vector& mainGridNodes = eclipseCase->mainGrid()->nodes(); appendNodes(m_minWorldCoordinate, m_maxWorldCoordinate, cellDimension(), mainGridNodes); size_t mainGridNodeCount = mainGridNodes.size(); size_t mainGridCellCount = mainGridNodeCount / 8; // Must create cells in main grid here, as this information is used when creating LGRs - appendCells(0, mainGridCellCount, reservoir->mainGrid(), reservoir->mainGrid()->cells()); + appendCells(0, mainGridCellCount, eclipseCase->mainGrid(), eclipseCase->mainGrid()->cells()); size_t totalCellCount = mainGridCellCount; @@ -206,9 +208,9 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) } // Create local grid and set local grid dimensions - RigLocalGrid* localGrid = new RigLocalGrid(reservoir->mainGrid()); - reservoir->mainGrid()->addLocalGrid(localGrid); - localGrid->setParentGrid(reservoir->mainGrid()); + RigLocalGrid* localGrid = new RigLocalGrid(eclipseCase->mainGrid()); + eclipseCase->mainGrid()->addLocalGrid(localGrid); + localGrid->setParentGrid(eclipseCase->mainGrid()); localGrid->setIndexToStartOfCells(mainGridNodes.size() / 8); cvf::Vec3st gridPointDimensions( @@ -221,13 +223,13 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) size_t cellIdx; for (cellIdx = 0; cellIdx < mainGridIndicesWithSubGrid.size(); cellIdx++) { - RigCell& cell = reservoir->mainGrid()->cells()[mainGridIndicesWithSubGrid[cellIdx]]; + RigCell& cell = eclipseCase->mainGrid()->cells()[mainGridIndicesWithSubGrid[cellIdx]]; caf::SizeTArray8& indices = cell.cornerIndices(); int nodeIdx; for (nodeIdx = 0; nodeIdx < 8; nodeIdx++) { - bb.add(reservoir->mainGrid()->nodes()[indices[nodeIdx]]); + bb.add(eclipseCase->mainGrid()->nodes()[indices[nodeIdx]]); } // Deactivate cell in main grid cell.setSubGrid(localGrid); @@ -237,13 +239,21 @@ void RigReservoirBuilderMock::populateReservoir(RigReservoir* reservoir) appendNodes(bb.min(), bb.max(), lgrCellDimensions, mainGridNodes); size_t subGridCellCount = (mainGridNodes.size() / 8) - totalCellCount; - appendCells(totalCellCount*8, subGridCellCount, localGrid, reservoir->mainGrid()->cells()); + appendCells(totalCellCount*8, subGridCellCount, localGrid, eclipseCase->mainGrid()->cells()); totalCellCount += subGridCellCount; } - reservoir->mainGrid()->setGridPointDimensions(m_gridPointDimensions); + eclipseCase->mainGrid()->setGridPointDimensions(m_gridPointDimensions); - addWellData(reservoir, reservoir->mainGrid()); + addWellData(eclipseCase, eclipseCase->mainGrid()); + + // Set all cells active + RigActiveCellInfo* activeCellInfo = eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + activeCellInfo->setGlobalCellCount(eclipseCase->mainGrid()->cells().size()); + for (size_t i = 0; i < eclipseCase->mainGrid()->cells().size(); i++) + { + activeCellInfo->setCellResultIndex(i, i); + } } @@ -268,7 +278,7 @@ void RigReservoirBuilderMock::setWorldCoordinates(cvf::Vec3d minWorldCoordinate, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QString& propertyName, std::vector* values) +bool RigReservoirBuilderMock::inputProperty(RigCaseData* eclipseCase, const QString& propertyName, std::vector* values) { size_t k; @@ -278,7 +288,7 @@ bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QStri /* generate secret number: */ int iSecret = rand() % 20 + 1; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { values->push_back(k * iSecret); } @@ -289,23 +299,14 @@ bool RigReservoirBuilderMock::inputProperty(RigReservoir* reservoir, const QStri //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::staticResult(RigReservoir* reservoir, const QString& result, std::vector* values) +bool RigReservoirBuilderMock::staticResult(RigCaseData* eclipseCase, const QString& result, std::vector* values) { size_t k; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { - RigCell& cell = reservoir->mainGrid()->cells()[k]; - if (cell.isActiveInMatrixModel()) { - if (cell.hostGrid() == reservoir->mainGrid()) - { - values->push_back((k * 2) % reservoir->mainGrid()->cells().size()); - } - else - { - values->push_back(500); - } + values->push_back((k * 2) % eclipseCase->mainGrid()->cells().size()); } } @@ -315,7 +316,7 @@ bool RigReservoirBuilderMock::staticResult(RigReservoir* reservoir, const QStrin //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QString& result, size_t stepIndex, std::vector* values) +bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QString& result, size_t stepIndex, std::vector* values) { int resultIndex = 1; @@ -330,20 +331,12 @@ bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QStri double offsetValue = 100 * resultIndex; size_t k; - for (k = 0; k < reservoir->mainGrid()->cells().size(); k++) + for (k = 0; k < eclipseCase->mainGrid()->cells().size(); k++) { - RigCell& cell = reservoir->mainGrid()->cells()[k]; - if (cell.isActiveInMatrixModel()) + RigCell& cell = eclipseCase->mainGrid()->cells()[k]; { - if (cell.hostGrid() == reservoir->mainGrid()) - { - double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % reservoir->mainGrid()->cells().size() ); - values->push_back(val); - } - else - { - values->push_back(500); - } + double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); + values->push_back(val); } } @@ -359,19 +352,19 @@ bool RigReservoirBuilderMock::dynamicResult(RigReservoir* reservoir, const QStri //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigReservoirBuilderMock::addWellData(RigReservoir* reservoir, RigGridBase* grid) +void RigReservoirBuilderMock::addWellData(RigCaseData* eclipseCase, RigGridBase* grid) { - CVF_ASSERT(reservoir); + CVF_ASSERT(eclipseCase); CVF_ASSERT(grid); cvf::Vec3st dim = grid->gridPointDimensions(); - cvf::Collection wells; + cvf::Collection wells; int wellIdx; for (wellIdx = 0; wellIdx < 1; wellIdx++) { - cvf::ref wellCellsTimeHistory = new RigWellResults; + cvf::ref wellCellsTimeHistory = new RigSingleWellResultsData; wellCellsTimeHistory->m_wellName = QString("Well %1").arg(wellIdx); wellCellsTimeHistory->m_wellCellsTimeSteps.resize(m_timeStepCount); @@ -469,6 +462,6 @@ void RigReservoirBuilderMock::addWellData(RigReservoir* reservoir, RigGridBase* wells.push_back(wellCellsTimeHistory.p()); } - reservoir->setWellResults(wells); + eclipseCase->setWellResults(wells); } diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 2d802b03d5..d6c0f0fec4 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -23,7 +23,7 @@ #include "cvfArray.h" #include "cvfVector3.h" #include "RigCell.h" -#include "RigReservoir.h" +#include "RigCaseData.h" class LocalGridRefinement { @@ -55,14 +55,14 @@ public: void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); - void populateReservoir(RigReservoir* reservoir); + void populateReservoir(RigCaseData* eclipseCase); - bool inputProperty(RigReservoir* reservoir, const QString& propertyName, std::vector* values ); - bool staticResult(RigReservoir* reservoir, const QString& result, std::vector* values ); - bool dynamicResult(RigReservoir* reservoir, const QString& result, size_t stepIndex, std::vector* values ); + bool inputProperty(RigCaseData* eclipseCase, const QString& propertyName, std::vector* values ); + bool staticResult(RigCaseData* eclipseCase, const QString& result, std::vector* values ); + bool dynamicResult(RigCaseData* eclipseCase, const QString& result, size_t stepIndex, std::vector* values ); private: - void addWellData(RigReservoir* reservoir, RigGridBase* grid); + void addWellData(RigCaseData* eclipseCase, RigGridBase* grid); static void appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells); static void appendNodes(const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes); diff --git a/ApplicationCode/ReservoirDataModel/RigWellResults.cpp b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp similarity index 94% rename from ApplicationCode/ReservoirDataModel/RigWellResults.cpp rename to ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp index e577d2dc6d..a36cf5752f 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellResults.cpp +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp @@ -16,16 +16,15 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" - -#include "RigWellResults.h" +#include "RigSingleWellResultsData.h" #include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigWellResultFrame& RigWellResults::wellResultFrame(size_t resultTimeStepIndex) const +const RigWellResultFrame& RigSingleWellResultsData::wellResultFrame(size_t resultTimeStepIndex) const { CVF_ASSERT(resultTimeStepIndex < m_resultTimeStepIndexToWellTimeStepIndex.size()); @@ -38,7 +37,7 @@ const RigWellResultFrame& RigWellResults::wellResultFrame(size_t resultTimeStepI //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const QList& resultTimes) +void RigSingleWellResultsData::computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector& resultTimes) { m_resultTimeStepIndexToWellTimeStepIndex.clear(); if (m_wellCellsTimeSteps.size() == 0) return; @@ -55,7 +54,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const } qDebug() << "Result TimeStamps"; - for (int i = 0; i < resultTimes.size(); i++) + for (size_t i = 0; i < resultTimes.size(); i++) { qDebug() << resultTimes[i].toString(); } @@ -66,7 +65,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const size_t wellIdx = 0; size_t activeWellIdx = cvf::UNDEFINED_SIZE_T; - while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < resultTimes.size()) + while (wellIdx <= m_wellCellsTimeSteps.size() && resultIdx < static_cast(resultTimes.size())) { if (wellIdx < m_wellCellsTimeSteps.size() && m_wellCellsTimeSteps[wellIdx].m_timestamp <= resultTimes[resultIdx]) { @@ -84,7 +83,7 @@ void RigWellResults::computeMappingFromResultTimeIndicesToWellTimeIndices(const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigWellResults::hasWellResult(size_t resultTimeStepIndex) const +bool RigSingleWellResultsData::hasWellResult(size_t resultTimeStepIndex) const { size_t wellTimeStepIndex = m_resultTimeStepIndexToWellTimeStepIndex[resultTimeStepIndex]; @@ -94,7 +93,7 @@ bool RigWellResults::hasWellResult(size_t resultTimeStepIndex) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigWellResults::firstResultTimeStep() const +size_t RigSingleWellResultsData::firstResultTimeStep() const { size_t i = 0; for(i = 0; i < m_resultTimeStepIndexToWellTimeStepIndex.size(); ++i) @@ -109,7 +108,7 @@ size_t RigWellResults::firstResultTimeStep() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigWellResults::computeStaticWellCellPath() +void RigSingleWellResultsData::computeStaticWellCellPath() { if (m_wellCellsTimeSteps.size() == 0) return; diff --git a/ApplicationCode/ReservoirDataModel/RigWellResults.h b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h similarity index 95% rename from ApplicationCode/ReservoirDataModel/RigWellResults.h rename to ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h index 9c247c4cf9..7e27f23073 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellResults.h +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.h @@ -18,8 +18,13 @@ #pragma once +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" + #include "RimDefines.h" #include +#include struct RigWellResultCell { @@ -94,7 +99,7 @@ public: //================================================================================================== /// //================================================================================================== -class RigWellResults : public cvf::Object +class RigSingleWellResultsData : public cvf::Object { public: bool hasWellResult(size_t resultTimeStepIndex) const; @@ -104,7 +109,7 @@ public: void computeStaticWellCellPath(); - void computeMappingFromResultTimeIndicesToWellTimeIndices(const QList& resultTimes); + void computeMappingFromResultTimeIndicesToWellTimeIndices(const std::vector& resultTimes); public: QString m_wellName; diff --git a/ApplicationCode/Resources/AppLogo48x48.png b/ApplicationCode/Resources/AppLogo48x48.png index ec13d014fc..8015d06ea7 100644 Binary files a/ApplicationCode/Resources/AppLogo48x48.png and b/ApplicationCode/Resources/AppLogo48x48.png differ diff --git a/ApplicationCode/Resources/Cases16x16.png b/ApplicationCode/Resources/Cases16x16.png new file mode 100644 index 0000000000..843e4d95a5 Binary files /dev/null and b/ApplicationCode/Resources/Cases16x16.png differ diff --git a/ApplicationCode/Resources/CreateGridCaseGroup16x16.png b/ApplicationCode/Resources/CreateGridCaseGroup16x16.png new file mode 100644 index 0000000000..65bb871267 Binary files /dev/null and b/ApplicationCode/Resources/CreateGridCaseGroup16x16.png differ diff --git a/ApplicationCode/Resources/GridCaseGroup16x16.png b/ApplicationCode/Resources/GridCaseGroup16x16.png new file mode 100644 index 0000000000..ed3a90af25 Binary files /dev/null and b/ApplicationCode/Resources/GridCaseGroup16x16.png differ diff --git a/ApplicationCode/Resources/Histogram16x16.png b/ApplicationCode/Resources/Histogram16x16.png new file mode 100644 index 0000000000..0a500bb997 Binary files /dev/null and b/ApplicationCode/Resources/Histogram16x16.png differ diff --git a/ApplicationCode/Resources/Histograms16x16.png b/ApplicationCode/Resources/Histograms16x16.png new file mode 100644 index 0000000000..08b0aa9f81 Binary files /dev/null and b/ApplicationCode/Resources/Histograms16x16.png differ diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 2028c1cff5..4bb322cec7 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -23,7 +23,13 @@ octave.png Folder.png EclipseInput48x48.png - + Cases16x16.png + CreateGridCaseGroup16x16.png + GridCaseGroup16x16.png + Histogram16x16.png + Histograms16x16.png + ZoomAll16x16.png + fs_CellFace.glsl vs_CellFace.glsl diff --git a/ApplicationCode/Resources/ZoomAll16x16.png b/ApplicationCode/Resources/ZoomAll16x16.png new file mode 100644 index 0000000000..9970c772ee Binary files /dev/null and b/ApplicationCode/Resources/ZoomAll16x16.png differ diff --git a/ApplicationCode/Resources/new16x16.png b/ApplicationCode/Resources/new16x16.png new file mode 100644 index 0000000000..7acec898d2 Binary files /dev/null and b/ApplicationCode/Resources/new16x16.png differ diff --git a/ApplicationCode/RIMain.cpp b/ApplicationCode/RiaMain.cpp similarity index 88% rename from ApplicationCode/RIMain.cpp rename to ApplicationCode/RiaMain.cpp index 1c877ae238..5804647de9 100644 --- a/ApplicationCode/RIMain.cpp +++ b/ApplicationCode/RiaMain.cpp @@ -16,18 +16,18 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiaStdInclude.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" int main(int argc, char *argv[]) { - RIApplication app(argc, argv); + RiaApplication app(argc, argv); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - RIMainWindow window; + RiuMainWindow window; QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)"; window.setWindowTitle("ResInsight " + platform); window.resize(1000, 800); diff --git a/ApplicationCode/RIStdInclude.cpp b/ApplicationCode/RiaStdInclude.cpp similarity index 96% rename from ApplicationCode/RIStdInclude.cpp rename to ApplicationCode/RiaStdInclude.cpp index e14a6d73e2..2c78f30884 100644 --- a/ApplicationCode/RIStdInclude.cpp +++ b/ApplicationCode/RiaStdInclude.cpp @@ -16,5 +16,5 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" diff --git a/ApplicationCode/RIStdInclude.h b/ApplicationCode/RiaStdInclude.h similarity index 100% rename from ApplicationCode/RIStdInclude.h rename to ApplicationCode/RiaStdInclude.h diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index e5de2c2e25..ca25c15ea8 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -1,4 +1,3 @@ -///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011-2012 Statoil ASA, Ceetron AS // @@ -16,7 +15,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" #include #include @@ -24,13 +23,13 @@ #include #include "RiaSocketServer.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RimReservoir.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RimCase.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" #include "RimInputProperty.h" -#include "RimInputReservoir.h" +#include "RimInputCase.h" #include "RimUiTreeModelPdm.h" //-------------------------------------------------------------------------------------------------- @@ -48,7 +47,7 @@ RiaSocketServer::RiaSocketServer(QObject* parent) m_invalidActiveCellCountDetected(false), m_readState(ReadingCommand) { - m_errorMessageDialog = new QErrorMessage(RIMainWindow::instance()); + m_errorMessageDialog = new QErrorMessage(RiuMainWindow::instance()); // TCP server setup @@ -152,18 +151,18 @@ void RiaSocketServer::handleClientConnection(QTcpSocket* clientToHandle) //-------------------------------------------------------------------------------------------------- /// Find the requested reservoir: Current, by index or by name //-------------------------------------------------------------------------------------------------- -RimReservoir* RiaSocketServer::findReservoir(const QString& caseName) +RimCase* RiaSocketServer::findReservoir(const QString& caseName) { if (caseName.isEmpty()) { - if (RIApplication::instance()->activeReservoirView()) + if (RiaApplication::instance()->activeReservoirView()) { - return RIApplication::instance()->activeReservoirView()->eclipseCase(); + return RiaApplication::instance()->activeReservoirView()->eclipseCase(); } } else { - RimProject* project = RIApplication::instance()->project(); + RimProject* project = RiaApplication::instance()->project(); if (!project) return NULL; bool isInt = false; @@ -242,7 +241,7 @@ void RiaSocketServer::readCommandFromOctave() QString caseName; QString propertyName; - RimReservoir* reservoir = NULL; + RimCase* reservoir = NULL; // Find the correct arguments @@ -281,18 +280,18 @@ void RiaSocketServer::readCommandFromOctave() size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; std::vector< std::vector >* scalarResultFrames = NULL; - if (reservoir && reservoir->reservoirData() && reservoir->reservoirData()->mainGrid() && reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)) + if (reservoir && reservoir->results(RifReaderInterface::MATRIX_RESULTS)) { - scalarResultIndex = reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(propertyName); + scalarResultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->findOrLoadScalarResult(propertyName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T && isSetProperty) { - scalarResultIndex = reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->addEmptyScalarResult(RimDefines::GENERATED, propertyName); + scalarResultIndex = reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->addEmptyScalarResult(RimDefines::GENERATED, propertyName, true); } if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) { - scalarResultFrames = &(reservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->cellScalarResults(scalarResultIndex)); + scalarResultFrames = &(reservoir->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->cellScalarResults(scalarResultIndex)); m_currentScalarIndex = scalarResultIndex; m_currentPropertyName = propertyName; } @@ -368,8 +367,14 @@ void RiaSocketServer::readCommandFromOctave() return; } - reservoir->reservoirData()->mainGrid()->calculateMatrixModelActiveCellInfo(activeCellInfo[0], activeCellInfo[1], activeCellInfo[2], activeCellInfo[3], - activeCellInfo[4], activeCellInfo[5], activeCellInfo[6], activeCellInfo[7]); + calculateMatrixModelActiveCellInfo(activeCellInfo[0], + activeCellInfo[1], + activeCellInfo[2], + activeCellInfo[3], + activeCellInfo[4], + activeCellInfo[5], + activeCellInfo[6], + activeCellInfo[7]); // First write timestep count quint64 timestepCount = (quint64)8; @@ -441,7 +446,7 @@ void RiaSocketServer::readPropertyDataFromOctave() size_t cellCountFromOctave = m_bytesPerTimeStepToRead / sizeof(double); - size_t gridActiveCellCount = m_currentReservoir->reservoirData()->mainGrid()->globalMatrixModelActiveCellCount(); + size_t gridActiveCellCount = m_currentReservoir->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS)->globalActiveCellCount(); size_t gridTotalCellCount = m_currentReservoir->reservoirData()->mainGrid()->cellCount(); if (cellCountFromOctave != gridActiveCellCount && cellCountFromOctave != gridTotalCellCount) @@ -497,7 +502,7 @@ void RiaSocketServer::readPropertyDataFromOctave() if (m_currentReservoir != NULL) { // Create a new input property if we have an input reservoir - RimInputReservoir* inputRes = dynamic_cast(m_currentReservoir); + RimInputCase* inputRes = dynamic_cast(m_currentReservoir); if (inputRes) { RimInputProperty* inputProperty = NULL; @@ -509,7 +514,7 @@ void RiaSocketServer::readPropertyDataFromOctave() inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - RimUiTreeModelPdm* treeModel = RIMainWindow::instance()->uiPdmModel(); + RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); treeModel->rebuildUiSubTree(inputRes->m_inputPropertyCollection()); } inputProperty->resolvedState = RimInputProperty::RESOLVED_NOT_SAVED; @@ -517,10 +522,9 @@ void RiaSocketServer::readPropertyDataFromOctave() if( m_currentScalarIndex != cvf::UNDEFINED_SIZE_T && m_currentReservoir->reservoirData() && - m_currentReservoir->reservoirData()->mainGrid() && - m_currentReservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS) ) + m_currentReservoir->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS) ) { - m_currentReservoir->reservoirData()->mainGrid()->results(RifReaderInterface::MATRIX_RESULTS)->recalculateMinMax(m_currentScalarIndex); + m_currentReservoir->reservoirData()->results(RifReaderInterface::MATRIX_RESULTS)->recalculateMinMax(m_currentScalarIndex); } for (size_t i = 0; i < m_currentReservoir->reservoirViews.size(); ++i) @@ -611,3 +615,77 @@ void RiaSocketServer::slotReadyRead() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaSocketServer::calculateMatrixModelActiveCellInfo(std::vector& gridNumber, std::vector& cellI, std::vector& cellJ, std::vector& cellK, std::vector& parentGridNumber, std::vector& hostCellI, std::vector& hostCellJ, std::vector& hostCellK) +{ + gridNumber.clear(); + cellI.clear(); + cellJ.clear(); + cellK.clear(); + parentGridNumber.clear(); + hostCellI.clear(); + hostCellJ.clear(); + hostCellK.clear(); + + if (!m_currentReservoir || !m_currentReservoir->reservoirData() || !m_currentReservoir->reservoirData()->mainGrid()) + { + return; + } + + RigActiveCellInfo* actCellInfo = m_currentReservoir->reservoirData()->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); + size_t numMatrixModelActiveCells = actCellInfo->globalActiveCellCount(); + + gridNumber.reserve(numMatrixModelActiveCells); + cellI.reserve(numMatrixModelActiveCells); + cellJ.reserve(numMatrixModelActiveCells); + cellK.reserve(numMatrixModelActiveCells); + parentGridNumber.reserve(numMatrixModelActiveCells); + hostCellI.reserve(numMatrixModelActiveCells); + hostCellJ.reserve(numMatrixModelActiveCells); + hostCellK.reserve(numMatrixModelActiveCells); + + const std::vector& globalCells = m_currentReservoir->reservoirData()->mainGrid()->cells(); + + for (size_t cIdx = 0; cIdx < globalCells.size(); ++cIdx) + { + if (actCellInfo->isActive(cIdx)) + { + RigGridBase* grid = globalCells[cIdx].hostGrid(); + CVF_ASSERT(grid != NULL); + size_t cellIndex = globalCells[cIdx].cellIndex(); + + size_t i, j, k; + grid->ijkFromCellIndex(cellIndex, &i, &j, &k); + + size_t pi, pj, pk; + RigGridBase* parentGrid = NULL; + + if (grid->isMainGrid()) + { + pi = i; + pj = j; + pk = k; + parentGrid = grid; + } + else + { + size_t parentCellIdx = globalCells[cIdx].parentCellIndex(); + parentGrid = (static_cast(grid))->parentGrid(); + CVF_ASSERT(parentGrid != NULL); + parentGrid->ijkFromCellIndex(parentCellIdx, &pi, &pj, &pk); + } + + gridNumber.push_back(static_cast(grid->gridIndex())); + cellI.push_back(static_cast(i)); + cellJ.push_back(static_cast(j)); + cellK.push_back(static_cast(k)); + parentGridNumber.push_back(static_cast(parentGrid->gridIndex())); + hostCellI.push_back(static_cast(pi)); + hostCellJ.push_back(static_cast(pj)); + hostCellK.push_back(static_cast(pk)); + } + } +} + diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.h b/ApplicationCode/SocketInterface/RiaSocketServer.h index e6e0d54553..6e19a1bb74 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.h +++ b/ApplicationCode/SocketInterface/RiaSocketServer.h @@ -27,7 +27,7 @@ class QTcpServer; class QTcpSocket; class QNetworkSession; class QErrorMessage; -class RimReservoir; +class RimCase; class RiaSocketServer : public QObject @@ -53,9 +53,19 @@ private: void handleClientConnection( QTcpSocket* clientToHandle); - RimReservoir* findReservoir(const QString &casename); + RimCase* findReservoir(const QString &casename); void terminateCurrentConnection(); + void calculateMatrixModelActiveCellInfo(std::vector& gridNumber, + std::vector& cellI, + std::vector& cellJ, + std::vector& cellK, + std::vector& parentGridNumber, + std::vector& hostCellI, + std::vector& hostCellJ, + std::vector& hostCellK); + + private: QTcpServer* m_tcpServer; QErrorMessage* m_errorMessageDialog; @@ -70,7 +80,7 @@ private: quint64 m_bytesPerTimeStepToRead; size_t m_currentTimeStepToRead; std::vector< std::vector >* m_scalarResultsToAdd; - RimReservoir* m_currentReservoir; + RimCase* m_currentReservoir; size_t m_currentScalarIndex; QString m_currentPropertyName; bool m_invalidActiveCellCountDetected; diff --git a/ApplicationCode/UserInterface/RICursors.cpp b/ApplicationCode/UserInterface/RiuCursors.cpp similarity index 92% rename from ApplicationCode/UserInterface/RICursors.cpp rename to ApplicationCode/UserInterface/RiuCursors.cpp index bdf913ec2a..bc84b95511 100644 --- a/ApplicationCode/UserInterface/RICursors.cpp +++ b/ApplicationCode/UserInterface/RiuCursors.cpp @@ -16,9 +16,9 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RICursors.h" +#include "RiuCursors.h" #include #include @@ -35,7 +35,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RICursors::RICursors() +RiuCursors::RiuCursors() { m_cursors[FILTER_BOX] = cursorFromFile(":/Cursors/curFilterBox.bmp", 10, 10); m_cursors[NORMAL] = cursorFromFile(":/Cursors/curNormal.bmp", 10, 10); @@ -53,10 +53,10 @@ RICursors::RICursors() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QCursor RICursors::get(CursorIndex cursorIdx) +QCursor RiuCursors::get(CursorIndex cursorIdx) { // Create our single instance in a local static variable - static RICursors myStaticInstance; + static RiuCursors myStaticInstance; return myStaticInstance.m_cursors[cursorIdx]; } @@ -65,7 +65,7 @@ QCursor RICursors::get(CursorIndex cursorIdx) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QCursor RICursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) +QCursor RiuCursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) { QImage image(fileName); if (image.width() == 0 || image.height() == 0) diff --git a/ApplicationCode/UserInterface/RICursors.h b/ApplicationCode/UserInterface/RiuCursors.h similarity index 97% rename from ApplicationCode/UserInterface/RICursors.h rename to ApplicationCode/UserInterface/RiuCursors.h index 136642c9fd..61fb559a01 100644 --- a/ApplicationCode/UserInterface/RICursors.h +++ b/ApplicationCode/UserInterface/RiuCursors.h @@ -27,7 +27,7 @@ // Singleton for getting the cursors // //================================================================================================== -class RICursors +class RiuCursors { public: enum CursorIndex @@ -48,7 +48,7 @@ public: static QCursor get(CursorIndex cursorIdx); private: - RICursors(); + RiuCursors(); static QCursor cursorFromFile(const QString& fileName, int hotspotX = -1, int hotspotY = -1); private: diff --git a/ApplicationCode/UserInterface/RIMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp similarity index 80% rename from ApplicationCode/UserInterface/RIMainWindow.cpp rename to ApplicationCode/UserInterface/RiuMainWindow.cpp index d26340fb8f..a7ce76fb97 100644 --- a/ApplicationCode/UserInterface/RIMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -16,20 +16,20 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIBaseDefs.h" +#include "RiaStdInclude.h" +#include "RiaBaseDefs.h" -#include "RIApplication.h" -#include "RIMainWindow.h" -#include "RIViewer.h" -#include "RIResultInfoPanel.h" -#include "RIProcessMonitor.h" -#include "RIPreferences.h" -#include "RIPreferencesDialog.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RiuViewer.h" +#include "RiuResultInfoPanel.h" +#include "RiuProcessMonitor.h" +#include "RiaPreferences.h" +#include "RiuPreferencesDialog.h" -#include "RigReservoir.h" -#include "RigReservoirCellResults.h" -#include "RimReservoir.h" +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" +#include "RimCase.h" #include "RimUiTreeModelPdm.h" #include "cvfqtBasicAboutDialog.h" @@ -40,24 +40,25 @@ #include "cafPdmUiPropertyView.h" #include "RimUiTreeView.h" +#include "RiuMultiCaseImportDialog.h" //================================================================================================== /// -/// \class RIMainWindow +/// \class RiuMainWindow /// /// Contains our main window /// //================================================================================================== -RIMainWindow* RIMainWindow::sm_mainWindowInstance = NULL; +RiuMainWindow* RiuMainWindow::sm_mainWindowInstance = NULL; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIMainWindow::RIMainWindow() +RiuMainWindow::RiuMainWindow() : m_treeView(NULL), m_pdmRoot(NULL), m_mainViewer(NULL), @@ -95,14 +96,14 @@ RIMainWindow::RIMainWindow() slotRefreshEditActions(); // Set pdm root so scripts are displayed - setPdmRoot(RIApplication::instance()->project()); + setPdmRoot(RiaApplication::instance()->project()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIMainWindow* RIMainWindow::instance() +RiuMainWindow* RiuMainWindow::instance() { return sm_mainWindowInstance; } @@ -110,18 +111,18 @@ RIMainWindow* RIMainWindow::instance() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::initializeGuiNewProjectLoaded() +void RiuMainWindow::initializeGuiNewProjectLoaded() { slotRefreshFileActions(); slotRefreshEditActions(); refreshAnimationActions(); - setPdmRoot(RIApplication::instance()->project()); + setPdmRoot(RiaApplication::instance()->project()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::cleanupGuiBeforeProjectClose() +void RiuMainWindow::cleanupGuiBeforeProjectClose() { setPdmRoot(NULL); setResultInfo(""); @@ -137,7 +138,7 @@ void RIMainWindow::cleanupGuiBeforeProjectClose() //-------------------------------------------------------------------------------------------------- /// Lightweight refresh of GUI (mainly toolbar actions). Called during idle processing //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshGuiLightweight() +void RiuMainWindow::refreshGuiLightweight() { refreshToolbars(); } @@ -145,7 +146,7 @@ void RIMainWindow::refreshGuiLightweight() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshToolbars() +void RiuMainWindow::refreshToolbars() { slotRefreshFileActions(); slotRefreshViewActions(); @@ -154,9 +155,9 @@ void RIMainWindow::refreshToolbars() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::closeEvent(QCloseEvent* event) +void RiuMainWindow::closeEvent(QCloseEvent* event) { - if (!RIApplication::instance()->closeProject(true)) + if (!RiaApplication::instance()->closeProject(true)) { event->ignore(); return; @@ -172,11 +173,13 @@ void RIMainWindow::closeEvent(QCloseEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createActions() +void RiuMainWindow::createActions() { // File actions m_openAction = new QAction(QIcon(":/AppLogo48x48.png"), "&Open Eclipse Case", this); m_openInputEclipseFileAction= new QAction(QIcon(":/EclipseInput48x48.png"), "&Open Input Eclipse Case", this); + m_openMultipleEclipseCasesAction = new QAction(QIcon(":/CreateGridCaseGroup16x16.png"), "&Create Grid Case Group from Files", this); + m_openProjectAction = new QAction(style()->standardIcon(QStyle::SP_DirOpenIcon), "&Open Project", this); m_openLastUsedProjectAction = new QAction("Open &Last Used Project", this); @@ -197,6 +200,7 @@ void RIMainWindow::createActions() connect(m_openAction, SIGNAL(triggered()), SLOT(slotOpenBinaryGridFiles())); connect(m_openInputEclipseFileAction,SIGNAL(triggered()), SLOT(slotOpenInputFiles())); + connect(m_openMultipleEclipseCasesAction,SIGNAL(triggered()), SLOT(slotOpenMultipleCases())); connect(m_openProjectAction, SIGNAL(triggered()), SLOT(slotOpenProject())); connect(m_openLastUsedProjectAction,SIGNAL(triggered()), SLOT(slotOpenLastUsedProject())); @@ -234,7 +238,7 @@ void RIMainWindow::createActions() m_viewFromBelow = new QAction(QIcon(":/UpViewArrow.png"),"Look Up", this); m_viewFromBelow->setToolTip("Look Up"); - m_zoomAll = new QAction(QIcon(),"Zoom all", this); + m_zoomAll = new QAction(QIcon(":/ZoomAll16x16.png"),"Zoom all", this); m_zoomAll->setToolTip("Zoom to view all"); connect(m_viewFromNorth, SIGNAL(triggered()), SLOT(slotViewFromNorth())); @@ -258,12 +262,13 @@ void RIMainWindow::createActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createMenus() +void RiuMainWindow::createMenus() { // File menu QMenu* fileMenu = menuBar()->addMenu("&File"); fileMenu->addAction(m_openAction); fileMenu->addAction(m_openInputEclipseFileAction); + fileMenu->addAction(m_openMultipleEclipseCasesAction); fileMenu->addAction(m_openProjectAction); fileMenu->addAction(m_openLastUsedProjectAction); @@ -325,7 +330,7 @@ void RIMainWindow::createMenus() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createToolBars() +void RiuMainWindow::createToolBars() { m_standardToolBar = addToolBar(tr("Standard")); @@ -345,6 +350,7 @@ void RIMainWindow::createToolBars() // View toolbar m_viewToolBar = addToolBar(tr("View")); m_viewToolBar->setObjectName(m_viewToolBar->windowTitle()); + m_viewToolBar->addAction(m_zoomAll); m_viewToolBar->addAction(m_viewFromNorth); m_viewToolBar->addAction(m_viewFromSouth); m_viewToolBar->addAction(m_viewFromEast); @@ -360,7 +366,7 @@ void RIMainWindow::createToolBars() /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::createDockPanels() +void RiuMainWindow::createDockPanels() { { QDockWidget* dockWidget = new QDockWidget("Project", this); @@ -369,6 +375,13 @@ void RIMainWindow::createDockPanels() m_treeView = new RimUiTreeView(dockWidget); m_treeView->setModel(m_treeModelPdm); + m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + + // Drag and drop configuration + m_treeView->setDragEnabled(true); + m_treeView->viewport()->setAcceptDrops(true); + m_treeView->setDropIndicatorShown(true); + m_treeView->setDragDropMode(QAbstractItemView::DragDrop); dockWidget->setWidget(m_treeView); @@ -379,7 +392,7 @@ void RIMainWindow::createDockPanels() QDockWidget* dockPanel = new QDockWidget("Result Info", this); dockPanel->setObjectName("dockResultInfoPanel"); dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - m_resultInfoPanel = new RIResultInfoPanel(dockPanel); + m_resultInfoPanel = new RiuResultInfoPanel(dockPanel); dockPanel->setWidget(m_resultInfoPanel); addDockWidget(Qt::BottomDockWidgetArea, dockPanel); @@ -389,7 +402,7 @@ void RIMainWindow::createDockPanels() QDockWidget* dockPanel = new QDockWidget("Process Monitor", this); dockPanel->setObjectName("dockProcessMonitor"); dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - m_processMonitor = new RIProcessMonitor(dockPanel); + m_processMonitor = new RiuProcessMonitor(dockPanel); dockPanel->setWidget(m_processMonitor); addDockWidget(Qt::BottomDockWidgetArea, dockPanel); @@ -416,7 +429,7 @@ void RIMainWindow::createDockPanels() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::saveWinGeoAndDockToolBarLayout() +void RiuMainWindow::saveWinGeoAndDockToolBarLayout() { // Company and appname set through QCoreApplication QSettings settings; @@ -432,7 +445,7 @@ void RIMainWindow::saveWinGeoAndDockToolBarLayout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::loadWinGeoAndDockToolBarLayout() +void RiuMainWindow::loadWinGeoAndDockToolBarLayout() { // Company and appname set through QCoreApplication QSettings settings; @@ -455,7 +468,7 @@ void RIMainWindow::loadWinGeoAndDockToolBarLayout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setResultInfo(const QString& info) const +void RiuMainWindow::setResultInfo(const QString& info) const { m_resultInfoPanel->setInfo(info); } @@ -471,9 +484,9 @@ void RIMainWindow::setResultInfo(const QString& info) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshFileActions() +void RiuMainWindow::slotRefreshFileActions() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool projectExists = true; m_saveProjectAction->setEnabled(projectExists); @@ -485,9 +498,9 @@ void RIMainWindow::slotRefreshFileActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshEditActions() +void RiuMainWindow::slotRefreshEditActions() { -// RIApplication* app = RIApplication::instance(); +// RiaApplication* app = RiaApplication::instance(); // RISceneManager* proj = app->project(); } @@ -495,9 +508,9 @@ void RIMainWindow::slotRefreshEditActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshViewActions() +void RiuMainWindow::slotRefreshViewActions() { -// RIApplication* app = RIApplication::instance(); +// RiaApplication* app = RiaApplication::instance(); // RISceneManager* proj = app->project(); bool enabled = true; @@ -512,12 +525,12 @@ void RIMainWindow::slotRefreshViewActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::refreshAnimationActions() +void RiuMainWindow::refreshAnimationActions() { caf::FrameAnimationControl* ac = NULL; - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - ac = RIApplication::instance()->activeReservoirView()->viewer()->animationControl(); + ac = RiaApplication::instance()->activeReservoirView()->viewer()->animationControl(); } m_animationToolBar->connectAnimationControl(ac); @@ -525,7 +538,7 @@ void RIMainWindow::refreshAnimationActions() QStringList timeStepStrings; int currentTimeStepIndex = 0; - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool enableAnimControls = false; if (app->activeReservoirView() && @@ -534,15 +547,15 @@ void RIMainWindow::refreshAnimationActions() { enableAnimControls = true; - if (app->activeReservoirView()->gridCellResults()) + if (app->activeReservoirView()->currentGridCellResults()) { if (app->activeReservoirView()->cellResult()->hasDynamicResult() || app->activeReservoirView()->propertyFilterCollection()->hasActiveDynamicFilters() || app->activeReservoirView()->wellCollection()->hasVisibleWellPipes()) { - QList timeStepDates = app->activeReservoirView()->gridCellResults()->timeStepDates(0); + std::vector timeStepDates = app->activeReservoirView()->currentGridCellResults()->cellResults()->timeStepDates(0); bool showHoursAndMinutes = false; - for (int i = 0; i < timeStepDates.size(); i++) + for (size_t i = 0; i < timeStepDates.size(); i++) { if (timeStepDates[i].time().hour() != 0.0 || timeStepDates[i].time().minute() != 0.0) { @@ -556,11 +569,11 @@ void RIMainWindow::refreshAnimationActions() formatString += " - hh:mm"; } - for (int i = 0; i < timeStepDates.size(); i++) + for (size_t i = 0; i < timeStepDates.size(); i++) { timeStepStrings += timeStepDates[i].toString(formatString); } - currentTimeStepIndex = RIApplication::instance()->activeReservoirView()->currentTimeStep(); + currentTimeStepIndex = RiaApplication::instance()->activeReservoirView()->currentTimeStep(); } else { @@ -580,12 +593,12 @@ void RIMainWindow::refreshAnimationActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotAbout() +void RiuMainWindow::slotAbout() { cvfqt::BasicAboutDialog dlg(this); dlg.setApplicationName(RI_APPLICATION_NAME); - dlg.setApplicationVersion(RIApplication::getVersionStringApp(true)); + dlg.setApplicationVersion(RiaApplication::getVersionStringApp(true)); dlg.setCopyright("Copyright 2012 Statoil ASA, Ceetron AS"); dlg.showCeeVizVersion(false); @@ -613,11 +626,11 @@ void RIMainWindow::slotAbout() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenBinaryGridFiles() +void RiuMainWindow::slotOpenBinaryGridFiles() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Open Eclipse File", defaultDir, "Eclipse Grid Files (*.GRID *.EGRID)"); @@ -641,11 +654,11 @@ void RIMainWindow::slotOpenBinaryGridFiles() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenInputFiles() +void RiuMainWindow::slotOpenInputFiles() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); QStringList fileNames = QFileDialog::getOpenFileNames(this, "Open Eclipse Input Files", defaultDir, "Eclipse Input Files and Input Properties (*.GRDECL *)"); @@ -662,11 +675,11 @@ void RIMainWindow::slotOpenInputFiles() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenProject() +void RiuMainWindow::slotOpenProject() { if (checkForDocumentModifications()) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); QString fileName = QFileDialog::getOpenFileName(this, "Open ResInsight Project", defaultDir, "ResInsight project (*.rip)"); @@ -684,18 +697,18 @@ void RIMainWindow::slotOpenProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotOpenLastUsedProject() +void RiuMainWindow::slotOpenLastUsedProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->loadLastUsedProject(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockModel() +void RiuMainWindow::slotMockModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createMockModel(); //m_mainViewer->setDefaultView(); @@ -704,9 +717,9 @@ void RIMainWindow::slotMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockResultsModel() +void RiuMainWindow::slotMockResultsModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createResultsMockModel(); //m_mainViewer->setDefaultView(); @@ -716,9 +729,9 @@ void RIMainWindow::slotMockResultsModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotMockLargeResultsModel() +void RiuMainWindow::slotMockLargeResultsModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createLargeResultsMockModel(); } @@ -726,9 +739,9 @@ void RIMainWindow::slotMockLargeResultsModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotInputMockModel() +void RiuMainWindow::slotInputMockModel() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->createInputMockModel(); } @@ -736,18 +749,18 @@ void RIMainWindow::slotInputMockModel() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSetCurrentFrame(int frameIndex) +void RiuMainWindow::slotSetCurrentFrame(int frameIndex) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // app->setTimeStep(frameIndex); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RIMainWindow::checkForDocumentModifications() +bool RiuMainWindow::checkForDocumentModifications() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // RISceneManager* project = app->sceneManager(); // if (project && project->isModified()) // { @@ -775,9 +788,9 @@ bool RIMainWindow::checkForDocumentModifications() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotCloseProject() +void RiuMainWindow::slotCloseProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); bool ret = app->closeProject(true); } @@ -785,7 +798,7 @@ void RIMainWindow::slotCloseProject() /// //-------------------------------------------------------------------------------------------------- -QMdiSubWindow* RIMainWindow::findMdiSubWindow(RIViewer* viewer) +QMdiSubWindow* RiuMainWindow::findMdiSubWindow(RiuViewer* viewer) { QList subws = m_mdiArea->subWindowList(); int i; @@ -804,7 +817,7 @@ QMdiSubWindow* RIMainWindow::findMdiSubWindow(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::removeViewer(RIViewer* viewer) +void RiuMainWindow::removeViewer(RiuViewer* viewer) { #if 0 m_CentralFrame->layout()->removeWidget(viewer->layoutWidget()); @@ -816,7 +829,7 @@ void RIMainWindow::removeViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::addViewer(RIViewer* viewer) +void RiuMainWindow::addViewer(RiuViewer* viewer) { #if 0 m_CentralFrame->layout()->addWidget(viewer->layoutWidget()); @@ -839,9 +852,9 @@ void RIMainWindow::addViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSaveProject() +void RiuMainWindow::slotSaveProject() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveProject(); } @@ -849,9 +862,9 @@ void RIMainWindow::slotSaveProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSaveProjectAs() +void RiuMainWindow::slotSaveProjectAs() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveProjectPromptForFileName(); } @@ -860,7 +873,7 @@ void RIMainWindow::slotSaveProjectAs() //-------------------------------------------------------------------------------------------------- /// This method needs to handle memory deallocation !!! //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) +void RiuMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) { m_pdmRoot = pdmRoot; @@ -878,92 +891,92 @@ void RIMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromNorth() +void RiuMainWindow::slotViewFromNorth() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,-1,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,-1,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromSouth() +void RiuMainWindow::slotViewFromSouth() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,1,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,1,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromEast() +void RiuMainWindow::slotViewFromEast() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(-1,0,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(-1,0,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromWest() +void RiuMainWindow::slotViewFromWest() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(1,0,0), cvf::Vec3d(0,0,1)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(1,0,0), cvf::Vec3d(0,0,1)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromAbove() +void RiuMainWindow::slotViewFromAbove() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,1,0)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,-1), cvf::Vec3d(0,1,0)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotViewFromBelow() +void RiuMainWindow::slotViewFromBelow() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,1), cvf::Vec3d(0,1,0)); + RiaApplication::instance()->activeReservoirView()->viewer()->setView(cvf::Vec3d(0,0,1), cvf::Vec3d(0,1,0)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotZoomAll() +void RiuMainWindow::slotZoomAll() { - if (RIApplication::instance()->activeReservoirView() && RIApplication::instance()->activeReservoirView()->viewer()) + if (RiaApplication::instance()->activeReservoirView() && RiaApplication::instance()->activeReservoirView()->viewer()) { - RIApplication::instance()->activeReservoirView()->viewer()->zoomAll(); + RiaApplication::instance()->activeReservoirView()->viewer()->zoomAll(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) +void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) { - RimProject * proj = RIApplication::instance()->project(); + RimProject * proj = RiaApplication::instance()->project(); if (!proj) return; size_t i; for (i = 0; i < proj->reservoirs().size(); ++i) { - RimReservoir* ri = proj->reservoirs()[i]; + RimCase* ri = proj->reservoirs()[i]; if (!ri) continue; size_t j; @@ -976,8 +989,8 @@ void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) riv->viewer()->layoutWidget() && riv->viewer()->layoutWidget()->parent() == subWindow) { - RimReservoirView* previousActiveReservoirView = RIApplication::instance()->activeReservoirView(); - RIApplication::instance()->setActiveReservoirView(riv); + RimReservoirView* previousActiveReservoirView = RiaApplication::instance()->activeReservoirView(); + RiaApplication::instance()->setActiveReservoirView(riv); if (previousActiveReservoirView && previousActiveReservoirView != riv) { QModelIndex previousViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(previousActiveReservoirView); @@ -1037,34 +1050,34 @@ void RIMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotUseShaders(bool enable) +void RiuMainWindow::slotUseShaders(bool enable) { - RIApplication::instance()->setUseShaders(enable); + RiaApplication::instance()->setUseShaders(enable); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotShowPerformanceInfo(bool enable) +void RiuMainWindow::slotShowPerformanceInfo(bool enable) { - RIApplication::instance()->setShowPerformanceInfo(enable); + RiaApplication::instance()->setShowPerformanceInfo(enable); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotRefreshDebugActions() +void RiuMainWindow::slotRefreshDebugActions() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotEditPreferences() +void RiuMainWindow::slotEditPreferences() { - RIApplication* app = RIApplication::instance(); - RIPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); + RiaApplication* app = RiaApplication::instance(); + RiuPreferencesDialog preferencesDialog(this, app->preferences(), "Preferences"); if (preferencesDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application @@ -1081,7 +1094,7 @@ void RIMainWindow::slotEditPreferences() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::setActiveViewer(RIViewer* viewer) +void RiuMainWindow::setActiveViewer(RiuViewer* viewer) { QMdiSubWindow * swin = findMdiSubWindow(viewer); if (swin) m_mdiArea->setActiveSubWindow(swin); @@ -1090,18 +1103,18 @@ void RIMainWindow::setActiveViewer(RIViewer* viewer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotFramerateChanged(double frameRate) +void RiuMainWindow::slotFramerateChanged(double frameRate) { - if (RIApplication::instance()->activeReservoirView() != NULL) + if (RiaApplication::instance()->activeReservoirView() != NULL) { - RIApplication::instance()->activeReservoirView()->maximumFrameRate.setValueFromUi(QVariant(frameRate)); + RiaApplication::instance()->activeReservoirView()->maximumFrameRate.setValueFromUi(QVariant(frameRate)); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor* RIMainWindow::processMonitor() +RiuProcessMonitor* RiuMainWindow::processMonitor() { return m_processMonitor; } @@ -1109,7 +1122,7 @@ RIProcessMonitor* RIMainWindow::processMonitor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotBuildWindowActions() +void RiuMainWindow::slotBuildWindowActions() { m_windowMenu->clear(); @@ -1126,9 +1139,9 @@ void RIMainWindow::slotBuildWindowActions() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) +void RiuMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) { - RimReservoirView* activeReservoirView = RIApplication::instance()->activeReservoirView(); + RimReservoirView* activeReservoirView = RiaApplication::instance()->activeReservoirView(); QModelIndex activeViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(activeReservoirView); QModelIndex tmp = current; @@ -1146,7 +1159,7 @@ void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelI // show new reservoir view and set this as activate view if (rimReservoirView != activeReservoirView) { - RIApplication::instance()->setActiveReservoirView(rimReservoirView); + RiaApplication::instance()->setActiveReservoirView(rimReservoirView); // Set focus in MDI area to this window if it exists if (rimReservoirView->viewer()) @@ -1172,7 +1185,7 @@ void RIMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelI //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotNewObjectPropertyView() +void RiuMainWindow::slotNewObjectPropertyView() { if (!m_treeModelPdm) return; @@ -1210,9 +1223,9 @@ void RIMainWindow::slotNewObjectPropertyView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotToFile() +void RiuMainWindow::slotSnapshotToFile() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveSnapshotPromtpForFilename(); } @@ -1220,9 +1233,9 @@ void RIMainWindow::slotSnapshotToFile() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotToClipboard() +void RiuMainWindow::slotSnapshotToClipboard() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->copySnapshotToClipboard(); } @@ -1230,9 +1243,9 @@ void RIMainWindow::slotSnapshotToClipboard() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::slotSnapshotAllViewsToFile() +void RiuMainWindow::slotSnapshotAllViewsToFile() { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->saveSnapshotForAllViews("snapshots"); } @@ -1240,7 +1253,7 @@ void RIMainWindow::slotSnapshotAllViewsToFile() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIMainWindow::hideAllDockWindows() +void RiuMainWindow::hideAllDockWindows() { QList dockWidgets = findChildren(); @@ -1249,3 +1262,43 @@ void RIMainWindow::hideAllDockWindows() dockWidgets[i]->close(); } } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::slotOpenMultipleCases() +{ + RiaApplication* app = RiaApplication::instance(); + + /* + RiuMultiCaseImportDialog dialog; + int action = dialog.exec(); + if (action == QDialog::Accepted) + { + QStringList gridFileNames = dialog.eclipseCaseFileNames(); + app->addEclipseCases(gridFileNames); + } + */ + + + QStringList gridFileNames; + + if (1) + { + gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += "Result Mock Debug Model With Results"; + gridFileNames += "Result Mock Debug Model With Results"; + } + else + { + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real0/BRUGGE_0000.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real30/BRUGGE_0030.EGRID"; + gridFileNames += "d:/Models/Statoil/MultipleRealisations/Case_with_10_timesteps/Real40/BRUGGE_0040.EGRID"; + } + + app->addEclipseCases(gridFileNames); + + +} diff --git a/ApplicationCode/UserInterface/RIMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h similarity index 89% rename from ApplicationCode/UserInterface/RIMainWindow.h rename to ApplicationCode/UserInterface/RiuMainWindow.h index 0f133900bd..463599aa36 100644 --- a/ApplicationCode/UserInterface/RIMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -32,9 +32,9 @@ class QLabel; class QLineEdit; class QItemSelection; -class RIViewer; -class RIResultInfoPanel; -class RIProcessMonitor; +class RiuViewer; +class RiuResultInfoPanel; +class RiuProcessMonitor; class RimUiTreeModelPdm; namespace caf @@ -52,13 +52,13 @@ namespace caf // // //================================================================================================== -class RIMainWindow : public QMainWindow +class RiuMainWindow : public QMainWindow { Q_OBJECT public: - RIMainWindow(); - static RIMainWindow* instance(); + RiuMainWindow(); + static RiuMainWindow* instance(); void initializeGuiNewProjectLoaded(); void cleanupGuiBeforeProjectClose(); @@ -66,9 +66,9 @@ public: void refreshGuiLightweight(); void refreshToolbars(); - void removeViewer( RIViewer* viewer ); - void addViewer(RIViewer* viewer); - void setActiveViewer(RIViewer* subWindow); + void removeViewer( RiuViewer* viewer ); + void addViewer(RiuViewer* viewer); + void setActiveViewer(RiuViewer* subWindow); void setResultInfo(const QString& info) const; @@ -76,7 +76,7 @@ public: RimUiTreeModelPdm* uiPdmModel() { return m_treeModelPdm;} - RIProcessMonitor* processMonitor(); + RiuProcessMonitor* processMonitor(); void hideAllDockWindows(); @@ -95,10 +95,10 @@ private: void updateMRUList(const QString &fileName, bool remove = false); - QMdiSubWindow* findMdiSubWindow(RIViewer* viewer); + QMdiSubWindow* findMdiSubWindow(RiuViewer* viewer); private: - static RIMainWindow* sm_mainWindowInstance; + static RiuMainWindow* sm_mainWindowInstance; QByteArray m_initialDockAndToolbarLayout; // Initial dock window and toolbar layout, used to reset GUI @@ -106,6 +106,7 @@ private: // File actions QAction* m_openAction; QAction* m_openInputEclipseFileAction; + QAction* m_openMultipleEclipseCasesAction; QAction* m_openProjectAction; QAction* m_openLastUsedProjectAction; QAction* m_saveProjectAction; @@ -149,9 +150,9 @@ private: QFrame* m_CentralFrame; QMdiArea* m_mdiArea; - RIViewer* m_mainViewer; - RIResultInfoPanel* m_resultInfoPanel; - RIProcessMonitor* m_processMonitor; + RiuViewer* m_mainViewer; + RiuResultInfoPanel* m_resultInfoPanel; + RiuProcessMonitor* m_processMonitor; QMenu* m_windowMenu; @@ -162,6 +163,7 @@ private slots: // File slots void slotOpenBinaryGridFiles(); void slotOpenInputFiles(); + void slotOpenMultipleCases(); void slotOpenProject(); void slotOpenLastUsedProject(); void slotSaveProject(); diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp new file mode 100644 index 0000000000..e6014f07a1 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuMultiCaseImportDialog.h" +#include "ui_RiuMultiCaseImportDialog.h" +#include +#include +#include +#include +#include "RiaApplication.h" + +class FileListModel: public QStringListModel +{ +public: + FileListModel(QObject *parent = 0) : m_isItemsEditable(false), QStringListModel(parent) + { + } + + virtual Qt::ItemFlags flags (const QModelIndex& index) const + { + if (m_isItemsEditable) + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; + else + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + + virtual QVariant data ( const QModelIndex & index, int role ) const + { + if (role == Qt::DecorationRole) + { + QFileInfo fileInfo(stringList()[index.row()]); + QFileIconProvider iconProv; + return QVariant(iconProv.icon(fileInfo)); + } + else + { + return QStringListModel::data(index, role); + } + } + + + void setItemsEditable(bool isEditable) + { + m_isItemsEditable = isEditable; + } + +private: + bool m_isItemsEditable; +}; + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuMultiCaseImportDialog::RiuMultiCaseImportDialog(QWidget *parent /*= 0*/) + : QDialog(parent) +{ + ui = new Ui::RiuMultiCaseImportDialog; + ui->setupUi(this); + + m_searchFolders = new FileListModel(this); + ui->m_searchFolderList->setModel(m_searchFolders); + + m_eclipseGridFiles = new FileListModel(this); + ui->m_eclipseCasesList->setModel(m_eclipseGridFiles); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuMultiCaseImportDialog::~RiuMultiCaseImportDialog() +{ + delete ui; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_addSearchFolderButton_clicked() +{ + QString selectedFolder = QFileDialog::getExistingDirectory(this, "Select an Eclipse case search folder", RiaApplication::instance()->defaultFileDialogDirectory("MULTICASEIMPORT")); + QStringList folderNames = m_searchFolders->stringList(); + + if (!folderNames.contains(selectedFolder)) + { + folderNames.push_back(selectedFolder); + m_searchFolders->setStringList(folderNames); + updateGridFileList(); + } + + RiaApplication::instance()->setDefaultFileDialogDirectory("MULTICASEIMPORT", selectedFolder); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_removeSearchFolderButton_clicked() +{ + QModelIndexList selection = ui->m_searchFolderList->selectionModel()->selectedIndexes(); + QStringList folderNames = m_searchFolders->stringList(); + + QStringList searchFoldersToRemove; + + for (int i = 0; i < selection.size(); ++i) + { + searchFoldersToRemove.push_back(folderNames[selection[i].row()]); + } + + for (int i = 0; i < searchFoldersToRemove.size(); ++i) + { + folderNames.removeOne(searchFoldersToRemove[i]); + } + + m_searchFolders->setStringList(folderNames); + + if (selection.size()) + { + updateGridFileList(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::updateGridFileList() +{ + + QStringList folderNames = m_searchFolders->stringList(); + QStringList gridFileNames; + + + // Filter the search folders to remove subfolders of existing roots' + + bool okToAdd = true; + QStringList searchFoldersToRemove; + + for (int i = 0; i < folderNames.size(); ++i) + for (int j = 0; j < folderNames.size(); ++j) + { + if ( i != j) + { + if (folderNames[i].startsWith(folderNames[j])) + { + // Remove folderNames[i] + searchFoldersToRemove.push_back(folderNames[i]); + } + } + } + + // Remove the subfolders when adding a root + + for (int i = 0; i < searchFoldersToRemove.size(); ++i) + { + folderNames.removeOne(searchFoldersToRemove[i]); + } + + for (int i = 0; i < folderNames.size(); i++) + { + QString folderName = folderNames[i]; + + appendEGRIDFilesRecursively(folderName, gridFileNames); + } + + m_eclipseGridFiles->setStringList(gridFileNames); +} + + +void RiuMultiCaseImportDialog::appendEGRIDFilesRecursively(const QString& folderName, QStringList& gridFileNames) +{ + { + QDir baseDir(folderName); + baseDir.setFilter(QDir::Files); + + QStringList nameFilters; + nameFilters << "*.egrid" << ".EGRID"; + baseDir.setNameFilters(nameFilters); + + QStringList fileNames = baseDir.entryList(); + + for (int i = 0; i < fileNames.size(); ++i) + { + QString fileName = fileNames[i]; + + QString absoluteFolderName = baseDir.absoluteFilePath(fileName); + + gridFileNames.append(absoluteFolderName); + } + } + + + { + QDir baseDir(folderName); + baseDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + + QStringList subFolders = baseDir.entryList(); + + for (int i = 0; i < subFolders.size(); ++i) + { + QString folderName = subFolders[i]; + + QString absoluteFolderName = baseDir.absoluteFilePath(folderName); + appendEGRIDFilesRecursively(absoluteFolderName, gridFileNames); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RiuMultiCaseImportDialog::eclipseCaseFileNames() const +{ + return m_eclipseGridFiles->stringList(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMultiCaseImportDialog::on_m_removeEclipseCaseButton_clicked() +{ + QModelIndexList selection = ui->m_eclipseCasesList->selectionModel()->selectedIndexes(); + if (selection.size()) + { + for (int i = 0; i < selection.size(); ++i) + { + ui->m_eclipseCasesList->model()->removeRow(selection[i].row(), selection[i].parent()); + } + + QModelIndexList selection = ui->m_eclipseCasesList->selectionModel()->selectedIndexes(); + QStringList fileNames = m_eclipseGridFiles->stringList(); + + QStringList filenamesToRemove; + + for (int i = 0; i < selection.size(); ++i) + { + filenamesToRemove.push_back(fileNames[selection[i].row()]); + } + + for (int i = 0; i < filenamesToRemove.size(); ++i) + { + fileNames.removeOne(filenamesToRemove[i]); + } + + m_eclipseGridFiles->setStringList(fileNames); + } +} diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h new file mode 100644 index 0000000000..815628d147 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +namespace Ui { + class RiuMultiCaseImportDialog; +}; + +class FileListModel; + +//================================================================================================== +// +// +// +//================================================================================================== + +class RiuMultiCaseImportDialog: public QDialog +{ + Q_OBJECT + +public: + RiuMultiCaseImportDialog(QWidget *parent = 0); + virtual ~RiuMultiCaseImportDialog(); + + QStringList eclipseCaseFileNames() const; + +protected slots: + void on_m_addSearchFolderButton_clicked(); + void on_m_removeSearchFolderButton_clicked(); + void on_m_removeEclipseCaseButton_clicked(); +private: + void updateGridFileList(); + static void appendEGRIDFilesRecursively(const QString& folderName, QStringList& gridFileNames); + Ui::RiuMultiCaseImportDialog* ui; + + FileListModel *m_searchFolders; + FileListModel *m_eclipseGridFiles; +}; diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui new file mode 100644 index 0000000000..ca27248841 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.ui @@ -0,0 +1,186 @@ + + + RiuMultiCaseImportDialog + + + + 0 + 0 + 755 + 736 + + + + Create Grid Case Group From Files + + + true + + + + + + Qt::Horizontal + + + + + + + QAbstractItemView::ExtendedSelection + + + + + + + Remove + + + + + + + Add + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Search Folders + + + + + + + Qt::Vertical + + + + 20 + 222 + + + + + + + + + + + + + 0 + 0 + + + + QAbstractItemView::ExtendedSelection + + + + + + + Selected Eclipse Cases + + + + + + + Remove + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 400 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + m_dialogButtons + accepted() + RiuMultiCaseImportDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + m_dialogButtons + rejected() + RiuMultiCaseImportDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/ApplicationCode/UserInterface/RIPreferencesDialog.cpp b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp similarity index 90% rename from ApplicationCode/UserInterface/RIPreferencesDialog.cpp rename to ApplicationCode/UserInterface/RiuPreferencesDialog.cpp index c77785a99d..7a094776c8 100644 --- a/ApplicationCode/UserInterface/RIPreferencesDialog.cpp +++ b/ApplicationCode/UserInterface/RiuPreferencesDialog.cpp @@ -16,8 +16,8 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIPreferencesDialog.h" +#include "RiaStdInclude.h" +#include "RiuPreferencesDialog.h" #include "cafAppEnum.h" #include "cafPdmObject.h" @@ -30,7 +30,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIPreferencesDialog::RIPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) +RiuPreferencesDialog::RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) : QDialog(parent) { CVF_ASSERT(object); @@ -44,7 +44,7 @@ RIPreferencesDialog::RIPreferencesDialog(QWidget* parent, caf::PdmObject* object //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIPreferencesDialog::setupUi() +void RiuPreferencesDialog::setupUi() { setWindowTitle(m_windowTitle); diff --git a/ApplicationCode/UserInterface/RIPreferencesDialog.h b/ApplicationCode/UserInterface/RiuPreferencesDialog.h similarity index 90% rename from ApplicationCode/UserInterface/RIPreferencesDialog.h rename to ApplicationCode/UserInterface/RiuPreferencesDialog.h index b33c4924d2..3751e108fb 100644 --- a/ApplicationCode/UserInterface/RIPreferencesDialog.h +++ b/ApplicationCode/UserInterface/RiuPreferencesDialog.h @@ -32,12 +32,12 @@ namespace caf // // //================================================================================================== -class RIPreferencesDialog : public QDialog +class RiuPreferencesDialog : public QDialog { Q_OBJECT public: - RIPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); + RiuPreferencesDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); private: void setupUi(); diff --git a/ApplicationCode/UserInterface/RIProcessMonitor.cpp b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp similarity index 89% rename from ApplicationCode/UserInterface/RIProcessMonitor.cpp rename to ApplicationCode/UserInterface/RiuProcessMonitor.cpp index c46a6a3fc9..4c4396954b 100644 --- a/ApplicationCode/UserInterface/RIProcessMonitor.cpp +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp @@ -16,17 +16,17 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RIProcessMonitor.h" +#include "RiuProcessMonitor.h" #include "cafUiProcess.h" -#include "RIApplication.h" +#include "RiaApplication.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor::RIProcessMonitor(QDockWidget* pParent) +RiuProcessMonitor::RiuProcessMonitor(QDockWidget* pParent) : QWidget(pParent) { m_monitoredProcess = NULL; @@ -70,7 +70,7 @@ RIProcessMonitor::RIProcessMonitor(QDockWidget* pParent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIProcessMonitor::~RIProcessMonitor() +RiuProcessMonitor::~RiuProcessMonitor() { } @@ -79,7 +79,7 @@ RIProcessMonitor::~RIProcessMonitor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) +void RiuProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) { setStatusMsg("N/A", caf::PROCESS_STATE_NORMAL); @@ -102,7 +102,7 @@ void RIProcessMonitor::startMonitorWorkProcess(caf::UiProcess* pProcess) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::stopMonitorWorkProcess() +void RiuProcessMonitor::stopMonitorWorkProcess() { m_monitoredProcess = NULL; @@ -118,7 +118,7 @@ void RIProcessMonitor::stopMonitorWorkProcess() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgType) +void RiuProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgType) { if (!m_labelStatus) return; @@ -138,7 +138,7 @@ void RIProcessMonitor::setStatusMsg(const QString& sStatusMsg, int iStatusMsgTyp //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::addStringToLog(const QString& sTxt) +void RiuProcessMonitor::addStringToLog(const QString& sTxt) { m_textEdit->moveCursor(QTextCursor::End); m_textEdit->insertPlainText(sTxt); @@ -150,7 +150,7 @@ void RIProcessMonitor::addStringToLog(const QString& sTxt) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsgType) +void RiuProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsgType) { setStatusMsg(sMsg, iStatusMsgType); } @@ -159,7 +159,7 @@ void RIProcessMonitor::slotShowProcStatusMsg(const QString& sMsg, int iStatusMsg //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotProcReadyReadStdOut() +void RiuProcessMonitor::slotProcReadyReadStdOut() { if (!m_monitoredProcess) return; @@ -174,7 +174,7 @@ void RIProcessMonitor::slotProcReadyReadStdOut() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotProcReadyReadStdErr() +void RiuProcessMonitor::slotProcReadyReadStdErr() { if (!m_monitoredProcess) return; @@ -188,18 +188,18 @@ void RIProcessMonitor::slotProcReadyReadStdErr() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotTerminateProcess() +void RiuProcessMonitor::slotTerminateProcess() { addStringToLog("Process terminated by user\n"); - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); app->terminateProcess(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIProcessMonitor::slotClearTextEdit() +void RiuProcessMonitor::slotClearTextEdit() { m_textEdit->clear(); } diff --git a/ApplicationCode/UserInterface/RIProcessMonitor.h b/ApplicationCode/UserInterface/RiuProcessMonitor.h similarity index 94% rename from ApplicationCode/UserInterface/RIProcessMonitor.h rename to ApplicationCode/UserInterface/RiuProcessMonitor.h index 7a421ac1e0..8a58d66ca2 100644 --- a/ApplicationCode/UserInterface/RIProcessMonitor.h +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.h @@ -34,7 +34,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class RIProcessMonitor : public QWidget +class RiuProcessMonitor : public QWidget { Q_OBJECT @@ -46,8 +46,8 @@ private: caf::UiProcess* m_monitoredProcess; // Pointer to the process we're monitoring. Needed to fetch text public: - RIProcessMonitor(QDockWidget* pParent); - ~RIProcessMonitor(); + RiuProcessMonitor(QDockWidget* pParent); + ~RiuProcessMonitor(); void startMonitorWorkProcess(caf::UiProcess* process); void stopMonitorWorkProcess(); diff --git a/ApplicationCode/UserInterface/RIResultInfoPanel.cpp b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp similarity index 88% rename from ApplicationCode/UserInterface/RIResultInfoPanel.cpp rename to ApplicationCode/UserInterface/RiuResultInfoPanel.cpp index 56ac7195ca..124f96f632 100644 --- a/ApplicationCode/UserInterface/RIResultInfoPanel.cpp +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp @@ -16,14 +16,14 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" -#include "RIResultInfoPanel.h" +#include "RiaStdInclude.h" +#include "RiuResultInfoPanel.h" //================================================================================================== /// -/// \class RIResultInfoPanel +/// \class RiuResultInfoPanel /// \ingroup ResInsight /// /// @@ -33,7 +33,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIResultInfoPanel::RIResultInfoPanel(QDockWidget* parent) +RiuResultInfoPanel::RiuResultInfoPanel(QDockWidget* parent) : QWidget(parent) { m_textEdit = new QTextEdit(this); @@ -49,7 +49,7 @@ RIResultInfoPanel::RIResultInfoPanel(QDockWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIResultInfoPanel::setInfo(const QString& info) +void RiuResultInfoPanel::setInfo(const QString& info) { QString tmp(info); @@ -62,7 +62,7 @@ void RIResultInfoPanel::setInfo(const QString& info) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIResultInfoPanel::convertStringToHTML(QString* str) +void RiuResultInfoPanel::convertStringToHTML(QString* str) { str->replace("\n", "
"); str->replace(" ", " "); @@ -72,7 +72,7 @@ void RIResultInfoPanel::convertStringToHTML(QString* str) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QSize RIResultInfoPanel::sizeHint () const +QSize RiuResultInfoPanel::sizeHint () const { // As small as possible fow now return QSize(20, 20); diff --git a/ApplicationCode/UserInterface/RIResultInfoPanel.h b/ApplicationCode/UserInterface/RiuResultInfoPanel.h similarity index 92% rename from ApplicationCode/UserInterface/RIResultInfoPanel.h rename to ApplicationCode/UserInterface/RiuResultInfoPanel.h index 3c753b3e86..9ee0ba1b24 100644 --- a/ApplicationCode/UserInterface/RIResultInfoPanel.h +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.h @@ -27,15 +27,15 @@ class QTextEdit; //================================================================================================== // -// RIResultInfoPanel +// RiuResultInfoPanel // //================================================================================================== -class RIResultInfoPanel : public QWidget +class RiuResultInfoPanel : public QWidget { Q_OBJECT public: - RIResultInfoPanel(QDockWidget* parent); + RiuResultInfoPanel(QDockWidget* parent); void setInfo(const QString& info); diff --git a/ApplicationCode/UserInterface/RIViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp similarity index 89% rename from ApplicationCode/UserInterface/RIViewer.cpp rename to ApplicationCode/UserInterface/RiuViewer.cpp index f612fc6aee..ff5a2d6657 100644 --- a/ApplicationCode/UserInterface/RIViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -16,19 +16,19 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RIStdInclude.h" +#include "RiaStdInclude.h" -#include "RIViewer.h" -#include "RIApplication.h" -#include "RIMainWindow.h" +#include "RiuViewer.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" #include "cvfqtOpenGLContext.h" #include "cvfqtPerformanceInfoHud.h" #include "cvfCamera.h" #include "cvfRendering.h" #include "cvfDrawableGeo.h" -#include "RICursors.h" -#include "RigReservoir.h" +#include "RiuCursors.h" +#include "RigCaseData.h" #include "cafUtils.h" #include "cafFrameAnimationControl.h" @@ -44,7 +44,7 @@ const double RI_MIN_NEARPLANE_DISTANCE = 0.1; //================================================================================================== /// -/// \class RIViewer +/// \class RiuViewer /// \ingroup ResInsight /// /// @@ -54,7 +54,7 @@ const double RI_MIN_NEARPLANE_DISTANCE = 0.1; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) +RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) : caf::Viewer(format, parent) { cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD); @@ -62,11 +62,12 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) axisCross->setAxisLabels("E", "N", "Z"); m_mainRendering->addOverlayItem(axisCross, cvf::OverlayItem::BOTTOM_LEFT, cvf::OverlayItem::VERTICAL); - setReleaseOGLResourcesEachFrame(true); + this->enableOverlyPainting(true); + this->setReleaseOGLResourcesEachFrame(true); QColor c; QPalette p = QApplication::palette(); - QColor frameAndTextColor(255, 255, 255, 200); + QColor frameAndTextColor(255, 255, 255, 255); p.setColor(QPalette::Window, QColor(144, 173, 208, 180)); p.setColor(QPalette::WindowText, frameAndTextColor); @@ -112,7 +113,7 @@ RIViewer::RIViewer(const QGLFormat& format, QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RIViewer::~RIViewer() +RiuViewer::~RiuViewer() { m_reservoirView->showWindow = false; m_reservoirView->cameraPosition = m_mainCamera->viewMatrix(); @@ -127,7 +128,7 @@ RIViewer::~RIViewer() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) +void RiuViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) { m_mainRendering->removeOverlayItem(m_legend1.p()); @@ -140,7 +141,7 @@ void RIViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) +void RiuViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) { m_mainRendering->removeOverlayItem(m_legend2.p()); @@ -152,7 +153,7 @@ void RIViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::updateLegends() +void RiuViewer::updateLegends() { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -174,7 +175,7 @@ void RIViewer::updateLegends() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setDefaultView() +void RiuViewer::setDefaultView() { cvf::BoundingBox bb; @@ -210,7 +211,7 @@ void RIViewer::setDefaultView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::mouseReleaseEvent(QMouseEvent* event) +void RiuViewer::mouseReleaseEvent(QMouseEvent* event) { m_mouseState.updateFromMouseEvent(event); @@ -218,7 +219,7 @@ void RIViewer::mouseReleaseEvent(QMouseEvent* event) // Get the currently set button press action // We get it here since left click performs it, while we let a clean right click cancel it - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); // Picking if (event->button() == Qt::LeftButton) @@ -232,7 +233,7 @@ void RIViewer::mouseReleaseEvent(QMouseEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::keyPressEvent(QKeyEvent* event) +void RiuViewer::keyPressEvent(QKeyEvent* event) { // Trap escape key so we can get out of direct button press actions if (event->key() == Qt::Key_Escape) @@ -245,11 +246,11 @@ void RIViewer::keyPressEvent(QKeyEvent* event) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::handlePickAction(int winPosX, int winPosY) +void RiuViewer::handlePickAction(int winPosX, int winPosY) { - RIApplication* app = RIApplication::instance(); + RiaApplication* app = RiaApplication::instance(); - RIMainWindow* mainWnd = RIMainWindow::instance(); + RiuMainWindow* mainWnd = RiuMainWindow::instance(); if (!mainWnd) return; QString pickInfo = "No hits"; @@ -309,7 +310,7 @@ void RIViewer::handlePickAction(int winPosX, int winPosY) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::slotEndAnimation() +void RiuViewer::slotEndAnimation() { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -327,7 +328,7 @@ void RIViewer::slotEndAnimation() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::slotSetCurrentFrame(int frameIndex) +void RiuViewer::slotSetCurrentFrame(int frameIndex) { cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); CVF_ASSERT(firstRendering); @@ -342,7 +343,7 @@ void RIViewer::slotSetCurrentFrame(int frameIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3d RIViewer::pointOfInterest() +cvf::Vec3d RiuViewer::pointOfInterest() { return m_navigationPolicy->pointOfInterest(); } @@ -350,7 +351,7 @@ cvf::Vec3d RIViewer::pointOfInterest() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setPointOfInterest(cvf::Vec3d poi) +void RiuViewer::setPointOfInterest(cvf::Vec3d poi) { m_navigationPolicy->setPointOfInterest(poi); } @@ -358,7 +359,7 @@ void RIViewer::setPointOfInterest(cvf::Vec3d poi) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setOwnerReservoirView(RimReservoirView * owner) +void RiuViewer::setOwnerReservoirView(RimReservoirView * owner) { m_reservoirView = owner; } @@ -366,7 +367,7 @@ void RIViewer::setOwnerReservoirView(RimReservoirView * owner) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setEnableMask(unsigned int mask) +void RiuViewer::setEnableMask(unsigned int mask) { m_mainRendering->setEnableMask(mask); } @@ -374,7 +375,7 @@ void RIViewer::setEnableMask(unsigned int mask) //-------------------------------------------------------------------------------------------------- /// Perform picking and return the index of the face that was hit, if a drawable geo was hit //-------------------------------------------------------------------------------------------------- -cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint) +cvf::Part* RiuViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, cvf::Vec3d* localIntersectionPoint) { CVF_ASSERT(faceHit); @@ -424,13 +425,13 @@ cvf::Part* RIViewer::pickPointAndFace(int winPosX, int winPosY, uint* faceHit, c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::paintOverlayItems(QPainter* painter) +void RiuViewer::paintOverlayItems(QPainter* painter) { // No support for overlay items using SW rendering yet. - if (!isShadersSupported()) - { - return; - } + //if (!isShadersSupported()) + //{ + // return; + //} int columnWidth = 200; int margin = 5; @@ -474,7 +475,7 @@ void RIViewer::paintOverlayItems(QPainter* painter) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setInfoText(QString text) +void RiuViewer::setInfoText(QString text) { m_InfoLabel->setText(text); } @@ -482,7 +483,7 @@ void RIViewer::setInfoText(QString text) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showInfoText(bool enable) +void RiuViewer::showInfoText(bool enable) { m_showInfoText = enable; } @@ -490,7 +491,7 @@ void RIViewer::showInfoText(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setHistogram(double min, double max, const std::vector& histogram) +void RiuViewer::setHistogram(double min, double max, const std::vector& histogram) { m_histogramWidget->setHistogramData(min, max, histogram); } @@ -498,7 +499,7 @@ void RIViewer::setHistogram(double min, double max, const std::vector& h //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::setHistogramPercentiles(double pmin, double pmax, double mean) +void RiuViewer::setHistogramPercentiles(double pmin, double pmax, double mean) { m_histogramWidget->setPercentiles(pmin, pmax); m_histogramWidget->setMean(mean); @@ -507,7 +508,7 @@ void RIViewer::setHistogramPercentiles(double pmin, double pmax, double mean) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showAnimationProgress(bool enable) +void RiuViewer::showAnimationProgress(bool enable) { m_showAnimProgress = enable; } @@ -515,7 +516,7 @@ void RIViewer::showAnimationProgress(bool enable) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RIViewer::showHistogram(bool enable) +void RiuViewer::showHistogram(bool enable) { m_showHistogram = enable; } diff --git a/ApplicationCode/UserInterface/RIViewer.h b/ApplicationCode/UserInterface/RiuViewer.h similarity index 96% rename from ApplicationCode/UserInterface/RIViewer.h rename to ApplicationCode/UserInterface/RiuViewer.h index b09ce90448..71c7b32790 100644 --- a/ApplicationCode/UserInterface/RIViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -38,16 +38,16 @@ namespace cvf //================================================================================================== // -// RIViewer +// RiuViewer // //================================================================================================== -class RIViewer : public caf::Viewer +class RiuViewer : public caf::Viewer { Q_OBJECT public: - RIViewer(const QGLFormat& format, QWidget* parent); - ~RIViewer(); + RiuViewer(const QGLFormat& format, QWidget* parent); + ~RiuViewer(); void setColorLegend1(cvf::OverlayScalarMapperLegend* legend); void setColorLegend2(cvf::OverlayScalarMapperLegend* legend); @@ -95,6 +95,7 @@ private: cvf::ref m_legend1; cvf::ref m_legend2; + caf::PdmPointer m_reservoirView; }; diff --git a/CommonCode/cvfStructGrid.cpp b/CommonCode/cvfStructGrid.cpp index 6cc7830321..a268228b9a 100644 --- a/CommonCode/cvfStructGrid.cpp +++ b/CommonCode/cvfStructGrid.cpp @@ -230,25 +230,25 @@ void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, size_t i; for (i = 0; i < cellCountI(); i += 10) // NB! Evaluate every n-th cell { - if (isCellActive(i, j, k)) + if (isCellValid(i, j, k)) { size_t cellIndex = cellIndexFromIJK(i, j, k); cellCornerVertices(cellIndex, cornerVerts); iSize += (cornerVerts[faceConnPosI[0]] - cornerVerts[faceConnNegI[0]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); + iSize += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); iSize += (cornerVerts[faceConnPosI[2]] - cornerVerts[faceConnNegI[2]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); + iSize += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); jSize += (cornerVerts[faceConnPosJ[0]] - cornerVerts[faceConnNegJ[0]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); + jSize += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); jSize += (cornerVerts[faceConnPosJ[2]] - cornerVerts[faceConnNegJ[2]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); + jSize += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); kSize += (cornerVerts[faceConnPosK[0]] - cornerVerts[faceConnNegK[0]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); + kSize += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); kSize += (cornerVerts[faceConnPosK[2]] - cornerVerts[faceConnNegK[2]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); + kSize += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); cellCount++; } diff --git a/CommonCode/cvfStructGrid.h b/CommonCode/cvfStructGrid.h index a08e67e2f1..4353192b74 100644 --- a/CommonCode/cvfStructGrid.h +++ b/CommonCode/cvfStructGrid.h @@ -57,7 +57,6 @@ public: size_t cellCountK() const; virtual bool isCellValid(size_t i, size_t j, size_t k) const = 0; - virtual bool isCellActive(size_t i, size_t j, size_t k) const = 0; virtual cvf::Vec3d minCoordinate() const = 0; virtual cvf::Vec3d maxCoordinate() const = 0; diff --git a/CommonCode/cvfStructGridScalarDataAccess.h b/CommonCode/cvfStructGridScalarDataAccess.h index 226a821357..cbdac5ee4e 100644 --- a/CommonCode/cvfStructGridScalarDataAccess.h +++ b/CommonCode/cvfStructGridScalarDataAccess.h @@ -30,16 +30,8 @@ namespace cvf { class StructGridScalarDataAccess : public Object { public: - virtual double cellScalar(size_t i, size_t j, size_t k) const = 0; - virtual double cellScalar(size_t cellIndex) const = 0; - virtual void cellCornerScalars(size_t i, size_t j, size_t k, double scalars[8]) const = 0; - - // Trenger vi denne? Kan erstattes av cellCornerScalars for kuttplan - virtual double gridPointScalar(size_t i, size_t j, size_t k) const = 0; - virtual bool pointScalar(const cvf::Vec3d& p, double* scalarValue) const = 0; - - // Vector results - virtual const cvf::Vec3d* cellVector(size_t i, size_t j, size_t k) const = 0; + virtual double cellScalar(size_t cellIndex) const = 0; + virtual void setCellScalar(size_t cellIndex, double value) = 0; }; diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 29995e5fee..2570559524 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(CMAKE_MAJOR_VERSION 0) set(CMAKE_MINOR_VERSION 9) -set(CMAKE_PATCH_VERSION 2) +set(CMAKE_PATCH_VERSION 3) set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}) diff --git a/VisualizationModules/LibCore/CMakeLists.txt b/VisualizationModules/LibCore/CMakeLists.txt index 6acce2eec9..f3c0ab4c6e 100644 --- a/VisualizationModules/LibCore/CMakeLists.txt +++ b/VisualizationModules/LibCore/CMakeLists.txt @@ -14,6 +14,7 @@ cvfAssert.h cvfBase.h cvfBase64.h cvfCharArray.h +cvfCodeLocation.h cvfCollection.h cvfCollection.inl cvfColor3.h @@ -24,6 +25,11 @@ cvfFlags.h cvfFlags.inl cvfFunctorRange.h cvfLibCore.h +cvfLogDestination.h +cvfLogDestinationConsole.h +cvfLogDestinationFile.h +cvfLogEvent.h +cvfLogManager.h cvfLogger.h cvfMath.h cvfMath.inl @@ -31,6 +37,7 @@ cvfMatrix3.h cvfMatrix3.inl cvfMatrix4.h cvfMatrix4.inl +cvfMutex.h cvfObject.h cvfObject.inl cvfPlane.h @@ -60,11 +67,17 @@ set(CEE_SOURCE_FILES cvfAssert.cpp cvfBase64.cpp cvfCharArray.cpp +cvfCodeLocation.cpp cvfColor3.cpp cvfColor4.cpp cvfDebugTimer.cpp +cvfLogDestinationConsole.cpp +cvfLogDestinationFile.cpp +cvfLogEvent.cpp +cvfLogManager.cpp cvfLogger.cpp cvfMath.cpp +cvfMutex.cpp cvfObject.cpp cvfPlane.cpp cvfPropertySet.cpp diff --git a/VisualizationModules/LibCore/cvfCodeLocation.cpp b/VisualizationModules/LibCore/cvfCodeLocation.cpp new file mode 100644 index 0000000000..4716136be2 --- /dev/null +++ b/VisualizationModules/LibCore/cvfCodeLocation.cpp @@ -0,0 +1,163 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfCodeLocation.h" + +#include +#include + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::CodeLocation +/// \ingroup Core +/// +/// Represents a source code location. +/// +/// Typically used with logging, asserts etc. Typically initialized using built-in compiler macros +/// such as __FILE__ and __LINE__. +/// +/// Note that the strings parameters for file name and function must be a static strings with a +/// lifetime that's longer than the lifetime of the CodeLocation object +/// +//================================================================================================== + +static const char* const EMPTY_STRING = ""; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation() +: m_fileName(EMPTY_STRING), + m_functionName(EMPTY_STRING), + m_lineNumber(-1) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation(const char* fileName, const char* functionName, int lineNumber) +: m_fileName(fileName), + m_functionName(functionName), + m_lineNumber(lineNumber) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CodeLocation::CodeLocation(const CodeLocation& other) +: m_fileName(other.m_fileName), + m_functionName(other.m_functionName), + m_lineNumber(other.m_lineNumber) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const CodeLocation& CodeLocation::operator=(CodeLocation rhs) +{ + // Copy-and-swap (copy already done since parameter is passed by value) + rhs.swap(*this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::fileName() const +{ + return m_fileName ? m_fileName : EMPTY_STRING; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::shortFileName() const +{ + if (m_fileName) + { + const char* ptrToLastSlash = strrchr(m_fileName, '/'); + +#ifdef WIN32 + const char* ptrToLastBwdSlash = strrchr(m_fileName, '\\'); + if (ptrToLastBwdSlash > ptrToLastSlash) + { + ptrToLastSlash = ptrToLastBwdSlash; + } +#endif + + if (ptrToLastSlash) + { + return ptrToLastSlash + 1; + } + else + { + return m_fileName; + } + } + else + { + return EMPTY_STRING; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* CodeLocation::functionName() const +{ + return m_functionName ? m_functionName : EMPTY_STRING; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int CodeLocation::lineNumber() const +{ + return m_lineNumber; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CodeLocation::swap(CodeLocation& other) +{ + std::swap(m_fileName, other.m_fileName); + std::swap(m_functionName, other.m_functionName); + std::swap(m_lineNumber, other.m_lineNumber); +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfCodeLocation.h b/VisualizationModules/LibCore/cvfCodeLocation.h new file mode 100644 index 0000000000..c8f5722a72 --- /dev/null +++ b/VisualizationModules/LibCore/cvfCodeLocation.h @@ -0,0 +1,65 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class CodeLocation +{ +public: + CodeLocation(); + CodeLocation(const char* fileName, const char* functionName, int lineNumber); + CodeLocation(const CodeLocation& other); + + const CodeLocation& operator=(CodeLocation rhs); + + const char* fileName() const; + const char* shortFileName() const; + const char* functionName() const; + int lineNumber() const; + void swap(CodeLocation& other); + +private: + const char* m_fileName; + const char* m_functionName; + int m_lineNumber; +}; + + +#if defined(_MSC_VER) +#define CVF_CODELOC_FUNCNAME __FUNCSIG__ +#elif defined(__GNUC__) +#define CVF_CODELOC_FUNCNAME __PRETTY_FUNCTION__ +#else +#define CVF_CODELOC_FUNCNAME "" +#endif + +#define CVF_CODE_LOCATION ::cvf::CodeLocation(__FILE__, CVF_CODELOC_FUNCNAME, __LINE__) + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestination.h b/VisualizationModules/LibCore/cvfLogDestination.h new file mode 100644 index 0000000000..9fa8e12ae0 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestination.h @@ -0,0 +1,44 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfObject.h" + +namespace cvf { + +class LogEvent; + + +//================================================================================================== +// +// Interface for log destinations +// +//================================================================================================== +class LogDestination : public Object +{ +public: + virtual void log(const LogEvent& logEvent) = 0; +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp b/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp new file mode 100644 index 0000000000..3ec37d5d57 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationConsole.cpp @@ -0,0 +1,141 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfLogDestinationConsole.h" +#include "cvfLogEvent.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#else +#include +#include +#endif + +namespace cvf { + + + +//================================================================================================== +/// +/// \class cvf::LogDestinationConsole +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::log(const LogEvent& logEvent) +{ + String str; + bool addLocationInfo = false; + + Logger::Level logEventLevel = logEvent.level(); + if (logEventLevel == Logger::LL_ERROR) + { + str = "ERROR: " + logEvent.message(); + addLocationInfo = true; + } + else if (logEventLevel == Logger::LL_WARNING) + { + str = "warn: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_INFO) + { + str = "info: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_DEBUG) + { + str = "debug: " + logEvent.message(); + } + + if (addLocationInfo) + { + str += "\n"; + str += String(" -func: %1\n").arg(logEvent.location().functionName()); + str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber()); + } + + CharArray charArrMsg = str.toAscii(); + const char* szMsg = charArrMsg.ptr(); + + { + Mutex::ScopedLock lock(m_mutex); + +#ifdef WIN32 + writeToWindowsConsole(szMsg, true); +#else + writeToStderr(szMsg, true); +#endif + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::writeToWindowsConsole(const char* theString, bool addNewLine) +{ +#ifdef WIN32 + CVF_ASSERT(theString); + + AllocConsole(); + + HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); + if (hStdOutputHandle && theString) + { + DWORD stringLength = static_cast(System::strlen(theString)); + + unsigned long iDum = 0; + WriteConsoleA(hStdOutputHandle, theString, stringLength, &iDum, NULL); + if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL); + } +#else + CVF_UNUSED(theString); + CVF_UNUSED(addNewLine); +#endif +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationConsole::writeToStderr(const char* theString, bool addNewLine) +{ + CVF_ASSERT(theString); + + if (theString) + { + fprintf(stderr, "%s", theString); + if (addNewLine) + { + fprintf(stderr, "\n"); + } + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogDestinationConsole.h b/VisualizationModules/LibCore/cvfLogDestinationConsole.h new file mode 100644 index 0000000000..87f3bdd00a --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationConsole.h @@ -0,0 +1,49 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfLogDestination.h" +#include "cvfMutex.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogDestinationConsole : public LogDestination +{ +public: + virtual void log(const LogEvent& logEvent); + +private: + static void writeToWindowsConsole(const char* theString, bool addNewLine); + static void writeToStderr(const char* theString, bool addNewLine); + +private: + Mutex m_mutex; +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogDestinationFile.cpp b/VisualizationModules/LibCore/cvfLogDestinationFile.cpp new file mode 100644 index 0000000000..67c65a1bcd --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationFile.cpp @@ -0,0 +1,169 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfLogDestinationFile.h" +#include "cvfLogEvent.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#else +#include +#include +#endif + +namespace cvf { + +class FileWrapper +{ +public: + FileWrapper(const String& fileName) + : m_fileName(fileName), + m_filePtr(NULL) + { + } + + ~FileWrapper() + { + if (m_filePtr) + { + fclose(m_filePtr); + } + } + + bool open(const String& mode) + { + CVF_ASSERT(m_filePtr == NULL); + +#ifdef WIN32 + if (_wfopen_s(&m_filePtr, m_fileName.c_str(), mode.c_str()) != 0) + { + m_filePtr = NULL; + } +#else + m_filePtr = ::fopen(m_fileName.toUtf8().ptr(), mode.toUtf8().ptr()); +#endif + + return m_filePtr != NULL; + } + + FILE* filePtr() + { + return m_filePtr; + } + +private: + String m_fileName; + FILE* m_filePtr; +}; + + +//================================================================================================== +/// +/// \class cvf::LogDestinationFile +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationFile::log(const LogEvent& logEvent) +{ + String str; + bool addLocationInfo = false; + + Logger::Level logEventLevel = logEvent.level(); + if (logEventLevel == Logger::LL_ERROR) + { + str = "ERROR: " + logEvent.message(); + addLocationInfo = true; + } + else if (logEventLevel == Logger::LL_WARNING) + { + str = "warn: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_INFO) + { + str = "info: " + logEvent.message(); + } + else if (logEventLevel == Logger::LL_DEBUG) + { + str = "debug: " + logEvent.message(); + } + + if (addLocationInfo) + { + str += "\n"; + str += String(" -func: %1\n").arg(logEvent.location().functionName()); + str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber()); + } + + CharArray charArrMsg = str.toAscii(); + const char* szMsg = charArrMsg.ptr(); + + Mutex::ScopedLock lock(m_mutex); + writeToFile(szMsg, true); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogDestinationFile::writeToFile(const char* theString, bool addNewLine) +{ + FileWrapper file(m_fileName); + if (m_firstTimeOpen) + { + if (!file.open("wt")) + { + return; + } + + m_firstTimeOpen = false; + } + else + { + if (!file.open("at")) + { + return; + } + } + + if (file.filePtr() && theString) + { + if (addNewLine) + { + fprintf(file.filePtr(), "%s\n", theString); + } + else + { + fprintf(file.filePtr(), "%s", theString); + } + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogDestinationFile.h b/VisualizationModules/LibCore/cvfLogDestinationFile.h new file mode 100644 index 0000000000..a01ddc344b --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogDestinationFile.h @@ -0,0 +1,53 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfLogDestination.h" +#include "cvfString.h" +#include "cvfMutex.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogDestinationFile : public LogDestination +{ +public: + LogDestinationFile(const String& fileName); + + virtual void log(const LogEvent& logEvent); + +private: + void writeToFile(const char* theString, bool addNewLine); + +private: + String m_fileName; + bool m_firstTimeOpen; // Initialized to true, Will be set to false after first write operation + Mutex m_mutex; +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogEvent.cpp b/VisualizationModules/LibCore/cvfLogEvent.cpp new file mode 100644 index 0000000000..7d08ffe386 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogEvent.cpp @@ -0,0 +1,128 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfLogEvent.h" + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::LogEvent +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent() +: m_level(Logger::LL_ERROR) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation) +: m_source(source), + m_message(message), + m_level(level), + m_codeLocation(codeLocation) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogEvent::LogEvent(const LogEvent& other) +: m_source(other.m_source), + m_message(other.m_message), + m_level(other.m_level), + m_codeLocation(other.m_codeLocation) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const LogEvent& LogEvent::operator=(LogEvent rhs) +{ + // Copy-and-swap (copy already done since parameter is passed by value) + rhs.swap(*this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const String& LogEvent::source() const +{ + return m_source; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger::Level LogEvent::level() const +{ + return m_level; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const String& LogEvent::message() const +{ + return m_message; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const CodeLocation& LogEvent::location() const +{ + return m_codeLocation; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogEvent::swap(LogEvent& other) +{ + m_source.swap(other.m_source); + m_message.swap(other.m_message); + std::swap(m_level, other.m_level); + m_codeLocation.swap(other.m_codeLocation); +} + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogEvent.h b/VisualizationModules/LibCore/cvfLogEvent.h new file mode 100644 index 0000000000..25c5c6592e --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogEvent.h @@ -0,0 +1,62 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfObject.h" +#include "cvfString.h" +#include "cvfLogger.h" + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogEvent +{ +public: + LogEvent(); + LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation); + LogEvent(const LogEvent& other); + + const LogEvent& operator=(LogEvent rhs); + + const String& source() const; + Logger::Level level() const; + const String& message() const; + const CodeLocation& location() const; + +private: + void swap(LogEvent& other); + +private: + String m_source; + String m_message; + Logger::Level m_level; + CodeLocation m_codeLocation; +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogManager.cpp b/VisualizationModules/LibCore/cvfLogManager.cpp new file mode 100644 index 0000000000..1facf09548 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogManager.cpp @@ -0,0 +1,236 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfLogManager.h" +#include "cvfLogger.h" +#include "cvfLogDestinationConsole.h" + +namespace cvf { + + + +//================================================================================================== +/// +/// \class cvf::LogManager +/// \ingroup Core +/// +/// +/// +//================================================================================================== + +cvf::ref LogManager::sm_logManagerInstance; +Mutex LogManager::sm_instanceMutex; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager::LogManager() +{ + // Create the root logger + ref rootLogger = new Logger("", Logger::LL_WARNING, new LogDestinationConsole); + m_loggerMap[""] = rootLogger; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager::~LogManager() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LogManager* LogManager::instance() +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + if (sm_logManagerInstance.isNull()) + { + sm_logManagerInstance = new LogManager; + } + + return sm_logManagerInstance.p(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setInstance(LogManager* logManagerInstance) +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + sm_logManagerInstance = logManagerInstance; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::shutdownInstance() +{ + Mutex::ScopedLock mutexLock(sm_instanceMutex); + + sm_logManagerInstance = NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// Returns logger with the specified name +/// +/// Will create the logger if it doesn't already exist. In this case, the newly created logger will +/// be initialized with the same logging level and appender as its parent. +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::logger(const String& loggerName) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + ref theLogger = find(loggerName); + if (theLogger.isNull()) + { + // Must create a new logger + // Try and find parent (optionally we'll use the root logger) and use its settings to initialize level and appender + String parentLoggerName = LogManager::nameOfParentLogger(loggerName); + ref parentLogger = find(parentLoggerName); + if (parentLogger.isNull()) + { + parentLogger = rootLogger(); + } + + CVF_ASSERT(parentLogger.notNull()); + + theLogger = new Logger(loggerName, parentLogger->level(), parentLogger->destination()); + m_loggerMap[loggerName] = theLogger; + } + + return theLogger.p(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::rootLogger() +{ + return logger(String()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setLevelRecursive(const String& baseLoggerName, int logLevel) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + const size_t baseNameLength = baseLoggerName.size(); + const bool baseNameIsRoot = (baseNameLength == 0); + + for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it) + { + Logger* logger = it->second.p(); + if (baseNameIsRoot) + { + logger->setLevel(logLevel); + } + else + { + const String& loggerName = logger->name(); + if (loggerName.startsWith(baseLoggerName) && + ((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) ) + { + logger->setLevel(logLevel); + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LogManager::setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination) +{ + Mutex::ScopedLock mutexLock(m_mutex); + + const size_t baseNameLength = baseLoggerName.size(); + const bool baseNameIsRoot = (baseNameLength == 0); + + for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it) + { + Logger* logger = it->second.p(); + if (baseNameIsRoot) + { + logger->setDestination(logDestination); + } + else + { + const String& loggerName = logger->name(); + if (loggerName.startsWith(baseLoggerName) && + ((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) ) + { + logger->setDestination(logDestination); + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Logger* LogManager::find(const String& loggerName) +{ + LoggerMap_T::iterator it = m_loggerMap.find(loggerName); + if (it != m_loggerMap.end()) + { + return it->second.p(); + } + else + { + return NULL; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// Determine name of the parent logger of \a childLoggerName +//-------------------------------------------------------------------------------------------------- +String LogManager::nameOfParentLogger(const String& childLoggerName) +{ + std::wstring childName = childLoggerName.toStdWString(); + std::wstring::size_type pos = childName.rfind('.'); + if (pos != std::wstring::npos) + { + std::wstring parentName = childName.substr(0, pos); + return parentName; + } + else + { + return String(); + } +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfLogManager.h b/VisualizationModules/LibCore/cvfLogManager.h new file mode 100644 index 0000000000..b3dde9e597 --- /dev/null +++ b/VisualizationModules/LibCore/cvfLogManager.h @@ -0,0 +1,74 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfObject.h" +#include "cvfString.h" +#include "cvfMutex.h" + +#include + +namespace cvf { + +class Logger; +class LogDestination; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class LogManager : public Object +{ +public: + LogManager(); + ~LogManager(); + + static LogManager* instance(); + static void setInstance(LogManager* logManagerInstance); + static void shutdownInstance(); + + Logger* logger(const String& loggerName); + Logger* rootLogger(); + + void setLevelRecursive(const String& baseLoggerName, int logLevel); + void setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination); + +private: + Logger* find(const String& loggerName); + static String nameOfParentLogger(const String& childLoggerName); + +private: + typedef std::map > LoggerMap_T; + LoggerMap_T m_loggerMap; + Mutex m_mutex; + static cvf::ref sm_logManagerInstance; + static Mutex sm_instanceMutex; + + CVF_DISABLE_COPY_AND_ASSIGN(LogManager); +}; + + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfLogger.cpp b/VisualizationModules/LibCore/cvfLogger.cpp index ad5ca091c3..d44feb8d65 100644 --- a/VisualizationModules/LibCore/cvfLogger.cpp +++ b/VisualizationModules/LibCore/cvfLogger.cpp @@ -19,7 +19,8 @@ #include "cvfBase.h" #include "cvfLogger.h" -#include "cvfTrace.h" +#include "cvfLogEvent.h" +#include "cvfLogDestination.h" namespace cvf { @@ -31,17 +32,20 @@ namespace cvf { /// \ingroup Core /// /// Logger class -/// -/// Currently, output is written using Trace, and special formatting of the string makes it possible -/// to navigate to source code using F4 in Visual Studio. See http://msdn.microsoft.com/en-us/library/yxkt8b26.aspx /// +/// Note that in itself, the Logger is not thread safe. This means that logger configuration, such +/// as setting the logging level and specifying the log destination, must be done in a single +/// threaded environment. +/// //================================================================================================== //-------------------------------------------------------------------------------------------------- /// Constructor //-------------------------------------------------------------------------------------------------- -Logger::Logger() -: m_debugLogging(false) +Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination) +: m_name(loggerName), + m_logLevel(logLevel), + m_destination(logDestination) { } @@ -51,62 +55,145 @@ Logger::Logger() //-------------------------------------------------------------------------------------------------- Logger::~Logger() { - } //-------------------------------------------------------------------------------------------------- -/// Use file and line to create a specially formatted string for Visual Studio. /// -/// \param message The actual error message -/// \param fileName Use system macro __FILE__ for source code file name -/// \param line Use system macro __LINE__ for source code line number +//-------------------------------------------------------------------------------------------------- +const String& Logger::name() const +{ + return m_name; +} + + +//-------------------------------------------------------------------------------------------------- +/// Set the logging level of this logger /// -/// __FILE__ and __LINE__ are used to create the variables used to navigate to the line in the -/// source code file the error message was logged at. +/// Set a level of 0 to disable all logging for this logger. //-------------------------------------------------------------------------------------------------- -void Logger::error(const String& message, const char* fileName, int lineNumber) +void Logger::setLevel(int logLevel) { - String tmp; - tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message; - - Trace::show(tmp); + m_logLevel = logLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Logger::enableDebug(bool enableDebugLogging) +int Logger::level() const { - m_debugLogging = enableDebugLogging; + return m_logLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool Logger::isDebugEnabled() const +LogDestination* Logger::destination() { - return m_debugLogging; + return m_destination.p(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Logger::debug(const String& message, const char* /*fileName*/, int /*lineNumber*/) +void Logger::setDestination(LogDestination* logDestination) { - if (m_debugLogging) + m_destination = logDestination; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::error(const String& message) +{ + error(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::error(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_ERROR && m_destination.notNull()) { - // For now, don't report file and line - String tmp; - tmp = "debug: " + message; - - Trace::show(tmp); + log(message, LL_ERROR, location); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::warning(const String& message) +{ + warning(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::warning(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_WARNING && m_destination.notNull()) + { + log(message, LL_WARNING, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::info(const String& message) +{ + info(message, CodeLocation()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::info(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_INFO && m_destination.notNull()) + { + log(message, LL_INFO, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::debug(const String& message, const CodeLocation& location) +{ + if (m_logLevel >= LL_DEBUG && m_destination.notNull()) + { + log(message, LL_DEBUG, location); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Logger::log(const String& message, Logger::Level messageLevel, const CodeLocation& location) +{ + if (m_logLevel >= messageLevel && m_destination.notNull()) + { + m_destination->log(LogEvent(m_name, message, messageLevel, location)); + } +} + + + + + } // namespace cvf diff --git a/VisualizationModules/LibCore/cvfLogger.h b/VisualizationModules/LibCore/cvfLogger.h index 8c29a9c8eb..d48e4363a6 100644 --- a/VisualizationModules/LibCore/cvfLogger.h +++ b/VisualizationModules/LibCore/cvfLogger.h @@ -21,9 +21,14 @@ #include "cvfObject.h" #include "cvfString.h" +#include "cvfCodeLocation.h" namespace cvf { - + +class LogEvent; +class LogDestination; + + //================================================================================================== // @@ -33,20 +38,57 @@ namespace cvf { class Logger : public Object { public: - Logger(); + enum Level + { + LL_ERROR = 1, + LL_WARNING, + LL_INFO, + LL_DEBUG + }; + +public: + Logger(const String& loggerName, int logLevel, LogDestination* logDestination); ~Logger(); - void error(const String& message, const char* fileName, int lineNumber); + const String& name() const; + int level() const; + void setLevel(int logLevel); + LogDestination* destination(); + void setDestination(LogDestination* logDestination); - void enableDebug(bool enableDebugLogging); - bool isDebugEnabled() const; - void debug(const String& message, const char* fileName, int lineNumber); + void error(const String& message); + void error(const String& message, const CodeLocation& location); + void warning(const String& message); + void warning(const String& message, const CodeLocation& location); + void info(const String& message); + void info(const String& message, const CodeLocation& location); + void debug(const String& message, const CodeLocation& location); + + bool isErrorEnabled() const { return m_logLevel >= LL_ERROR; } + bool isWarningEnabled() const { return m_logLevel >= LL_WARNING; } + bool isInfoEnabled() const { return m_logLevel >= LL_INFO; } + bool isDebugEnabled() const { return m_logLevel >= LL_DEBUG; } private: - bool m_debugLogging; // Whether debug messages get logged or not + void log(const String& message, Logger::Level messageLevel, const CodeLocation& location); + +private: + String m_name; // Logger name + int m_logLevel; // Logging level, all messages with a level less than or equal to this level will be logged + ref m_destination; + + CVF_DISABLE_COPY_AND_ASSIGN(Logger); }; +// Helper macros for writing log messages to a logger +#define CVF_LOG_ERROR(theLogger, theMessage) if ((theLogger)->isErrorEnabled()) { (theLogger)->error((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_WARNING(theLogger, theMessage) if ((theLogger)->isWarningEnabled()) { (theLogger)->warning((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_INFO(theLogger, theMessage) if ((theLogger)->isInfoEnabled()) { (theLogger)->info((theMessage), CVF_CODE_LOCATION); } +#define CVF_LOG_DEBUG(theLogger, theMessage) if ((theLogger)->isDebugEnabled()) { (theLogger)->debug((theMessage), CVF_CODE_LOCATION); } + + + } // cvf diff --git a/VisualizationModules/LibCore/cvfMutex.cpp b/VisualizationModules/LibCore/cvfMutex.cpp new file mode 100644 index 0000000000..532005c7a1 --- /dev/null +++ b/VisualizationModules/LibCore/cvfMutex.cpp @@ -0,0 +1,202 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfMutex.h" + +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4668) +#include +#pragma warning (pop) +#endif + +#ifdef CVF_LINUX +#include +#endif + +namespace cvf { + + +//================================================================================================== +// +// Win32 implementation using critical section +// +//================================================================================================== +#ifdef WIN32 +class MutexImpl +{ +public: + MutexImpl() + { + ::InitializeCriticalSection(&m_critSection); + } + + ~MutexImpl() + { + ::DeleteCriticalSection(&m_critSection); + } + + void lock() + { + ::EnterCriticalSection(&m_critSection); + } + + void unlock() + { + ::LeaveCriticalSection(&m_critSection); + } + +private: + CRITICAL_SECTION m_critSection; +}; +#endif + + +//================================================================================================== +// +// Linux implementation using POSIX/Pthreads +// +//================================================================================================== +#ifdef CVF_LINUX +class MutexImpl +{ +public: + MutexImpl() + { + pthread_mutexattr_t mutexAttribs; + + int errCode = 0; + CVF_UNUSED(errCode); + errCode = pthread_mutexattr_init(&mutexAttribs); + CVF_ASSERT(errCode == 0); + + // Use a recursive mutex to be aligned with Win32 implementation + errCode = pthread_mutexattr_settype(&mutexAttribs, PTHREAD_MUTEX_RECURSIVE); + CVF_ASSERT(errCode == 0); + + errCode = pthread_mutex_init(&m_mutex, &mutexAttribs); + CVF_ASSERT(errCode == 0); + + // We're done with the attribs object + errCode = pthread_mutexattr_destroy(&mutexAttribs); + CVF_ASSERT(errCode == 0); + } + + ~MutexImpl() + { + int errCode = pthread_mutex_destroy(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + + void lock() + { + int errCode = pthread_mutex_lock(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + + void unlock() + { + int errCode = pthread_mutex_unlock(&m_mutex); + CVF_UNUSED(errCode); + CVF_TIGHT_ASSERT(errCode == 0); + } + +private: + pthread_mutex_t m_mutex; +}; +#endif + + + +//================================================================================================== +/// +/// \class cvf::Mutex +/// \ingroup Core +/// +/// Implements a recursive mutex where the same thread can acquire the lock multiple times. +/// +/// The mutex is implemented as an recursive mutex since on Windows platforms its implementation +/// is based critical sections. Win32 critical sections are always recursive, and therefore we also +/// make the other platform implementations recursive for consistency. +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::Mutex() +: m_pimpl(new MutexImpl) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::~Mutex() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Mutex::lock() +{ + m_pimpl->lock(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Mutex::unlock() +{ + m_pimpl->unlock(); +} + + +//================================================================================================== +/// +/// \class cvf::Mutex::ScopedLock +/// \ingroup Core +/// +/// +/// +//================================================================================================== +Mutex::ScopedLock::ScopedLock(Mutex& mutex) +: m_theMutex(mutex) +{ + m_theMutex.lock(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Mutex::ScopedLock::~ScopedLock() +{ + m_theMutex.unlock(); +} + + +} // namespace cvf + diff --git a/VisualizationModules/LibCore/cvfMutex.h b/VisualizationModules/LibCore/cvfMutex.h new file mode 100644 index 0000000000..5571a9717c --- /dev/null +++ b/VisualizationModules/LibCore/cvfMutex.h @@ -0,0 +1,60 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include + +namespace cvf { + + +//================================================================================================== +// +// +// +//================================================================================================== +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + + class ScopedLock + { + public: + ScopedLock(Mutex& mutex); + ~ScopedLock(); + + private: + Mutex& m_theMutex; + }; + +private: + std::auto_ptr m_pimpl; + + CVF_DISABLE_COPY_AND_ASSIGN(Mutex); +}; + + +} // cvf + + diff --git a/VisualizationModules/LibCore/cvfString.cpp b/VisualizationModules/LibCore/cvfString.cpp index 9e9b6754b8..b042a5daf0 100644 --- a/VisualizationModules/LibCore/cvfString.cpp +++ b/VisualizationModules/LibCore/cvfString.cpp @@ -1063,6 +1063,15 @@ size_t String::find(const String& str, size_t start) const } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool String::startsWith(const String& str) const +{ + return (find(str) == 0); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/VisualizationModules/LibCore/cvfString.h b/VisualizationModules/LibCore/cvfString.h index 7a0d45e0b0..35c820e867 100644 --- a/VisualizationModules/LibCore/cvfString.h +++ b/VisualizationModules/LibCore/cvfString.h @@ -69,6 +69,7 @@ public: std::vector split(const String& delimiters = " ") const; size_t find(const String& str, size_t start = 0) const; + bool startsWith(const String& str) const; String subString(size_t start, size_t length = npos) const; void replace(const String& before, const String& after); diff --git a/VisualizationModules/LibRender/CMakeLists.txt b/VisualizationModules/LibRender/CMakeLists.txt index f2005f4d69..d4ea84debf 100644 --- a/VisualizationModules/LibRender/CMakeLists.txt +++ b/VisualizationModules/LibRender/CMakeLists.txt @@ -20,6 +20,7 @@ include_directories(glew) set(CEE_HEADER_FILES cvfBufferObjectManaged.h cvfCamera.h +cvfCameraAnimation.h cvfDrawable.h cvfDrawableGeo.h cvfDrawableText.h @@ -98,6 +99,7 @@ cvfViewport.h set(CEE_SOURCE_FILES cvfBufferObjectManaged.cpp cvfCamera.cpp +cvfCameraAnimation.cpp cvfDrawable.cpp cvfDrawableGeo.cpp cvfDrawableVectors.cpp diff --git a/VisualizationModules/LibRender/cvfCamera.cpp b/VisualizationModules/LibRender/cvfCamera.cpp index 6ea6a8ebc7..0aea6f4b47 100644 --- a/VisualizationModules/LibRender/cvfCamera.cpp +++ b/VisualizationModules/LibRender/cvfCamera.cpp @@ -268,13 +268,23 @@ void Camera::setProjectionAsPixelExact2D() /// the view to. The relativeDistance parameter specifies the distance from the camera to the /// center of the bounding box //-------------------------------------------------------------------------------------------------- -void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double distanceScaleFactor) +void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor) +{ + // Use old view direction, but look towards model center + Vec3d eye = fitViewEyePosition(boundingBox, dir, up, coverageFactor); + + // Will update cached values + setFromLookAt(eye, boundingBox.center(), up); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Vec3d Camera::fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor) const { CVF_ASSERT(projection() == PERSPECTIVE); - // TODO! !!! !! !! - CVF_UNUSED(distanceScaleFactor); - cvf::Vec3d corners[8]; boundingBox.cornerVertices(corners); @@ -312,8 +322,8 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec distUp += (centerToCornerSide*boxEyeNorm); // Adjust for the distance scale factor - distRight /= distanceScaleFactor; - distUp /= distanceScaleFactor; + distRight /= coverageFactor; + distUp /= coverageFactor; dist = CVF_MAX(dist, distRight); dist = CVF_MAX(dist, distUp); @@ -328,8 +338,7 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec // Use old view direction, but look towards model center Vec3d eye = boundingBox.center()- dir.getNormalized()*dist; - // Will update cached values - setFromLookAt(eye, boundingBox.center(), up); + return eye; } @@ -1023,6 +1032,5 @@ void Camera::applyOpenGL() const #endif } - } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfCamera.h b/VisualizationModules/LibRender/cvfCamera.h index d00e364cf4..c247c47fe0 100644 --- a/VisualizationModules/LibRender/cvfCamera.h +++ b/VisualizationModules/LibRender/cvfCamera.h @@ -66,6 +66,8 @@ public: void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); void fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9); + Vec3d fitViewEyePosition(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9) const; + void setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01); const Mat4d& viewMatrix() const; diff --git a/VisualizationModules/LibRender/cvfCameraAnimation.cpp b/VisualizationModules/LibRender/cvfCameraAnimation.cpp new file mode 100644 index 0000000000..f18144f184 --- /dev/null +++ b/VisualizationModules/LibRender/cvfCameraAnimation.cpp @@ -0,0 +1,109 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cvfBase.h" +#include "cvfCameraAnimation.h" +#include "cvfCamera.h" +#include "cvfTimer.h" + +namespace cvf { + + +//================================================================================================== +/// +/// \class cvf::CameraAnimation +/// \ingroup Render +/// +/// Support class for creating a camera path animation from one camera configuration to another. +/// +//================================================================================================== + + +//-------------------------------------------------------------------------------------------------- +/// Configures the animation with start and end point +//-------------------------------------------------------------------------------------------------- +CameraAnimation::CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp) +: m_currentPos(currentPos), + m_currentDir(currentDir), + m_currentUp(currentUp), + m_newPos(newPos), + m_newDir(newDir), + m_newUp(newUp), + m_animDuration(0.75), + m_animDone(false) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// Returns the next position in the animation. After the duration of the animation is used up, +/// the method returns the end point and after that always returns false. +/// +/// So usage would be: +/// \code +/// cvf::Vec3d pos, dir, up; +/// while(anim.newPosition(&pos, &dir, &up)) +/// { +/// m_camera->setFromLookAt(pos, pos + dir, up); +/// repaint(); +/// } +/// \endcode +//-------------------------------------------------------------------------------------------------- +bool CameraAnimation::newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up) +{ + if (m_animDone) + { + return false; + } + + if (m_timer.isNull()) + { + m_timer = new Timer; + } + + double timeNow = m_timer->time(); + + if (timeNow > m_animDuration) + { + *pos = m_newPos; + *dir = m_newDir; + *up = m_newUp; + + m_animDone = true; + + return true; + } + + *pos = m_currentPos + (m_newPos - m_currentPos)*(timeNow/m_animDuration); + *dir = m_currentDir + (m_newDir - m_currentDir)*(timeNow/m_animDuration); + *up = m_currentUp + (m_newUp - m_currentUp )*(timeNow/m_animDuration); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// Sets the duration of the animation +//-------------------------------------------------------------------------------------------------- +void CameraAnimation::setDuration(double seconds) +{ + m_animDuration = seconds; +} + +} // namespace cvf + diff --git a/VisualizationModules/LibRender/cvfCameraAnimation.h b/VisualizationModules/LibRender/cvfCameraAnimation.h new file mode 100644 index 0000000000..70e166f8bf --- /dev/null +++ b/VisualizationModules/LibRender/cvfCameraAnimation.h @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2012 Ceetron AS +// +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cvfObject.h" +#include "cvfVector3.h" + +namespace cvf { + +class Timer; + +//================================================================================================== +// +// Camera animation class +// +//================================================================================================== +class CameraAnimation : public Object +{ +public: + CameraAnimation(const Vec3d& currentPos, const Vec3d& currentDir, const Vec3d& currentUp, const Vec3d& newPos, const Vec3d& newDir, const Vec3d& newUp); + + void setDuration(double seconds); + + bool newPosition(Vec3d* pos, Vec3d* dir, Vec3d* up); + +private: + Vec3d m_currentPos; + Vec3d m_currentDir; + Vec3d m_currentUp; + Vec3d m_newPos; + Vec3d m_newDir; + Vec3d m_newUp; + + ref m_timer; + double m_animDuration; + bool m_animDone; +}; + +} diff --git a/VisualizationModules/LibRender/cvfDrawableGeo.cpp b/VisualizationModules/LibRender/cvfDrawableGeo.cpp index 447496332e..28ee7bba9c 100644 --- a/VisualizationModules/LibRender/cvfDrawableGeo.cpp +++ b/VisualizationModules/LibRender/cvfDrawableGeo.cpp @@ -1273,8 +1273,6 @@ BoundingBox DrawableGeo::boundingBox() const //-------------------------------------------------------------------------------------------------- bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* faceHit) const { - CVF_ASSERT(intersectionPoint); - bool anyHits = false; double minDistSquared = 1.0e300; @@ -1314,19 +1312,23 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* f double distSquared = (ray.origin() - localIntersect).lengthSquared(); #pragma omp critical { - if (distSquared < minDistSquared) + if (distSquared < minDistSquared) + { + if (intersectionPoint) { - *intersectionPoint = localIntersect; - minDistSquared = distSquared; - - if (faceHit) - { - *faceHit = i + accumulatedFaceCount; - } + *intersectionPoint = localIntersect; } - anyHits = true; - } + + minDistSquared = distSquared; + + if (faceHit) + { + *faceHit = i + accumulatedFaceCount; + } + } + anyHits = true; } + } } // End omp parallel for accumulatedFaceCount += numPrimFaces; } diff --git a/VisualizationModules/LibRender/cvfDrawableText.cpp b/VisualizationModules/LibRender/cvfDrawableText.cpp index 1948122fdf..11ac32b535 100644 --- a/VisualizationModules/LibRender/cvfDrawableText.cpp +++ b/VisualizationModules/LibRender/cvfDrawableText.cpp @@ -64,7 +64,8 @@ DrawableText::DrawableText() m_borderColor(Color3::BLACK), m_drawBackground(true), m_drawBorder(true), - m_checkPosVisible(true) + m_checkPosVisible(true), + m_useDepthBuffer(false) { } @@ -158,6 +159,15 @@ void DrawableText::setCheckPosVisible(bool checkpos) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void DrawableText::setUseDepthBuffer(bool useDepthBuffer) +{ + m_useDepthBuffer = useDepthBuffer; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -323,7 +333,7 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr if (!m_checkPosVisible || labelAnchorVisible(oglContext, proj, m_positions[pos], shaderProgram == NULL)) { // Note: Need to adjust for the current viewport, as the coords returned from project are in global windows coordinates - projCoords.push_back(Vec3f(static_cast(proj.x() - matrixState.viewportPosition().x()), static_cast(proj.y() - matrixState.viewportPosition().y()), 0.0f)); + projCoords.push_back(Vec3f(static_cast(proj.x() - matrixState.viewportPosition().x()), static_cast(proj.y() - matrixState.viewportPosition().y()), static_cast(1.0 - 2.0*proj.z()))); // Map z into 1 .. -1 textsToDraw.push_back(m_texts[pos]); } } @@ -355,12 +365,13 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr drawer.setBorderColor(m_borderColor); drawer.setDrawBorder(m_drawBorder); drawer.setDrawBackground(m_drawBackground); + drawer.setUseDepthBuffer(m_useDepthBuffer); size_t i; for (i = 0; i < textsToDraw.size(); i++) { Vec3f pos = projCoords[i]; - drawer.addText(textsToDraw[i], Vec2f(pos)); + drawer.addText(textsToDraw[i], pos); } if (shaderProgram) @@ -423,4 +434,38 @@ bool DrawableText::labelAnchorVisible(OpenGLContext* oglContext, const Vec3d win } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool DrawableText::rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint) +{ + Vec3d pickCoord2d; + camera.project(ray.origin(), &pickCoord2d); + + size_t i; + for (i = 0; i < m_positions.size(); i++) + { + Vec3d proj; + camera.project(Vec3d(m_positions[i]), &proj); + + Vec3f posTextDrawer = Vec3f(static_cast(proj.x() - camera.viewport()->x()), static_cast(proj.y() - camera.viewport()->y()), static_cast(1.0 - 2.0*proj.z())); // Map z into 1 .. -1 + + if (TextDrawer::pickText(Vec3f(pickCoord2d), m_texts[i], posTextDrawer, m_font.p())) + { + if (m_useDepthBuffer) + { + *intersectionPoint = Vec3d(m_positions[i]); + } + else + { + *intersectionPoint = ray.origin(); + } + + return true; + } + } + + return false; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfDrawableText.h b/VisualizationModules/LibRender/cvfDrawableText.h index 9299ecd699..f9a6bdacfc 100644 --- a/VisualizationModules/LibRender/cvfDrawableText.h +++ b/VisualizationModules/LibRender/cvfDrawableText.h @@ -30,6 +30,7 @@ class Font; class DrawableGeo; class ShaderProgram; class BufferObjectManaged; +class Camera; //================================================================================================== @@ -55,6 +56,7 @@ public: void setDrawBackground(bool drawBackground); void setDrawBorder(bool drawBorder); void setCheckPosVisible(bool checkpos); + void setUseDepthBuffer(bool useDepthBuffer); virtual void createUploadBufferObjectsGPU(OpenGLContext* /*oglContext*/) {} virtual void releaseBufferObjectsGPU() {} @@ -69,6 +71,7 @@ public: virtual BoundingBox boundingBox() const; virtual bool rayIntersectCreateDetail(const Ray& ray, Vec3d* intersectionPoint, ref* hitDetail) const; + bool rayIntersect(const Ray& ray, const Camera& camera, Vec3d* intersectionPoint); // TO BE REMOVED! virtual void renderFixedFunction(OpenGLContext* oglContext, const MatrixState& matrixState) { renderSoftware(oglContext, matrixState); } @@ -92,6 +95,7 @@ private: bool m_drawBackground; bool m_drawBorder; bool m_checkPosVisible; + bool m_useDepthBuffer; BoundingBox m_boundingBox; // }; diff --git a/VisualizationModules/LibRender/cvfOpenGL.cpp b/VisualizationModules/LibRender/cvfOpenGL.cpp index 3d76136ca0..b021de0ae9 100644 --- a/VisualizationModules/LibRender/cvfOpenGL.cpp +++ b/VisualizationModules/LibRender/cvfOpenGL.cpp @@ -136,7 +136,7 @@ String OpenGL::mapOpenGLErrorToString(cvfGLenum errorCode) //-------------------------------------------------------------------------------------------------- /// Returns false if no error. //-------------------------------------------------------------------------------------------------- -bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line) +bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation) { // glGetError will end up in an endless loop if no context is current CVF_ASSERT(oglContext); @@ -157,7 +157,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope String errCodeStr = mapOpenGLErrorToString(err); String msg = String("Operation: ") + operation; msg += "OGL(" + errCodeStr + "): "; - logger->error(msg, fileName, line); + logger->error(msg, codeLocation); } err = glGetError(); @@ -170,7 +170,7 @@ bool OpenGL::testAndReportOpenGLError(OpenGLContext* oglContext, const char* ope //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line) +void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation) { if (OpenGL::m_enableCheckOgl) { @@ -186,7 +186,7 @@ void OpenGL::cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int { String errCodeStr = mapOpenGLErrorToString(err); String msg = "OGL(" + errCodeStr + "): "; - logger->error(msg, fileName, line); + logger->error(msg, codeLocation); } err = glGetError(); diff --git a/VisualizationModules/LibRender/cvfOpenGL.h b/VisualizationModules/LibRender/cvfOpenGL.h index a08b3dbd0f..691563dc73 100644 --- a/VisualizationModules/LibRender/cvfOpenGL.h +++ b/VisualizationModules/LibRender/cvfOpenGL.h @@ -84,6 +84,7 @@ #include "cvfOpenGLTypes.h" #include "cvfString.h" +#include "cvfCodeLocation.h" // As long as we're using GLEW we will almost always need the context and context group when doing OpenGL calls #include "cvfOpenGLContext.h" @@ -105,9 +106,9 @@ public: static void clearOpenGLError(OpenGLContext* oglContext); static String mapOpenGLErrorToString(cvfGLenum errorCode); - static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const char* fileName, int line); + static bool testAndReportOpenGLError(OpenGLContext* oglContext, const char* operation, const CodeLocation& codeLocation); - static void cvf_check_ogl(OpenGLContext* oglContext, const char* fileName, int line); + static void cvf_check_ogl(OpenGLContext* oglContext, const CodeLocation& codeLocation); static void enableCheckOgl(bool enable); static bool isCheckOglEnabled(); @@ -123,8 +124,8 @@ private: #define CVF_OGL_BUFFER_OFFSET(BYTE_OFFSET) ((char*)NULL + (BYTE_OFFSET)) // Define used to log error messages with file and line -#define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, __FILE__, __LINE__) +#define CVF_CHECK_OGL(OGL_CTX_PTR) cvf::OpenGL::cvf_check_ogl(OGL_CTX_PTR, CVF_CODE_LOCATION) #define CVF_CLEAR_OGL_ERROR(OGL_CTX_PTR) cvf::OpenGL::clearOpenGLError(OGL_CTX_PTR) -#define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, __FILE__, __LINE__) +#define CVF_TEST_AND_REPORT_OPENGL_ERROR(OGL_CTX_PTR, OPERATION) cvf::OpenGL::testAndReportOpenGLError(OGL_CTX_PTR, OPERATION, CVF_CODE_LOCATION) diff --git a/VisualizationModules/LibRender/cvfOpenGLContext.h b/VisualizationModules/LibRender/cvfOpenGLContext.h index 32f0520207..2ae21727d9 100644 --- a/VisualizationModules/LibRender/cvfOpenGLContext.h +++ b/VisualizationModules/LibRender/cvfOpenGLContext.h @@ -58,9 +58,9 @@ private: friend class OpenGLContextGroup; }; -#define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), __FILE__, __LINE__ ) +#define CVF_LOG_RENDER_ERROR(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->error((THE_MESSAGE), CVF_CODE_LOCATION) -#define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), __FILE__, __LINE__ ) +#define CVF_LOG_RENDER_DEBUG(OGL_CTX_PTR, THE_MESSAGE) OGL_CTX_PTR->group()->logger()->debug((THE_MESSAGE), CVF_CODE_LOCATION) #define CVF_SHOULD_LOG_RENDER_DEBUG(OGL_CTX_PTR) OGL_CTX_PTR->group()->logger()->isDebugEnabled() diff --git a/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp b/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp index ad6e99c802..abf299e7b2 100644 --- a/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp +++ b/VisualizationModules/LibRender/cvfOpenGLContextGroup.cpp @@ -23,7 +23,7 @@ #include "cvfOpenGLContext.h" #include "cvfOpenGLResourceManager.h" #include "cvfOpenGLCapabilities.h" -#include "cvfTrace.h" +#include "cvfLogDestinationConsole.h" #include @@ -58,7 +58,7 @@ OpenGLContextGroup::OpenGLContextGroup() m_wglewContextStruct(NULL) { m_resourceManager = new OpenGLResourceManager; - m_logger = new Logger; + m_logger = new Logger("cvf.OpenGL", Logger::LL_WARNING, new LogDestinationConsole); m_capabilities = new OpenGLCapabilities; } diff --git a/VisualizationModules/LibRender/cvfOverlayImage.cpp b/VisualizationModules/LibRender/cvfOverlayImage.cpp index 0bb7443fc8..1c42403920 100644 --- a/VisualizationModules/LibRender/cvfOverlayImage.cpp +++ b/VisualizationModules/LibRender/cvfOverlayImage.cpp @@ -40,6 +40,7 @@ #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" #endif +#include "cvfTexture2D_FF.h" namespace cvf { @@ -152,6 +153,23 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons if (software) { + // Create a POW2 texture for software rendering if needed + if (m_image.notNull() && m_pow2Image.isNull() && (!Math::isPow2(m_image->width()) || !Math::isPow2(m_image->height()))) + { + m_pow2Image = new TextureImage; + m_pow2Image->allocate(Math::roundUpPow2(m_image->width()), Math::roundUpPow2(m_image->height())); + m_pow2Image->fill(Color4ub(Color3::BLACK)); + + for (uint y = 0; y < m_image->height(); ++y) + { + for (uint x = 0; x < m_image->width(); ++x) + { + m_pow2Image->setPixel(x, y, m_image->pixel(x, y)); + } + } + } + + if (ShaderProgram::supportedOpenGL(oglContext)) { ShaderProgram::useNoProgram(oglContext); @@ -164,7 +182,34 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons RenderStateLighting_FF light(false); light.applyOpenGL(oglContext); + + if (m_textureBindings.isNull()) + { + // Use fixed function texture setup + ref texture = new Texture2D_FF(m_pow2Image.notNull() ? m_pow2Image.p() : m_image.p()); + texture->setWrapMode(Texture2D_FF::CLAMP); + texture->setMinFilter(Texture2D_FF::NEAREST); + texture->setMagFilter(Texture2D_FF::NEAREST); + texture->setupTexture(oglContext); + texture->setupTextureParams(oglContext); + + ref textureMapping = new RenderStateTextureMapping_FF(texture.p()); + textureMapping->setTextureFunction(m_blendMode == TEXTURE_ALPHA ? RenderStateTextureMapping_FF::MODULATE : RenderStateTextureMapping_FF::DECAL); + + m_textureBindings = textureMapping; + } #endif + // Adjust texture coordinates + if (m_pow2Image.notNull()) + { + float xMax = static_cast(m_image->width())/static_cast(m_pow2Image->width()); + float yMax = static_cast(m_image->height())/static_cast(m_pow2Image->height()); + textureCoords[2] = xMax; + textureCoords[4] = xMax; + textureCoords[5] = yMax; + textureCoords[7] = yMax; + } + projCam.applyOpenGL(); } else @@ -200,10 +245,23 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons m_shaderProgram->clearUniformApplyTracking(); m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState); } + + if (m_texture->textureOglId() == 0) + { + m_texture->setupTexture(oglContext); + } + + if (m_textureBindings.isNull()) + { + cvf::RenderStateTextureBindings* textureBindings = new cvf::RenderStateTextureBindings; + textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D"); + m_textureBindings = textureBindings; + } } - Vec3f min(1.0f, 1.0f, 0.0f); - Vec3f max(static_cast(size.x() - 1), static_cast(size.y() - 1), 0.0f); + float offset = 0.0f; + Vec3f min(offset, offset, 0.0f); + Vec3f max(static_cast(size.x()) + offset, static_cast(size.y()) + offset, 0.0f); // Setup the vertex array float* v1 = &vertexArray[0]; @@ -214,12 +272,6 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f; v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f; v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f; - - - if (m_texture->textureOglId() == 0) - { - m_texture->setupTexture(oglContext); - } if (m_blendMode != NO_BLENDING) { @@ -233,7 +285,7 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons if (software) { #ifndef CVF_OPENGL_ES - glColor4f(1.0f, 1.0f, 1.0f, m_alpha); + glColor4f(1.0f, 1.0f, 1.0f, m_blendMode == GLOBAL_ALPHA ? m_alpha : 1.0f); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(textureCoords[0], textureCoords[1]); glVertex3fv(v1); @@ -263,6 +315,17 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons blend.applyOpenGL(oglContext); } + RenderStateDepth resetDepth; + resetDepth.applyOpenGL(oglContext); + + if (software) + { +#ifndef CVF_OPENGL_ES + RenderStateTextureMapping_FF resetTextureMapping; + resetTextureMapping.applyOpenGL(oglContext); +#endif + } + if (!software) { glDisableVertexAttribArray(ShaderProgram::VERTEX); @@ -277,11 +340,11 @@ void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, cons void OverlayImage::setImage(TextureImage* image) { m_image = image; + m_pow2Image = NULL; m_texture = new Texture(image); - m_textureBindings = new cvf::RenderStateTextureBindings; - m_textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D"); + m_textureBindings = NULL; } diff --git a/VisualizationModules/LibRender/cvfOverlayImage.h b/VisualizationModules/LibRender/cvfOverlayImage.h index 8a68e5274f..854f491475 100644 --- a/VisualizationModules/LibRender/cvfOverlayImage.h +++ b/VisualizationModules/LibRender/cvfOverlayImage.h @@ -25,7 +25,7 @@ namespace cvf { class TextureImage; class Sampler; -class RenderStateTextureBindings; +class RenderState; class Texture; class ShaderProgram; @@ -68,8 +68,9 @@ private: private: Vec2ui m_size; ref m_image; + ref m_pow2Image; ref m_sampler; - ref m_textureBindings; + ref m_textureBindings; ref m_texture; ref m_shaderProgram; diff --git a/VisualizationModules/LibRender/cvfOverlayItem.h b/VisualizationModules/LibRender/cvfOverlayItem.h index d196c29e16..a419c93015 100644 --- a/VisualizationModules/LibRender/cvfOverlayItem.h +++ b/VisualizationModules/LibRender/cvfOverlayItem.h @@ -43,7 +43,8 @@ public: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, - BOTTOM_RIGHT + BOTTOM_RIGHT, + UNMANAGED }; enum LayoutDirection @@ -56,10 +57,17 @@ public: virtual Vec2ui sizeHint() = 0; // In Pixels virtual Vec2ui maximumSize() = 0; // In Pixels virtual Vec2ui minimumSize() = 0; // In Pixels + + cvf::Vec2i unmanagedPosition() const { return m_unmanagedPosition; } + void setUnmanagedPosition(cvf::Vec2i val) { m_unmanagedPosition = val; } virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) = 0; virtual bool pick(int oglXCoord, int oglYCoord, const Vec2i& position, const Vec2ui& size); + +private: + Vec2i m_unmanagedPosition; + }; } diff --git a/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp b/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp index 8a0c6d9d2a..a28fb8bf08 100644 --- a/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp +++ b/VisualizationModules/LibRender/cvfOverlayNavigationCube.cpp @@ -40,9 +40,15 @@ #include "cvfPrimitiveSetIndexedUShort.h" #include "cvfShaderProgramGenerator.h" #include "cvfShaderSourceProvider.h" +#include "cvfRay.h" +#include "cvfRenderStateDepth.h" +#include "cvfTexture.h" +#include "cvfSampler.h" +#include "cvfRenderStateTextureBindings.h" #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" +#include "cvfTexture2D_FF.h" #endif @@ -63,12 +69,22 @@ namespace cvf { //-------------------------------------------------------------------------------------------------- OverlayNavigationCube::OverlayNavigationCube(Camera* camera, Font* font) : m_camera(camera), - m_xLabel("ax"), - m_yLabel("by"), - m_zLabel("cz"), - m_textColor(Color3::BLACK), m_font(font), - m_size(120, 120) + m_xLabel("x"), + m_yLabel("y"), + m_zLabel("z"), + m_textColor(Color3::BLACK), + m_size(120, 120), + m_homeViewDirection(-Vec3f::Z_AXIS), + m_homeUp(Vec3f::Y_AXIS), + m_hightlightItem(NCI_NONE), + m_upVector(Vec3d::Z_AXIS), + m_frontVector(-Vec3d::Y_AXIS), + m_xFaceColor(Color3::RED), + m_yFaceColor(Color3::GREEN), + m_zFaceColor(Color3::BLUE), + m_itemHighlightColor(Color3::GRAY), + m_2dItemsColor(Color3::WHITE) { } @@ -78,14 +94,13 @@ OverlayNavigationCube::OverlayNavigationCube(Camera* camera, Font* font) //-------------------------------------------------------------------------------------------------- OverlayNavigationCube::~OverlayNavigationCube() { - // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::setAxisLabels( const String& xLabel, const String& yLabel, const String& zLabel ) +void OverlayNavigationCube::setAxisLabels(const String& xLabel, const String& yLabel, const String& zLabel) { // Clipping of axis label text is depends on m_size and // z-part of axisMatrix.setTranslation(Vec3d(0, 0, -4.4)) defined in OverlayNavigationCube::render() @@ -147,8 +162,7 @@ void OverlayNavigationCube::setSize(const Vec2ui& size) //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) { - Mat4d viewMatrix = m_camera->viewMatrix(); - render(oglContext, position, size, false, viewMatrix); + render(oglContext, position, size, false); } @@ -157,21 +171,25 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) { - Mat4d viewMatrix = m_camera->viewMatrix(); - render(oglContext, position, size, true, viewMatrix); + render(oglContext, position, size, true); } //-------------------------------------------------------------------------------------------------- /// Set up camera/viewport and render //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix) +void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software) { if (size.x() <= 0 || size.y() <= 0) { return; } + if (software && ShaderProgram::supportedOpenGL(oglContext)) + { + ShaderProgram::useNoProgram(oglContext); + } + if (m_axis.isNull()) { createAxisGeometry(software); @@ -181,22 +199,42 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit { createCubeGeos(); - // Create the shader for the cube geometry - ShaderProgramGenerator gen("CubeGeoShader", ShaderSourceProvider::instance()); - gen.configureStandardHeadlightColor(); - m_cubeGeoShader = gen.generate(); - m_cubeGeoShader->linkProgram(oglContext); + if (!software) + { + // Create the shader for the cube geometry + ShaderProgramGenerator gen("CubeGeoShader", ShaderSourceProvider::instance()); + gen.configureStandardHeadlightColor(); + m_cubeGeoShader = gen.generate(); + m_cubeGeoShader->linkProgram(oglContext); + + { + ShaderProgramGenerator gen("CubeGeoTextureShader", ShaderSourceProvider::instance()); + + gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture); + gen.addFragmentCode(cvf::ShaderSourceRepository::light_Headlight); + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + + m_cubeGeoTextureShader = gen.generate(); + + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_specularIntensity", 0.1f)); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_ambientIntensity", 0.2f)); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_emissiveColor", cvf::Vec3f(0.0f, 0.0f, 0.0f))); + m_cubeGeoTextureShader->setDefaultUniform(new cvf::UniformFloat("u_ecLightPosition", cvf::Vec3f(0.5f, 5.0f, 7.0f))); + + m_cubeGeoTextureShader->linkProgram(oglContext); + } + } } - // Position the camera far enough away to make the axis and the text fit within the viewport - Mat4d axisMatrix = viewMatrix; - axisMatrix.setTranslation(Vec3d(0, 0, -2.0)); + if (m_2dGeos.size() == 0) + { + create2dGeos(); + } // Setup camera Camera cam; - cam.setProjectionAsPerspective(40.0, 0.05, 100.0); - cam.setViewMatrix(axisMatrix); - cam.setViewport(position.x(), position.y(), size.x(), size.y()); + configureLocalCamera(&cam, position, size); // Setup viewport cam.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); @@ -204,7 +242,6 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit // Do the actual rendering - // ----------------------------------------------- MatrixState matrixState(cam); if (software) { @@ -216,8 +253,9 @@ void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2i& posit } renderCubeGeos(oglContext, software, matrixState); - renderAxisLabels(oglContext, software, matrixState); + + render2dItems(oglContext, position, size, software); } @@ -275,23 +313,25 @@ void OverlayNavigationCube::createAxisGeometry(bool software) ref vertexArray = new Vec3fArray; vertexArray->resize(3); - vertexArray->set(0, cp[0]); // X axis - vertexArray->set(1, cp[0]); // Y axis - vertexArray->set(2, cp[0]); // Z axis + vertexArray->set(0, cp[0]); // X axis + vertexArray->set(1, cp[0]); // Y axis + vertexArray->set(2, cp[0]); // Z axis // Direction & magnitude of the vectors + float arrowLength = 0.8f; + ref vectorArray = new Vec3fArray; vectorArray->resize(3); - vectorArray->set(0, Vec3f::X_AXIS); // X axis - vectorArray->set(1, Vec3f::Y_AXIS); // Y axis - vectorArray->set(2, Vec3f::Z_AXIS); // Z axis + vectorArray->set(0, arrowLength*Vec3f::X_AXIS); + vectorArray->set(1, arrowLength*Vec3f::Y_AXIS); + vectorArray->set(2, arrowLength*Vec3f::Z_AXIS); // Create the arrow glyph for the vector drawer GeometryBuilderTriangles arrowBuilder; ArrowGenerator gen; - gen.setShaftRelativeRadius(0.045f); - gen.setHeadRelativeRadius(0.12f); - gen.setHeadRelativeLength(0.2f); + gen.setShaftRelativeRadius(0.020f); + gen.setHeadRelativeRadius(0.05f); + gen.setHeadRelativeLength(0.1f); gen.setNumSlices(30); gen.generate(&arrowBuilder); @@ -310,6 +350,61 @@ void OverlayNavigationCube::createAxisGeometry(bool software) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::updateTextureBindings(OpenGLContext* oglContext, bool software) +{ + m_faceTextureBindings.clear(); + + for (size_t i = 0; i < 6; i++) + { + NavCubeFace face = static_cast(i); + std::map >::iterator it = m_faceTextures.find(face); + + if (it != m_faceTextures.end()) + { + if (software) + { +#ifndef CVF_OPENGL_ES + // Use fixed function texture setup + ref texture = new Texture2D_FF(it->second.p()); + texture->setWrapMode(Texture2D_FF::CLAMP); + texture->setMinFilter(Texture2D_FF::NEAREST); + texture->setMagFilter(Texture2D_FF::NEAREST); + texture->setupTexture(oglContext); + texture->setupTextureParams(oglContext); + + ref textureMapping = new RenderStateTextureMapping_FF(texture.p()); + textureMapping->setTextureFunction(RenderStateTextureMapping_FF::MODULATE); + + m_faceTextureBindings[face] = textureMapping; +#else + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#endif + + } + else + { + ref texture = new cvf::Texture(it->second.p()); + ref sampler = new cvf::Sampler; + texture->enableMipmapGeneration(true); + sampler->setWrapMode(Sampler::CLAMP_TO_EDGE); + sampler->setMinFilter(Sampler::LINEAR_MIPMAP_LINEAR); + sampler->setMagFilter(Sampler::NEAREST); + + ref texBind = new cvf::RenderStateTextureBindings; + texBind->addBinding(texture.p(), sampler.p(), "u_texture2D"); + + texBind->setupTextures(oglContext); + + m_faceTextureBindings[face] = texBind; + } + } + } +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -317,10 +412,312 @@ void OverlayNavigationCube::renderCubeGeos(OpenGLContext* oglContext, bool softw { CVF_UNUSED(software); - for (size_t i = 0; i < m_cubeGeos.size(); ++i) + if (m_faceTextureBindings.size() != m_faceTextures.size()) { - m_cubeGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + updateTextureBindings(oglContext, software); } + + if (software) + { +#ifndef CVF_OPENGL_ES + RenderStateMaterial_FF mat; + mat.enableColorMaterial(true); + mat.applyOpenGL(oglContext); + + RenderStateLighting_FF light; + light.applyOpenGL(oglContext); +#endif + } + + for (size_t i = 0; i < 6; i++) + { + NavCubeFace face = static_cast(i); + + std::map >::iterator it = m_faceTextures.find(m_cubeGeoFace[i]); + ShaderProgram* shader = NULL; + bool hasTexture = it != m_faceTextures.end(); + + if (hasTexture) + { + RenderState* textureBinding = m_faceTextureBindings[face].p(); + CVF_ASSERT(textureBinding); + textureBinding->applyOpenGL(oglContext); + } + + if (!software) + { + shader = hasTexture ? m_cubeGeoTextureShader.p() : m_cubeGeoShader.p(); + + if (shader->useProgram(oglContext)) + { + shader->applyFixedUniforms(oglContext, matrixState); + } + } + + Color3f faceColor; + switch (face) + { + case NCF_X_POS: + case NCF_X_NEG: faceColor = m_xFaceColor; break; + case NCF_Y_POS: + case NCF_Y_NEG: faceColor = m_yFaceColor; break; + case NCF_Z_POS: + case NCF_Z_NEG: faceColor = m_zFaceColor; break; + } + + for (size_t i = 0; i < m_cubeGeos.size(); ++i) + { + if (m_cubeGeoFace[i] == face) + { + Color3f renderFaceColor = faceColor; + cvf::Vec3f emissiveColor = cvf::Vec3f(0.0f, 0.0f, 0.0f); + + if (m_cubeItemType[i] == m_hightlightItem) + { + renderFaceColor = m_itemHighlightColor; + emissiveColor = cvf::Vec3f(-0.25f, -0.25f, -0.25f); + } + + if (software) + { + if (hasTexture) + { + glColor3f(1.0f, 1.0f, 1.0f); + } + else + { + glColor3fv(renderFaceColor.ptr()); + } + + m_cubeGeos[i]->renderImmediateMode(oglContext, matrixState); + } + else + { + if (hasTexture) + { + UniformFloat uniform("u_emissiveColor", emissiveColor); + shader->applyUniform(oglContext, uniform); + } + else + { + UniformFloat uniform("u_color", Color4f(renderFaceColor)); + shader->applyUniform(oglContext, uniform); + } + + m_cubeGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::render2dItems(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software) +{ + Camera cam; + cam.setViewport(position.x(), position.y(), size.x(), size.y()); + cam.setProjectionAsUnitOrtho(); + + // Setup viewport + cam.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH); + cam.applyOpenGL(); + + RenderStateDepth depth(false); + depth.applyOpenGL(oglContext); + + MatrixState matrixState(cam); + + if (software) + { +#ifdef CVF_OPENGL_ES + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#else + RenderStateLighting_FF light(false); + light.applyOpenGL(oglContext); + glColor3fv(m_hightlightItem == NCI_HOME ? m_itemHighlightColor.ptr() : m_2dItemsColor.ptr()); + + m_homeGeo->renderImmediateMode(oglContext, matrixState); +#endif + } + else + { + if (m_cubeGeoShader->useProgram(oglContext)) + { + m_cubeGeoShader->applyFixedUniforms(oglContext, matrixState); + } + + UniformFloat colorUniform("u_color", Color4f(m_hightlightItem == NCI_HOME ? m_itemHighlightColor : m_2dItemsColor)); + m_cubeGeoShader->applyUniform(oglContext, colorUniform); + m_homeGeo->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + + if (isFaceAlignedViewPoint()) + { + for (size_t i = 0; i < m_2dGeos.size(); ++i) + { + Color3f renderFaceColor = Color3f(1,1,1); + + if (m_2dItemType[i] == m_hightlightItem) + { + renderFaceColor = m_itemHighlightColor; + } + + if (software) + { + glColor3fv(renderFaceColor.ptr()); + m_2dGeos[i]->renderImmediateMode(oglContext, matrixState); + } + else + { + UniformFloat colorUniform("u_color", Color4f(renderFaceColor)); + m_cubeGeoShader->applyUniform(oglContext, colorUniform); + + m_2dGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState); + } + } + } + + RenderStateDepth resetDepth; + resetDepth.applyOpenGL(oglContext); + + if (software) + { +#ifdef CVF_OPENGL_ES + CVF_FAIL_MSG("Not supported on OpenGL ES"); +#else + RenderStateLighting_FF resetLight; + resetLight.applyOpenGL(oglContext); +#endif + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::create2dGeos() +{ + // "Home" aka. House geometry + { + m_homeGeo = new DrawableGeo; + + ref vertexArray = new Vec3fArray(12); + vertexArray->set(0, Vec3f(-0.97f, 0.86f, 0.0f)); + vertexArray->set(1, Vec3f(-0.68f, 0.86f, 0.0f)); + vertexArray->set(2, Vec3f(-0.825f, 1.0f, 0.0f)); + vertexArray->set(3, Vec3f(-0.825f, 1.0f, 0.0f)); + + vertexArray->set(4, Vec3f(-0.9f, 0.76f, 0.0f)); + vertexArray->set(5, Vec3f(-0.75f, 0.76f, 0.0f)); + vertexArray->set(6, Vec3f(-0.75f, 0.86f, 0.0f)); + vertexArray->set(7, Vec3f(-0.9f, 0.86f, 0.0f)); + + vertexArray->set(8, Vec3f(-0.77f, 0.86f, 0.0f)); + vertexArray->set(9, Vec3f(-0.75f, 0.86f, 0.0f)); + vertexArray->set(10, Vec3f(-0.75f, 1.0f, 0.0f)); + vertexArray->set(11, Vec3f(-0.77f, 1.0f, 0.0f)); + + for (size_t i = 0; i < vertexArray->size(); ++i) + { + Vec3f v = vertexArray->get(i); + v.x() = 0.5f + v.x()/2.0f; + v.y() = 0.5f + v.y()/2.0f; + vertexArray->set(i, v); + } + + m_homeGeo->setVertexArray(vertexArray.p()); + + ref indices = new cvf::UShortArray(18); + indices->set(0, 0); indices->set(1, 1); indices->set(2, 2); + indices->set(3, 0); indices->set(4, 2); indices->set(5, 3); + + indices->set(6, 4); indices->set(7, 5); indices->set(8, 6); + indices->set(9, 4); indices->set(10, 6); indices->set(11, 7); + + indices->set(12, 8); indices->set(13, 9); indices->set(14, 10); + indices->set(15, 8); indices->set(16, 10); indices->set(17, 11); + + ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); + primSet->setIndices(indices.p()); + m_homeGeo->addPrimitiveSet(primSet.p()); + m_homeGeo->computeNormals(); + } + + m_2dGeos.push_back(create2dArrow(Vec3f(-0.7f, 0,0), Vec3f(-0.9f, 0,0)).p()); m_2dItemType.push_back(NCI_ARROW_LEFT); + m_2dGeos.push_back(create2dArrow(Vec3f(0.7f, 0,0), Vec3f(0.9f, 0,0)).p()); m_2dItemType.push_back(NCI_ARROW_RIGHT); + m_2dGeos.push_back(create2dArrow(Vec3f(0, -0.7f,0), Vec3f(0, -0.9f,0)).p()); m_2dItemType.push_back(NCI_ARROW_BOTTOM); + m_2dGeos.push_back(create2dArrow(Vec3f(0, 0.7f,0), Vec3f(0, 0.9f,0)).p()); m_2dItemType.push_back(NCI_ARROW_TOP); + + // Rotate arrows + m_2dGeos.push_back(create2dArrow(Vec3f(0.75f, 0.65f, 0.0f), Vec3f(0.87f,0.49f, 0.0f)).p()); m_2dItemType.push_back(NCI_ROTATE_CW); + m_2dGeos.push_back(create2dArrow(Vec3f(0.71f, 0.70f, 0.0f), Vec3f(0.59f,0.86f, 0.0f)).p()); m_2dItemType.push_back(NCI_ROTATE_CCW); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +ref OverlayNavigationCube::create2dArrow(const Vec3f& start, const Vec3f& end) +{ + float fWidth = 0.042f; + float fArrowWidth = 0.12f; + float fBaseRelLength = 0.50f; + float fLength = (end - start).length(); + + Vec3f vUp = Vec3f(0,0,1); + Vec3f vDir = (end - start); + Vec3f vRight = vUp^vDir; + vDir.normalize(); + vRight.normalize(); + + Vec3f vBaseBL = start + vDir*fLength*fBaseRelLength + vRight*fWidth; + Vec3f vBaseBR = start + vRight*fWidth; + Vec3f vBaseTL = start + vDir*fLength*fBaseRelLength - vRight*fWidth; + Vec3f vBaseTR = start - vRight*fWidth; + + Vec3f vArrowB = start + vDir*fLength*fBaseRelLength + vRight*fArrowWidth; + Vec3f vArrowT = start + vDir*fLength*fBaseRelLength - vRight*fArrowWidth; + + ref geo = new DrawableGeo; + + ref vertexArray = new Vec3fArray(7); + + vertexArray->set(0, vBaseBL); + vertexArray->set(1, vBaseBR); + vertexArray->set(2, vBaseTR); + vertexArray->set(3, vBaseTL); + + vertexArray->set(4, vArrowT); + vertexArray->set(5, end); + vertexArray->set(6, vArrowB); + + for (size_t i = 0; i < vertexArray->size(); ++i) + { + Vec3f v = vertexArray->get(i); + v.x() = 0.5f + v.x()/2.0f; + v.y() = 0.5f + v.y()/2.0f; + vertexArray->set(i, v); + } + + geo->setVertexArray(vertexArray.p()); + + ref indices = new cvf::UShortArray(9); + indices->set(0, 0); indices->set(1, 1); indices->set(2, 2); + indices->set(3, 0); indices->set(4, 2); indices->set(5, 3); + indices->set(6, 4); indices->set(7, 5); indices->set(8, 6); + + ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); + primSet->setIndices(indices.p()); + geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); + + m_2dGeos.push_back(geo.p()); + m_2dItemType.push_back(NCI_HOME); + + return geo; } @@ -329,14 +726,22 @@ void OverlayNavigationCube::renderCubeGeos(OpenGLContext* oglContext, bool softw //-------------------------------------------------------------------------------------------------- void OverlayNavigationCube::renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState) { + if (m_xLabel.isEmpty() && m_yLabel.isEmpty() && m_zLabel.isEmpty()) + { + return; + } + + float fBoxLength = 0.65f; + // Multiply with 1.08 will slightly pull the labels away from the corresponding arrow head - Vec3f xPos(1.08f, 0, 0); - Vec3f yPos(0, 1.08f, 0); - Vec3f zPos(0, 0, 1.08f); + Vec3f xPos(0.5f, -fBoxLength/2.0f, -fBoxLength/2.0f); + Vec3f yPos(-fBoxLength/2.0f, 0.5f, -fBoxLength/2.0f); + Vec3f zPos(-fBoxLength/2.0f, -fBoxLength/2.0f, 0.5f); DrawableText drawableText; drawableText.setFont(m_font.p()); drawableText.setCheckPosVisible(false); + drawableText.setUseDepthBuffer(true); drawableText.setDrawBorder(false); drawableText.setDrawBackground(false); drawableText.setVerticalAlignment(TextDrawer::CENTER); @@ -346,7 +751,6 @@ void OverlayNavigationCube::renderAxisLabels(OpenGLContext* oglContext, bool sof if (!m_yLabel.isEmpty()) drawableText.addText(m_yLabel, yPos); if (!m_zLabel.isEmpty()) drawableText.addText(m_zLabel, zPos); - // Do the actual rendering // ----------------------------------------------- if (software) @@ -415,14 +819,14 @@ void OverlayNavigationCube::createCubeGeos() m_cubeGeos.clear(); - createCubeFaceGeos(NCF_Y_NEG, cp[0], cp[1], cp[5], cp[4]);//, m_yNegAxisName, m_yFaceColor, m_textureNegYAxis.p()); // Front - createCubeFaceGeos(NCF_Y_POS, cp[2], cp[3], cp[7], cp[6]);//, m_yPosAxisName, m_yFaceColor, m_texturePosYAxis.p()); // Back + createCubeFaceGeos(NCF_Y_NEG, cp[0], cp[1], cp[5], cp[4]); + createCubeFaceGeos(NCF_Y_POS, cp[2], cp[3], cp[7], cp[6]); - createCubeFaceGeos(NCF_Z_POS, cp[4], cp[5], cp[6], cp[7]);//, m_zPosAxisName, m_zFaceColor, m_texturePosZAxis.p()); // Top - createCubeFaceGeos(NCF_Z_NEG, cp[3], cp[2], cp[1], cp[0]);//, m_zNegAxisName, m_zFaceColor, m_textureNegZAxis.p()); // Bottom + createCubeFaceGeos(NCF_Z_POS, cp[4], cp[5], cp[6], cp[7]); + createCubeFaceGeos(NCF_Z_NEG, cp[3], cp[2], cp[1], cp[0]); - createCubeFaceGeos(NCF_X_NEG, cp[3], cp[0], cp[4], cp[7]);//, m_xNegAxisName, m_xFaceColor, m_textureNegXAxis.p()); // left - createCubeFaceGeos(NCF_X_POS, cp[1], cp[2], cp[6], cp[5]);//, m_xPosAxisName, m_xFaceColor, m_texturePosXAxis.p()); // Right + createCubeFaceGeos(NCF_X_NEG, cp[3], cp[0], cp[4], cp[7]); + createCubeFaceGeos(NCF_X_POS, cp[1], cp[2], cp[6], cp[5]); } @@ -440,71 +844,82 @@ void OverlayNavigationCube::createCubeGeos() /// |---|----------|---| /// 1 2 //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4)//, const String& name, const Color3f& baseColor, TextureImage* texture) +void OverlayNavigationCube::createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4) { - // Get the orientation vectors for the face -// Vec3f vNormal, vUp, vRight; -// faceOrientation(face, &vNormal, &vUp, &vRight); + Vec2f t1(0,0); + Vec2f t2(1,0); + Vec2f t3(1,1); + Vec2f t4(0,1); float fCornerFactor = 0.175f; - Vec3f p12 = p1 + (p2 - p1)*fCornerFactor; - Vec3f p14 = p1 + (p4 - p1)*fCornerFactor; - Vec3f pi1 = p1 + (p12 - p1) + (p14 - p1); + float fOneMinusCF = 1.0f - fCornerFactor; + Vec3f p12 = p1 + (p2 - p1)*fCornerFactor; Vec2f t12(fCornerFactor, 0); + Vec3f p14 = p1 + (p4 - p1)*fCornerFactor; Vec2f t14(0, fCornerFactor); + Vec3f pi1 = p1 + (p12 - p1) + (p14 - p1); Vec2f ti1(fCornerFactor, fCornerFactor); - Vec3f p21 = p2 + (p1 - p2)*fCornerFactor; - Vec3f p23 = p2 + (p3 - p2)*fCornerFactor; - Vec3f pi2 = p2 + (p21 - p2) + (p23 - p2); + Vec3f p21 = p2 + (p1 - p2)*fCornerFactor; Vec2f t21(fOneMinusCF, 0); + Vec3f p23 = p2 + (p3 - p2)*fCornerFactor; Vec2f t23(1.0, fCornerFactor); + Vec3f pi2 = p2 + (p21 - p2) + (p23 - p2); Vec2f ti2(fOneMinusCF, fCornerFactor); - Vec3f p32 = p3 + (p2 - p3)*fCornerFactor; - Vec3f p34 = p3 + (p4 - p3)*fCornerFactor; - Vec3f pi3 = p3 + (p32 - p3) + (p34 - p3); + Vec3f p32 = p3 + (p2 - p3)*fCornerFactor; Vec2f t32(1.0, fOneMinusCF); + Vec3f p34 = p3 + (p4 - p3)*fCornerFactor; Vec2f t34(fOneMinusCF, 1.0); + Vec3f pi3 = p3 + (p32 - p3) + (p34 - p3); Vec2f ti3(fOneMinusCF, fOneMinusCF); - Vec3f p41 = p4 + (p1 - p4)*fCornerFactor; - Vec3f p43 = p4 + (p3 - p4)*fCornerFactor; - Vec3f pi4 = p4 + (p41 - p4) + (p43 - p4); + Vec3f p41 = p4 + (p1 - p4)*fCornerFactor; Vec2f t41(0, fOneMinusCF); + Vec3f p43 = p4 + (p3 - p4)*fCornerFactor; Vec2f t43(fCornerFactor, 1.0); + Vec3f pi4 = p4 + (p41 - p4) + (p43 - p4); Vec2f ti4(fCornerFactor, fOneMinusCF); // Bottom left m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p1, p12, pi1, p14).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p1, p12, pi1, p14, t1, t12, ti1, t14).p()); // Bottom right m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p2, p23, pi2, p21).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p2, p23, pi2, p21, t2, t23, ti2, t21).p()); // Top right m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p3, p34, pi3, p32).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p3, p34, pi3, p32, t3, t34, ti3, t32).p()); // Top left m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p4, p41, pi4, p43).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p4, p41, pi4, p43, t4, t41, ti4, t43).p()); // Bottom m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM)); - m_cubeGeos.push_back(createQuadGeo(p12, p21, pi2, pi1).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p12, p21, pi2, pi1, t12, t21, ti2, ti1).p()); // Top m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP)); - m_cubeGeos.push_back(createQuadGeo(p34, p43, pi4, pi3).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p34, p43, pi4, pi3, t34, t43, ti4, ti3).p()); // Right m_cubeItemType.push_back(navCubeItem(face, NCFI_RIGHT)); - m_cubeGeos.push_back(createQuadGeo(p23, p32, pi3, pi2).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p23, p32, pi3, pi2, t23, t32, ti3, ti2).p()); // Left m_cubeItemType.push_back(navCubeItem(face, NCFI_LEFT)); - m_cubeGeos.push_back(createQuadGeo(p41, p14, pi1, pi4).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(p41, p14, pi1, pi4, t41, t14, ti1, ti4).p()); // Inner part m_cubeItemType.push_back(navCubeItem(face, NCFI_CENTER)); - m_cubeGeos.push_back(createQuadGeo(pi1, pi2, pi3, pi4).p()); + m_cubeGeoFace.push_back(face); + m_cubeGeos.push_back(createQuadGeo(pi1, pi2, pi3, pi4, ti1, ti2, ti3, ti4).p()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4) +ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4, const Vec2f& t1, const Vec2f& t2, const Vec2f& t3, const Vec2f& t4) { ref geo = new DrawableGeo; @@ -514,7 +929,14 @@ ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec vertexArray->set(2, v3); vertexArray->set(3, v4); + ref textureCoordArray = new Vec2fArray(4); + textureCoordArray->set(0, t1); + textureCoordArray->set(1, t2); + textureCoordArray->set(2, t3); + textureCoordArray->set(3, t4); + geo->setVertexArray(vertexArray.p()); + geo->setTextureCoordArray(textureCoordArray.p()); ref indices = new cvf::UShortArray(6); indices->set(0, 0); @@ -527,6 +949,7 @@ ref OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec ref primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES); primSet->setIndices(indices.p()); geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); return geo; } @@ -560,11 +983,9 @@ void OverlayNavigationCube::navCubeCornerPoints(Vec3f points[8]) } -/************************************************************************************************* - *//** - * Convert face + faceItem to VTNavCubeItem - * - *************************************************************************************************/ +//-------------------------------------------------------------------------------------------------- +/// Convert face + faceItem to NavCubeItem +//-------------------------------------------------------------------------------------------------- OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFace face, NavCubeFaceItem faceItem) const { NavCubeItem item = NCI_NONE; @@ -673,12 +1094,6 @@ OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFac } break; } - - case NCF_NONE: - { - CVF_FAIL_MSG("Illegal nav cube face specified"); - break; - } } return item; @@ -688,38 +1103,449 @@ OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFac //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void OverlayNavigationCube::faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const +bool OverlayNavigationCube::pick(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) { - CVF_ASSERT(normal && upVector && rightVector); - - switch (face) - { - case NCF_X_POS: *normal = Vec3f::X_AXIS; break; - case NCF_X_NEG: *normal = -Vec3f::X_AXIS; break; - case NCF_Y_POS: *normal = Vec3f::Y_AXIS; break; - case NCF_Y_NEG: *normal = -Vec3f::Y_AXIS; break; - case NCF_Z_POS: *normal = Vec3f::Z_AXIS; break; - case NCF_Z_NEG: *normal = -Vec3f::Z_AXIS; break; - case NCF_NONE: CVF_FAIL_MSG("Illegal nav cube face"); break; - } - - if ((*normal)*m_upVector == 0.0) - { - if (*normal == m_upVector) *upVector = -m_frontVector; - else *upVector = m_frontVector; - } - else - { - *upVector = m_upVector; - } - - *rightVector = *upVector^*normal; - - normal->normalize(); - upVector->normalize(); - rightVector->normalize(); + return pickItem(winCoordX, winCoordY, position, size) != cvf::UNDEFINED_UINT; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::updateHighlight(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + // Early out + if (winCoordX < position.x() || winCoordX > (position.x() + static_cast(size.x())) || + winCoordY < position.y() || winCoordY > (position.y() + static_cast(size.y()))) + { + bool redraw = m_hightlightItem != NCI_NONE; + m_hightlightItem = NCI_NONE; + return redraw; + } + + NavCubeItem item2d = pick2dItem(winCoordX, winCoordY, position, size); + if (item2d != NCI_NONE) + { + bool redraw = m_hightlightItem != item2d; + m_hightlightItem = item2d; + return redraw; + } + + size_t itemIndex = pickItem(winCoordX, winCoordY, position, size); + + bool redraw = false; + + if (itemIndex == cvf::UNDEFINED_SIZE_T) + { + if (m_hightlightItem != NCI_NONE) + { + m_hightlightItem = NCI_NONE; + redraw = true; + } + } + else + { + if (m_hightlightItem != m_cubeItemType[itemIndex]) + { + m_hightlightItem = m_cubeItemType[itemIndex]; + redraw = true; + } + } + + return redraw; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::processSelection(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size, Vec3d* viewDir, Vec3d* up) +{ + *viewDir = Vec3d::UNDEFINED; + *up = Vec3d::UNDEFINED; + + NavCubeItem faceItem = pick2dItem(winCoordX, winCoordY, position, size); + + if (faceItem == NCI_NONE) + { + size_t minIndex = pickItem(winCoordX, winCoordY, position, size); + + if (minIndex == cvf::UNDEFINED_SIZE_T) + { + return false; + } + + faceItem = m_cubeItemType[minIndex]; + } + + if (faceItem == NCI_NONE) + { + return false; + } + + viewConfigurationFromNavCubeItem(faceItem, viewDir, up); + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t OverlayNavigationCube::pickItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + Camera cam; + configureLocalCamera(&cam, position, size); + + ref ray = cam.rayFromWindowCoordinates(winCoordX, winCoordY); + + double minDistSq = cvf::UNDEFINED_DOUBLE_THRESHOLD; + size_t minIndex = cvf::UNDEFINED_SIZE_T; + + for (size_t i = 0; i < m_cubeGeos.size(); ++i) + { + Vec3d intersectionPoint; + ref detail; + if (m_cubeGeos[i]->rayIntersectCreateDetail(*ray, &intersectionPoint, &detail)) + { + double distSq = ray->origin().pointDistanceSquared(intersectionPoint); + + if (distSq < minDistSq) + { + minDistSq = distSq; + minIndex = i; + } + } + } + + return minIndex; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +OverlayNavigationCube::NavCubeItem OverlayNavigationCube::pick2dItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size) +{ + Vec2f vpOrigin; + vpOrigin.x() = static_cast(position.x()) + static_cast(size.x())*0.5f; + vpOrigin.y() = static_cast(position.y()) + static_cast(size.y())*0.5f; + + Vec2f relCoord; + relCoord.x() = (static_cast(winCoordX) - vpOrigin.x())/(static_cast(size.x())*0.5f); + relCoord.y() = (static_cast(winCoordY) - vpOrigin.y())/(static_cast(size.y())*0.5f); + + // Check for home + Rectf home(-0.97f, 0.76f, 0.21f, 0.24f); + if (home.contains(relCoord)) return NCI_HOME; + + if (isFaceAlignedViewPoint()) + { + float fEnd = 0.9f; + float fStart = 0.7f; + float fWidth = 0.12f; + + Rectf leftArrow(-fEnd, -fWidth, 0.2f, 2*fWidth); + Rectf rightArrow(fStart, -fWidth, 0.2f, 2*fWidth); + Rectf topArrow(-fWidth, fStart, 2*fWidth, 0.2f); + Rectf bottomArrow(-fWidth, -fEnd, 2*fWidth, 0.2f); + Rectf rotateCW(0.75f, 0.49f, 0.12f, 0.16f); + Rectf rotateCCW(0.59f, 0.70f, 0.12f, 0.16f); + + if (leftArrow.contains(relCoord)) return NCI_ARROW_LEFT; + else if (rightArrow.contains(relCoord)) return NCI_ARROW_RIGHT; + else if (topArrow.contains(relCoord)) return NCI_ARROW_TOP; + else if (bottomArrow.contains(relCoord)) return NCI_ARROW_BOTTOM; + else if (rotateCW.contains(relCoord)) return NCI_ROTATE_CW; + else if (rotateCCW.contains(relCoord)) return NCI_ROTATE_CCW; + } + + return NCI_NONE; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size) +{ + // Position the camera far enough away to make the axis and the text fit within the viewport + Mat4d axisMatrix = m_camera->viewMatrix(); + axisMatrix.setTranslation(Vec3d(0, 0, -2.0)); + + // Setup camera + camera->setProjectionAsPerspective(40.0, 0.05, 100.0); + camera->setViewMatrix(axisMatrix); + camera->setViewport(position.x(), position.y(), size.x(), size.y()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up) +{ + // Handle Home and Rotate specially, as they do not fall into the simple "view from" category + if (item == NCI_HOME) + { + *viewDir = m_homeViewDirection; + *up = m_homeUp; + return; + } + else if ((item == NCI_ROTATE_CW) || (item == NCI_ROTATE_CCW)) + { + *viewDir = m_camera->direction(); + *up = m_camera->up(); + + Mat4d mat = Mat4d::fromRotation(*viewDir, Math::toRadians(item == NCI_ROTATE_CW ? -90.0 : 90.0)); + up->transformVector(mat); + + return; + } + + // Determine the view from point based on the VTNavCubeItem + Vec3d viewFrom; + + switch(item) + { + case NCI_ARROW_LEFT: + case NCI_ARROW_RIGHT: + case NCI_ARROW_TOP: + case NCI_ARROW_BOTTOM: + { + Vec3d currentViewDir = m_camera->direction(); + Vec3d currentUp = m_camera->up(); + Vec3d rightVec = currentViewDir^currentUp; + + if (item == NCI_ARROW_LEFT) viewFrom = -rightVec; + else if (item == NCI_ARROW_RIGHT) viewFrom = rightVec; + else if (item == NCI_ARROW_TOP) viewFrom = currentUp; + else if (item == NCI_ARROW_BOTTOM) viewFrom = -currentUp; + break; + } + case NCI_CORNER_XN_YN_ZN: viewFrom = Vec3d(-1, -1, -1); break; + case NCI_CORNER_XP_YN_ZN: viewFrom = Vec3d( 1, -1, -1); break; + case NCI_CORNER_XP_YP_ZN: viewFrom = Vec3d( 1, 1, -1); break; + case NCI_CORNER_XN_YP_ZN: viewFrom = Vec3d(-1, 1, -1); break; + case NCI_CORNER_XN_YN_ZP: viewFrom = Vec3d(-1, -1, 1); break; + case NCI_CORNER_XP_YN_ZP: viewFrom = Vec3d( 1, -1, 1); break; + case NCI_CORNER_XP_YP_ZP: viewFrom = Vec3d( 1, 1, 1); break; + case NCI_CORNER_XN_YP_ZP: viewFrom = Vec3d(-1, 1, 1); break; + case NCI_EDGE_YN_ZN: viewFrom = Vec3d( 0, -1, -1); break; + case NCI_EDGE_XP_ZN: viewFrom = Vec3d( 1, 0, -1); break; + case NCI_EDGE_YP_ZN: viewFrom = Vec3d( 0, 1, -1); break; + case NCI_EDGE_XN_ZN: viewFrom = Vec3d(-1, 0, -1); break; + case NCI_EDGE_YN_ZP: viewFrom = Vec3d( 0, -1, 1); break; + case NCI_EDGE_XP_ZP: viewFrom = Vec3d( 1, 0, 1); break; + case NCI_EDGE_YP_ZP: viewFrom = Vec3d( 0, 1, 1); break; + case NCI_EDGE_XN_ZP: viewFrom = Vec3d(-1, 0, 1); break; + case NCI_EDGE_XN_YN: viewFrom = Vec3d(-1, -1, 0); break; + case NCI_EDGE_XP_YN: viewFrom = Vec3d( 1, -1, 0); break; + case NCI_EDGE_XP_YP: viewFrom = Vec3d( 1, 1, 0); break; + case NCI_EDGE_XN_YP: viewFrom = Vec3d(-1, 1, 0); break; + case NCI_FACE_X_POS: viewFrom = Vec3d( 1, 0, 0); break; + case NCI_FACE_X_NEG: viewFrom = Vec3d(-1, 0, 0); break; + case NCI_FACE_Y_POS: viewFrom = Vec3d( 0, 1, 0); break; + case NCI_FACE_Y_NEG: viewFrom = Vec3d( 0, -1, 0); break; + case NCI_FACE_Z_POS: viewFrom = Vec3d( 0, 0, 1); break; + case NCI_FACE_Z_NEG: viewFrom = Vec3d( 0, 0, -1); break; + case NCI_NONE: + case NCI_HOME: + case NCI_ROTATE_CW: + case NCI_ROTATE_CCW: + default: CVF_ASSERT(0); break; + } + + *viewDir = Vec3d::ZERO - viewFrom; + + // Find the new up vector + *up = computeNewUpVector(viewFrom, m_camera->up()); +} + + +//-------------------------------------------------------------------------------------------------- +/// Find the new up vector +//-------------------------------------------------------------------------------------------------- +Vec3d OverlayNavigationCube::computeNewUpVector(const Vec3d& viewFrom, const Vec3d currentUp) const +{ + Vec3d upVector = currentUp; + upVector.normalize(); + + // Snap to axis before rotate, give priority to Z axis if equal + upVector = snapToAxis(upVector, &Vec3d::Z_AXIS); + + Vec3d currentUpVectorSnapped = upVector; + Vec3d viewDir = -viewFrom; + + // New approach: + Vec3d currentViewDir = m_camera->direction(); + Vec3d rotAxis; + + if (vectorsParallelFuzzy(currentViewDir, viewDir)) + { + // The current and new dirs are parallel, just use the up vector as it is perpendicular to the view dir + rotAxis = currentUp; + } + else + { + rotAxis = currentViewDir^viewDir; + } + + rotAxis.normalize(); + + // Guard acos against out-of-domain input + const double dotProduct = Math::clamp(currentViewDir*viewDir, -1.0, 1.0); + const double angle = Math::acos(dotProduct); + Mat4d rotMat = Mat4d::fromRotation(rotAxis, angle); + upVector.transformVector(rotMat); + + // Snap to closest axis + if (cvf::Math::abs(upVector*currentUpVectorSnapped) > 0.01) + { + upVector = currentUpVectorSnapped; + } + else + { + upVector = snapToAxis(upVector, ¤tUpVectorSnapped); + } + + if (vectorsParallelFuzzy(upVector, viewDir)) + { + // The found up vector and view dir are parallel, select another axis based on the current up vector + if (vectorsParallelFuzzy(Vec3d::Z_AXIS, viewDir)) + { + if (cvf::Math::abs(currentUp.y()) >= cvf::Math::abs(currentUp.x())) upVector = (currentUp.y() >= 0.0f) ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + else upVector = (currentUp.x() >= 0.0f) ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + } + else if (vectorsParallelFuzzy(Vec3d::Y_AXIS, viewDir)) + { + if (cvf::Math::abs(currentUp.x()) >= cvf::Math::abs(currentUp.z())) upVector = (currentUp.x() >= 0.0f) ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + else upVector = (currentUp.z() >= 0.0f) ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + } + else + { + if (cvf::Math::abs(currentUp.y()) >= cvf::Math::abs(currentUp.z())) upVector = (currentUp.y() >= 0.0f) ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + else upVector = (currentUp.z() >= 0.0f) ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + } + } + + return upVector; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +Vec3d OverlayNavigationCube::snapToAxis(const Vec3d& vector, const Vec3d* pPreferIfEqual) +{ + // Snap to closest axis + int closestAxis = findClosestAxis(vector); + + if (pPreferIfEqual) + { + int closestPreferAxis = findClosestAxis(*pPreferIfEqual); + + if (closestAxis != closestPreferAxis) + { + if (cvf::Math::abs(cvf::Math::abs(vector[closestAxis]) - cvf::Math::abs(vector[closestPreferAxis])) < 0.01) + { + closestAxis = closestPreferAxis; + } + } + } + + Vec3d snapVector = vector; + + if (closestAxis == 0) snapVector = vector.x() >= 0.0f ? Vec3d::X_AXIS : -Vec3d::X_AXIS; + if (closestAxis == 1) snapVector = vector.y() >= 0.0f ? Vec3d::Y_AXIS : -Vec3d::Y_AXIS; + if (closestAxis == 2) snapVector = vector.z() >= 0.0f ? Vec3d::Z_AXIS : -Vec3d::Z_AXIS; + + return snapVector; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::vectorsParallelFuzzy(Vec3d v1, Vec3d v2) +{ + v1.normalize(); + v2.normalize(); + if (cvf::Math::abs(v1*v2) < 0.999f) return false; + + return true; +} + + +//-------------------------------------------------------------------------------------------------- +/// Static +//-------------------------------------------------------------------------------------------------- +int OverlayNavigationCube::findClosestAxis(const Vec3d& vector) +{ + int retAxis = 0; + double largest = cvf::Math::abs(vector.x()); + + if (cvf::Math::abs(vector.y()) > largest) + { + largest = cvf::Math::abs(vector.y()); + retAxis = 1; + } + + if (cvf::Math::abs(vector.z()) > largest) + { + retAxis = 2; + } + + return retAxis; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::setFaceTexture(NavCubeFace face, TextureImage* texture) +{ + m_faceTextures[face] = texture; + m_faceTextureBindings.clear(); +} + + +//-------------------------------------------------------------------------------------------------- +/// Check if the current view dir is aligned with a face (principal axis) +//-------------------------------------------------------------------------------------------------- +bool OverlayNavigationCube::isFaceAlignedViewPoint() const +{ + Vec3d viewDir = m_camera->direction().getNormalized(); + Vec3d upVector = m_camera->up().getNormalized(); + + // First check up vector + float fThreshold = 0.999f; + if ((Math::abs(upVector*Vec3d::X_AXIS) < fThreshold) && + (Math::abs(upVector*Vec3d::Y_AXIS) < fThreshold) && + (Math::abs(upVector*Vec3d::Z_AXIS) < fThreshold)) + { + return false; + } + + if (viewDir*Vec3d::X_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::X_AXIS < -fThreshold) return true; + else if (viewDir*Vec3d::Y_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::Y_AXIS < -fThreshold) return true; + else if (viewDir*Vec3d::Z_AXIS > fThreshold) return true; + else if (viewDir*Vec3d::Z_AXIS < -fThreshold) return true; + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// Set the "home" camera angle, which is used when the user presses the house 2d item +//-------------------------------------------------------------------------------------------------- +void OverlayNavigationCube::setHome(const Vec3d& viewDirection, const Vec3d& up) +{ + m_homeViewDirection = viewDirection; + m_homeUp = up; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfOverlayNavigationCube.h b/VisualizationModules/LibRender/cvfOverlayNavigationCube.h index e878ecf9ce..1a5750f47d 100644 --- a/VisualizationModules/LibRender/cvfOverlayNavigationCube.h +++ b/VisualizationModules/LibRender/cvfOverlayNavigationCube.h @@ -26,6 +26,8 @@ #include "cvfBoundingBox.h" #include "cvfCollection.h" +#include + namespace cvf { class Camera; @@ -35,7 +37,7 @@ class Font; class ShaderProgram; class MatrixState; class TextureImage; - +class RenderState; //================================================================================================== // @@ -45,8 +47,8 @@ class TextureImage; class OverlayNavigationCube: public OverlayItem { public: - enum NavCubeFace { - NCF_NONE, + enum NavCubeFace + { NCF_X_POS, NCF_X_NEG, NCF_Y_POS, @@ -55,8 +57,31 @@ public: NCF_Z_NEG }; - // Note that the order of the items starting at the VT_NCFI_BOTTOM_LEFT is important (in a CCW order) - enum NavCubeFaceItem { +public: + OverlayNavigationCube(Camera* camera, Font* font); + ~OverlayNavigationCube(); + + virtual Vec2ui sizeHint(); + virtual Vec2ui maximumSize(); + virtual Vec2ui minimumSize(); + + virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + virtual bool pick(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + + bool updateHighlight(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + bool processSelection(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size, Vec3d* viewDir, Vec3d* up); + + void setSize(const Vec2ui& size); + void setHome(const Vec3d& viewDirection, const Vec3d& up); + void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel); + void setAxisLabelsColor(const Color3f& color); + void setFaceTexture(NavCubeFace face, TextureImage* texture); + +private: + // Note that the order of the items starting at the NCFI_BOTTOM_LEFT is important (in a CCW order) + enum NavCubeFaceItem + { NCFI_NONE, NCFI_CENTER, NCFI_BOTTOM_LEFT, @@ -111,77 +136,76 @@ public: NCI_ROTATE_CCW }; -public: - OverlayNavigationCube(Camera* camera, Font* font); - ~OverlayNavigationCube(); +private: + void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software); + void createAxisGeometry(bool software); + void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState); + void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState); + void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + void render2dItems(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software); - virtual Vec2ui sizeHint(); - virtual Vec2ui maximumSize(); - virtual Vec2ui minimumSize(); + void createCubeGeos(); + void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4); + ref createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4, const Vec2f& t1, const Vec2f& t2, const Vec2f& t3, const Vec2f& t4); + void navCubeCornerPoints(Vec3f points[8]); + void create2dGeos(); + ref create2dArrow(const Vec3f& start, const Vec3f& end); - virtual void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); - virtual void renderSoftware(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size); + NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const; - void setSize(const Vec2ui& size); - void updateHighlight(int winCoordX, int winCoordY); - void processSelection(int winCoordX, int winCoordY, const BoundingBox& boundingBox, Vec3d* eye, Vec3d* viewDirection); + void configureLocalCamera(Camera* camera, const Vec2i& position, const Vec2ui& size); - void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel); - void setAxisLabelsColor(const Color3f& color); + void viewConfigurationFromNavCubeItem(NavCubeItem item, Vec3d* viewDir, Vec3d* up); + Vec3d computeNewUpVector(const Vec3d& viewFrom, const Vec3d currentUp) const; + + size_t pickItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + NavCubeItem pick2dItem(int winCoordX, int winCoordY, const Vec2i& position, const Vec2ui& size); + + void updateTextureBindings(OpenGLContext* oglContext, bool software); + bool isFaceAlignedViewPoint() const; + + static Vec3d snapToAxis(const Vec3d& vector, const Vec3d* pPreferIfEqual = NULL); + static bool vectorsParallelFuzzy(Vec3d v1, Vec3d v2); + static int findClosestAxis(const Vec3d& vector); private: - void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix); - void createAxisGeometry(bool software); - void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState); - void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState); - void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); - void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState); + ref m_camera; // This camera's view matrix will be used to orient the axis cross + ref m_font; + String m_xLabel; // Label to display on x axis, default 'x' + String m_yLabel; + String m_zLabel; + Color3f m_textColor; // Text color - void createCubeGeos(); - void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);//, const String& name, const Color3f& baseColor, TextureImage* texture); - void navCubeCornerPoints(Vec3f points[8]); - ref createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4); + Vec2ui m_size; // Pixel size of the nav cube area - NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const; - void faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const; + Vec3d m_homeViewDirection; + Vec3d m_homeUp; -private: - ref m_camera; // This camera's view matrix will be used to orient the axis cross - String m_xLabel; // Label to display on x axis, default 'x' - String m_yLabel; - String m_zLabel; - Color3f m_textColor; // Text color - ref m_font; + Collection m_cubeGeos; // These arrays have the same length + std::vector m_cubeItemType; // These arrays have the same length + std::vector m_cubeGeoFace; // These arrays have the same length - Vec2ui m_size; // Pixel size of the axis area + ref m_homeGeo; // These arrays have the same length + Collection m_2dGeos; // These arrays have the same length + std::vector m_2dItemType; - Collection m_cubeGeos; - std::vector m_cubeItemType; ref m_cubeGeoShader; + ref m_cubeGeoTextureShader; ref m_axis; - NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons) - Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces - Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces + NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons) + Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces + Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces - String m_xPosAxisName; ///< The name of the X_POS face - String m_xNegAxisName; ///< The name of the X_NEG face - String m_yPosAxisName; ///< The name of the Y_POS face - String m_yNegAxisName; ///< The name of the Y_NEG face - String m_zPosAxisName; ///< The name of the Z_POS face - String m_zNegAxisName; ///< The name of the Z_NEG face + Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces + Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces + Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces + Color3f m_itemHighlightColor; + Color3f m_2dItemsColor; - ref m_texturePosXAxis; ///< The texture to draw on the X_POS face. If NULL, the specified text will be drawn. - ref m_textureNegXAxis; ///< The texture to draw on the X_NEG face. If NULL, the specified text will be drawn. - ref m_texturePosYAxis; ///< The texture to draw on the Y_POS face. If NULL, the specified text will be drawn. - ref m_textureNegYAxis; ///< The texture to draw on the Y_NEG face. If NULL, the specified text will be drawn. - ref m_texturePosZAxis; ///< The texture to draw on the Z_POS face. If NULL, the specified text will be drawn. - ref m_textureNegZAxis; ///< The texture to draw on the Z_NEG face. If NULL, the specified text will be drawn. - - Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces - Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces - Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces + std::map > m_faceTextures; + std::map > m_faceTextureBindings; }; } - diff --git a/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp b/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp index 93ea5c99a6..f5b649083e 100644 --- a/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp +++ b/VisualizationModules/LibRender/cvfOverlayScalarMapperLegend.cpp @@ -686,7 +686,14 @@ void OverlayScalarMapperLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout) if (m_scalarMapper.isNull()) t = 0; else t = m_scalarMapper->normalizedValue(m_tickValues[i]); t = Math::clamp(t, 0.0, 1.1); - layout->tickPixelPos->set(i, t*layout->legendRect.height()); + if (i != numTicks -1) + { + layout->tickPixelPos->set(i, t*layout->legendRect.height()); + } + else + { + layout->tickPixelPos->set(i, layout->legendRect.height()); // Make sure we get a value at the top even if the scalarmapper range is zero + } } } diff --git a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp index e3c8fd53a8..8cccdcae42 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.cpp @@ -22,6 +22,7 @@ #include "cvfMath.h" #include "cvfTextureImage.h" #include +#include namespace cvf { @@ -34,6 +35,9 @@ namespace cvf { /// Configured by specifying a number of level colors and a min/max range. //================================================================================================== ScalarMapperContinuousLog::ScalarMapperContinuousLog() + : m_hasNegativeRange(false), + m_logRange(0.0), + m_logRangeMin(0.0) { } @@ -43,17 +47,16 @@ ScalarMapperContinuousLog::ScalarMapperContinuousLog() //-------------------------------------------------------------------------------------------------- double ScalarMapperContinuousLog::normalizedValue(double scalarValue) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + if (m_hasNegativeRange) scalarValue = -1.0*scalarValue; + double logValue; - - if (scalarValue <= 0) logValue = logRangeMin; + + if (scalarValue <= 0) logValue = std::numeric_limits::min_exponent10; else logValue = log10(scalarValue); - if (logRange != 0) + if (m_logRange != 0) { - return cvf::Math::clamp((logValue - logRangeMin)/logRange, 0.0, 1.0); + return cvf::Math::clamp((logValue - m_logRangeMin)/m_logRange, 0.0, 1.0); } else { @@ -66,13 +69,37 @@ double ScalarMapperContinuousLog::normalizedValue(double scalarValue) const //-------------------------------------------------------------------------------------------------- double ScalarMapperContinuousLog::domainValue(double normalizedPosition) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double logValue = normalizedPosition*m_logRange + m_logRangeMin; + double domainVal = pow(10, logValue); - double logValue = normalizedPosition*logRange + logRangeMin; - - return pow(10, logValue); + if (m_hasNegativeRange) + domainVal *= -1.0; + + return domainVal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ScalarMapperContinuousLog::rangeUpdated() +{ + m_hasNegativeRange = false; + + double transformedRangeMax = m_rangeMax; + double transformedRangeMin = m_rangeMin; + + if ( m_rangeMax <= 0 && m_rangeMin <= 0) + { + m_hasNegativeRange = true; + + transformedRangeMax = -1.0*transformedRangeMax; + transformedRangeMin = -1.0*transformedRangeMin; + } + + double logRangeMax = (transformedRangeMax > 0) ? log10(transformedRangeMax): std::numeric_limits::min_exponent10; + m_logRangeMin = (transformedRangeMin > 0) ? log10(transformedRangeMin): std::numeric_limits::min_exponent10; + + m_logRange = logRangeMax - m_logRangeMin; } } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h index 72a1b62d80..eda29b7339 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h +++ b/VisualizationModules/LibRender/cvfScalarMapperContinuousLog.h @@ -38,6 +38,15 @@ public: virtual double normalizedValue( double domainValue ) const; virtual double domainValue( double normalizedPosition ) const; + + // +protected: + virtual void rangeUpdated(); + +private: + double m_logRange; + double m_logRangeMin; + bool m_hasNegativeRange; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp index 6af6569e9e..febea0c299 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.cpp @@ -41,7 +41,7 @@ ScalarMapperDiscreteLinear::ScalarMapperDiscreteLinear() //-------------------------------------------------------------------------------------------------- Vec2f ScalarMapperDiscreteLinear::mapToTextureCoord(double scalarValue) const { - double discVal = discretize(scalarValue); + double discVal = discretize(scalarValue, m_sortedLevels); return ScalarMapperRangeBased::mapToTextureCoord(discVal); } @@ -50,20 +50,20 @@ Vec2f ScalarMapperDiscreteLinear::mapToTextureCoord(double scalarValue) const //-------------------------------------------------------------------------------------------------- Color3ub ScalarMapperDiscreteLinear::mapToColor(double scalarValue) const { - double discVal = discretize(scalarValue); + double discVal = discretize(scalarValue, m_sortedLevels); return ScalarMapperRangeBased::mapToColor(discVal); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double ScalarMapperDiscreteLinear::discretize(double scalarValue) const +double ScalarMapperDiscreteLinear::discretize(double scalarValue, const std::set& sortedLevels) { std::set::iterator it; - it = m_sortedLevels.upper_bound(scalarValue); - if (it == m_sortedLevels.begin()) return (*it); - if (it == m_sortedLevels.end()) return (*m_sortedLevels.rbegin()); + it = sortedLevels.upper_bound(scalarValue); + if (it == sortedLevels.begin()) return (*it); + if (it == sortedLevels.end()) return (*sortedLevels.rbegin()); double upperValue = *it; it--; double lowerValue = *it; diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h index 824fe00946..da8fcb5fd9 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLinear.h @@ -23,6 +23,7 @@ namespace cvf { + class ScalarMapperDiscreteLog; //================================================================================================== // // Maps scalar values to texture coordinates/colors @@ -42,8 +43,8 @@ public: virtual double domainValue( double normalizedPosition ) const; private: - double discretize(double scalarValue) const; - + static double discretize(double scalarValue, const std::set& sortedLevels); + friend class ScalarMapperDiscreteLog; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp index 0ee3cbabd6..48e1adb274 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.cpp @@ -18,6 +18,7 @@ //################################################################################################## #include "cvfScalarMapperDiscreteLog.h" +#include "cvfScalarMapperDiscreteLinear.h" #include #include "cvfMath.h" @@ -31,42 +32,87 @@ namespace cvf { /// Maps scalar values to texture coordinates/colors using discrete logarithmic mapping //================================================================================================== +ScalarMapperDiscreteLog::ScalarMapperDiscreteLog() +{ + m_decadeLevelCount = 2; +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double ScalarMapperDiscreteLog::normalizedValue(double domainScalarValue) const +Vec2f ScalarMapperDiscreteLog::mapToTextureCoord(double scalarValue) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double discVal = ScalarMapperDiscreteLinear::discretize(scalarValue, m_sortedLevels); + return ScalarMapperRangeBased::mapToTextureCoord(discVal); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Color3ub ScalarMapperDiscreteLog::mapToColor(double scalarValue) const +{ + double discVal = ScalarMapperDiscreteLinear::discretize(scalarValue, m_sortedLevels); + return ScalarMapperRangeBased::mapToColor(discVal); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double ScalarMapperDiscreteLog::normalizedValue(double scalarValue) const +{ + if (m_hasNegativeRange) scalarValue = -1.0*scalarValue; + double logValue; - if (domainScalarValue <= 0) logValue = logRangeMin; - else logValue = log10(domainScalarValue); + if (scalarValue <= 0) logValue = std::numeric_limits::min_exponent10; + else logValue = log10(scalarValue); - if (logRange != 0) + if (m_logRange != 0) { - return cvf::Math::clamp((logValue - logRangeMin)/logRange, 0.0, 1.0); + return cvf::Math::clamp((logValue - m_logRangeMin)/m_logRange, 0.0, 1.0); } else { return 0; } -} +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double ScalarMapperDiscreteLog::domainValue(double normalizedPosition) const { - double logRangeMax = log10(m_rangeMax); - double logRangeMin = log10(m_rangeMin); - double logRange = logRangeMax - logRangeMin; + double logValue = normalizedPosition*m_logRange + m_logRangeMin; + double domainVal = pow(10, logValue); - double logValue = normalizedPosition*logRange + logRangeMin; + if (m_hasNegativeRange) + domainVal *= -1.0; - return pow(10, logValue); + return domainVal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ScalarMapperDiscreteLog::rangeUpdated() +{ + m_hasNegativeRange = false; + + double transformedRangeMax = m_rangeMax; + double transformedRangeMin = m_rangeMin; + + if ( m_rangeMax <= 0 && m_rangeMin <= 0) + { + m_hasNegativeRange = true; + + transformedRangeMax = -1.0*transformedRangeMax; + transformedRangeMin = -1.0*transformedRangeMin; + } + + double logRangeMax = (transformedRangeMax > 0) ? log10(transformedRangeMax): std::numeric_limits::min_exponent10; + m_logRangeMin = (transformedRangeMin > 0) ? log10(transformedRangeMin): std::numeric_limits::min_exponent10; + + m_logRange = logRangeMax - m_logRangeMin; } } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h index b947b99bd8..bba36fbbea 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h +++ b/VisualizationModules/LibRender/cvfScalarMapperDiscreteLog.h @@ -19,7 +19,7 @@ #pragma once -#include "cvfScalarMapperDiscreteLinear.h" +#include "cvfScalarMapperRangeBased.h" namespace cvf { @@ -29,14 +29,24 @@ namespace cvf { // //================================================================================================== -class ScalarMapperDiscreteLog : public ScalarMapperDiscreteLinear +class ScalarMapperDiscreteLog : public ScalarMapperRangeBased { public: - ScalarMapperDiscreteLog() {m_decadeLevelCount = 2; } + ScalarMapperDiscreteLog(); // Implementing the Scalarmapper interface - + virtual Vec2f mapToTextureCoord(double scalarValue) const; + virtual Color3ub mapToColor(double scalarValue) const; virtual double normalizedValue( double domainValue ) const; virtual double domainValue( double normalizedPosition ) const; + + // +protected: + virtual void rangeUpdated(); + +private: + double m_logRange; + double m_logRangeMin; + bool m_hasNegativeRange; }; } diff --git a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp index 5110300155..f2c41620e5 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp +++ b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.cpp @@ -56,6 +56,7 @@ void ScalarMapperRangeBased::setRange(double min, double max) m_rangeMin = min; m_rangeMax = max; updateSortedLevels(); + rangeUpdated(); } @@ -160,7 +161,8 @@ bool ScalarMapperRangeBased::updateTexture(TextureImage* image) const // Then calculate a stepsize that is humanly understandable // basically rounded to whole or half of the decade in question - +// decadeParts - The number of steps wanted within a decade +// decadeValue - The value used to describe the current decade to round off within static double adjust(double domainValue, double decadeValue, unsigned int decadeParts = 2) { if (decadeValue == 0) return domainValue; // Conceptually correct @@ -200,7 +202,7 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) if (m_userDefinedLevelValues.empty()) { - domainValues->push_back(m_rangeMin); + domainValues->push_back(domainValue(0)); if (m_levelCount > 1) { double stepSizeNorm = 1.0/m_levelCount; @@ -213,17 +215,19 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) { double prevNormPos = normalizedValue(prevDomValue); double newNormPos = prevNormPos + stepSizeNorm; + double domValue = domainValue(newNormPos); double domStep = domValue - prevDomValue; double newLevel; - newLevel = prevDomValue + adjust(domStep, domStep, m_decadeLevelCount); + //newLevel = prevDomValue + adjust(domStep, domStep, m_decadeLevelCount); + newLevel = domValue; // Must handle first level specially to get a good absolute staring point // For log domain this must be done all the time, and it does not hamper linear, so.. do it always newLevel = adjust(newLevel, domStep, m_decadeLevelCount); - if (newLevel > m_rangeMax - domStep*0.4) break; + if (normalizedValue(newLevel) > 1.0 - stepSizeNorm*0.4) break; domainValues->push_back(newLevel); prevDomValue = newLevel; @@ -237,7 +241,7 @@ void ScalarMapperRangeBased::majorTickValues( std::vector* domainValues) } } } - domainValues->push_back(m_rangeMax); + domainValues->push_back(domainValue(1)); } else { diff --git a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h index 93cbadcef1..2a818fb75f 100644 --- a/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h +++ b/VisualizationModules/LibRender/cvfScalarMapperRangeBased.h @@ -48,6 +48,8 @@ public: virtual void majorTickValues(std::vector* domainValues ) const; protected: + virtual void rangeUpdated() {}; //< Called when the range is changed. Subclasses can reimplment to recalculate cached values + double m_rangeMin; double m_rangeMax; unsigned int m_decadeLevelCount; diff --git a/VisualizationModules/LibRender/cvfTextDrawer.cpp b/VisualizationModules/LibRender/cvfTextDrawer.cpp index ad3f7ed460..86a635d9a0 100644 --- a/VisualizationModules/LibRender/cvfTextDrawer.cpp +++ b/VisualizationModules/LibRender/cvfTextDrawer.cpp @@ -34,6 +34,7 @@ #include "cvfMatrixState.h" #include "cvfRenderStateDepth.h" #include "cvfRenderStateBlending.h" +#include "cvfRenderStatePolygonOffset.h" #ifndef CVF_OPENGL_ES #include "cvfRenderState_FF.h" @@ -60,7 +61,8 @@ TextDrawer::TextDrawer(Font* font) m_textColor(Color3::GRAY), m_backgroundColor(1.0f, 1.0f, 0.8f), m_borderColor(Color3::DARK_GRAY), - m_verticalAlignment(0) // BASELINE + m_useDepthBuffer(false), + m_verticalAlignment(0) // BASELINE { CVF_ASSERT(font); CVF_ASSERT(!font->isEmpty()); @@ -88,6 +90,22 @@ void TextDrawer::addText(const String& text, const Vec2f& pos) } +//-------------------------------------------------------------------------------------------------- +/// Add text to be drawn +/// +/// Note: The Z coordinate needs to correspond with the orthographic projection that is setup +/// to render the text. So the range should be <1..-1> with 1 being closest to the near plane. +//-------------------------------------------------------------------------------------------------- +void TextDrawer::addText(const String& text, const Vec3f& pos) +{ + CVF_ASSERT(!text.isEmpty()); + CVF_ASSERT(!pos.isUndefined()); + + m_texts.push_back(text); + m_positions.push_back(pos); +} + + //-------------------------------------------------------------------------------------------------- /// Remove all texts in the drawer //-------------------------------------------------------------------------------------------------- @@ -192,6 +210,15 @@ void TextDrawer::setDrawBorder(bool drawBorder) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TextDrawer::setUseDepthBuffer(bool useDepthBuffer) +{ + m_useDepthBuffer = useDepthBuffer; +} + + //-------------------------------------------------------------------------------------------------- /// Returns the color used to draw the text //-------------------------------------------------------------------------------------------------- @@ -284,7 +311,7 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix MatrixState projMatrixState(projCam); // Turn off depth test - RenderStateDepth depth(false, RenderStateDepth::LESS, false); + RenderStateDepth depth(m_useDepthBuffer, RenderStateDepth::LESS, m_useDepthBuffer); depth.applyOpenGL(oglContext); // Setup viewport @@ -322,6 +349,13 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // ------------------------------------------------------------------------- if (m_drawBackground || m_drawBorder) { + if (m_useDepthBuffer) + { + RenderStatePolygonOffset polygonOffset; + polygonOffset.configurePolygonPositiveOffset(); + polygonOffset.applyOpenGL(oglContext); + } + ref backgroundShader; if (!softwareRendering) @@ -353,10 +387,10 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix Vec3f max = Vec3f(min.x() + static_cast(textExtent.x()) + offset.x()*2.0f, min.y() + static_cast(textExtent.y()) + offset.y()*2.0f, 0.0f); // Draw the background triangle - v1[0] = min.x(); v1[1] = min.y(); - v2[0] = max.x(); v2[1] = min.y(); - v3[0] = max.x(); v3[1] = max.y(); - v4[0] = min.x(); v4[1] = max.y(); + v1[0] = min.x(); v1[1] = min.y(); v1[2] = pos.z(); + v2[0] = max.x(); v2[1] = min.y(); v2[2] = pos.z(); + v3[0] = max.x(); v3[1] = max.y(); v3[2] = pos.z(); + v4[0] = min.x(); v4[1] = max.y(); v4[2] = pos.z(); if (m_drawBackground) { @@ -408,6 +442,12 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix } } } + + if (m_useDepthBuffer) + { + RenderStatePolygonOffset resetPolygonOffset; + resetPolygonOffset.applyOpenGL(oglContext); + } } // Render texts @@ -459,7 +499,6 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // Need to round off to integer positions to avoid buggy text drawing on iPad2 pos.x() = cvf::Math::floor(pos.x()); pos.y() = cvf::Math::floor(pos.y()); - pos.z() = cvf::Math::floor(pos.z()); // Cursor incrementor Vec2f cursor(pos); @@ -484,18 +523,22 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix // Lower left corner v1[0] = cursor.x() + static_cast(glyph->horizontalBearingX()); v1[1] = cursor.y() + static_cast(glyph->horizontalBearingY()) - textureHeight + static_cast(m_verticalAlignment); + v1[2] = pos.z(); // Lower right corner v2[0] = v1[0] + textureWidth; v2[1] = v1[1]; + v2[2] = pos.z(); // Upper right corner v3[0] = v2[0]; v3[1] = v1[1] + textureHeight; + v3[2] = pos.z(); // Upper left corner v4[0] = v1[0]; v4[1] = v3[1]; + v4[2] = pos.z(); glyph->setupAndBindTexture(oglContext, softwareRendering); @@ -591,4 +634,32 @@ void TextDrawer::doRender2d(OpenGLContext* oglContext, const MatrixState& matrix CVF_CHECK_OGL(oglContext); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool TextDrawer::pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font) +{ + // Figure out margin + ref glyph = font->getGlyph(L'A'); + float charHeight = static_cast(glyph->height()); + float charWidth = static_cast(glyph->width()); + + float offsetX = cvf::Math::floor(charWidth/2.0f); + float offsetY = cvf::Math::floor(charHeight/2.0f); + + Vec2ui textExtent = font->textExtent(text); + + Vec3f min = pos; + Vec3f max = Vec3f(min.x() + static_cast(textExtent.x()) + offsetX*2.0f, min.y() + static_cast(textExtent.y()) + offsetY*2.0f, 0.0f); + + if (pickCoord2d.x() > min.x() && pickCoord2d.x() < max.x() && + pickCoord2d.y() > min.y() && pickCoord2d.y() < max.y()) + { + return true; + } + + return false; +} + } // namespace cvf diff --git a/VisualizationModules/LibRender/cvfTextDrawer.h b/VisualizationModules/LibRender/cvfTextDrawer.h index 1e00354671..208bf507b2 100644 --- a/VisualizationModules/LibRender/cvfTextDrawer.h +++ b/VisualizationModules/LibRender/cvfTextDrawer.h @@ -55,6 +55,7 @@ public: virtual ~TextDrawer(); void addText(const String& text, const Vec2f& pos); + void addText(const String& text, const Vec3f& pos); void removeAllTexts(); void setVerticalAlignment(Alignment alignment); @@ -63,16 +64,21 @@ public: void setBorderColor(const Color3f& color); void setDrawBackground(bool drawBackground); void setDrawBorder(bool drawBorder); + void setUseDepthBuffer(bool useDepthBuffer); Color3f textColor() const; Color3f backgroundColor() const; Color3f borderColor() const; bool drawBackground() const; bool drawBorder() const; + bool useDepthBuffer() const; + void render(OpenGLContext* oglContext, const MatrixState& matrixState); void renderSoftware(OpenGLContext* oglContext, const MatrixState& matrixState); + static bool pickText(const Vec3f& pickCoord2d, const String& text, const Vec3f& pos, Font* font); + private: void doRender2d(OpenGLContext* oglContext, const MatrixState& matrixState, bool softwareRendering); @@ -87,6 +93,7 @@ private: Color3f m_textColor; Color3f m_backgroundColor; Color3f m_borderColor; + bool m_useDepthBuffer; short m_verticalAlignment;// Vertical alignment for horizontal text }; diff --git a/VisualizationModules/LibRender/cvfUniform.h b/VisualizationModules/LibRender/cvfUniform.h index 17687287ad..7c7345cf8d 100644 --- a/VisualizationModules/LibRender/cvfUniform.h +++ b/VisualizationModules/LibRender/cvfUniform.h @@ -62,6 +62,7 @@ protected: private: CharArray m_name; + CVF_DISABLE_COPY_AND_ASSIGN(Uniform); }; @@ -85,6 +86,7 @@ public: private: IntArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformInt); }; @@ -120,6 +122,7 @@ public: private: FloatArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformFloat); }; @@ -129,7 +132,7 @@ private: // // //================================================================================================== -class UniformMatrixf: public Uniform +class UniformMatrixf : public Uniform { public: UniformMatrixf(const char* name); @@ -142,6 +145,7 @@ public: private: FloatArray m_data; + CVF_DISABLE_COPY_AND_ASSIGN(UniformMatrixf); }; diff --git a/VisualizationModules/LibViewing/cvfRendering.cpp b/VisualizationModules/LibViewing/cvfRendering.cpp index b29e6cc711..e5664f7397 100644 --- a/VisualizationModules/LibViewing/cvfRendering.cpp +++ b/VisualizationModules/LibViewing/cvfRendering.cpp @@ -308,6 +308,25 @@ void Rendering::renderOverlayItems(OpenGLContext* oglContext, bool useSoftwareRe item->render(oglContext, rect.min(), Vec2ui(static_cast(rect.width()), static_cast(rect.height()))); } } + + for (size_t i = 0; i < m_overlayItems.size(); i++) + { + OverlayItemLayout item = m_overlayItems.at(i); + if ((item.corner == OverlayItem::UNMANAGED) ) + { + Vec2ui size = item.overlayItem->sizeHint(); + Vec2i pos = item.overlayItem->unmanagedPosition(); + + if (useSoftwareRendering) + { + item.overlayItem->renderSoftware(oglContext, pos, size); + } + else + { + item.overlayItem->render(oglContext, pos, size); + } + } + } } @@ -904,6 +923,24 @@ OverlayItem* Rendering::overlayItemFromWindowCoordinates(int x, int y) } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Recti Rendering::overlayItemRect(OverlayItem* item) +{ + OverlayItemRectMap itemRectMap; + calculateOverlayItemLayout(&itemRectMap); + + OverlayItemRectMap::iterator it = itemRectMap.find(item); + if (it != itemRectMap.end()) + { + return it->second; + } + + return cvf::Recti(); +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -963,6 +1000,5 @@ String Rendering::debugString() const return str; } - } // namespace cvf diff --git a/VisualizationModules/LibViewing/cvfRendering.h b/VisualizationModules/LibViewing/cvfRendering.h index 7061de66b8..1875538b80 100644 --- a/VisualizationModules/LibViewing/cvfRendering.h +++ b/VisualizationModules/LibViewing/cvfRendering.h @@ -113,6 +113,7 @@ public: OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction); const OverlayItem* overlayItem(size_t index, OverlayItem::LayoutCorner* corner, OverlayItem::LayoutDirection* direction) const; OverlayItem* overlayItemFromWindowCoordinates(int x, int y); + Recti overlayItemRect(OverlayItem* item); void removeOverlayItem(const OverlayItem* overlayItem); void removeAllOverlayItems(); diff --git a/cafProjectDataModel/cafPdmDocument.cpp b/cafProjectDataModel/cafPdmDocument.cpp index 0e16c8a468..8bc3cac261 100644 --- a/cafProjectDataModel/cafPdmDocument.cpp +++ b/cafProjectDataModel/cafPdmDocument.cpp @@ -40,7 +40,6 @@ PdmObjectGroup::PdmObjectGroup() //-------------------------------------------------------------------------------------------------- PdmObjectGroup::~PdmObjectGroup() { - deleteObjects(); } //-------------------------------------------------------------------------------------------------- @@ -72,6 +71,33 @@ void PdmObjectGroup::addObject(PdmObject * obj) objects.push_back(obj); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectGroup::initAfterReadTraversal(PdmObject* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + PdmObjectGroup::initAfterReadTraversal(children[cIdx]); + } + + object->initAfterRead(); +} + + CAF_PDM_SOURCE_INIT(PdmDocument, "PdmDocument"); @@ -157,29 +183,6 @@ void PdmDocument::writeFile(QIODevice* xmlFile) xmlStream.writeEndDocument(); } -void PdmDocument::initAfterReadTraversal(PdmObject* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::initAfterReadTraversal(children[cIdx]); - if (children[cIdx]) children[cIdx]->initAfterRead(); - } - - object->initAfterRead(); -} void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) { @@ -199,7 +202,6 @@ void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) for (cIdx = 0; cIdx < children.size(); ++cIdx) { PdmDocument::setupBeforeSaveTraversal(children[cIdx]); - if (children[cIdx]) children[cIdx]->setupBeforeSave(); } object->setupBeforeSave(); diff --git a/cafProjectDataModel/cafPdmDocument.h b/cafProjectDataModel/cafPdmDocument.h index 7289c654f8..8c58fe950f 100644 --- a/cafProjectDataModel/cafPdmDocument.h +++ b/cafProjectDataModel/cafPdmDocument.h @@ -44,7 +44,8 @@ public: void removeNullPtrs(); void addObject(PdmObject * obj); - // Needs renaming to objectsByType + static void initAfterReadTraversal(PdmObject * root); + template void objectsByType(std::vector >* typedObjects ) const { @@ -57,6 +58,38 @@ public: } } + template + void createCopyByType(std::vector >* copyOfTypedObjects) const + { + std::vector > sourceTypedObjects; + objectsByType(&sourceTypedObjects); + + QString encodedXml; + { + // Write original objects to XML file + PdmObjectGroup typedObjectGroup; + for (size_t i = 0; i < sourceTypedObjects.size(); i++) + { + typedObjectGroup.addObject(sourceTypedObjects[i]); + } + + QXmlStreamWriter xmlStream(&encodedXml); + xmlStream.setAutoFormatting(true); + + typedObjectGroup.writeFields(xmlStream); + } + + // Read back XML into object group, factory methods will be called that will create new objects + PdmObjectGroup destinationObjectGroup; + QXmlStreamReader xmlStream(encodedXml); + destinationObjectGroup.readFields(xmlStream); + + for (size_t it = 0; it < destinationObjectGroup.objects.size(); it++) + { + T* obj = dynamic_cast(destinationObjectGroup.objects[it]); + if (obj) copyOfTypedObjects->push_back(obj); + } + } }; //================================================================================================== @@ -78,7 +111,6 @@ class PdmDocument: public PdmObjectGroup void writeFile(QIODevice* device); private: - static void initAfterReadTraversal(PdmObject * root); static void setupBeforeSaveTraversal(PdmObject * root); }; diff --git a/cafProjectDataModel/cafPdmField.cpp b/cafProjectDataModel/cafPdmField.cpp index 7a398f8aaa..fb0f118c7b 100644 --- a/cafProjectDataModel/cafPdmField.cpp +++ b/cafProjectDataModel/cafPdmField.cpp @@ -59,13 +59,13 @@ bool PdmFieldHandle::assertValid() const { if (m_keyword == "UNDEFINED") { - std::cout << "Detected use of non-initialized field\n"; + std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n"; return false; } if (!PdmObject::isValidXmlElementName(m_keyword)) { - std::cout << "Detected keyword " << m_keyword.toStdString() << " which is an invalid Xml element name\n"; + std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n"; return false; } @@ -136,18 +136,40 @@ void PdmFieldReader::readFieldData(PdmField & field, QXmlStrea //-------------------------------------------------------------------------------------------------- /// Specialized read operation for Bool`s //-------------------------------------------------------------------------------------------------- -void operator >> (QTextStream& str, bool& value) +QTextStream& operator >> (QTextStream& str, bool& value) { QString text; str >> text; if (text == "True" || text == "true" || text == "1" || text == "Yes" || text == "yes") value = true; else value = false; + + return str; } -void operator << (QTextStream& str, const bool& value) +QTextStream& operator << (QTextStream& str, const bool& value) { if (value) str << "True "; else str << "False "; + + return str; } +//-------------------------------------------------------------------------------------------------- +/// Specialized read operation for QDateTimes`s +//-------------------------------------------------------------------------------------------------- +#include +QTextStream& operator >> (QTextStream& str, QDateTime& value) +{ + QString text; + str >> text; + value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss"); + return str; +} + +QTextStream& operator << (QTextStream& str, const QDateTime& value) +{ + QString text = value.toString("yyyy_MM_dd-HH:mm:ss"); + str << text; + return str; +} diff --git a/cafProjectDataModel/cafPdmField.h b/cafProjectDataModel/cafPdmField.h index 0498119946..7c77f03997 100644 --- a/cafProjectDataModel/cafPdmField.h +++ b/cafProjectDataModel/cafPdmField.h @@ -212,6 +212,7 @@ public: void push_back(DataType* pointer); void set(size_t index, DataType* pointer); void insert(size_t indexAfter, DataType* pointer); + void insert(size_t indexAfter, const std::vector >& objects); void clear(); void erase(size_t index); diff --git a/cafProjectDataModel/cafPdmField.inl b/cafProjectDataModel/cafPdmField.inl index 12c7c9331d..9d8c635f41 100644 --- a/cafProjectDataModel/cafPdmField.inl +++ b/cafProjectDataModel/cafPdmField.inl @@ -19,6 +19,7 @@ #include "cafPdmObject.h" #include +#include #include "cafPdmUiFieldEditorHandle.h" namespace caf @@ -226,26 +227,66 @@ template void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) { PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - if (!xmlStream.isStartElement()) return; // Todo: Error handling - - QString className = xmlStream.name().toString(); - - if (m_fieldValue.isNull()) + if (!xmlStream.isStartElement()) { - m_fieldValue.setRawPtr(caf::PdmObjectFactory::instance()->create(className)); - if (m_fieldValue.notNull()) - { - m_fieldValue.rawPtr()->addParentField(this); - } + return; // This happens when the field is "shortcut" empty (written like: ) } - if (m_fieldValue.isNull()) return; // Warning: Unknown className read + QString className = xmlStream.name().toString(); + PdmObject* obj = NULL; - if (xmlStream.name() != m_fieldValue.rawPtr()->classKeyword()) return; // Error: Field contains different class type than on file + // Create an object if needed + if (m_fieldValue.isNull()) + { + obj = caf::PdmObjectFactory::instance()->create(className); - m_fieldValue.rawPtr()->readFields(xmlStream); + if (obj == NULL) + { + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + return; + } + else + { + if (dynamic_cast(obj) == NULL) + { + assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + m_fieldValue.setRawPtr(obj); + obj->addParentField(this); + } + } + else + { + obj = m_fieldValue.rawPtr(); + } + + if (className != obj->classKeyword()) + { + // Error: Field contains different class type than on file + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + std::cout << " Expected class name: " << obj->classKeyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + // Everything seems ok, so read the contents of the object: + + obj->readFields(xmlStream); + + // Make stream point to endElement of this field - // Make stream point to end of element QXmlStreamReader::TokenType type; type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); @@ -422,6 +463,25 @@ void PdmPointersField::insert(size_t indexAfter, DataType* pointer) if (pointer) pointer->addParentField(this); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmPointersField::insert(size_t indexAfter, const std::vector >& objects) +{ + m_pointers.insert(m_pointers.begin()+indexAfter, objects.begin(), objects.end()); + + typename std::vector< PdmPointer< DataType > >::iterator it; + for (it = m_pointers.begin()+indexAfter; it != m_pointers.end(); ++it) + { + if (!it->isNull()) + { + (*it)->addParentField(this); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -521,8 +581,17 @@ template { // Warning: Unknown className read // Skip to corresponding end element - xmlStream.skipCurrentElement(); + + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; + + // Skip to EndElement of the object + xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + continue; } @@ -530,18 +599,24 @@ template if (currentObject == NULL) { - // Warning: Inconsistency in factory !! Assert ? - // Skip to corresponding end element + assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword + + // Skip to EndElement of the object xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + continue; } currentObject->readFields(xmlStream); this->push_back(currentObject); - // Skip comments and for some reason: Characters. The last bit should not be correct, - // but Qt reports a character token between EndElement and StartElement + // Jump off the end element, and head for next start element (or the final EndElement of the field) + // Qt reports a character token between EndElements and StartElements so skip it QXmlStreamReader::TokenType type; type = xmlStream.readNext(); diff --git a/cafProjectDataModel/cafPdmFieldImpl.h b/cafProjectDataModel/cafPdmFieldImpl.h index 33f04d52c0..ac3bb79c51 100644 --- a/cafProjectDataModel/cafPdmFieldImpl.h +++ b/cafProjectDataModel/cafPdmFieldImpl.h @@ -411,6 +411,24 @@ struct PdmFieldReader > > } // End of namespace caf +//================================================================================================== +/// QTextStream Stream operator overloading for bool`s +/// Prints bool`s as "True"/"False", and reads them too +//================================================================================================== + +QTextStream& operator >> (QTextStream& str, bool& value); +QTextStream& operator << (QTextStream& str, const bool& value); + + +//================================================================================================== +/// QTextStream Stream operator overloading for QDateTimes`s +/// +//================================================================================================== +//class QDateTime; +QTextStream& operator >> (QTextStream& str, QDateTime& value); +QTextStream& operator << (QTextStream& str, const QDateTime& value); + + //================================================================================================== /// QTextStream Stream operator overloading for std::vector of things. /// Makes automated IO of PdmField< std::vector< Whatever > possible as long as @@ -418,17 +436,18 @@ struct PdmFieldReader > > //================================================================================================== template < typename T > -void operator << (QTextStream& str, const std::vector& sobj) +QTextStream& operator << (QTextStream& str, const std::vector& sobj) { size_t i; for (i = 0; i < sobj.size(); ++i) { str << sobj[i] << " "; } + return str; } template < typename T > -void operator >> (QTextStream& str, std::vector& sobj) +QTextStream& operator >> (QTextStream& str, std::vector& sobj) { while (str.status() == QTextStream::Ok ) { @@ -436,13 +455,5 @@ void operator >> (QTextStream& str, std::vector& sobj) str >> d; if (str.status() == QTextStream::Ok ) sobj.push_back(d); } + return str; } - -//================================================================================================== -/// QTextStream Stream operator overloading for bool`s -/// Prints bool`s as "True"/"False", and reads them too -//================================================================================================== - -void operator >> (QTextStream& str, bool& value); -void operator << (QTextStream& str, const bool& value); - diff --git a/cafProjectDataModel/cafPdmObject.cpp b/cafProjectDataModel/cafPdmObject.cpp index 56eff83b56..ed063420cd 100644 --- a/cafProjectDataModel/cafPdmObject.cpp +++ b/cafProjectDataModel/cafPdmObject.cpp @@ -30,36 +30,13 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// Reads all the fields into this PdmObject -/// Assumes xmlStream points to the start element token of the containing object. +/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields. /// ( and not first token of object content) /// This makes attribute based field storage possible. -/// Leaves the xmlStream pointing to the EndElement corresponding to the start element. +/// Leaves the xmlStream pointing to the EndElement of the PdmObject. //-------------------------------------------------------------------------------------------------- void PdmObject::readFields (QXmlStreamReader& xmlStream ) { - if (!xmlStream.isStartElement()) - { - // Error - return ; - } -/* - Attributes will not be used ... - - QXmlStreamAttributes attribs = xmlStream.attributes(); - int i; - for (i = 0; i < attribs.size(); ++i) - { - QString name = attribs[i].name().toString(); - - PdmFieldBase* field = findField(name); - - if (field) - { - //field->readFieldData(attribs[i].value().toString()); - } - } - */ - bool isObjectFinished = false; QXmlStreamReader::TokenType type; while(!isObjectFinished) @@ -71,6 +48,11 @@ void PdmObject::readFields (QXmlStreamReader& xmlStream ) case QXmlStreamReader::StartElement: { QString name = xmlStream.name().toString(); + if (name == QString("SimpleObjPtrField")) + { + int a; + a = 2 + 7; + } PdmFieldHandle* currentField = findField(name); if (currentField) { @@ -99,6 +81,7 @@ void PdmObject::readFields (QXmlStreamReader& xmlStream ) case QXmlStreamReader::EndElement: { // End of object. + QString name = xmlStream.name().toString(); // For debugging isObjectFinished = true; } break; diff --git a/cafProjectDataModel/cafPdmObject.h b/cafProjectDataModel/cafPdmObject.h index 660c4335f4..82861bf202 100644 --- a/cafProjectDataModel/cafPdmObject.h +++ b/cafProjectDataModel/cafPdmObject.h @@ -61,14 +61,16 @@ class PdmUiEditorAttribute; #define CAF_PDM_HEADER_INIT \ public: \ virtual QString classKeyword() { return classKeywordStatic(); } \ - static QString classKeywordStatic() + static QString classKeywordStatic(); \ + static bool Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() /// CAF_PDM_SOURCE_INIT associates the file keyword used for storage with the class and initializes the factory /// Place this in the cpp file, preferably above the constructor #define CAF_PDM_SOURCE_INIT(ClassName, keyword) \ + bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } \ - static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator() + static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator() /// InitObject sets up the user interface related information for the object /// Placed in the constructor of your PdmObject @@ -86,6 +88,8 @@ public: \ #define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \ { \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ addField(field, keyword, default, &objDescr); \ } @@ -94,6 +98,8 @@ public: \ #define CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \ { \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ addFieldNoDefault(field, keyword, &objDescr); \ } @@ -126,6 +132,10 @@ public: /// void parentObjects(std::vector& objects) const; + /// + template + void parentObjectsOfType(std::vector& objects) const; + /// Method to be called from the Ui classes creating Auto Gui to get the group information /// supplied by the \sa defineUiOrdering method that can be reimplemented void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) const; @@ -210,4 +220,24 @@ private: std::set m_pointersReferencingMe; }; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmObject::parentObjectsOfType(std::vector& objects) const +{ + std::vector parents; + this->parentObjects(parents); + + for (size_t i = 0; i < parents.size(); i++) + { + T* objectOfType = dynamic_cast(parents[i]); + if (objectOfType) + { + objects.push_back(objectOfType); + } + } +} + + } // End of namespace caf diff --git a/cafUserInterface/cafUiTreeModelPdm.cpp b/cafUserInterface/cafUiTreeModelPdm.cpp index f9bc0a315e..f1195d9478 100644 --- a/cafUserInterface/cafUiTreeModelPdm.cpp +++ b/cafUserInterface/cafUiTreeModelPdm.cpp @@ -293,9 +293,9 @@ Qt::ItemFlags UiTreeModelPdm::flags(const QModelIndex &index) const } //-------------------------------------------------------------------------------------------------- -/// +/// TO BE DELETED //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent); @@ -311,7 +311,7 @@ bool UiTreeModelPdm::insertRows(int position, int rows, const QModelIndex &paren //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::removeRows(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) +bool UiTreeModelPdm::removeRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/) { if (rows <= 0) return true; @@ -344,7 +344,7 @@ void UiTreeModelPdm::rebuildUiSubTree(PdmObject* root) QModelIndex item = getModelIndexFromPdmObject(root); if (item.isValid()) { - this->removeRows(0, rowCount(item), item); + this->removeRows_special(0, rowCount(item), item); PdmUiTreeItem* treeItem = getTreeItemFromIndex(item); @@ -426,6 +426,7 @@ PdmUiTreeItem* UiTreeItemBuilderPdm::buildViewItems(PdmUiTreeItem* parentTreeIte return NULL; } + // NOTE: if position is -1, the item is appended to the parent tree item PdmUiTreeItem* objectTreeItem = new PdmUiTreeItem(parentTreeItem, position, object); std::vector fields; @@ -445,7 +446,8 @@ PdmUiTreeItem* UiTreeItemBuilderPdm::buildViewItems(PdmUiTreeItem* parentTreeIte caf::PdmObject* childObj = children[i]; assert(childObj); - UiTreeItemBuilderPdm::buildViewItems(objectTreeItem, position, childObj); + // NOTE: -1 as second argument indicates that child objects will be appended to collection + UiTreeItemBuilderPdm::buildViewItems(objectTreeItem, -1, childObj); } } diff --git a/cafUserInterface/cafUiTreeModelPdm.h b/cafUserInterface/cafUiTreeModelPdm.h index 77fcf07bd6..b5f8f7de4e 100644 --- a/cafUserInterface/cafUiTreeModelPdm.h +++ b/cafUserInterface/cafUiTreeModelPdm.h @@ -62,10 +62,12 @@ public: virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - virtual bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + // TO BE DELETED, NOT USED + virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); -private: + virtual bool removeRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); + +protected: QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& root, const PdmObject * object) const; private: diff --git a/cafViewer/cafCadNavigation.cpp b/cafViewer/cafCadNavigation.cpp index 03c0b67cd9..28b4023d91 100644 --- a/cafViewer/cafCadNavigation.cpp +++ b/cafViewer/cafCadNavigation.cpp @@ -83,7 +83,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) } m_trackball->startNavigation(cvf::ManipulatorTrackball::ROTATE, translatedMousePosX, translatedMousePosY); - //m_viewer->setCursor(RICursors::get(RICursors::ROTATE)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); m_isRotating = true; isEventHandled = true; } @@ -98,7 +98,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) if (me->button() == Qt::MidButton) { m_trackball->endNavigation(); - //m_viewer->setCursor(RICursors::get(RICursors::PICK)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::PICK)); m_isRotating = false; isEventHandled = true; } diff --git a/cafViewer/cafCeetronNavigation.cpp b/cafViewer/cafCeetronNavigation.cpp index 4b09a40da2..e4a444ed20 100644 --- a/cafViewer/cafCeetronNavigation.cpp +++ b/cafViewer/cafCeetronNavigation.cpp @@ -237,19 +237,19 @@ void caf::CeetronNavigation::setCursorFromCurrentState() switch (navType) { case ManipulatorTrackball::PAN: - //m_viewer->setCursor(RICursors::get(RICursors::PAN)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::PAN)); return; case ManipulatorTrackball::WALK: - //m_viewer->setCursor(RICursors::get(RICursors::WALK)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::WALK)); return; case ManipulatorTrackball::ROTATE: - //m_viewer->setCursor(RICursors::get(RICursors::ROTATE)); + //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); return; default: break; } - // m_viewer->setCursor(RICursors::get(RICursors::PICK)); + // m_viewer->setCursor(RiuCursors::get(RiuCursors::PICK)); } //-------------------------------------------------------------------------------------------------- diff --git a/cafViewer/cafViewer.cpp b/cafViewer/cafViewer.cpp index 97ac316856..ccc4e257db 100644 --- a/cafViewer/cafViewer.cpp +++ b/cafViewer/cafViewer.cpp @@ -26,6 +26,8 @@ #include "cvfRenderQueueSorter.h" #include "cvfScene.h" #include "cvfModel.h" +#include "cvfTextureImage.h" +#include "cvfOverlayImage.h" #include "cvfqtOpenGLContext.h" @@ -62,7 +64,8 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) m_maxFarPlaneDistance(cvf::UNDEFINED_DOUBLE), m_releaseOGLResourcesEachFrame(false), m_paintCounter(0), - m_navigationPolicyEnabled(true) + m_navigationPolicyEnabled(true), + m_isOverlyPaintingEnabled(true) { m_layoutWidget = parentWidget(); @@ -89,6 +92,11 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent) this->setNavigationPolicy(new caf::CadNavigation); + m_overlayTextureImage = new cvf::TextureImage; + m_overlayImage = new cvf::OverlayImage(m_overlayTextureImage.p()); + m_overlayImage->setBlending(cvf::OverlayImage::TEXTURE_ALPHA); + m_overlayImage->setUnmanagedPosition(cvf::Vec2i(0,0)); + setupMainRendering(); setupRenderingSequence(); @@ -121,6 +129,8 @@ void caf::Viewer::setupMainRendering() { m_mainRendering->renderEngine()->enableForcedImmediateMode(true); } + + updateOverlayImagePresence(); } //-------------------------------------------------------------------------------------------------- @@ -358,6 +368,7 @@ void caf::Viewer::resizeGL(int width, int height) void caf::Viewer::enablePerfInfoHud(bool enable) { m_showPerfInfoHud = enable; + updateOverlayImagePresence(); } @@ -391,6 +402,66 @@ void caf::Viewer::paintEvent(QPaintEvent* event) return; } + // If Qt overlay painting is enabled, paint to an QImage, and set it to the cvf::OverlayImage + + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + // Set up image to draw to, and painter + if (m_overlayPaintingQImage.size() != this->size()) + { + m_overlayPaintingQImage = QImage(this->size(), QImage::Format_ARGB32); + } + + m_overlayPaintingQImage.fill(Qt::transparent); + QPainter overlyPainter(&m_overlayPaintingQImage); + + // Call virtual method to allow subclasses to paint on the OpenGlCanvas + + if (m_isOverlyPaintingEnabled) + { + this->paintOverlayItems(&overlyPainter); + } + + // Draw performance overlay + + if (m_showPerfInfoHud ) + { + cvfqt::PerformanceInfoHud hud; + hud.addStrings(m_renderingSequence->performanceInfo()); + hud.addStrings(*m_mainCamera); + hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); + hud.draw(&overlyPainter, width(), height()); + } + + // Convert the QImage into the cvf::TextureImage, + // handling vertical mirroring and (possible) byteswapping + + if (m_overlayTextureImage->height() != this->height() || m_overlayTextureImage->width() != this->width()) + { + m_overlayTextureImage->allocate(this->width(), this->height()); + } + + int height = m_overlayTextureImage->height(); + int width = m_overlayTextureImage->width(); + +#pragma omp parallel for + for (int y = 0 ; y < height; ++y) + { + int negy = height - 1 - y; + for (int x = 0 ; x < width; ++x) + { + // Should probably do direct conversion on byte level. Would be faster + // QImage.bits() and cvf::TextureImage.ptr() (casting away const) + QRgb qtRgbaVal = m_overlayPaintingQImage.pixel(x, negy); + cvf::Color4ub cvfRgbVal(qRed(qtRgbaVal), qGreen(qtRgbaVal), qBlue(qtRgbaVal), qAlpha(qtRgbaVal)); + m_overlayTextureImage->setPixel(x, y, cvfRgbVal); + } + } + + m_overlayImage->setImage(m_overlayTextureImage.p()); + m_overlayImage->setPixelSize(cvf::Vec2ui(this->width(), this->height())); + } + #if QT_VERSION >= 0x040600 // Qt 4.6 painter.beginNativePainting(); @@ -417,17 +488,7 @@ void caf::Viewer::paintEvent(QPaintEvent* event) painter.endNativePainting(); #endif - // Call virtual method to allow subclasses to paint on the OpenGlCanvas - this->paintOverlayItems(&painter); - - if (m_showPerfInfoHud && isShadersSupported()) - { - cvfqt::PerformanceInfoHud hud; - hud.addStrings(m_renderingSequence->performanceInfo()); - hud.addStrings(*m_mainCamera); - hud.addString(QString("PaintCount: %1").arg(m_paintCounter++)); - hud.draw(&painter, width(), height()); - } + } //-------------------------------------------------------------------------------------------------- @@ -696,3 +757,35 @@ int caf::Viewer::currentFrameIndex() else return 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool caf::Viewer::isOverlyPaintingEnabled() const +{ + return m_isOverlyPaintingEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::enableOverlyPainting(bool val) +{ + m_isOverlyPaintingEnabled = val; + updateOverlayImagePresence(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::updateOverlayImagePresence() +{ + if (m_isOverlyPaintingEnabled || m_showPerfInfoHud) + { + m_mainRendering->addOverlayItem(m_overlayImage.p(), cvf::OverlayItem::UNMANAGED, cvf::OverlayItem::VERTICAL); + } + else + { + m_mainRendering->removeOverlayItem(m_overlayImage.p()); + } +} + diff --git a/cafViewer/cafViewer.h b/cafViewer/cafViewer.h index d3708ba00c..e9ad4bf13e 100644 --- a/cafViewer/cafViewer.h +++ b/cafViewer/cafViewer.h @@ -26,9 +26,6 @@ #include "cvfVector3.h" #include "cvfOpenGL.h" - -//#include "cvfManipulatorTrackball.h" - #include "cafOpenGLWidget.h" @@ -39,6 +36,8 @@ namespace cvf { class RenderSequence; class OverlayScalarMapperLegend; class HitItemCollection; + class OverlayImage; + class TextureImage; } namespace caf { @@ -100,6 +99,11 @@ public: bool rayPick(int winPosX, int winPosY, cvf::HitItemCollection* pickedPoints) ; + // QPainter based drawing on top of the OpenGL graphics + + bool isOverlyPaintingEnabled() const; + void enableOverlyPainting(bool val); + // Performance information for debugging etc. void enablePerfInfoHud(bool enable); bool isPerfInfoHudEnabled(); @@ -131,10 +135,9 @@ protected: virtual void paintEvent(QPaintEvent* event); // Support the navigation policy concept - virtual bool event( QEvent* e ); - cvf::ref - m_navigationPolicy; - bool m_navigationPolicyEnabled; + virtual bool event( QEvent* e ); + cvf::ref m_navigationPolicy; + bool m_navigationPolicyEnabled; // Actual rendering objects cvf::ref m_renderingSequence; @@ -142,31 +145,35 @@ protected: cvf::ref m_mainCamera; cvf::ref m_mainRendering; - double m_minNearPlaneDistance; - double m_maxFarPlaneDistance; + double m_minNearPlaneDistance; + double m_maxFarPlaneDistance; private: - void updateCamera(int width, int height); + void updateCamera(int width, int height); - void releaseOGlResourcesForCurrentFrame(); - void debugShowRenderingSequencePartNames(); + void releaseOGlResourcesForCurrentFrame(); + void debugShowRenderingSequencePartNames(); - bool m_showPerfInfoHud; - size_t m_paintCounter; - bool m_releaseOGLResourcesEachFrame; - QPointer m_layoutWidget; + bool m_showPerfInfoHud; + size_t m_paintCounter; + bool m_releaseOGLResourcesEachFrame; + QPointer m_layoutWidget; + bool m_isOverlyPaintingEnabled; + cvf::ref m_overlayTextureImage; + cvf::ref m_overlayImage; + QImage m_overlayPaintingQImage; + void updateOverlayImagePresence(); // System to make sure we share OpenGL resources - static Viewer* sharedWidget(); - static cvf::OpenGLContextGroup* contextGroup(); - static std::list - sm_viewers; + static Viewer* sharedWidget(); + static cvf::OpenGLContextGroup* contextGroup(); + static std::list sm_viewers; static cvf::ref - sm_openGLContextGroup; + sm_openGLContextGroup; - caf::FrameAnimationControl* m_animationControl; - cvf::Collection m_frameScenes; + caf::FrameAnimationControl* m_animationControl; + cvf::Collection m_frameScenes; }; } // End namespace caf